2018/2/14 新手逆向入门ing:
二进制的另类解法
1.符号执行就是在运行程序时,用符号代替真实值。通过符号执行把所有的路径进行一个遍历分析得到正确结果。
2.Angr是一个多架构的二进制分析平台。
3.Angr由于会对每一个路径遍历,所以当路径过多,循环过大,条件太过复杂时,会造成路径爆炸,耗尽内存。
<1:
v3 = "Dufhbmf";
v4 = "pG`imos";
v5 = "ewUglpt";
for ( i = 0; i <= 11; ++i )
{
if ( (&v3)[8 * (i % 3)][2 * (i / 3)] - *(_BYTE *)(i + a1) != 1 )
return 1LL;
}
return 0LL;
}
这道题来自WhaleCTF,可以通过Angr简单得短时间内解决:
In [1]: import angr
WARNING | 2018-02-14 23:06:58,339 | angr.analyses.disassembly_utils | Your verison of capstone does not support MIPS instruction groups.
In [2]: proj=angr.Project('./r100',auto_load_libs=False) #加载这个项目,auto_load_libs=Flase是不让它自动的加载引用得动态链接库
In [3]: state=proj.factory.entry_state() #获得程序得初始状态
In [4]: simgr=proj.factory.simgr(state) #遍历路径
In [5]: simgr.explore(find=0x400844,avoid=0x400855)
Out[5]: <SimulationManager with 2 active, 1 found, 12 avoid>
In [6]: simgr.found[0].posix.dumps(0) #打印找到的值
Out[6]: 'Code_Talkers\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
<2:
还有一类是通过输入参数的
int i; // [sp+14h] [bp-4h]@1
for ( i = 0; *(_BYTE *)(i + a1); ++i )
{
if ( encrypted[(signed __int64)i] != ((unsigned __int8)((unsigned __int8)(*(_BYTE *)(i + a1) ^ i) << ((i ^ 9) & 3)) | (unsigned __int8)((signed int)(unsigned __int8)(*(_BYTE *)(i + a1) ^ i) >> (8 - ((i ^ 9) & 3))))
+ 8 )
return 0LL;
}
return i == 23;
}
这类题还需要import一个库claripy:
In [1]: import angr
WARNING | 2018-02-14 23:24:27,638 | angr.analyses.disassembly_utils | Your verison of capstone does not support MIPS instruction groups.
In [2]: import claripy
In [3]: proj=angr.Project('./ais3_crackme',auto_load_libs=False) #加载项目
In [4]: argv1=claripy.BVS('argv1',50*8) #设一个参数,以二进制的形式,猜测长度可能不超过50
In [5]: state=proj.factory.entry_state(args=['./ais3_crackme',argv1]) #获得程序的初始状态,需要参数
In [6]: simgr=proj.factory.simgr(state) #遍历
In [7]: simgr.explore(find=0x400602,avoid=0x40060E)
Out[7]: <SimulationManager with 3 active, 1 found, 46 avoid>
In [8]: print simgr.found[0].solver.eval(argv1,cast_to=str) #由于输入的是二进制,所以需要处理以字符串打印
ais3{I_tak3_g00d_n0t3s}
Angr的好处还是有的,它不用纠结于算法问题,据说它不仅仅可以在逆向中有用,还可以应用于pwn中。不过现在对于Angr的了解还是太少了,还是应该好好了解一番。今天先就这样吧~