OllyDbg学习之路-3

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

时间: 2024-10-29 09:09:42

OllyDbg学习之路-3的相关文章

Azure云平台学习之路(三)——Cloud Services

1.什么是云服务? 能够部署高度可用的且可无限缩放的应用程序和API.简而言之,就是你写的CMD程序按照一定的框架进行少量修改就能运行在Azure云平台上. 2.Azure云服务有什么特点? (1)专注应用程序而不是硬件,PaaS的一种. (2)支持多种框架和语言. (3)集成了运行状况监视和负载平衡. (4)自动缩放优化成本和性能 3.建立云服务之前,我们需要建立一个云存储,来记录我们的程序的日志信息(当然,这不是必须的) (1)选择左边导航栏的"存储".主面板上显示的是所有已有的存

linux学习之路之LVM

试想一种情况,当初我们在规划磁盘的时候,只给某一个磁盘或分区之划分了30G的容量,但是后来,随着业务的需求,该磁盘或者分区的使用量会越来越大,等到以后再有数据存放时,发现该磁盘或者分区的容量不够用,此时该怎么办了?可以新增一个磁盘,经过格式化,挂载等过程就可以使用这个磁盘了,再将原来磁盘的数据完全的复制过来.等到后来又发现,规划的磁盘又太大了,然后又使用上述方法来减少磁盘的大小.虽然这种方法可行,但是效率低,比较复杂.不应该是我们首选的方法. 当然,我们可以这样做,将多个磁盘或者分区(PV)组合

我的算法学习之路

关于 严格来说,本文题目应该是我的数据结构和算法学习之路,但这个写法实在太绕口--况且CS中的算法往往暗指数据结构和算法(例如算法导论指的实际上是数据结构和算法导论),所以我认为本文题目是合理的. 这篇文章讲了什么? 我这些年学习数据结构和算法的总结. 一些不错的算法书籍和教程. 算法的重要性. 初学 第一次接触数据结构是在大二下学期的数据结构课程.然而这门课程并没有让我入门--当时自己正忙于倒卖各种MP3和耳机,对于这些课程根本就不屑一顾--反正最后考试划个重点也能过,于是这门整个计算机专业本

一个女大学生的代码学习之路(二)

首先说一下,写这种文章是由于我在四月四日晚上,在手动搭建自己的第一个ssh项目的时候,遇到了一个配置的问题,怎么解决也弄不好,当时是四号晚上九点,我看了一眼表,我就想两个小时之内,我要是能搞定就算行了,但是其实,我搞到三点才OK(凌晨),那时候已经是五号了,转天是一家子去扫墓的时候,结果我居然以这种一个理由没有去,理由是我太累了么?我只是就是搭了一个架子,就是由于我的包太混乱了,导致不兼容,所以tomcat总也不启动,你可能认为好笑,这么简单一个问题怎么就费这多多时间呢,但是作为一个刚接触三框架

kafka学习之路(二)——提高

kafka学习之路(二)--提高 消息发送流程 因为Kafka内在就是分布式的,一个Kafka集群通常包括多个代理.为了均衡负载,将话题分成多个分区,每个代理存储一或多个分区.多个生产者和消费者能够同时生产和获取消息.     过程: 1.Producer根据指定的partition方法(round-robin.hash等),将消息发布到指定topic的partition里面 2.kafka集群接收到Producer发过来的消息后,将其持久化到硬盘,并保留消息指定时长(可配置),而不关注消息是否

Android开发学习之路--网络编程之xml、json

一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载xampp,然后安装之类的就不再多讲了,参考http://cnbin.github.io/blog/2015/06/05/mac-an-zhuang-he-shi-yong-xampp/.安装好后,启动xampp,之后在浏览器输入localhost或者127.0.0.1就可以看到如下所示了: 这个就

Qt学习之路

  Qt学习之路_14(简易音乐播放器) Qt学习之路_13(简易俄罗斯方块) Qt学习之路_12(简易数据管理系统) Qt学习之路_11(简易多文档编辑器) Qt学习之路_10(Qt中statusBar,MessageBox和Timer的简单处理) Qt学习之路_9(Qt中Item Widget初步探索) Qt学习之路_8(Qt中与文件目录相关操作) Qt学习之路_7(线性布局和网格布局初步探索) Qt学习之路_6(Qt局域网聊天软件) Qt学习之路_5(Qt TCP的初步使用) Qt学习之路

Java学习之路(二)--Thinking in Java

针对昨天Java学习之路(一)--Thinking in Java中的类的静态方法不能访问创建非静态类,给出了将内部类修改成为static静态类,操作方便简单.现在给出第二种不需要添加删除的另一种极为高效的方式.可以将内部类从你所创建的类中复制粘贴到类外,作为一个外部类,在static主方法中就可以创建类的引用了. 源代码如下: ? class test{ int s; char c; } public class test1 { public static class test{ int s;

Linux常用命令学习之路(每天都会更新)

Linux学习之路 1:显示日期时间的命令:date date->可以显示出星期月日时分秒年 date +%Y/%m/%d->可以显示出:年/月/日(date后面必须有至少一个空格) date +%H:%M:%S->显示出:时:分:秒(date后面必须有至少一个空格) date +%h->显示:月(英文的) 2:显示日历命令:cal: cal ->显示当月的日历 cal 2009->显示整个2009的日历 cal 10 2009->显示2009年10月的日历 3: