机器码注入实例的调试练习(第三个注入实例)
1,打开文本记事本【这里必须是32位的文本记事本程序】,因为目前的OD无法调试64位程序。。。
2,打开之后,用OD附加,按F9运行,因为本实例是用远程注入线程的模式启动注入代码的,所以断一下线程加载。选项-》调试设置-》事件-》中断于新线程
3,打开cmd控制台,CD到文件夹路径,输入程序.exe pid,pid为记事本的进程ID,运行一下,OD会断在注入线程的开始处。
CE0000中存放的是线程回调函数的参数,为这样的一个结构体
typedef struct _THREAD_PARAM
{
FARPROC pFunc[2]; // LoadLibraryA(), GetProcAddress()
} THREAD_PARAM, *PTHREAD_PARAM;
当然这个地址是随机的哈,系统自己选择合适的地址分配的内存。
运行到第七行,再看图
紧接着第七行,PUSH ESP,ESP中存放的是"USER32.DLL“,将这个字窜指针压入了栈,下一行CALL 【ESI】,ESI的值是CE0000,不正好是LOADLIBRARY函数的起始地址么。看到这儿我真想说,尼妈,真高级!太奇妙了。
接下来猜一下吧,如法炮制调用GETPROCADDRESS吧。跟踪一下。
下面是要分析的最重要的地方。。。
这张图是CALLD1003F后的图,看一下栈窗口与数据窗口,D10033被压入栈,其中存放的是一个字符窜,但显然这是一个假函数,也就没有退出函数时弹出下一个指令地址的动作(RET),接着一条指令又是一个假CALL,会压入D10044到栈再跳转到D10058处去执行
跳转D10058后,再看一下栈窗口跟数据窗口,二次CALL压入了二个字符窜,最后再压一个窗口句柄,这里压的是0,EAX里存放的MESSAGEBOX的指针。。。到此完结。奇妙吧,真他妈太牛了,不过这样的技巧也就汇编代码能实现。。。
可以用这种方法防范反汇编。
总结:看二处假CALL,都用的短跳转,第一处
. 6A 00 push 0x0
0040102E . E8 0C000000 call asmtest1.0040103F //E8 0C,看第一个字符窜长度,REVERSECORE,11个字节加上最后的结尾正好0xC.
第二处
E8 14000000 call asmtest1.00401058 //E8 14,www.reversecore.com,加上结尾正好20个字节。
要让人眼花缭乱,技巧也就在这了,代码与代码之间书写时不能用NOP来填充。