使用汇编语言编写注入代码
@author: dlive
0x00 前言
使用OD中的汇编功能编写汇编程序,直接使用汇编代码编写函数,实现弹出messagebox的功能,对汇编功底有一定要求,详细分析该章节的汇编代码会学到很多东西。
0x01 new tips for OD
在反汇编窗口右键,选择此处为新EIP,可以修改EIP指向选中的位置,与直接通过调试方式转到指定地址不一样的是,寄存器和栈中的内容未改变
0x02 编写ThreadProc函数
向notepad.exe注入的汇编代码如下,其功能为接收两个参数:kernel32.LoadLibraryA和kernel32.GetProcAddress的地址,并弹出一个user32.MessageBox框
PUSH EBP
MOV EBP,ESP ; 生成栈桢
MOV ESI,DWORD PTR SS:[EBP+8] ; ESI = pParam 从栈上获取函数参数
PUSH 6C6C
PUSH 642E3233
PUSH 72657375
PUSH ESP ; - "user32.dll"(ESP为字符串首地址),LoadLibraryA的参数
CALL DWORD PTR DS:[ESI] ; LoadLibraryA("user32.dll")
PUSH 41786F
PUSH 42656761
PUSH 7373654D
PUSH ESP ; - "MessageBoxA"(同上"user32.dll"的解释)
PUSH EAX ; - hMod(EAX是LoadLibraryA的返回值)
CALL DWORD PTR DS:[ESI+4] ; GetProcAddress(hMod, "MessageBoxA")
PUSH 0 ; - MB_OK (0)
CALL 0040112C
<ASCII> ; - "ReverseCore", 0
CALL 00401145
<ASCII> ; - "www.reversecore.com", 0
PUSH 0 ; - hWnd (0)
CALL EAX ; MessageBoxA(0, "www.reversecore.com", "ReverseCore", 0)
XOR EAX,EAX
MOV ESP,EBP
POP EBP
RETN
大部分汇编代码较好理解,可动态调试时明显看出其功能。
汇编中使用了两种将字符串数据包含进代码的方法。
使用push指令将字符串数据压栈
PUSH 41786F
PUSH 42656761
PUSH 7373654D
这段代码还是比较好理解的,实际上是将字符串压到栈上
可以看到运行到call指令前,栈上的情况如下
字符串’user32.dll‘即为栈上的\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c
使用call指令将字符串数据压栈
第二种将字符串保存在代码中的方法为使用call指令
call func_address指令的本质为push eip+4,jmp func_address
在03d8002e处执行call 03d8003f实际上是执行了push 03d80033, jmp 03d8003f
可以在数据窗口中看出从03d80033到03d8003e存储的内容为ReverseCore的字符串,所以push 03d80033实际上是将字符串的首地址压栈
f7跟进call, 可以看到跳转到的内容如下
这仍然是一个将字符串压栈的过程,第一行的call指令将首地址为03d90044的字符串“www.reversecore.com”压栈
然后跳转到03d90058
该地址的内容如上图,调用了MessageBoxA函数