记两次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 

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

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函数处下断点才可以正确中断程序。

你可能感兴趣的:(逆向,编译器,c++,后端,安全)