6.比较和跳转指令
(1)cmp eax,ecx 相当于sub eax,ecx 但不保存结果到第一个操作数。
根据结果改变零标志位(Z)。相等时,零标志位置1。
根据结果正负改变符号标志位(S)。运算结果为负时,置为1。
cmp允许寄存器与byte、word、dword类型的内存单元做比较。
eg:cmp ax,word ptr ds:[405000]
(2)test 两个数值进行与操作,结果不保存,改变相应标志位
eg:test eax,eax 这个指令可以确定eax是否为0
(3)关于寻找跳转,容易忽略提示框中的本地调用来自xxx。
7.call、ret
(1)ret指令不仅仅可用于子程序的返回,eg:
1 2 |
push 401256 ret |
等价于
1 |
jmp 401256 |
(2)改变程序代码后,反汇编界面右键重新分析。(否则分析可能出错,如栈中信息没有分析出函数间调用。)
8.循环、字符串指令和寻址方式
(1)loop [lable] 等价于 cx=cx-1 若cx!=0 转到lable
loopz/loope 等价于cx=cx-1 若cx!=0且zf=1 转到lable
loopnz/loopne 等价于cx=cx-1 若cx!=0且zf=0 转到lable
(2)movs 从一个地址向另一个地址复制数据。源地址保存在ESI寄存器中,目的地址保存在EDI寄存器中。
也可以写为movsb、movsw、movsd
注意拷贝的方向取决于方向标志位D
(3)rep 可作为一些指令的前缀,尤其是movs指令。前缀表示当前指令需要执行的次数ecx。每次循环ecx值减1。
(4)lods 该指令从源地址esi拷贝数据到eax中。
也有一次拷贝两个字节和一个字节的lodsw和lodsb
(5)stos 将eax的值拷贝到edi指向的内存单元中
也有一次拷贝两个字节和一个字节的stosw和stosb
(6)cmps 比较esi和edi指向内存单元的内容
执行算数减法运算,差值为0时候零标志位z置为1。
因为该指令影响零标志位z,所以可配合repe/repz前缀指令使用,直至ecx值为0或零标志位为0。
(7)间接寻址,若想在执行指令前看到真实地址。需在该指令下断点,执行时查看。
9.基本概念
(1)win操作系统支持的动态链接库dll文件与exe文件具有相同格式。动态链接库可导出函数供其他执行文件(exe、dll)调用,不需要在多个可执行文件中有相同的静态副本,而是把功能放置在dll。缩减可执行文件大小,节省内存。
(2)反汇编界面ctrl+N可获取API的名称列表(当前模块中的名称,请注意现在所在模块是否在主程序),按某一字母键,光标定位到以该字母起始的API上。可右键选择反汇编窗口跟随。
(3)retn 10h 即执行retn操作之外(返回后 删除返回地址,esp移动相应字节),esp还要向高地址移动10h来清理函数参数的堆栈空间。
(4)大部分程序启动的时候都会停在入口点处,还有一些程序通过一些修改让其再启动的时候不停在入口点处。
(5)command bar中输入?(API)可快速定位,ctrl+G输入显示的HEX即可。也可在ctrl+G中直接输入API,转到。注意API严格区分大小写。
10.断点
(1)设置一个断点后,二进制代码的变化
40104C处设置断点,在nop区汇编代码于40101A来查看40104C处二进制代码。执行后观察到eax。发现原来的33D2变为了CCD2。设置断点后,OD会将对应指令处的第一个字节替换为CC。但为了不影响界面显示效果,OD会将CC显示为原字节。但是可以从内存单元中读取出其真实的内容。反调试常用此法检测断点。
(2)内存断点
设置内存断点后,任何代码访问(读、写、执行)了该处代码都会触发异常。
如下图,选中数据区Hello,右键设置内存断点。F9继续执行时,会在40100E进入的函数里触发异常。
但当发现断下后,OD已经将内存页的访问属性设置正常了。如果F7就会正常继续运行。若程序其他代码部分再次尝试访问,会再次触发异常。
测试发现push并不会触发??bug?(但教学示例又说会断,见下,也是很迷惑了,skip一下,可能过段时间就会明白了?)(更新:找到了教学的cm然后测试,push确实会断……但指令不同,或许有什么差异把?继续迷茫)
—————————————————↓教学示例↓—————————————————
——————— 大专栏 OllyDbg学习之路-3——————————↑教学示例↑—————————————————
但内存访问断点有两个缺点,它不会出现在B断点列表中,所以自己要记得设置的位置。不能同时设置多个内存断点。
OD也可以对区段设置断点,上侧栏点击M打开内存窗口,选中部分右键可发现相应选项。
如果程序会检测函数首字节是否为0xCC的话,这时候F2断点可能就失效了,也许设置内存访问断点可以绕过这个检测。
设置内存访问断点也可以通过检测内存页的属性并恢复内存页的属性来进行保护。
11.硬件断点与条件断点
(1)先搜了搜网上资料了解一下内存断点和硬件断点的区别。
https://www.zhihu.com/question/52625624
摘一点:
win系统,内存是一页一页的。每个内存页都有属性,比如可申请当前页面里的内容不作为代码执行,因为只想用来存放数据,如果不这样设置可能会遭到恶意利用。(缓冲区溢出攻击)
内存断点所做的是将所下断点地址所在的内存页增加一个PAGE_NOACCESS属性。该属性会把该内存页设为禁止任何形式访问,若访问则会触发一个内存访问异常。OD捕获该异常,判断触发异常的地址与下断点的地址是否相同,相同触发内存断点,暂停被调试程序运行,否则放行。
但内存断点很消耗资源,用它调试很多大型程序慢到几乎不可用。PAGE_NOACCESS属性设置会使一整个内存页无法访问。即程序访问该内存页非断点地址同样触发异常,OD收到异常后特殊处理,临时放行。
只在写入时候断下的内存断点是将内存页属性设置为PAGE_EXECUTE_READ。
虽然内存断点的效率经常很不理想,但是因为仅仅是修改了一个内存属性,所以内存断点可以下数量非常多、单断点范围非常大。这是它的优势。←我试了试,OD里面难道不是只能下一个内存断点吗。
关于硬件断点:CPU为程序调试中硬件断点提供6个寄存器作为支持,DR0/DR1/DR2/DR3/DR6/DR7。DR0~DR3四个寄存器用来存放欲下断的地址,DR6和DR7用来控制断点的大小和触发断点的时机。把用户需求转一下格式放入寄存器,等系统发消息,收到消息就暂停程序。
寄存器数量限制使得硬件断点最多4个,且OD在特定设置或插件影响下可能内部还会占用一两个用以辅助程序调试。可用数量就更有限了。并且每个断点的最大范围是4个字节。但由于CPU的直接支持,硬件断点的效率非常高,毕竟只是写了个寄存器。
so通常情况,能用硬件断点就别用内存断点。
(2)OD提供了一个窗口,菜单栏Debug-Hardware breakpoints,可用查看管理硬件断点。断点可设置1、2、4个字节的长度。4字节的只针对4的倍数的地址,2字节也只针对2的倍数的地址。
(3)硬件访问/写入断点是断在触发硬件断点的下一条指令处。而内存断点是断在触发断点指令处。
(4)条件断点实际上就是普通的CC断点,只不过该断点的触发需要满足设置的条件,如果满足设置的条件,那么程序就会中断下来,如果不满足条件的话,就和没有设置CC断点差不多。OD帮助文档里介绍了条件断点设置可以使用的符号以及书写方式。
(5)条件记录断点,除了有条件断点的作用,还能记录断点处函数表达式、参数的值。
(6)
条件记录断点编辑
条件记录断点触发在log中查看
12.消息断点
(1)获取编辑框中文本,通常使用的API是GetDlgItemTextA或者GetWindowTextA,也可以使用Unicode版的API函数GetDlgItemTextW或者GetWindowTextW,或发送消息直接获取编辑框中文本。但是,不能指望从GetDlgItemTextA或者GetWindowTextA下手获取一些保护强度比较高的编辑框控件中的文本。
(2)有时候从Ctrl+N打开的列表里有GetDlgItemTextA,但并不意味这个函数就是用来读取用户输入的用户名和序列号的,可能是获取用户输入的其他字段,或仅仅是作者故意添加来误导的。且API函数可用不同方式来动态加载,不一定要通过导入表。(比如可在别的段中构建一个类似导入表的东西来进行函数绑定,逆向就不太好找了)
(3)消息断点和普通CC断点区别为,CC断点在程序启动前就能设置,但对消息断点,只能在窗口创建后才能设置。所以run到窗口出现,点w打开windows窗口。选中需要行,右键可设置消息断点。打开断点b窗口,右键编辑条件,可以发现消息断点也是一个条件断点。
(4)单击鼠标左键时,系统会发送WM_LBUTTONDOWN消息,松开鼠标左键,会发送WM_LBUTTONUP。L代表左键。一般选择Break on any window(当前程序的任何窗口接收到该消息都中断),以及Pause program(中断程序),还要选中下面的Log WinProc arguments(记录消息过程函数的参数值)。
(5)触发的消息断点会断在一段不属于主程序的陌生代码。回到主程序的代码处:点击菜单栏M,主程序代码是401000开头的区段,选中这个区段code,右键设置内存断点。然后F9即可。不清除内存访问断点,F9运行,发现是单步。继续单步,就会发现一些感兴趣的API或代码了。
(6)为了记录下程序接收到的(按钮,输入的文本内容)等所有信息,可以对消息处理函数TranslateMessage或者DefWindowProcA设置条件断点。如果想完整的记录下这两个API函数的参数信息,通过命令栏BP给TranslateMessage和DefWindowProcA设置断点。打开B窗口,分别右键选择反汇编窗口跟入。在断点这一行右键,条件记录。expression填入MSG。打开L窗口,右键先保存到文件,然后run。在这个日志文件,就可以在其中挑选感兴趣的消息,设置相应消息断点印证猜想了。
原文地址:https://www.cnblogs.com/liuzhongrong/p/12289246.html