Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
相信不少朋友用C++开发程序时,用debug版本可以运行,但用Release版本就不行了,或者倒过来。根本原因就是Release版本优化的问题,如果用Release版本调试会看到“面目全非”的反汇编代码,而debug版本没有做任何优化,代码与汇编能一一对上。
本人菜鸟一枚,抛砖引玉举几个例子,在代码调试的角度看看Release对代码做了什么手脚,为了篇幅下面只贴上Release版本反汇编代码,读者可以自己运行看看Debug版本的。
欢迎补充!
/*********************************
运行和调试环境:VS2010 + win 7
程序类型:控制台
配置:默认
/*********************************
1. 变量优化------国家穷,能省就省
#include "stdio.h"
void main(){
int intA;
int intB;
char ch[5]={0};
char *pCh=ch;
pCh+=11111;//数组越界
*pCh='q';//内存非法写入数据
intA=100;
scanf("%d\n",&intB);
printf("%d\n",intA);
return;
}
#include "stdio.h"
void main(){
002A1000 push ebp
002A1001 mov ebp,esp
002A1003 sub esp,8 //栈顶抬高8个字节,即分配8字节空间
002A1006 mov eax,dword ptr [___security_cookie (2A3000h)]
002A100B xor eax,ebp
002A100D mov dword ptr [ebp-4],eax //4个字节GS栈保护security_cookie
int intA; //优化掉
int intB;
char ch[5]={0};//优化掉
char *pCh=ch; //优化掉
pCh+=11111; //优化掉
*pCh='q'; //优化掉
intA=100; //优化掉
scanf("%d\n",&intB);
002A1010 lea eax,[ebp-8]
002A1013 push eax //可以看出为intB分分配4字节空间
002A1014 push offset string "%d\n" (2A20F4h)
002A1019 call dword ptr [__imp__scanf (2A20A4h)]
printf("%d\n",intA);
002A101F push 64h //立即数,intA被优化掉了
002A1021 push offset string "%d\n" (2A20F4h)
002A1026 call dword ptr [__imp__printf (2A209Ch)]
return;
}
#include "stdio.h"
void main(){
int intA;
int intB;
scanf("%d",&intB);
if (intB)
{
intA=13;
}else intA=16;
printf("%d",intA);
}
#include "stdio.h"
void main(){
01361000 push ebp
01361001 mov ebp,esp
01361003 push ecx
int intA;
int intB;
scanf("%d",&intB);
01361004 lea eax,[intB] //intB变量栈空间,这里相当lea eax,dword ptr[ebp-4]
01361007 push eax
01361008 push offset string "%d" (13620F4h)
0136100D call dword ptr [__imp__scanf (13620A4h)]
if (intB) //if语句,有木有发现,怎么没有cmp,jmp这些明显判断语句?往下看
01361013 mov eax,dword ptr [intB] //取出intB的值,下面假设输入intB为5
01361016 neg eax //求反,影响标志位CF,如果intB非零,CF=1,否则为0。这里CF=1
01361018 sbb eax,eax //带位相减。由于CF=1,所以eax=0xFFFFFFFF
0136101A and eax,FFFFFFFDh //与运算后eax=0xFFFFFFFD
0136101D add eax,10h //溢出,结果为eax=0xD(十进制13),所以说0xFFFFFFFD相当于-3
{
intA=13; //<-----------13
}else intA=16;//
printf("%d",intA);
01361020 push eax
01361021 push offset string "%d" (13620F4h)
01361026 call dword ptr [__imp__printf (136209Ch)]
0136102C add esp,10h
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)