刚入门,vc++项目运用IDA进行代码级逆向主要有几个过程:
1.检查RTTI是不是敞开,假如敞开,则利用RTTI信息获取有关类名、承继联系、虚函数地址。
2.经过1得到的类名和承继联系,用自个写的脚本将其转换成一个c++完好的项目,里边包含.h和对应的.cpp。
3.具体剖析某个类的构造的时分,一定要找到他的构造函数。(构造函数通常出如今[ecx+n]进行一系列赋值的情况下)。
4.经过3找到的构造函数得到里边的最大偏移,暂定此偏移即是类的巨细,然后在2树立的项目里边写入变量名,用DWORD unknow_n表明未知变量,n代表变量的偏移,等具体剖析到某个偏移时才赋予他一个你自个取的名字。
5.经过4获取的类的巨细也许不是那么精确,还能够依据在堆平分配目标时new之前的push判别巨细,别的还能够依据
反汇编STL的操作,比方vector他的很多操作都会判别分配内存是不是够用,然后会new一个2倍的空间,释放本来的空间,这个时分能够精确判别他的巨细。
6.那么怎样确定5中说到的STL呢,由于不一样版别的STL代码和内存规划不一样,所以咱们首要需要用工具检查软件的编译器版别,然后经过检查某些特定字符串(如"list is too long"),或许经过构造函数中STL某些公共基类虚函数表初始化得知STL信息。
7.假如要剖析的主程序是能够写plugin 并供给SDK的,先剖析SDK中的类(那些没有出如今头文件中的类),得到一些数据构造,这些构造也许是plugin和主程序通用的,为咱们剖析主程序打基础。
8.对于某些特定函数先要了解其源代码,比方最常见的string.c_str()这个函数有个标志性的判别size是不是大于16,以此为头绪进行剖析。
9.当心IDA自身的缺点(模板类型导入,c++头文件解析,F5插件sp-value判别过错致使虚函数参数个数推导过错,F5回来浮点和bool不显现等等)
___________________
弥补对于sp的疑问:
假如看到F5出来之后栈变量内存空间堆叠、函数参数显着不对,则犯错的因素通常是由于调用stdcall或许类虚函数的时分不知道函数回来时add esp多少,致使IDA无法推导出esp如今和ebp的间隔。而ebp+n又被F5当成是标识变量的办法,比方
sub esp,8
mov DWORD ptr [esp],0
call stdcallfun //这个函数是导入函数假如没有签名判别栈帧也许呈现疑问
mov DWORD ptr [esp],1
这两行代码IDA会翻译成
mov DWORD ptr [esp+8-8],0
mov DWORD ptr [esp+8-8],1
F5判别他们是栈中同一个变量,所以反汇编是v1=0:v1=1;
但假如stdcallfun 最后ret 4,这时第二个esp判别就犯错了,精确的应该是mov DWORD [esp +4-4],1。所以反汇编是v1=0:v2=1;
呈现这种疑问,咱们能够手动调整函数的sp-value(ALT+K)。但最麻烦的情况函数整体sp平衡,部分sp过错,这时分就需要图形形式下看跳转分支,翻开选项的stack-point调查每个分支,总归要保证每个分支结束时sp一样就能够了,这样能够处理大多数疑问。
别的有关IDA无法导入STL类型到local type的处理办法如下:
比方你要导入一个std::vector的类型或许最常见的std::string类型到IDA里边,能够先用主程序对应的版别的编译器写上:
std::vector var1;
std::string var2;
关闭编译器优化,翻开debug信息,然后编译生成.pdb文件,最后用IDA解析.pdb文件,这时上面两个类型就到你的local type里边去了。但这时你给变量指定这些导入的类型时依旧会报错(不辨认尖括号),咱们必须先把这些local type同步到idb文件,然后在structure窗口下复制这些类型,然后取上别号,比方取名为std::vector_A 。只需不呈现尖括号,就能够直接在F5里边运用这个类型。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)