angr学习(四)

例子中脚本解释:

0ctf_momo_3

 

脚本解释

脚本思路

由于程序对输入验证是单字符比较,可以用爆破的方式,由于mov混淆不具有变异特性,验证分支入口特点明显,有以下三个:

edx, dword ptr [edx*4 + 0x81fe260]
al, byte ptr [0x81fe6e0]
dl, byte ptr [0x81fe6e4]

将所有的验证分支存储起来之后,遍历爆破。

爆破验证指定两个寄存器中的值相等即输入字符正确。

 

脚本编写思路

 

insn_bytes = ''.join(p.loader.memory.read_bytes(addr, size))

读取所需执行的字节

 

insns = [] for cs_insn in p.arch.capstone.disasm(insn_bytes, addr): insns.append(CapstoneInsn(cs_insn))

 

capstone.py:

for _path in _path_list: 
_cs = _load_lib(_path)
  if _cs is not None:
     break

根据程序的平台架构选择相应的库文件,将指定字节反编译,并根据指令类型生成CapstoneInsn对象。得到一个CapstoneInsn对象列表。

CapstoneInsn对象数据形如: 地址+指令+操作数

 
block = CapstoneBlock(addr, insns, 0, p.arch)

将CapstoneInsn对象转化为字符。

 

state.posix.files[0].content.store(0, flag + "\n")

相当于read(0,flag,len(flag))

 
e = p.surveyors.Explorer(start=state, find=(target,)) e.run()

运行模拟引擎(耗时原因),在地址范围内生成状态列表

 

assert len(e.found) == 1 np = e.found[0]

确保到达目标地址可行,取第一种状态 np类型为SimState

 

while(True): 
    nb_size = target - np.addr
    if nb_size <= 0: 
       break 
    np=p.factory.successors(np, size=nb_size).flat_successors[0]        

将指定的state进行具体化模拟

 

al = np.regs.eax[7:0] 
dl = np.regs.edx[7:0] 
al_val = al._model_concrete.value
dl_val = dl._model_concrete.value 
if al_val == dl_val: 
    flag_arr.append(trychar)
    break

对进行比较所用的寄存器中的值取出来比较,如果相等则保存该值。

爆破完成后输出即可,循环执行模拟引擎所以相当耗时。

posted @ 2017-11-25 01:09  fancy鑫  阅读(1239)  评论(0编辑  收藏  举报