| 关键词: nbsp DWORD ebp mov PTR 代码 程序 SEGMENT 800 编译 |
原始出处:脚本安全小组(www.cnsst.org)信息来源:邪恶八进制信息安全团队(www.eviloctal.com)文章作者:独孤依人(cnsst)文章备注:2007年10月27日星期六晚作于海南海口看了李子明写的那篇《让汇编揭开死循环的神秘面纱》后,突然有个想法,那就是能不能把C++的代码直接翻译成ASM的,那样对于我们程序分析就更加清析了,也不用反汇编去分析了。在网上没看到相关类似的教程,于是,便有了此文。首先,我们来看看子明兄原文中的小程序:#include <stdio.h>void main(){ int i, b[10]; for ( i = 0; i <= 10; i++ ) { b = 0; }}请问这个程序是否有错?A.正常 B.越界 C.死循环我想很多朋友会选择B,当然不排除有选择A和C的,其实正确答案是C,子明兄在文章中用逆向工程把原理已经说得很清楚了,这里就不再累述了。从子明兄文章里我们可以总结出逆向工程具体的流程大概如下: 1、 高级语言程序(C、C++、...)-->编译-->生成可执行程序(机器码/汇编语言) 2、可执行程序-->反编译(IDA、OD、WIN32DASM等反编译软件)-->汇编代码 3、汇编代码-->分析、了解汇编代码程序流程-->进行逆向分析或者实现某个功能 4、逆向工程完毕在我们没有程序源代码的情况下,做逆向分析也只有按照上述的流程(各位大大有什么更好的方法还希望分享下),然后我们在有源代码的情况,是不是可以直接来生成汇编代码而省去反编译那一步呢?答案是肯定的。我们先把程序做如下改变(看汇编代码的时候更清楚):/* Author : 独孤依人(CNSST) Date : 2007-10-27 Content: 代码演示让VC++直接生成汇编代码程序示例*/#include <stdio.h>void main(){ int i=0, b[10]={1,2,3,4,5,6,7,8,9,10}; for ( i = 0; i <= 10; i++ ) { b = 0; }}接下来,我们通过如下几步设置:1) 选择菜单工程(Project)设置(Settings),出现如图1所示界面: 图1=800) window.open('/uploadfile/200902/20090212103343287.webp');" src="/uploadfile/200902/20090212103343287.webp" onload="if(this.width>'800')this.width='800';if(this.height>'800')this.height='800';" border=0> 2) 选择C/C++标签,然后在分类(Category)中选择Listing Files,然后在列表文件类型(Listing file type)选择Assembly with Source code,如果图2所示: 图2=800) window.open('/uploadfile/200902/20090212103343554.webp');" src="/uploadfile/200902/20090212103343554.webp" onload="if(this.width>'800')this.width='800';if(this.height>'800')this.height='800';" border=0> 这样设置之后就可以输出汇编代码了。3) 编译构件执行后,我们看到Debug目录已生成了对应的汇编代码,如图3所示: 图3=800) window.open('/uploadfile/200902/20090212103343263.webp');" src="/uploadfile/200902/20090212103343263.webp" onload="if(this.width>'800')this.width='800';if(this.height>'800')this.height='800';" border=0> 下面,我对生成的汇编代码做简单的解释(CNSST注://……为我加上的解释):TITLE C:\Documents and Settings\Administrator\桌面\test\test.cpp //程序名 .386P //编译成386保护模式指令include listing.incif @Version gt 510 //判断汇编语言编译器版本是否大于5.1.model FLAT //以FLAT内存模式编译Else //以下声明一些段,之后对应C的相关代码,程序生成时都有相关注释。_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'_TEXT ENDS_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'_DATA ENDSCONST SEGMENT DWORD USE32 PUBLIC 'CONST'CONST ENDS_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'_BSS ENDS$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'$$SYMBOLS ENDS$$TYPES SEGMENT BYTE USE32 'DEBTYP'$$TYPES ENDS_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'_TLS ENDS; COMDAT _main_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'_TEXT ENDSFLAT GROUP _DATA, CONST, _BSS //所有的段共享FLAT组 ASSUME CS: FLAT, DS: FLAT, SS: FLATendifPUBLIC _main; COMDAT _main_TEXT SEGMENT_i$ = -4_b$ = -44_main PROC NEAR ; COMDAT; 4 : { push ebp mov ebp, esp sub esp, 108 ; 0000006cH push ebx push esi push edi lea edi, DWORD PTR [ebp-108] mov ecx, 27 ; 0000001bH mov eax, -858993460 ; ccccccccH rep stosd; 5 : int i=0, b[10]={1,2,3,4,5,6,7,8,9,10}; mov DWORD PTR _i$[ebp], 0 mov DWORD PTR _b$[ebp], 1 mov DWORD PTR _b$[ebp+4], 2 mov DWORD PTR _b$[ebp+8], 3 mov DWORD PTR _b$[ebp+12], 4 mov DWORD PTR _b$[ebp+16], 5 mov DWORD PTR _b$[ebp+20], 6 mov DWORD PTR _b$[ebp+24], 7 mov DWORD PTR _b$[ebp+28], 8 mov DWORD PTR _b$[ebp+32], 9 mov DWORD PTR _b$[ebp+36], 10 ; 0000000aH; 6 : for ( i = 0; i <= 10; i++ ) mov DWORD PTR _i$[ebp], 0 jmp SHORT $L529$L530: mov eax, DWORD PTR _i$[ebp] add eax, 1 mov DWORD PTR _i$[ebp], eax$L529: cmp DWORD PTR _i$[ebp], 10 ; 0000000aH jg SHORT $L531; 8 : b = 0; mov ecx, DWORD PTR _i$[ebp] mov DWORD PTR _b$[ebp+ecx*4], 0; 9 : } jmp SHORT $L530$L531:; 10 : } pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0_main ENDP_TEXT ENDSEND直接生成的汇编代码看起来比反汇编的直观多了,再来分析其中的原理,挑出其中的一段代码如下:; 5 : int i=0, b[10]={1,2,3,4,5,6,7,8,9,10}; mov DWORD PTR _i$[ebp], 0 mov DWORD PTR _b$[ebp], 1 mov DWORD PTR _b$[ebp+4], 2 mov DWORD PTR _b$[ebp+8], 3 mov DWORD PTR _b$[ebp+12], 4 mov DWORD PTR _b$[ebp+16], 5 mov DWORD PTR _b$[ebp+20], 6 mov DWORD PTR _b$[ebp+24], 7 mov DWORD PTR _b$[ebp+28], 8 mov DWORD PTR _b$[ebp+32], 9 mov DWORD PTR _b$[ebp+36], 10 ; 0000000aH; 6 : for ( i = 0; i <= 10; i++ ) mov DWORD PTR _i$[ebp], 0 jmp SHORT $L529这段代码让迷团浮出水面,具体分析见子明兄原文,这里也不再累述。此文到此算是结束了,对逆向工程也许没有什么用,但对于学习逆向工程的朋友或许有些帮助。本文方法只是一个小技巧而已,除此之外,还可以通过命令行程序CL.exe来做到,这里也不再累述。最后,祝愿小组所有的兄弟学业、爱情、事业有成,同时欢迎大家来我们脚本安全小组(www.cnsst.org)做客。 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|