其实之前一直也都是说,Debug是调试版本,Release是发行版本,发行版本会对程序进行优化,实现代码的精简,效率的提高。这个问题一直也仅仅就是当做教程里的话而已。最近在逆向一个程序在还原代码的时候无聊了,顺便看了下源代码编译出来的程序在调试版本和发行版本里有什么异同。
实验程序:test.cpp
- #include "stdafx.h"
- int test(int a,int b);
- int _tmain(int argc, _TCHAR* argv[])
- {
- int i;
- i=test(1,2);
- printf("%5d",i);
- return 0;
- }
- int test(int a,int b)
- {
- int c,d,i;
- d = a+b;
- i = 1;
- while (c < 100)
- {
- c = c+i;
- }
- switch (c)
- {
- case 0:
- {
- d=1;
- };
- case 1:
- {
- d=c;
- break;
- };
- default:
- {
- d=0;
- break;
- }
- }
- return d;
- }
在Release模式下,会得到如下形式:
- wmain:
- 00401000 push ecx
- 00401001 mov eax,dword ptr [esp]
- 00401004 cmp eax,64h
- 00401007 jge wmain+0Eh (40100Eh)
- 00401009 mov eax,64h
- 0040100E mov ecx,eax
- 00401010 sub ecx,0
- 00401013 je wmain+1Ch (40101Ch)
- 00401015 sub ecx,1
- 00401018 je wmain+1Ch (40101Ch)
- 0040101A xor eax,eax
- 0040101C push eax
- 0040101D push offset string "%5d" (4020F4h)
- 00401022 call dword ptr [__imp__printf (4020A0h)]
- 00401028 xor eax,eax
- 0040102A add esp,0Ch
- 0040102D ret
而在Debug模式下,会得到
- wmain:
- 004113B0 push ebp
- 004113B1 mov ebp,esp
- 004113B3 sub esp,0CCh
- 004113B9 push ebx
- 004113BA push esi
- 004113BB push edi
- 004113BC lea edi,[ebp-0CCh]
- 004113C2 mov ecx,33h
- 004113C7 mov eax,0CCCCCCCCh
- 004113CC rep stos dword ptr es:[edi]
- 004113CE push 2
- 004113D0 push 1
- 004113D2 call test (41100Ah)
- 004113D7 add esp,8
- 004113DA mov dword ptr [i],eax
- 004113DD mov esi,esp
- 004113DF mov eax,dword ptr [i]
- 004113E2 push eax
- 004113E3 push offset string "%5d" (41573Ch)
- 004113E8 call dword ptr [__imp__printf (4182BCh)]
- 004113EE add esp,8
- 004113F1 cmp esi,esp
- 004113F3 call @ILT+325(__RTC_CheckEsp) (41114Ah)
- 004113F8 xor eax,eax
- 004113FA pop edi
- 004113FB pop esi
- 004113FC pop ebx
- 004113FD add esp,0CCh
- 00411403 cmp ebp,esp
- 00411405 call @ILT+325(__RTC_CheckEsp) (41114Ah)
- 0041140A mov esp,ebp
- 0041140C pop ebp
- 0041140D ret
感觉从Debug的Dasm可以还原出完整的基本源码,而Release版本,还原的风格可能已经完全改变了,即使还原也和原文有区别,因为代码格式的精简导致的。而且从某种情况说,针对某种情况的代码,诸如for循环等等在不同的代码环境中,优化得到的代码也不大相同。由于我采用的VS2008编译,自动加上了CheckEsp等等操作,是VS2008的安全优化,敬请忽略。