标签:.com ant 元数据 method 堆栈 c函数 技术分享 没有 bsp
参考 http://bobao.360.cn/learning/detail/4732.html
一、通过返回劫持技术欺骗IDA的 F5
现在的反编译器一直在追求一个目标,就是准确识别并抽离编译器生成的低级簿记(bookkeeping)逻辑,这类信息包括函数的预处理代码段/结尾代码段或者控制流元数据
反编译器会在输出结果中去掉这类信息,因为源代码级别并不会涉及到寄存器保存、栈帧空间分配管理等概念。下面是一种实例:
void __declspec(naked) Func() { printf("hello 2"); __asm { pop eax mov esp,ebp pop ebp ret } } unsigned int next = (unsigned int )Func; void AntiMethod2() { __asm { sub esp,4 mov eax,next mov [esp],eax ret } }
使用IDA反编译结果如下,Func函数的调用明显被忽视了
二、正数SP(堆桟指针)值
对IDA Pro而言,如果某个函数在返回之前没有清理已分配的堆桟(即平衡堆桟指针stack pointer sp),那么反编译器将拒绝处理该函数
这种情况之所以出现,原因在于IDA无法合理的方式推断特定函数调用的类型定义。
因此开发者可以将其作为反编译对抗技术,具体方法是使用不透明谓词技术来破坏堆栈指针的平衡状态,达到干扰效果。
这里的add esp, 0x102永远不会被执行,但是反编译的时候栈帧已经被破坏了
void AntiMethod3() { __asm { pop eax lea esp,[esp-4] cmp esp,0x1000 ja _Label add esp,0x102 } _Label: __asm add esp,4 printf("Hello Method3"); __asm{ mov esp,ebp pop ebp ret } }
结果F5如下:
三、碎片指令迷惑F5
让反编译的结果和运行结果完全不一样 ,这里的xor和jz指令就是不让反编译器直接识别E8
void AntiMethod3() { __asm { xor eax,eax jz _Label _emit 0xE8 } _Label: printf("Hello Method3"); }
这里利用E8字节,让反编译的结果有一个call指令,但实际上我们并没有执行,反编译结果如下
F5结果如下:
四:利用返回指令
我们经常能看到这类函数,比如标准库中的exit()
或者abort()
函数都属于noreturn
函数。
在生成指定函数的伪代码时,反编译器会忽略调用noreturn
函数后的任何代码。因为反编译器认为,调用类似exit()
函数时,位于这些函数后面的代码永远得不到执行机会。
标签:.com ant 元数据 method 堆栈 c函数 技术分享 没有 bsp
原文地址:http://www.cnblogs.com/aliflycoris/p/7899261.html