Ollydbg中F8的Bug

用Ollydbg调试以下代码,可以展示出其F8单步步过所存在的一个Bug:

#include <windows.h>

int main()
{
    CONTEXT ctx;
    ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
    GetThreadContext(GetCurrentThread(), &ctx);
    ctx.Dr7 = 0x101;
    ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
    SetThreadContext(GetCurrentThread(), &ctx);

    return 0;
}

代码中会调用SetThreadContext设置调试寄存器dr0有效(并未指定dr0的值)。

如果你用Od在call SetThreadContext处F8,程序基本上将会跑飞,不会停在下一条指令处。

这和Od的F8的原理有关。

重启程序,来到call GetThreadContext后按F8,如下图:

内存区0x0012FC80是局部变量ctx的地址,内容是刚刚从GetThreadContext获得的。右边是当前调试寄存器的值。

可以看到内存偏移0x0012FC84处,即ctx.Dr0的值为0x00401023,与右边寄存器窗口中DR0的值相等。

Od的F8原理,若当前指令为call,则会在call指令的下一条指令即返回指令处设置一个一次性的硬件断点。

也就说,cCall GetThreadContext即0x0040101D处按F8,Od会在下一条指令即0x00401023处设置一个硬件断点,当前使用dr0存放地址。

设置硬件断点的方法是调用SetThreadContext,使得右边寄存器窗口的DR0变成0x00401023。

之后被调试程序调用GetThreadContext,得到的其实是用SetThreadContext设置过的内容,局部变量ctx.Dr0也就变成了0x00401023。

基于上面的道理,下面F8步过 call esi 就会导致右边窗口DR0的值发生改变,这里不要让它改变,让它依旧保持为0x00401023。

直接F9来到SetThreadContext处,先别按F8,而是按回车进入SetThreadContext内部,在第一条指令处下断。

这样做的目的是为了在SetThreadContext处按F8后能先进入其内部,而非直接运行函数。

按F8断在SetThreadContext的开头处:

打开硬件断点列表,发现Od记录了一个一次性硬件断点,地址为0x00401041,与右边调试寄存器内DR0的值相同。

这正好是call SetThreadContext的下一条指令的地址(call SetThreadContext的返回地址)。

这印证了前面所说在call处F8会在返回地址处设硬件断点。

关键的来了。

如果接着在call NtSetContextThread处F8,或者不在SetThreadContext内部下断而直接在call SetThreadContext处F8,程序就会跑飞。

原因是这样的:

在call SetThreadContext按F8时,根据前面所述原理,Od会在下一条指令即0x00401041处设硬件断点,以期望程序运行到那里断下来。

那样就会形成我们平常见到的效果,在call处F8,接着断在下一行。

Od是这样想的,但是此时调用的函数是SetThreadContext,该函数也会设置一遍寄存器的值,会把Od设置过的内容覆盖掉。

本来Od设置了DR0为0x00401041,而被调试程序调用SetThreadContext,将DR0设置成了局部变量ctx中的内容,即0x00401023。

这使得0x00401041断点无效,程序之后将不能断在0x00401041,如果后面没有其他断点,程序将一直跑下去。

结果就是跑飞了,完全没有平常F8见到的效果。

但是Od很傻,它的硬件断点列表中还记录着自己设置的内容,并不是调试寄存器的真实值。

重启程序,在call SetThreadContext之后的 pop esi 处下断,然后在call SetThreadContext处按F8,会发现程序直接断在了 pop esi 处。

就像按了F9一样。程序没有停在call SetThreadContext的下一条指令xor eax, eax处,可见Od设置的DR0失效了。

可是Od的硬件断点列表中依然有指令xor eax, eax的地址0x00401041,和右边寄存器窗口中的真实值不符。

接着再按F8,会发现Od又将自己硬件断点列表中的值写回调试寄存器了。

这个Bug不仅Od原版存在,而且各种加插件版本的Od也有。

归根结底,这是Od内部源码设计的问题,没有考虑周全,最终变成了一种反调试的行为。

时间: 2024-10-15 23:00:28

Ollydbg中F8的Bug的相关文章

关于AFNetworking中header的bug问题

关于AFNetworking中header的bug问题 [摘要:AFNetworking那个正在ios开辟中便未几道了,网上一搜一大推,然则详细用法我便没有道了,偶然间我会整顿一下详细的一些用法.本日首要接头一下我正在应用傍边闭于header上里的一些bug问] AFNetworking这个在ios开发中就不多说了,网上一搜一大推,但是具体用法我就不说了,有时间我会整理一下具体的一些用法.今天主要讨论一下我在使用当中关于header上面的一些bug问题. 首先关于一个登录保持,我和服务器人员通过

R语言学习中的小bug:R中矩阵相乘错误于A %*% B: 需要数值/复数矩阵/矢量参数

遇到了小bug: R中矩阵相乘错误于A %*% B: 需要数值/复数矩阵/矢量参数 看到网上别人的做法,发现了用class(A)和class(B)之后才发现,是因为读入的时候数据的类型不对,A.B的类型并不是matrix,才导致了这个问题. 用as.matrix来变型一下,就OK了. R语言学习中的小bug:R中矩阵相乘错误于A %*% B: 需要数值/复数矩阵/矢量参数,布布扣,bubuko.com

CSS中常见的BUG调试

1.布局--layout 布局是windows提出的概念,用于控制元素的尺寸和定位. 拥有布局的元素负责自身及其子元素的尺寸及定位,而没有布局的元素仅仅能依靠近期的祖先元素进行控制. 通常在IE6中出现的BUG.非常可能是由于布局的缘故而产生的,因而修复IE中BUG的时候,第一件事就是尝试通过规则迫使元素拥有布局来看是否能修复. 默认情况下拥有布局的元素包含:body.html(标准模式下).table.tr.td.img.hr.input.select.textarea.button.ifra

onbeforeunload与a标签在IE中的冲突bug(转载)

onbeforeunload与a标签在IE中的冲突bug onbeforeunload 是window的一个事件,目前Firefox,IE都支持,主要用来提示用户是否真的要离开该页面,通常在一些比较重要的数据提交之前,防止用户误操作导致数据丢失.典型的应用如gmail中,在写邮件的时候,如果刷新页面或者关闭页面,会出现提示. 但是在IE下点击一些a标签时,也会触发onbeforeunload事件.并且href中写javascript:void(0)也不行,而在Firefox中不会出现类似的情况.

react项目中遇到的BUG

前情提要:最近在学习react,然后就将项目中遇到的bug总结下来,作为借鉴! 项目结构: demo |app |app.js |main.js |center.js |toutiao.js |quanzi.js |shipin.js |dinggou.js |style.css |build |index.html |.babelrc |package.json |node_modules |webpack.config.js html文件: <!DOCTYPE html> <html

JSPatch来更新已上线的App中出现的BUG(超级详细)

JSPatch来更新已上线的App中出现的BUG(超级详细) 字数2858 阅读422 评论15 喜欢29 JSPatch的作用是什么呢? 简单来说:(后面有具体的操作步骤以及在操作过程中会出现的错误) 1.iOS应用程序上架到AppStore需要等待苹果公司的审核,一般审核时间需要1到2周.虽然程序在上架前会经过测试人员的测试,但有时候还是不免会发生新版本上线后出现严重的bug,导致用户刚升级到新版本就出现crash,严重影响用户体验. 2.这时能做的只是赶紧修复bug然后提交等待漫长的App

IE6中的常见BUG与相应的解决办法

开发前端的同学一定都知道,IE6是兼容BUG最多的浏览器,它不支持PNG alpha通道暂且不论.其文档的解析理解规范也引起了诸多恼人的BUG,有时甚至让人感到绝望.本文主要讲解一些比较容易遇到的IE6BUG,以及解决的办法. 一.IE6双倍边距bug 当页面上的元素使用float浮动时,不管是向左还是向右浮动:只要该元素带有margin像素都会使该值乘以2,例如“margin-left:10px” 在IE6中,该值就会被解析为20px.想要解决这个BUG就需要在该元素中加入display:in

avascript 运动中Offset的bug解决方案

这篇文章主要介绍了Javascript 运动中Offset的bug解决方案,需要的朋友可以参考下 我们先来看看这个bug 是怎么产生的. 代码如下: 1 <style type="text/css"> 2 #div1 { 3 width: 200px; 4 height: 200px; 5 background: red; 6 7 } 8 </style> 代码如下: 1 <body> 2 <div id="div1">

var 在异步中引发的 bug

问题复现 for (var i = 0; i < 10; i++) { $http.get("/uri").then(function(data)){ mydata[i].data = data; } } 报错: unable to get property 'mydata' of null 问题原因 第一步,听说 var 和 let 作用域范围不同,所以特定尝试下 let,看是否能解决这个 bug. for (let i = 0; i < 10; i++) { $http