作者:土人甜层_233 | 来源:互联网 | 2023-09-06 12:00
拆解一个Windows程序要比拆解一个DOS程序容易得多,因为在Windows中,只要API函数被使用,想对寻找蛛丝马迹的人隐藏一些东西是比较困难的。因此分析一个程序,用什么API
拆解一个Windows程序要比拆解一个DOS程序容易得多,因为在Windows中,只要API函数被使用,想对寻找蛛丝马迹的人隐藏一些东西是比较困难的。因此分析一个程序,用什么API函数作为切入点就显得比较关键了。
先把TraceMe这个序列号验证程序流程图给大家展示出来:
TraceMe序列号验证程序流程图
运行源文件如下图:
一 加载目标文件调试
– System breakpoint:系统断点,OllyDbg用CreateProcessA加载DEBUG_ONLY_THIS_PROCESS参数执行,程序运行之后会触发一个INT13,在系统空间里。
– Entry point of main module:主模块的入口点,即文件的入口点。
– WinMain:程序的WinMain()函数入口点。
- 1.虚拟地址:一般情况下,同一程序的同一条指令在不同系统环境下此值相同。
- 2.机器码:这就是CPU执行的机器代码。
- 3.汇编指令:和机器码对应的程序代码。
错误且笨重的调试方法:从开始进入一直F8单步过,停下时设置断点,再进入该断点(一般为call),通过不断的设置断点,取消旧断点,进入新断点的方法找突破,最后却陷入了程序的死循环。费时又费力。
正确的方法:找到API函数,跟进,本例中是GetDlgItemTextA或GetDlgItemTextW,在它下方的调用处及以下会出现之前写入的用户名和密码,通过设置Z标志位(本例为Je处),将je修为nop,保存、备份。就完成了TraceMe。
以上是调试成功了,下面用相应指令修改,生成可执行文件。
↓
↓
↓
↓
二 调试技巧总结
1. F2下断点,Alt+b打开断点编辑器,可编辑所有下过的断点,空格键可快速切换断点状态。
2. 当位于某个CALL中,这时想返回到调用这个CALL的地方时,可以按“Ctrl+F9”快捷键执行返回功能。这样OD就会停在遇到的第一个返回命令(如RET、RETF或IRET)。
3. 如果跟进系统DLL提供的API函数中,此时想返回到应用程序领空里,可以按快捷键“Alt+F9”执行返回到用户代码命令。
4.所谓领空,实际上就是指在某一时刻,CPU执行的指令所在的某段代码的所有者。
5.如004013F7这类地址一般是可执行文件领空,7C8114AB这类大地址一般是系统DLL所在的地址空间。
6.程序通常读取文本框内容的字符串用的是以下两个函数:
– GetDlgItemTextA(GetDlgItemTextW)
– GetWindowTextA(GetWindowTextW)
7. 一般我们要结合经验通过猜测的方式多尝试几遍设陷阱,找出相关的函数。
8. 按“Ctrl+G”键打开跟随表达式的窗口。
9. 也可以通过“Ctrl+N”键打开应用程序的导入表(输入表),然后查看应用程序总共导入了哪些函数来以此推断需要在哪里挖坑下陷阱!
10. 关于返回值,汇编代码的返回值约定是存放在eax这个寄存器里边的,如果32位的eax不够存放返回值,系统会将返回值放在内存某个位置并把该位置的地址放在eax返回。