Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
binwalk
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fact-gitdep
binwalk
Commits
fd3c32d5
Commit
fd3c32d5
authored
Sep 22, 2017
by
devttys0
Committed by
GitHub
Sep 22, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #267 from boblivion/pfsextraction
Added PFS/0.9 extraction support
parents
40ae0ae4
06c20533
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
115 additions
and
0 deletions
+115
-0
unpfs.py
src/binwalk/plugins/unpfs.py
+115
-0
No files found.
src/binwalk/plugins/unpfs.py
0 → 100644
View file @
fd3c32d5
import
os
import
errno
import
struct
import
binwalk.core.plugin
import
binwalk.core.compat
from
binwalk.core.common
import
BlockFile
as
open
class
PFSCommon
(
object
):
def
_make_short
(
self
,
data
,
endianess
):
"""Returns a 2 byte integer."""
data
=
binwalk
.
core
.
compat
.
str2bytes
(
data
)
return
struct
.
unpack
(
'
%
sH'
%
endianess
,
data
)[
0
]
def
_make_int
(
self
,
data
,
endianess
):
"""Returns a 4 byte integer."""
data
=
binwalk
.
core
.
compat
.
str2bytes
(
data
)
return
struct
.
unpack
(
'
%
sI'
%
endianess
,
data
)[
0
]
class
PFS
(
PFSCommon
):
"""Class for accessing PFS meta-data."""
HEADER_SIZE
=
16
def
__init__
(
self
,
fname
,
endianess
=
'<'
):
self
.
endianess
=
endianess
self
.
meta
=
open
(
fname
,
'rb'
)
header
=
self
.
meta
.
read
(
self
.
HEADER_SIZE
)
self
.
file_list_start
=
self
.
meta
.
tell
()
self
.
num_files
=
self
.
_make_short
(
header
[
-
2
:],
endianess
)
self
.
node_size
=
self
.
_get_fname_len
()
+
12
def
_get_fname_len
(
self
,
bufflen
=
128
):
"""Returns the number of bytes designated for the filename."""
buff
=
self
.
meta
.
peek
(
bufflen
)
strlen
=
buff
.
find
(
'
\0
'
)
for
i
,
b
in
enumerate
(
buff
[
strlen
:]):
if
b
!=
'
\0
'
:
return
strlen
+
i
return
bufflen
def
_get_node
(
self
):
"""Reads a chunk of meta data from file and returns a PFSNode."""
data
=
self
.
meta
.
read
(
self
.
node_size
)
return
PFSNode
(
data
,
self
.
endianess
)
def
get_end_of_meta_data
(
self
):
"""Returns integer indicating the end of the file system meta data."""
return
self
.
HEADER_SIZE
+
self
.
node_size
*
self
.
num_files
def
entries
(
self
):
"""Returns file meta-data entries one by one."""
self
.
meta
.
seek
(
self
.
file_list_start
)
for
i
in
range
(
0
,
self
.
num_files
):
yield
self
.
_get_node
()
def
__enter__
(
self
):
return
self
def
__exit__
(
self
,
type
,
value
,
traceback
):
self
.
meta
.
close
()
class
PFSNode
(
PFSCommon
):
"""A node in the PFS Filesystem containing meta-data about a single file."""
def
__init__
(
self
,
data
,
endianess
):
self
.
fname
,
data
=
data
[:
-
12
],
data
[
-
12
:]
self
.
_decode_fname
()
self
.
inode_no
=
self
.
_make_int
(
data
[:
4
],
endianess
)
self
.
foffset
=
self
.
_make_int
(
data
[
4
:
8
],
endianess
)
self
.
fsize
=
self
.
_make_int
(
data
[
8
:],
endianess
)
def
_decode_fname
(
self
):
"""Extracts the actual string from the available bytes."""
self
.
fname
=
self
.
fname
[:
self
.
fname
.
find
(
'
\0
'
)]
self
.
fname
=
self
.
fname
.
replace
(
'
\\
'
,
'/'
)
class
PFSExtractor
(
binwalk
.
core
.
plugin
.
Plugin
):
"""
Extractor for known PFS/0.9 File System Formats.
"""
MODULES
=
[
'Signature'
]
def
init
(
self
):
if
self
.
module
.
extractor
.
enabled
:
self
.
module
.
extractor
.
add_rule
(
regex
=
'^pfs filesystem'
,
extension
=
'pfs'
,
cmd
=
self
.
extractor
)
def
_create_dir_from_fname
(
self
,
fname
):
try
:
os
.
makedirs
(
os
.
path
.
dirname
(
fname
))
except
OSError
as
e
:
if
e
.
errno
!=
errno
.
EEXIST
:
raise
e
def
extractor
(
self
,
fname
):
fname
=
os
.
path
.
abspath
(
fname
)
try
:
with
PFS
(
fname
)
as
fs
:
# The end of PFS meta data is the start of the actual data
data
=
open
(
fname
,
'rb'
)
data
.
seek
(
fs
.
get_end_of_meta_data
())
for
entry
in
fs
.
entries
():
self
.
_create_dir_from_fname
(
entry
.
fname
)
outfile
=
open
(
entry
.
fname
,
'wb'
)
outfile
.
write
(
data
.
read
(
entry
.
fsize
))
outfile
.
close
()
data
.
close
()
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
as
e
:
return
False
return
True
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment