首页 电脑 电脑学堂 查看内容

让VC++直接生成汇编代码

2009-2-12 03:34 874 0

摘要: 原始出处:脚本安全小组(www.cnsst.org)信息来源:邪恶八进制信息安全团队(www.eviloctal.com)文章作者:独孤依人(cnsst)文章备注:20...
关键词: 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)做客。
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部