二进制代码的分析是计算机科学和软件工程学科的许多领域的关键活动,从软件安全和程序分析到反向工程。手动二进制分析是一项艰巨且耗时的任务,有一些软件工具试图自动化或协助人类分析师。但是,这些工具中的大多数都有几种技术和商业限制,这些限制限制了大部分学术和从业者社区的访问和使用。 Barf是一个开源二进制分析框架,旨在支持信息安全纪律中常见的广泛二进制代码分析任务。它是一个可脚本的平台,它支持从多个体系结构,二进制翻译为中间表示形式,代码分析插件的可扩展框架以及与外部工具(例如辩论者,SMT求解器和仪器工具)进行互操作的指令。该框架主要用于人类辅助分析,但可以完全自动化。
Barf项目包括Barf和相关工具和软件包。到目前为止,该项目由以下项目组成:
有关更多信息,请参见:
当前状态:
| 最新版本 | V0.6.0 |
|---|---|
| URL | https://github.com/programa-stic/barf-project/releases/tag/v0.6.0 |
| 更改日志 | https://github.com/programa-stic/barf-project/blob/v0.6.0/changelog.md |
在Ubuntu 16.04(X86_64)上测试了所有软件包。
Barf是用于二进制分析和反向工程的Python软件包。它可以:
ELF , PE等)加载二进制程序,它目前正在开发中。
BARF取决于以下SMT求解器:
以下命令在系统上安装barf :
$ sudo python setup.py install您也可以在本地安装它:
$ sudo python setup.py install --usersudo pip install pyasmjitsudo apt-get install graphviz这是一个非常简单的示例,它显示了如何打开二进制文件并打印每个指令及其转换为中间语言( REIL )。
from barf import BARF
# Open binary file.
barf = BARF ( "examples/misc/samples/bin/branch4.x86" )
# Print assembly instruction.
for addr , asm_instr , reil_instrs in barf . translate ():
print ( "{:#x} {}" . format ( addr , asm_instr ))
# Print REIL translation.
for reil_instr in reil_instrs :
print ( " t {}" . format ( reil_instr ))我们还可以恢复CFG并将其保存到.dot文件中。
# Recover CFG.
cfg = barf . recover_cfg ()
# Save CFG to a .dot file.
cfg . save ( "branch4.x86_cfg" )我们可以使用SMT求解器检查代码的限制。例如,假设您有以下代码:
80483ed: 55 push ebp
80483ee: 89 e5 mov ebp,esp
80483f0: 83 ec 10 sub esp,0x10
80483f3: 8b 45 f8 mov eax,DWORD PTR [ebp-0x8]
80483f6: 8b 55 f4 mov edx,DWORD PTR [ebp-0xc]
80483f9: 01 d0 add eax,edx
80483fb: 83 c0 05 add eax,0x5
80483fe: 89 45 fc mov DWORD PTR [ebp-0x4],eax
8048401: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
8048404: c9 leave
8048405: c3 ret
而且,您想知道必须将哪些值分配给内存位置ebp-0x4 , ebp-0x8和ebp-0xc以便在执行代码后在eax寄存器中获取特定值。
首先,我们将说明添加到分析仪组件中。
from barf import BARF
# Open ELF file
barf = BARF ( "examples/misc/samples/bin/constraint1.x86" )
# Add instructions to analyze.
for addr , asm_instr , reil_instrs in barf . translate ( 0x80483ed , 0x8048401 ):
for reil_instr in reil_instrs :
barf . code_analyzer . add_instruction ( reil_instr )然后,我们为感兴趣的每个变量生成表达式,并添加对它们的所需限制。
ebp = barf . code_analyzer . get_register_expr ( "ebp" , mode = "post" )
# Preconditions: set range for variable a and b
a = barf . code_analyzer . get_memory_expr ( ebp - 0x8 , 4 , mode = "pre" )
b = barf . code_analyzer . get_memory_expr ( ebp - 0xc , 4 , mode = "pre" )
for constr in [ a >= 2 , a <= 100 , b >= 2 , b <= 100 ]:
barf . code_analyzer . add_constraint ( constr )
# Postconditions: set desired value for the result
c = barf . code_analyzer . get_memory_expr ( ebp - 0x4 , 4 , mode = "post" )
for constr in [ c >= 26 , c <= 28 ]:
barf . code_analyzer . add_constraint ( constr )最后,我们检查是我们建立的限制可以解决。
if barf . code_analyzer . check () == 'sat' :
print ( "[+] Satisfiable! Possible assignments:" )
# Get concrete value for expressions
a_val = barf . code_analyzer . get_expr_value ( a )
b_val = barf . code_analyzer . get_expr_value ( b )
c_val = barf . code_analyzer . get_expr_value ( c )
# Print values
print ( "- a: {0:#010x} ({0})" . format ( a_val ))
print ( "- b: {0:#010x} ({0})" . format ( b_val ))
print ( "- c: {0:#010x} ({0})" . format ( c_val ))
assert a_val + b_val + 5 == c_val
else :
print ( "[-] Unsatisfiable!" )您可以在示例目录中看到这些和更多示例。
该框架分为三个主要组成部分:核心,拱门和分析。
该组件包含必需模块:
REIL :提供REIL语言的定义。它还实现了模拟器和解析器。SMT :提供与Z3和CVC4 SMT求解器接口的手段。此外,它提供了将REIL指令转换为SMT表达式的功能。BI :二进制接口模块负责加载二进制文件进行处理(它使用Pefile和Pyelftools。)。 每个支持的体系结构都作为子组件提供,其中包含以下模块。
Architecture :描述体系结构,即,寄存器,内存地址大小。Translator :为每个受支持的说明提供翻译以供电。Disassembler :提供拆卸功能(它使用Capstone。)。Parser :将指令从字符串转换为对象形式。 到目前为止,该组件由模块组成:控制流图,呼叫图和代码分析仪。前两个分别为CFG和CG恢复提供了功能。后者是SMT求解器相关功能的高级接口。
BARFgadgets是一个建立在Barf上的Python脚本,可让您在二进制程序中搜索,分类和验证ROP小工具。搜索阶段找到了二进制中的所有ret , jmp和调用 - call的小工具。分类阶段根据以下类型进行了先前发现的小工具分类:
这是通过教学仿真完成的。最后,验证阶段包括使用SMT求解器在第二阶段验证分配给每个小工具的语义。
usage: BARFgadgets [-h] [--version] [--bdepth BDEPTH] [--idepth IDEPTH] [-u]
[-c] [-v] [-o OUTPUT] [-t] [--sort {addr,depth}] [--color]
[--show-binary] [--show-classification] [--show-invalid]
[--summary SUMMARY] [-r {8,16,32,64}]
filename
Tool for finding, classifying and verifying ROP gadgets.
positional arguments:
filename Binary file name.
optional arguments:
-h, --help show this help message and exit
--version Display version.
--bdepth BDEPTH Gadget depth in number of bytes.
--idepth IDEPTH Gadget depth in number of instructions.
-u, --unique Remove duplicate gadgets (in all steps).
-c, --classify Run gadgets classification.
-v, --verify Run gadgets verification (includes classification).
-o OUTPUT, --output OUTPUT
Save output to file.
-t, --time Print time of each processing step.
--sort {addr,depth} Sort gadgets by address or depth (number of
instructions) in ascending order.
--color Format gadgets with ANSI color sequences, for output
in a 256-color terminal or console.
--show-binary Show binary code for each gadget.
--show-classification
Show classification for each gadget.
--show-invalid Show invalid gadget, i.e., gadgets that were
classified but did not pass the verification process.
--summary SUMMARY Save summary to file.
-r {8,16,32,64} Filter verified gadgets by operands register size.
有关更多信息,请参见Readme。
BARFcfg是建立在Barf上的Python脚本,可让您恢复二进制程序的控制流图。
usage: BARFcfg [-h] [-s SYMBOL_FILE] [-f {txt,pdf,png,dot}] [-t]
[-d OUTPUT_DIR] [-b] [--show-reil]
[--immediate-format {hex,dec}] [-a | -r RECOVER]
filename
Tool for recovering CFG of a binary.
positional arguments:
filename Binary file name.
optional arguments:
-h, --help show this help message and exit
-s SYMBOL_FILE, --symbol-file SYMBOL_FILE
Load symbols from file.
-f {txt,pdf,png,dot}, --format {txt,pdf,png,dot}
Output format.
-t, --time Print process time.
-d OUTPUT_DIR, --output-dir OUTPUT_DIR
Output directory.
-b, --brief Brief output.
--show-reil Show REIL translation.
--immediate-format {hex,dec}
Output format.
-a, --recover-all Recover all functions.
-r RECOVER, --recover RECOVER
Recover specified functions by address (comma
separated).
BARFcg是一个基于Barf的Python脚本,可让您恢复二进制程序的呼叫图。
usage: BARFcg [-h] [-s SYMBOL_FILE] [-f {pdf,png,dot}] [-t] [-a | -r RECOVER]
filename
Tool for recovering CG of a binary.
positional arguments:
filename Binary file name.
optional arguments:
-h, --help show this help message and exit
-s SYMBOL_FILE, --symbol-file SYMBOL_FILE
Load symbols from file.
-f {pdf,png,dot}, --format {pdf,png,dot}
Output format.
-t, --time Print process time.
-a, --recover-all Recover all functions.
-r RECOVER, --recover RECOVER
Recover specified functions by address (comma
separated).
Pyasmjit是用于X86_64/ARM组装代码生成和执行的Python软件包。
开发此软件包是为了测试从X86_64/ARM到REIL的Barf指令翻译。主要思想是能够本地运行代码的片段。然后,将相同的片段翻译成reil并在Reil VM中执行。最后,这两个最终上下文(通过本机执行获得的一个和仿真的上下文)都在与差异进行比较。
有关更多信息,请参见Pyasmjit。
BSD 2-CAREASE许可证。有关更多信息,请参见许可证。