《****核心原理》学习笔记(二)
《****核心原理》学习笔记(一)
记录下OD快速查找指定代码的四种方法
例子为****核心原理(中第二章的helloword程序
0x01 代码执行法
例子中需要查找的是main()函数中的MessageBoxW函数,在调试器中调制helloword程序时候(单步执行F8)时,main()函数中的MessageBoxW函数在某个时刻就会被调用执行。弹出消息对话框,显示helloword。
代码执行法的基本原理就是,在程序功能非常明确时,逐条执行指令来查找需要查找的位置。代码执行法仅适用于被调试的代码量不大、且程序功能明确的情况。倘若被调试的代码量很大且比较复杂时,此种方法就不再适用了。
在00401144处有一条调用00401000函数的call指令 我们F7跟进。
地址40100E处有一条调用MessageBoxW()的API的语句,在前面(00401002、00401007)分别有push语句,它们把消息对话框的标题与显示字符串保存到栈(Stack)中,并作为参数传递给MessageBoxW函数。
PS:Win32应用程序中,API函数的参数是通过栈传递的。VC++中默认的默认的字符串是使用unicode码表示的,并且,处理字符串的API函数也全部变更为Unicode系列函数。
0x02 字符串检索法
OD初次载入待调试的程序时,都会先经历一个预分析的过程。此过程中会查看进程内存,程序中引用的字符串和调用的API都会摘录出来,整理到另外一个列表中,这样的列表对调试是相当有用的。
地址401007处有一条PUSH 004092A0命令,该命令中引用的004092A0处即是字符串"hello world".双击字符串
光标定位到main函数中调用MessageBoxW函数的代码处
OD中Go to(ctrl+G)命令可以进一步查看在内存4092A0地址处的字符串,
需要注意的是,4092A0这个地址,它与我们之前看到的代码区域地址(401XXX)不同,在程序中,代码与数据所在的区域是彼此分开的。
0x03 API检索法
1)在调用代码中设置断点
查看程序调用了哪些API函数,如图;
可以看到在40100E地址处,它是user32.MessageBoxW() API 双击它,光标即定位到调用它的地址处(40100E).
2)在调用代码中设置断点
OD并不能为所有可执行文件都列出API函数调用列表。
使用压缩器或者保护器后的程序,文件结构就会改变。
这种情况下,dll代码库被加载到内存后,我们可以直接向dll代码库添加断点,
在OD中打开内存映射窗口(alt+M)
内存映射窗口中显示了一部分helloword进程的内存,可以看到USER32库也被加载到了内存。
使用od的查看所有模块,可以列出被加载的dll文件中提供的所有api。搜索messageboxw:
USER32模块中有一个Export类型的MessageBoxW函数,双击
观察MessageBoxW函数的地址空间可以发现,它与helloworld使用的地址空间完全不同。
再看右下角的栈信息
这里对应一个00401014的返回地址,helloworld的main()函数调用完messageboxw函数后,程序执行流将返回到该地址处,
Ctrl+F9可以快速运行到MessageBoxW函数的RETN命令处,F7也可以但会到401014地址处,地址401014上方的就是地址40100E,它就是调用messageboxw函数的地方。