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
f0136375
Commit
f0136375
authored
Nov 17, 2016
by
Craig Heffner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added D-Link ROMFSv9.0 extractor
parent
a912500a
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
226 additions
and
0 deletions
+226
-0
extract.conf
src/binwalk/config/extract.conf
+1
-0
dlromfsextract.py
src/binwalk/plugins/dlromfsextract.py
+225
-0
No files found.
src/binwalk/config/extract.conf
View file @
f0136375
...
...
@@ -15,6 +15,7 @@
# o cpio
# o Raw LZMA/deflate streams
# o Hilink encrypted uImage firmware
# o D-Link "ROMFSv9.0" file systems
#
# There are also alternative extractors for the following file formats, implemented as plugins:
#
...
...
src/binwalk/plugins/dlromfsextract.py
0 → 100644
View file @
f0136375
import
os
import
struct
import
binwalk.core.plugin
import
binwalk.core.common
try
:
import
lzma
except
ImportError
as
e
:
pass
class
RomFSCommon
(
object
):
def
_read_next_word
(
self
):
value
=
struct
.
unpack
(
"
%
sL"
%
self
.
endianess
,
self
.
data
[
self
.
index
:
self
.
index
+
4
])[
0
]
self
.
index
+=
4
return
value
def
_read_next_uid
(
self
):
uid
=
int
(
self
.
data
[
self
.
index
:
self
.
index
+
4
])
self
.
index
+=
4
return
uid
def
_read_next_block
(
self
,
size
):
size
=
int
(
size
)
data
=
self
.
data
[
self
.
index
:
self
.
index
+
size
]
self
.
index
+=
size
return
data
def
_read_next_string
(
self
):
data
=
""
while
True
:
byte
=
self
.
data
[
self
.
index
]
try
:
byte
=
chr
(
byte
)
except
TypeError
as
e
:
pass
if
byte
==
"
\x00
"
:
break
else
:
data
+=
byte
self
.
index
+=
1
return
data
class
RomFSEntry
(
RomFSCommon
):
DIR_STRUCT_MASK
=
0x00000001
DATA_MASK
=
0x00000008
COMPRESSED_MASK
=
0x005B0000
def
__init__
(
self
,
data
,
endianess
=
"<"
):
self
.
data
=
data
self
.
endianess
=
endianess
self
.
index
=
0
self
.
type
=
self
.
_read_next_word
()
self
.
unknown2
=
self
.
_read_next_word
()
self
.
unknown3
=
self
.
_read_next_word
()
self
.
size
=
self
.
_read_next_word
()
self
.
unknown4
=
self
.
_read_next_word
()
self
.
offset
=
self
.
_read_next_word
()
self
.
unknown5
=
self
.
_read_next_word
()
self
.
uid
=
self
.
_read_next_uid
()
class
RomFSDirStruct
(
RomFSCommon
):
SIZE
=
0x20
def
__init__
(
self
,
data
,
endianess
=
"<"
):
self
.
index
=
0
self
.
data
=
data
self
.
endianess
=
endianess
self
.
directory
=
False
self
.
uid
=
None
self
.
ls
=
[]
for
(
uid
,
entry
)
in
self
.
next
():
if
self
.
uid
is
None
:
self
.
uid
=
uid
if
entry
in
[
'.'
,
'..'
]:
self
.
directory
=
True
continue
self
.
ls
.
append
((
uid
,
entry
))
def
next
(
self
):
while
self
.
index
<
len
(
self
.
data
):
uid
=
self
.
_read_next_word
()
dont_care
=
self
.
_read_next_word
()
entry
=
self
.
_read_next_string
()
total_size
=
int
(
4
+
4
+
len
(
entry
))
count
=
int
(
total_size
/
self
.
SIZE
)
if
count
==
0
:
mod
=
self
.
SIZE
-
total_size
else
:
mod
=
self
.
SIZE
-
int
(
total_size
-
(
count
*
self
.
SIZE
))
if
mod
>
0
:
remainder
=
self
.
_read_next_block
(
mod
)
yield
(
uid
,
entry
)
class
FileContainer
(
object
):
def
__init__
(
self
):
pass
class
RomFS
(
object
):
SUPERBLOCK_SIZE
=
0x20
FILE_ENTRY_SIZE
=
0x20
def
__init__
(
self
,
fname
,
endianess
=
"<"
):
self
.
endianess
=
endianess
self
.
data
=
open
(
fname
,
"rb"
)
.
read
()
self
.
entries
=
self
.
_process_all_entries
()
def
get_data
(
self
,
uid
):
start
=
self
.
entries
[
uid
]
.
offset
end
=
start
+
self
.
entries
[
uid
]
.
size
data
=
self
.
data
[
start
:
end
]
try
:
data
=
lzma
.
decompress
(
data
)
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
as
e
:
pass
return
data
def
build_path
(
self
,
uid
):
path
=
self
.
entries
[
uid
]
.
name
while
uid
!=
0
:
uid
=
self
.
entries
[
uid
]
.
parent
path
=
os
.
path
.
join
(
self
.
entries
[
uid
]
.
name
,
path
)
return
path
.
replace
(
".."
,
""
)
def
_process_all_entries
(
self
):
entries
=
{}
offset
=
self
.
SUPERBLOCK_SIZE
while
True
:
try
:
entry
=
RomFSEntry
(
self
.
data
[
offset
:
offset
+
self
.
FILE_ENTRY_SIZE
],
endianess
=
self
.
endianess
)
except
ValueError
as
e
:
break
if
not
entry
.
uid
in
entries
:
entries
[
entry
.
uid
]
=
FileContainer
()
entries
[
entry
.
uid
]
.
offset
=
entry
.
offset
entries
[
entry
.
uid
]
.
size
=
entry
.
size
entries
[
entry
.
uid
]
.
type
=
entry
.
type
if
entry
.
uid
==
0
:
entries
[
entry
.
uid
]
.
name
=
os
.
path
.
sep
if
entry
.
type
&
entry
.
DIR_STRUCT_MASK
:
entries
[
entry
.
uid
]
.
type
=
"directory"
ds
=
RomFSDirStruct
(
self
.
data
[
entry
.
offset
:
entry
.
offset
+
entry
.
size
],
endianess
=
self
.
endianess
)
for
(
uid
,
name
)
in
ds
.
ls
:
if
not
uid
in
entries
:
entries
[
uid
]
=
FileContainer
()
entries
[
uid
]
.
parent
=
ds
.
uid
entries
[
uid
]
.
name
=
name
else
:
entries
[
entry
.
uid
]
.
type
=
"data"
offset
+=
self
.
FILE_ENTRY_SIZE
return
entries
if
__name__
==
'__main__'
:
import
sys
try
:
infile
=
sys
.
argv
[
1
]
outdir
=
sys
.
argv
[
2
]
except
IndexError
as
e
:
print
(
"Usage:
%
s <input file> <output directory>"
%
sys
.
argv
[
0
])
sys
.
exit
(
1
)
class
DlinkROMFSExtractPlugin
(
binwalk
.
core
.
plugin
.
Plugin
):
'''
Gzip extractor plugin.
'''
MODULES
=
[
'Signature'
]
BLOCK_SIZE
=
10
*
1024
def
init
(
self
):
# If the extractor is enabled for the module we're currently loaded
# into, then register self.extractor as a D-Link ROMFS file system extraction rule.
if
self
.
module
.
extractor
.
enabled
:
self
.
module
.
extractor
.
add_rule
(
txtrule
=
None
,
regex
=
"^d-link romfs filesystem"
,
extension
=
"romfs"
,
recurse
=
False
,
cmd
=
self
.
extractor
)
def
extractor
(
self
,
fname
):
infile
=
os
.
path
.
abspath
(
fname
)
outdir
=
os
.
path
.
join
(
os
.
path
.
dirname
(
infile
),
"romfs-root"
)
outdir
=
binwalk
.
core
.
common
.
unique_file_name
(
outdir
)
# TODO: Support big endian targets.
fs
=
RomFS
(
infile
)
os
.
mkdir
(
outdir
)
for
(
uid
,
info
)
in
fs
.
entries
.
items
():
if
hasattr
(
info
,
'name'
)
and
hasattr
(
info
,
'parent'
):
path
=
fs
.
build_path
(
uid
)
.
strip
(
os
.
path
.
sep
)
fname
=
os
.
path
.
join
(
outdir
,
path
)
if
info
.
type
==
"directory"
and
not
os
.
path
.
exists
(
fname
):
os
.
makedirs
(
fname
)
else
:
fdata
=
fs
.
get_data
(
uid
)
with
open
(
fname
,
'wb'
)
as
fp
:
fp
.
write
(
fdata
)
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