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
9258050b
Commit
9258050b
authored
Jan 08, 2014
by
devttys0
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated setup
parent
ef96a6fd
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
372 additions
and
357 deletions
+372
-357
setup.py
setup.py
+128
-113
hexdiff.py
src/binwalk/modules/hexdiff.py
+244
-244
No files found.
setup.py
View file @
9258050b
...
...
@@ -11,153 +11,168 @@ MODULE_NAME = "binwalk"
# Python2/3 compliance
try
:
raw_input
raw_input
except
NameError
:
raw_input
=
input
raw_input
=
input
# This is super hacky.
if
"--yes"
in
sys
.
argv
:
sys
.
argv
.
pop
(
sys
.
argv
.
index
(
"--yes"
))
IGNORE_WARNINGS
=
True
sys
.
argv
.
pop
(
sys
.
argv
.
index
(
"--yes"
))
IGNORE_WARNINGS
=
True
else
:
IGNORE_WARNINGS
=
False
IGNORE_WARNINGS
=
False
# cd into the src directory, no matter where setup.py was invoked from
os
.
chdir
(
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)),
"src"
))
def
which
(
command
):
# /usr/local/bin is usually the default install path, though it may not be in $PATH
usr_local_bin
=
os
.
path
.
sep
.
join
([
os
.
path
.
sep
,
'usr'
,
'local'
,
'bin'
,
command
])
# /usr/local/bin is usually the default install path, though it may not be in $PATH
usr_local_bin
=
os
.
path
.
sep
.
join
([
os
.
path
.
sep
,
'usr'
,
'local'
,
'bin'
,
command
])
try
:
location
=
subprocess
.
Popen
([
"which"
,
command
],
shell
=
False
,
stdout
=
subprocess
.
PIPE
)
.
communicate
()[
0
]
.
strip
()
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
as
e
:
pass
try
:
location
=
subprocess
.
Popen
([
"which"
,
command
],
shell
=
False
,
stdout
=
subprocess
.
PIPE
)
.
communicate
()[
0
]
.
strip
()
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
as
e
:
pass
if
not
location
and
os
.
path
.
exists
(
usr_local_bin
):
location
=
usr_local_bin
if
not
location
and
os
.
path
.
exists
(
usr_local_bin
):
location
=
usr_local_bin
return
location
return
location
def
warning
(
lines
,
terminate
=
True
,
prompt
=
True
):
WIDTH
=
115
WIDTH
=
115
if
not
IGNORE_WARNINGS
:
print
(
"
\n
"
+
"*"
*
WIDTH
)
for
line
in
lines
:
print
(
line
)
print
(
"*"
*
WIDTH
,
"
\n
"
)
if
prompt
:
if
raw_input
(
'Continue installation anyway (Y/n)? '
)
.
lower
()
.
startswith
(
'n'
):
terminate
=
True
else
:
terminate
=
False
if
terminate
:
sys
.
exit
(
1
)
def
find_binwalk_module_paths
():
paths
=
[]
try
:
import
binwalk
paths
=
binwalk
.
__path__
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
:
pass
return
paths
def
remove_binwalk_module
():
for
path
in
find_binwalk_module_paths
():
try
:
remove_tree
(
path
)
except
OSError
as
e
:
pass
script_path
=
which
(
MODULE_NAME
)
if
script_path
:
try
:
print
(
"removing '
%
s'"
%
script_path
)
os
.
unlink
(
script_path
)
except
KeyboardInterrupt
as
e
:
pass
except
Exception
as
e
:
pass
if
not
IGNORE_WARNINGS
:
print
(
"
\n
"
+
"*"
*
WIDTH
)
for
line
in
lines
:
print
(
line
)
print
(
"*"
*
WIDTH
,
"
\n
"
)
class
UninstallCommand
(
Command
):
description
=
"Uninstalls the Python module"
user_options
=
[]
if
prompt
:
if
raw_input
(
'Continue installation anyway (Y/n)? '
)
.
lower
()
.
startswith
(
'n'
):
terminate
=
True
else
:
terminate
=
False
def
initialize_options
(
self
):
pass
if
terminate
:
sys
.
exit
(
1
)
def
finalize_options
(
self
)
:
pass
class
UninstallCommand
(
Command
):
description
=
"Uninstalls the Python module"
user_options
=
[]
def
initialize_options
(
self
):
pass
def
finalize_options
(
self
):
pass
def
run
(
self
):
try
:
import
binwalk
for
path
in
binwalk
.
__path__
:
try
:
remove_tree
(
path
)
except
OSError
as
e
:
pass
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
as
e
:
pass
script_path
=
which
(
MODULE_NAME
)
if
script_path
:
try
:
print
(
"removing '
%
s'"
%
script_path
)
os
.
unlink
(
script_path
)
except
KeyboardInterrupt
as
e
:
pass
except
Exception
as
e
:
pass
def
run
(
self
):
remove_binwalk_module
()
class
CleanCommand
(
Command
):
description
=
"Clean Python build directories"
user_options
=
[]
def
initialize_options
(
self
):
pass
def
finalize_options
(
self
):
pass
def
run
(
self
):
try
:
remove_tree
(
"build"
)
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
:
pass
try
:
remove_tree
(
"dist"
)
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
:
pass
description
=
"Clean Python build directories"
user_options
=
[]
def
initialize_options
(
self
):
pass
def
finalize_options
(
self
):
pass
def
run
(
self
):
try
:
remove_tree
(
"build"
)
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
:
pass
try
:
remove_tree
(
"dist"
)
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
:
pass
# Check pre-requisite Python modules during an install
if
"install"
in
sys
.
argv
:
print
(
"checking pre-requisites"
)
try
:
import
pyqtgraph
from
pyqtgraph.Qt
import
QtCore
,
QtGui
,
QtOpenGL
except
ImportError
as
e
:
msg
=
[
"Pre-requisite warning: "
+
str
(
e
),
"To take advantage of
%
s's graphing capabilities, please install this module."
%
MODULE_NAME
,
]
warning
(
msg
,
prompt
=
True
)
print
(
"checking pre-requisites"
)
try
:
import
pyqtgraph
from
pyqtgraph.Qt
import
QtCore
,
QtGui
,
QtOpenGL
except
ImportError
as
e
:
msg
=
[
"Pre-requisite warning: "
+
str
(
e
),
"To take advantage of
%
s's graphing capabilities, please install this module."
%
MODULE_NAME
,
]
warning
(
msg
,
prompt
=
True
)
# If an older version of binwalk is currently installed, completely remove it to prevent conflicts
existing_binwalk_modules
=
find_binwalk_module_paths
()
if
existing_binwalk_modules
and
not
os
.
path
.
exists
(
os
.
path
.
join
(
existing_binwalk_modules
[
0
],
"core"
)):
remove_binwalk_module
()
# Re-build the magic file during a build/install
if
"install"
in
sys
.
argv
or
"build"
in
sys
.
argv
:
# Generate a new magic file from the files in the magic directory
print
(
"creating
%
s magic file"
%
MODULE_NAME
)
magic_files
=
os
.
listdir
(
"magic"
)
magic_files
.
sort
()
fd
=
open
(
"
%
s/magic/
%
s"
%
(
MODULE_NAME
,
MODULE_NAME
),
"wb"
)
for
magic
in
magic_files
:
fpath
=
os
.
path
.
join
(
"magic"
,
magic
)
if
os
.
path
.
isfile
(
fpath
):
fd
.
write
(
open
(
fpath
,
"rb"
)
.
read
())
fd
.
close
()
# Generate a new magic file from the files in the magic directory
print
(
"creating
%
s magic file"
%
MODULE_NAME
)
magic_files
=
os
.
listdir
(
"magic"
)
magic_files
.
sort
()
fd
=
open
(
"
%
s/magic/
%
s"
%
(
MODULE_NAME
,
MODULE_NAME
),
"wb"
)
for
magic
in
magic_files
:
fpath
=
os
.
path
.
join
(
"magic"
,
magic
)
if
os
.
path
.
isfile
(
fpath
):
fd
.
write
(
open
(
fpath
,
"rb"
)
.
read
())
fd
.
close
()
# The data files to install along with the module
install_data_files
=
[
"magic/*"
,
"config/*"
,
"plugins/*"
,
"modules/*"
,
"core/*"
]
# Install the module, script, and support files
setup
(
name
=
MODULE_NAME
,
version
=
"2.0.0 beta"
,
description
=
"Firmware analysis tool"
,
author
=
"Craig Heffner"
,
url
=
"https://github.com/devttys0/
%
s"
%
MODULE_NAME
,
version
=
"2.0.0 beta"
,
description
=
"Firmware analysis tool"
,
author
=
"Craig Heffner"
,
url
=
"https://github.com/devttys0/
%
s"
%
MODULE_NAME
,
requires
=
[
"magic"
,
"pyqtgraph"
],
packages
=
[
MODULE_NAME
],
package_data
=
{
MODULE_NAME
:
install_data_files
},
scripts
=
[
os
.
path
.
join
(
"scripts"
,
MODULE_NAME
)],
requires
=
[
"magic"
,
"pyqtgraph"
],
packages
=
[
MODULE_NAME
],
package_data
=
{
MODULE_NAME
:
install_data_files
},
scripts
=
[
os
.
path
.
join
(
"scripts"
,
MODULE_NAME
)],
cmdclass
=
{
'clean'
:
CleanCommand
,
'uninstall'
:
UninstallCommand
}
cmdclass
=
{
'clean'
:
CleanCommand
,
'uninstall'
:
UninstallCommand
}
)
src/binwalk/modules/hexdiff.py
View file @
9258050b
...
...
@@ -9,248 +9,248 @@ from binwalk.core.module import Module, Option, Kwarg
# TODO: This code is an effing mess.
class
HexDiff
(
Module
):
ALL_SAME
=
0
ALL_DIFF
=
1
SOME_DIFF
=
2
DEFAULT_DIFF_SIZE
=
0x100
DEFAULT_BLOCK_SIZE
=
16
COLORS
=
{
'red'
:
'31'
,
'green'
:
'32'
,
'blue'
:
'34'
,
}
TITLE
=
"Binary Diffing"
CLI
=
[
Option
(
short
=
'W'
,
long
=
'hexdump'
,
kwargs
=
{
'enabled'
:
True
},
description
=
'Perform a hexdump / diff of a file or files'
),
Option
(
short
=
'G'
,
long
=
'green'
,
kwargs
=
{
'show_green'
:
True
,
'show_blue'
:
False
,
'show_red'
:
False
},
description
=
'Only show lines containing bytes that are the same among all files'
),
Option
(
short
=
'i'
,
long
=
'red'
,
kwargs
=
{
'show_red'
:
True
,
'show_blue'
:
False
,
'show_green'
:
False
},
description
=
'Only show lines containing bytes that are different among all files'
),
Option
(
short
=
'U'
,
long
=
'blue'
,
kwargs
=
{
'show_blue'
:
True
,
'show_red'
:
False
,
'show_green'
:
False
},
description
=
'Only show lines containing bytes that are different among some files'
),
Option
(
short
=
'w'
,
long
=
'terse'
,
kwargs
=
{
'terse'
:
True
},
description
=
'Diff all files, but only display a hex dump of the first file'
),
]
KWARGS
=
[
Kwarg
(
name
=
'show_red'
,
default
=
True
),
Kwarg
(
name
=
'show_blue'
,
default
=
True
),
Kwarg
(
name
=
'show_green'
,
default
=
True
),
Kwarg
(
name
=
'terse'
,
default
=
False
),
Kwarg
(
name
=
'enabled'
,
default
=
False
),
]
HEADER_FORMAT
=
"
\n
%
s
\n
"
RESULT_FORMAT
=
"
%
s
\n
"
RESULT
=
[
'description'
]
def
_no_colorize
(
self
,
c
,
color
=
"red"
,
bold
=
True
):
return
c
def
_colorize
(
self
,
c
,
color
=
"red"
,
bold
=
True
):
attr
=
[]
attr
.
append
(
self
.
COLORS
[
color
])
if
bold
:
attr
.
append
(
'1'
)
return
"
\x1b
[
%
sm
%
s
\x1b
[0m"
%
(
';'
.
join
(
attr
),
c
)
def
_color_filter
(
self
,
data
):
red
=
'
\x1b
['
+
self
.
COLORS
[
'red'
]
+
';'
green
=
'
\x1b
['
+
self
.
COLORS
[
'green'
]
+
';'
blue
=
'
\x1b
['
+
self
.
COLORS
[
'blue'
]
+
';'
if
self
.
show_blue
and
blue
in
data
:
return
True
if
self
.
show_green
and
green
in
data
:
return
True
if
self
.
show_red
and
red
in
data
:
return
True
return
False
def
_print_block_hex
(
self
,
alt_text
=
"*"
):
if
self
.
_color_filter
(
self
.
block_hex
):
desc
=
self
.
block_hex
self
.
printed_alt_text
=
False
elif
not
self
.
printed_alt_text
:
desc
=
"
%
s"
%
alt_text
self
.
printed_alt_text
=
True
self
.
result
(
description
=
desc
)
self
.
block_hex
=
""
return
True
def
_build_block
(
self
,
c
,
highlight
=
None
):
if
highlight
==
self
.
ALL_DIFF
:
self
.
block_hex
+=
self
.
colorize
(
c
,
color
=
"red"
)
elif
highlight
==
self
.
ALL_SAME
:
self
.
block_hex
+=
self
.
colorize
(
c
,
color
=
"green"
)
elif
highlight
==
self
.
SOME_DIFF
:
self
.
block_hex
+=
self
.
colorize
(
c
,
color
=
"blue"
)
else
:
self
.
block_hex
+=
c
def
_build_header
(
self
,
files
,
block_size
):
header
=
"OFFSET"
+
(
" "
*
6
)
+
files
[
0
]
.
name
for
i
in
range
(
1
,
len
(
files
)):
header
+=
" "
*
((
block_size
*
3
)
+
2
+
block_size
+
8
-
len
(
files
[
i
-
1
]
.
name
))
header
+=
files
[
i
]
.
name
return
header
def
init
(
self
):
block
=
self
.
config
.
block
if
not
block
:
block
=
self
.
DEFAULT_BLOCK_SIZE
if
self
.
terse
:
header_files
=
self
.
config
.
target_files
[:
1
]
else
:
header_files
=
self
.
config
.
target_files
self
.
HEADER
=
self
.
_build_header
(
header_files
,
block
)
if
hasattr
(
sys
.
stderr
,
'isatty'
)
and
sys
.
stderr
.
isatty
()
and
platform
.
system
()
!=
'Windows'
:
curses
.
setupterm
()
self
.
colorize
=
self
.
_colorize
else
:
self
.
colorize
=
self
.
_no_colorize
def
run
(
self
):
i
=
0
total
=
0
data
=
{}
delim
=
'/'
self
.
block_hex
=
""
self
.
printed_alt_text
=
False
offset
=
self
.
config
.
offset
size
=
self
.
config
.
length
block
=
self
.
config
.
block
self
.
header
()
if
not
block
:
block
=
self
.
DEFAULT_BLOCK_SIZE
# If negative offset, then we're going that far back from the end of the file
if
offset
<
0
:
size
=
offset
*
-
1
#if common.BlockFile.READ_BLOCK_SIZE < block:
#
read_block_size = block
#else:
#
read_block_size = common.BlockFile.READ_BLOCK_SIZE
read_block_size
=
common
.
BlockFile
.
DEFAULT_BLOCK_READ_SIZE
# BlockFile handles calculation of negative offsets, if one was specified
offset
=
self
.
config
.
target_files
[
0
]
.
offset
size
=
self
.
config
.
target_files
[
0
]
.
length
while
total
<
size
:
i
=
0
files_finished
=
0
for
fp
in
self
.
config
.
target_files
:
(
ddata
,
dlen
)
=
fp
.
read_block
()
data
[
fp
.
name
]
=
ddata
if
not
ddata
or
dlen
==
0
:
files_finished
+=
1
if
files_finished
==
len
(
self
.
config
.
target_files
):
break
while
i
<
read_block_size
and
(
total
+
i
)
<
size
:
diff_same
=
{}
alt_text
=
"*"
+
" "
*
8
self
.
_build_block
(
"
%.08
X "
%
(
total
+
i
+
offset
))
# For each byte in this block, is the byte the same in all files, the same in some files, or different in all files?
for
j
in
range
(
0
,
block
):
byte_list
=
[]
try
:
c
=
data
[
self
.
config
.
target_files
[
0
]
.
name
][
j
+
i
]
except
:
c
=
None
for
f
in
self
.
config
.
target_files
:
try
:
c
=
data
[
f
.
name
][
j
+
i
]
except
Exception
as
e
:
c
=
None
if
c
not
in
byte_list
:
byte_list
.
append
(
c
)
if
len
(
byte_list
)
==
1
:
diff_same
[
j
]
=
self
.
ALL_SAME
elif
len
(
byte_list
)
==
len
(
self
.
config
.
target_files
):
diff_same
[
j
]
=
self
.
ALL_DIFF
else
:
diff_same
[
j
]
=
self
.
SOME_DIFF
for
index
in
range
(
0
,
len
(
self
.
config
.
target_files
)):
if
self
.
terse
and
index
>
0
:
break
f
=
self
.
config
.
target_files
[
index
]
alt_text
+=
" "
*
(
3
+
(
3
*
block
)
+
3
+
block
+
3
)
alt_text
+=
delim
for
j
in
range
(
0
,
block
):
try
:
self
.
_build_block
(
"
%.2
X "
%
ord
(
data
[
f
.
name
][
j
+
i
]),
highlight
=
diff_same
[
j
])
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
as
e
:
self
.
_build_block
(
" "
)
if
(
j
+
1
)
==
block
:
self
.
_build_block
(
" |"
)
for
k
in
range
(
0
,
block
):
try
:
if
data
[
f
.
name
][
k
+
i
]
in
string
.
printable
and
data
[
f
.
name
][
k
+
i
]
not
in
string
.
whitespace
:
self
.
_build_block
(
data
[
f
.
name
][
k
+
i
],
highlight
=
diff_same
[
k
])
else
:
self
.
_build_block
(
'.'
,
highlight
=
diff_same
[
k
])
except
:
self
.
_build_block
(
' '
)
if
index
==
len
(
self
.
config
.
target_files
)
-
1
or
(
self
.
terse
and
index
==
0
):
self
.
_build_block
(
"|"
)
else
:
self
.
_build_block
(
'|
%
s '
%
delim
)
if
self
.
_print_block_hex
(
alt_text
=
alt_text
[:
-
1
]
.
strip
()):
if
delim
==
'
\\
'
:
delim
=
'/'
else
:
delim
=
'
\\
'
i
+=
block
total
+=
read_block_size
self
.
footer
()
return
True
ALL_SAME
=
0
ALL_DIFF
=
1
SOME_DIFF
=
2
DEFAULT_DIFF_SIZE
=
0x100
DEFAULT_BLOCK_SIZE
=
16
COLORS
=
{
'red'
:
'31'
,
'green'
:
'32'
,
'blue'
:
'34'
,
}
TITLE
=
"Binary Diffing"
CLI
=
[
Option
(
short
=
'W'
,
long
=
'hexdump'
,
kwargs
=
{
'enabled'
:
True
},
description
=
'Perform a hexdump / diff of a file or files'
),
Option
(
short
=
'G'
,
long
=
'green'
,
kwargs
=
{
'show_green'
:
True
,
'show_blue'
:
False
,
'show_red'
:
False
},
description
=
'Only show lines containing bytes that are the same among all files'
),
Option
(
short
=
'i'
,
long
=
'red'
,
kwargs
=
{
'show_red'
:
True
,
'show_blue'
:
False
,
'show_green'
:
False
},
description
=
'Only show lines containing bytes that are different among all files'
),
Option
(
short
=
'U'
,
long
=
'blue'
,
kwargs
=
{
'show_blue'
:
True
,
'show_red'
:
False
,
'show_green'
:
False
},
description
=
'Only show lines containing bytes that are different among some files'
),
Option
(
short
=
'w'
,
long
=
'terse'
,
kwargs
=
{
'terse'
:
True
},
description
=
'Diff all files, but only display a hex dump of the first file'
),
]
KWARGS
=
[
Kwarg
(
name
=
'show_red'
,
default
=
True
),
Kwarg
(
name
=
'show_blue'
,
default
=
True
),
Kwarg
(
name
=
'show_green'
,
default
=
True
),
Kwarg
(
name
=
'terse'
,
default
=
False
),
Kwarg
(
name
=
'enabled'
,
default
=
False
),
]
HEADER_FORMAT
=
"
\n
%
s
\n
"
RESULT_FORMAT
=
"
%
s
\n
"
RESULT
=
[
'description'
]
def
_no_colorize
(
self
,
c
,
color
=
"red"
,
bold
=
True
):
return
c
def
_colorize
(
self
,
c
,
color
=
"red"
,
bold
=
True
):
attr
=
[]
attr
.
append
(
self
.
COLORS
[
color
])
if
bold
:
attr
.
append
(
'1'
)
return
"
\x1b
[
%
sm
%
s
\x1b
[0m"
%
(
';'
.
join
(
attr
),
c
)
def
_color_filter
(
self
,
data
):
red
=
'
\x1b
['
+
self
.
COLORS
[
'red'
]
+
';'
green
=
'
\x1b
['
+
self
.
COLORS
[
'green'
]
+
';'
blue
=
'
\x1b
['
+
self
.
COLORS
[
'blue'
]
+
';'
if
self
.
show_blue
and
blue
in
data
:
return
True
if
self
.
show_green
and
green
in
data
:
return
True
if
self
.
show_red
and
red
in
data
:
return
True
return
False
def
_print_block_hex
(
self
,
alt_text
=
"*"
):
if
self
.
_color_filter
(
self
.
block_hex
):
desc
=
self
.
block_hex
self
.
printed_alt_text
=
False
elif
not
self
.
printed_alt_text
:
desc
=
"
%
s"
%
alt_text
self
.
printed_alt_text
=
True
self
.
result
(
description
=
desc
)
self
.
block_hex
=
""
return
True
def
_build_block
(
self
,
c
,
highlight
=
None
):
if
highlight
==
self
.
ALL_DIFF
:
self
.
block_hex
+=
self
.
colorize
(
c
,
color
=
"red"
)
elif
highlight
==
self
.
ALL_SAME
:
self
.
block_hex
+=
self
.
colorize
(
c
,
color
=
"green"
)
elif
highlight
==
self
.
SOME_DIFF
:
self
.
block_hex
+=
self
.
colorize
(
c
,
color
=
"blue"
)
else
:
self
.
block_hex
+=
c
def
_build_header
(
self
,
files
,
block_size
):
header
=
"OFFSET"
+
(
" "
*
6
)
+
files
[
0
]
.
name
for
i
in
range
(
1
,
len
(
files
)):
header
+=
" "
*
((
block_size
*
3
)
+
2
+
block_size
+
8
-
len
(
files
[
i
-
1
]
.
name
))
header
+=
files
[
i
]
.
name
return
header
def
init
(
self
):
block
=
self
.
config
.
block
if
not
block
:
block
=
self
.
DEFAULT_BLOCK_SIZE
if
self
.
terse
:
header_files
=
self
.
config
.
target_files
[:
1
]
else
:
header_files
=
self
.
config
.
target_files
self
.
HEADER
=
self
.
_build_header
(
header_files
,
block
)
if
hasattr
(
sys
.
stderr
,
'isatty'
)
and
sys
.
stderr
.
isatty
()
and
platform
.
system
()
!=
'Windows'
:
curses
.
setupterm
()
self
.
colorize
=
self
.
_colorize
else
:
self
.
colorize
=
self
.
_no_colorize
def
run
(
self
):
i
=
0
total
=
0
data
=
{}
delim
=
'/'
self
.
block_hex
=
""
self
.
printed_alt_text
=
False
offset
=
self
.
config
.
offset
size
=
self
.
config
.
length
block
=
self
.
config
.
block
self
.
header
()
if
not
block
:
block
=
self
.
DEFAULT_BLOCK_SIZE
# If negative offset, then we're going that far back from the end of the file
if
offset
<
0
:
size
=
offset
*
-
1
#if common.BlockFile.READ_BLOCK_SIZE < block:
#
read_block_size = block
#else:
#
read_block_size = common.BlockFile.READ_BLOCK_SIZE
read_block_size
=
common
.
BlockFile
.
DEFAULT_BLOCK_READ_SIZE
# BlockFile handles calculation of negative offsets, if one was specified
offset
=
self
.
config
.
target_files
[
0
]
.
offset
size
=
self
.
config
.
target_files
[
0
]
.
length
while
total
<
size
:
i
=
0
files_finished
=
0
for
fp
in
self
.
config
.
target_files
:
(
ddata
,
dlen
)
=
fp
.
read_block
()
data
[
fp
.
name
]
=
ddata
if
not
ddata
or
dlen
==
0
:
files_finished
+=
1
if
files_finished
==
len
(
self
.
config
.
target_files
):
break
while
i
<
read_block_size
and
(
total
+
i
)
<
size
:
diff_same
=
{}
alt_text
=
"*"
+
" "
*
8
self
.
_build_block
(
"
%.08
X "
%
(
total
+
i
+
offset
))
# For each byte in this block, is the byte the same in all files, the same in some files, or different in all files?
for
j
in
range
(
0
,
block
):
byte_list
=
[]
try
:
c
=
data
[
self
.
config
.
target_files
[
0
]
.
name
][
j
+
i
]
except
:
c
=
None
for
f
in
self
.
config
.
target_files
:
try
:
c
=
data
[
f
.
name
][
j
+
i
]
except
Exception
as
e
:
c
=
None
if
c
not
in
byte_list
:
byte_list
.
append
(
c
)
if
len
(
byte_list
)
==
1
:
diff_same
[
j
]
=
self
.
ALL_SAME
elif
len
(
byte_list
)
==
len
(
self
.
config
.
target_files
):
diff_same
[
j
]
=
self
.
ALL_DIFF
else
:
diff_same
[
j
]
=
self
.
SOME_DIFF
for
index
in
range
(
0
,
len
(
self
.
config
.
target_files
)):
if
self
.
terse
and
index
>
0
:
break
f
=
self
.
config
.
target_files
[
index
]
alt_text
+=
" "
*
(
3
+
(
3
*
block
)
+
3
+
block
+
3
)
alt_text
+=
delim
for
j
in
range
(
0
,
block
):
try
:
self
.
_build_block
(
"
%.2
X "
%
ord
(
data
[
f
.
name
][
j
+
i
]),
highlight
=
diff_same
[
j
])
except
KeyboardInterrupt
as
e
:
raise
e
except
Exception
as
e
:
self
.
_build_block
(
" "
)
if
(
j
+
1
)
==
block
:
self
.
_build_block
(
" |"
)
for
k
in
range
(
0
,
block
):
try
:
if
data
[
f
.
name
][
k
+
i
]
in
string
.
printable
and
data
[
f
.
name
][
k
+
i
]
not
in
string
.
whitespace
:
self
.
_build_block
(
data
[
f
.
name
][
k
+
i
],
highlight
=
diff_same
[
k
])
else
:
self
.
_build_block
(
'.'
,
highlight
=
diff_same
[
k
])
except
:
self
.
_build_block
(
' '
)
if
index
==
len
(
self
.
config
.
target_files
)
-
1
or
(
self
.
terse
and
index
==
0
):
self
.
_build_block
(
"|"
)
else
:
self
.
_build_block
(
'|
%
s '
%
delim
)
if
self
.
_print_block_hex
(
alt_text
=
alt_text
[:
-
1
]
.
strip
()):
if
delim
==
'
\\
'
:
delim
=
'/'
else
:
delim
=
'
\\
'
i
+=
block
total
+=
read_block_size
self
.
footer
()
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