记两次OD调试的过程,OD下断点无效的解决过程

问题

在使用OD(OllyDbg)的过程中,我们可以使用断点开进行反汇编代码的暂停执行,通常在调试自己代码的时候我们会使用搜索expresion的方式来在特定代码处下断点,但是有时候我们成功在所谓有效的expression处下了断点之后执行代码,代码却没有暂停,直接运行到程序结束。这是为什么呢。

注:expression在这里表示一个可以被OD检测到的函数

答案

这是因为我们的代码在编译的过程中,由于

  • 不同字符集的设置
  • 编译器的优化过程
  • 编译器的自主选择

在我们的代码编译之后,可执行文件并没有调用我们认为程序会调用的函数。

解决方法

  • 在进行expression搜索的过程中或者bp expression命令的时候采用对应字符集的expression,例如在你编写程序的时候使用了MessageBox函数,编译后就是unicode字符集对应的窗口函数MessageBoxWASCLL字符集对应的窗口函数MessageBoxA
  • 在使用vs系列编译器时,关闭c、c++的编译优化选项,在使用gccg++命令时,使用-O参数来关闭编译器优化,例如gcc -O0 a.c -o a.exe
  • 某些时候即使你关闭了代码优化,你所使用的函数也不会成为最后编译器编译所使用的函数,例如在你仅仅使用printf函数来输出一串简单的字符时,你的编译器还是会将其替换为puts函数。

例子

例1

程序a.c如下

#include <windows.h>

int a = 1;

int main(void){
    MessageBox(0,NULL,NULL,MB_OK);
	
	// 需要调试的部分开始
    a = 65536
	// 需要调试的部分结束
	
    return 0;
}

使用Mingw编译

g++ -O0 a.c -o a.exe

正确姿势:OD中你必须使用对应的字符集下的函数才能成功对MessageBox函数调用处下断点,在gccg++中默认使用的是ASCLL字符集,你必须在MessageBoxA函数处下断点才能成功暂停程序。

例2

程序b.c如下:

#include<cstdio>

void test(){
	return;
}

int main(void){
	printf("test start \n");
	
	// 需要调试的部分开始
	__asm__("nop");
	test();
	// 需要调试的部分结束
	
	printf("test stop  \n");
	return 0;
}

使用Mingw编译

g++ -O0 b.c -o b.exe

正确姿势: 在编译的过程中,虽然使用了-O0停用编译优化,但是由于printf函数用的太简单,编译器还会有可能使用puts函数替换printf函数,此时在puts函数处下断点才可以正确中断程序。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值