源码分析
通过阅读源码,可以得知几个关键的函数
run_at(self, ircfg, addr, lbl_stop=None, step=False)
- ifcgf: 中间表示的控制流图(ir)
- addr: 指定符号执行的起始位置
- lbl_stop: 指定符号执行的停止位置(
target_label = loc_db.get_offset_location(end_addr)需要转成 loc_key对象 - step: 控制执行模式, 默认False,当打开时,会输出单步执行的信息
eval_updt_irblock(self, irb, step=False)
- irb: 要执行的中间表示基本块(ir块)
- step: 控制执行模式, 默认False,当打开时,会输出单步执行的信息
这两个函数,一个是符号执行的入口,通过传入的地址,来获取对应的ir块,然后遍历ir块的指令
# 从传入的地址开始,遍历ir块
def run_at(self, ircfg, addr, lbl_stop=None, step=False):
"""
Symbolic execution starting at @addr
@addr: address to execute (int or ExprInt or label)
@lbl_stop: LocKey to stop execution on
@step: display intermediate steps
"""
while True:
irblock = ircfg.get_block(addr)
if irblock is None:
break
if irblock.loc_key == lbl_stop:
break
addr = self.eval_updt_irblock(irblock, step=step)
return addr
# 遍历执行ir块中的指令
def eval_updt_irblock(self, irb, step=False):
"""
Symbolic execution of the @irb on the current state
@irb: irbloc instance
@step: display intermediate steps
"""
for assignblk in irb:
if step:
print('Instr', assignblk.instr)
print('Assignblk:')
print(assignblk)
print('_' * 80)
self.eval_updt_assignblk(assignblk) # 执行指令
if step:
self.dump(mems=False)
self.dump(ids=False)
print('_' * 80)
dst = self.eval_expr(self.lifter.IRDst) # 得到下一个ir块的地址
return dst
功能扩展
在第一篇文章中,miasm不能自动跳转执行函数花指令,我们需要手动来处理,重新运行,有了上面两个函数的理解,就可以开始给miasm增加新功能了
新建一个文件名为:funcEngine.py
这里直接贴增加重载后的类
from miasm.ir.symbexec import SymbolicExecutionEngine
from miasm.expression.expression import *
class FuncExecutionEngine(SymbolicExecutionEngine):
def __init__(self, ira):
super().__init__(ira)
self.jump = False
def is_function_call_assignblk(self, assignblk):
for dst, src in assignblk.items():
instr = assignblk.instr
if instr.name == "BL":
if isinstance(src, ExprOp):
for i, arg in enumerate(src.args):
if isinstance(arg, ExprLoc):
return 1, arg
return 0, False
def eval_updt_irblock(self, irb, step=False):
"""
Symbolic execution of the @irb on the current state
@irb: irbloc instance
@step: display intermediate steps
"""
for assignblk in irb:
instr = assignblk.instr
offset = instr.offset
if step:
print(f"0x{offset:x} ", instr)
print('Assignblk:')
print(assignblk)
print('_' * 80)
self.eval_updt_assignblk(assignblk)
if step:
self.dump(mems=False)
self.dump(ids=False)
print('=' * 80)
status, is_jump = self.is_function_call_assignblk(assignblk)
if status == 1:
new_offset = 0
for variable, value in viewitems(self.symbols.symbols_id):
if variable.name == "X0":
new_offset = value.args[0].arg
self.symbols.symbols_id[ExprId("LR", 64)] = ExprInt(instr.offset + 4, 64)
self.symbols.symbols_id[ExprId("PC", 64)] = ExprInt(new_offset, 64)
self.jump = True
return new_offset
dst = self.eval_expr(self.lifter.IRDst)
return dst
def run_at_into_func(self, mdis, ira, addr, lbl_stop=None, step=False, deep=1):
asm_cfg = mdis.dis_multiblock(addr)
ir_cfg = ira.new_ircfg_from_asmcfg(asm_cfg)
while True:
irblock = ir_cfg.get_block(addr)
if irblock is None and deep:
asm_cfg = mdis.dis_multiblock(addr)
ir_cfg = ira.new_ircfg_from_asmcfg(asm_cfg)
deep -= 1
print("**************************************** [jump] ****************************************")
continue
if irblock is None and self.jump:
self.jump = False
asm_cfg = mdis.dis_multiblock(addr)
ir_cfg = ira.new_ircfg_from_asmcfg(asm_cfg)
print("**************************************** [ret] ****************************************")
continue
if irblock is None:
break
if irblock.loc_key == lbl_stop:
break
addr = self.eval_updt_irblock(irblock, step=step)
return addr
那么调用也需要改动
import loguru
from miasm.analysis.binary import Container
from miasm.analysis.machine import Machine
from miasm.core.locationdb import LocationDB
from funcEngine import FuncExecutionEngine
soPath = "libmetasec_ov.so"
loc_db = LocationDB()
container = Container.from_stream(open(soPath, "rb"), loc_db)
machine = Machine("aarch64l")
start_addr = 0x67BA8
mdis = machine.dis_engine(container.bin_stream, loc_db=loc_db)
ira = machine.ira(mdis.loc_db)
STACK_BASE = 0x10000000
STACK_SIZE = 0x10000
sb = FuncExecutionEngine(ira)
sb.run_at_into_func(mdis, ira, start_addr, step=True)
新增了一个run_at_into_func函数,原理就是,当执行到函数跳转,如bl指令的时候,记录函数返回地址,写入lr寄存器,因为是分析arm64,指令是+4,模拟真实指令跳转,在跳转时,修改了lr和pc寄存器
当跳转的函数执行完毕后,irblock会得到空,这时通过lr的地址,再跳回原来的函数,因为原函数的ir已经被覆盖,所以需要重新构建ir中间表示,这时因为寄存器没有改变,lr的值会被保存,符号会继续执行add的操作,最终会自动得到br x1的地址
效果展示:
目标花指令

效果图:
0x67ba8 SUB X0, X29, 0x68
Assignblk:
X0 = X29 + -0x68
________________________________________________________________________________
X0 = X29 + 0xFFFFFFFFFFFFFF98
================================================================================
0x67bac SUB SP, SP, 0x40
Assignblk:
SP = SP + -0x40
________________________________________________________________________________
X0 = X29 + 0xFFFFFFFFFFFFFF98
SP = SP + 0xFFFFFFFFFFFFFFC0
================================================================================
0x67bb0 STP X29, LR, [SP, 0x30]
Assignblk:
@64[SP + 0x30] = X29
@64[SP + 0x30 + 0x8] = LR
________________________________________________________________________________
X0 = X29 + 0xFFFFFFFFFFFFFF98
SP = SP + 0xFFFFFFFFFFFFFFC0
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
================================================================================
0x67bb4 STP X0, X1, [SP]
Assignblk:
@64[SP + 0x0] = X0
@64[SP + 0x0 + 0x8] = X1
________________________________________________________________________________
X0 = X29 + 0xFFFFFFFFFFFFFF98
SP = SP + 0xFFFFFFFFFFFFFFC0
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
================================================================================
0x67bb8 STP X3, X2, [SP, 0x10]
Assignblk:
@64[SP + 0x10] = X3
@64[SP + 0x10 + 0x8] = X2
________________________________________________________________________________
X0 = X29 + 0xFFFFFFFFFFFFFF98
SP = SP + 0xFFFFFFFFFFFFFFC0
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
================================================================================
0x67bbc STP X7, X6, [SP, 0x20]
Assignblk:
@64[SP + 0x20] = X7
@64[SP + 0x20 + 0x8] = X6
________________________________________________________________________________
X0 = X29 + 0xFFFFFFFFFFFFFF98
SP = SP + 0xFFFFFFFFFFFFFFC0
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFE0] = X7
@64[SP + 0xFFFFFFFFFFFFFFE8] = X6
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
================================================================================
0x67bc0 BL loc_key_691
Assignblk:
X0 = call_func_ret(loc_key_691, SP)
SP = call_func_stack(loc_key_691, SP)
________________________________________________________________________________
X0 = call_func_ret(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0)
SP = call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0)
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFE0] = X7
@64[SP + 0xFFFFFFFFFFFFFFE8] = X6
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
================================================================================
**************************************** [jump] ****************************************
0x67bcc SUB SP, SP, 0x10
Assignblk:
SP = SP + -0x10
________________________________________________________________________________
X0 = call_func_ret(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0)
SP = call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0
LR = 0x67BC4
PC = 0x67BCC
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFE0] = X7
@64[SP + 0xFFFFFFFFFFFFFFE8] = X6
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
================================================================================
0x67bd0 STP X29, LR, [SP]
Assignblk:
@64[SP + 0x0] = X29
@64[SP + 0x0 + 0x8] = LR
________________________________________________________________________________
X0 = call_func_ret(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0)
SP = call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0
LR = 0x67BC4
PC = 0x67BCC
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFE0] = X7
@64[SP + 0xFFFFFFFFFFFFFFE8] = X6
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0] = X29
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF8] = 0x67BC4
================================================================================
0x67bd4 LDR X0, [SP, 0x8]
Assignblk:
X0 = @64[SP + 0x8]
________________________________________________________________________________
X0 = 0x67BC4
SP = call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0
LR = 0x67BC4
PC = 0x67BCC
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFE0] = X7
@64[SP + 0xFFFFFFFFFFFFFFE8] = X6
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0] = X29
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF8] = 0x67BC4
================================================================================
0x67bd8 LDP X29, LR, [SP]
Assignblk:
X29 = @64[SP + 0x0]
LR = @64[SP + 0x0 + 0x8]
________________________________________________________________________________
X0 = 0x67BC4
SP = call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0
LR = 0x67BC4
PC = 0x67BCC
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFE0] = X7
@64[SP + 0xFFFFFFFFFFFFFFE8] = X6
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0] = X29
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF8] = 0x67BC4
================================================================================
0x67bdc ADD SP, SP, 0x10
Assignblk:
SP = SP + 0x10
________________________________________________________________________________
X0 = 0x67BC4
SP = call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0)
LR = 0x67BC4
PC = 0x67BCC
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFE0] = X7
@64[SP + 0xFFFFFFFFFFFFFFE8] = X6
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0] = X29
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF8] = 0x67BC4
================================================================================
0x67be0 RET LR
Assignblk:
PC = LR
IRDst = LR
________________________________________________________________________________
X0 = 0x67BC4
SP = call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0)
LR = 0x67BC4
PC = 0x67BC4
IRDst = 0x67BC4
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFE0] = X7
@64[SP + 0xFFFFFFFFFFFFFFE8] = X6
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0] = X29
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF8] = 0x67BC4
================================================================================
**************************************** [ret] ****************************************
0x67bc4 ADD X1, X0, 0x34
Assignblk:
X1 = X0 + 0x34
________________________________________________________________________________
X0 = 0x67BC4
SP = call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0)
LR = 0x67BC4
PC = 0x67BC4
IRDst = 0x67BC4
X1 = 0x67BF8
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFE0] = X7
@64[SP + 0xFFFFFFFFFFFFFFE8] = X6
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0] = X29
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF8] = 0x67BC4
================================================================================
0x67bc8 BR X1
Assignblk:
PC = X1
IRDst = X1
________________________________________________________________________________
X0 = 0x67BC4
SP = call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0)
LR = 0x67BC4
PC = 0x67BF8
IRDst = 0x67BF8
X1 = 0x67BF8
@64[SP + 0xFFFFFFFFFFFFFFC0] = X29 + 0xFFFFFFFFFFFFFF98
@64[SP + 0xFFFFFFFFFFFFFFC8] = X1
@64[SP + 0xFFFFFFFFFFFFFFD0] = X3
@64[SP + 0xFFFFFFFFFFFFFFD8] = X2
@64[SP + 0xFFFFFFFFFFFFFFE0] = X7
@64[SP + 0xFFFFFFFFFFFFFFE8] = X6
@64[SP + 0xFFFFFFFFFFFFFFF0] = X29
@64[SP + 0xFFFFFFFFFFFFFFF8] = LR
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF0] = X29
@64[call_func_stack(0x67BCC, SP + 0xFFFFFFFFFFFFFFC0) + 0xFFFFFFFFFFFFFFF8] = 0x67BC4
================================================================================
最终可以看到x1的正确地址

当然样本只是个例,可能需要更多优化!!!
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!