zoukankan      html  css  js  c++  java
  • MASM的反反汇编技术

    reference:http://www.aogosoft.com/downpage.asp?mode=viewtext&id=54

    由于汇编语言是与机器语言机器码一一对应的,所以程序的代码非常简洁,编译、链接程序不会在其中加入任何其它代码,所以,用Win32DASM等把汇编工具反汇编汇编语言写的程序,其列出的汇编代码几乎与编写的顺序、过程、代码一模一样,这也是汇编语言简洁的证据。
    但是这种过于简洁的代码却给了破解者提供了方便,破解者只需要有一定的Windows SDK编程与汇编的经验,破解就非常简单,根本不需要用SoftICE这些动态工具就可以破解。于是,相应的防止跟踪的技术就出来了,比如花指令、不按规则调用API等等,今天就花指令和大家研究研究。
    花指令,其实就是在程序中加入一些字节来干扰静态工具反汇编,毕竟汇编工具没有人的思维,所以这招非常好骗。

    我在RadAsm中写入以下代码:

        .386
        .Model Flat, StdCall
        Option Casemap :None
    ;_____________________________________________________________
    
        Include windows.inc
        Include user32.inc
        Include kernel32.inc
    
        IncludeLib user32.lib
        IncludeLib kernel32.lib
    ;_____________________________________________________________
    
        .data
        Welcome db "欢迎来到汇编的世界",0
    ;_____________________________________________________________
    
        .CODE
    START:
        invoke MessageBox,0,offset Welcome,0,0
        invoke ExitProcess,0
        END START

    对应的反汇编程序:

    00401000 >/$  6A 00         push    0                                ; /(initial cpu selection)
    00401002  |.  6A 00         push    0                                ; |Title = NULL
    00401004  |.  68 00304000   push    00403000                         ; |欢迎来到汇编的世界
    00401009  |.  6A 00         push    0                                ; |hOwner = NULL
    0040100B  |.  E8 08000000   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
    00401010  |.  6A 00         push    0                                ; /ExitCode = 0
    00401012  \.  E8 07000000   call    <jmp.&kernel32.ExitProcess>      ; \ExitProcess
    00401017      CC            int3
    00401018   $- FF25 08204000 jmp     dword ptr [<&user32.MessageBoxA>>;  user32.MessageBoxA
    0040101E   .- FF25 00204000 jmp     dword ptr [<&kernel32.ExitProces>;  kernel32.ExitProcess

    修改code段代码为:

        .CODE
    START:
        lea eax,Welcome
        invoke MessageBox,0,eax,0,0
        invoke ExitProcess,0
        END START

    也就是说,我们并没有使用花指令,而是在使用字符串时先把字符串的地址传给eax,然后再把eax做为参数传给MessageBox,这样做,Win23DASM这些反汇编工具就无法识别了,好,用Win32DASM重新打开编译的文件,在[参考]菜单中,[字符串]这一项灰色显示,提示这个程序没有字符串,骗过它了!^_^

    反汇编变成了这样:

    00401000 >/$  8D05 00304000 lea     eax, dword ptr [403000]          ; /(initial cpu selection)
    00401006  |?  6A 00         push    0
    00401008  |?  6A 00         push    0
    0040100A  |?  50            push    eax
    0040100B  |.  6A 00         push    0                                ; \MessageBoxA
    0040100D  |?  E8 08000000   call    <jmp.&user32.MessageBoxA>
    00401012  \.  6A 00         push    0                                ; \ExitProcess
    00401014   ?  E8 07000000   call    <jmp.&kernel32.ExitProcess>
    00401019   ?  CC            int3
    0040101A   ?- FF25 08204000 jmp     dword ptr [<&user32.MessageBoxA>>;  user32.MessageBoxA
    00401020   ?- FF25 00204000 jmp     dword ptr [<&kernel32.ExitProces>;  kernel32.ExitProcess

    还有就是使用花指令,花指令不但可以使反汇编工具无法识别出字符串,更会让它们把汇编出错误的代码,花指令一般都是使用一些无用的字节来进行干扰,但是干扰反汇编的字节仍是可以使用的,像这样子:

        .data
        
        Welcome db "你是不是在搞笑哦!",0
    ;_____________________________________________________________
    
        .CODE
    START:
        jz @F
        jnz @F
        www db "欢迎来到汇编世界",0
      @@:
        lea eax,www
        lea ebx,Welcome
        invoke MessageBox,0,eax,ebx,0
        invoke ExitProcess,0
        END START

    反汇编后:

    00401000 > $ /74 13         je      short 00401015
    00401002   . |75 11         jnz     short 00401015
    00401004   . |BB B6D3ADC0   mov     ebx, C0ADD3B6
    00401009   . |B4 B5         mov     ah, 0B5
    0040100B   . |BD BBE3B1E0   mov     ebp, E0B1E3BB
    00401010   . |CA C0BD       retf    0BDC0
    00401013   . |E7 00         out     0, eax
    00401015   > \8D05 04104000 lea     eax, dword ptr [401004]
    0040101B   .  8D1D 00304000 lea     ebx, dword ptr [403000]
    00401021   .  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
    00401023   .  53            push    ebx                              ; |Title => "你是",B2,"",BB,"是在",B8,"阈",A6,"?,B6,"?,A1,""
    00401024   .  50            push    eax                              ; |Text => ""BB,"",B6,"?,AD,"?,B4,"?,BD,"",BB,"惚嗍?,BD,"?
    00401025   .  6A 00         push    0                                ; |hOwner = NULL
    00401027   .  E8 08000000   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
    0040102C   .  6A 00         push    0                                ; /ExitCode = 0
    0040102E   .  E8 07000000   call    <jmp.&kernel32.ExitProcess>      ; \ExitProcess
    00401033      CC            int3
    00401034   $- FF25 08204000 jmp     dword ptr [<&user32.MessageBoxA>>;  user32.MessageBoxA
    0040103A   .- FF25 00204000 jmp     dword ptr [<&kernel32.ExitProces>;  kernel32.ExitProcess

    感觉还是有些明显,我们手动调用API来试试。

        .data
        
        Welcome db "你是不是在搞笑哦!",0
    ;_____________________________________________________________
    
        .CODE
    START:
        lea eax,Welcome
        push 0
        push 0
        push eax
        push 0
        jz @F
        jnz @F
        www db "欢迎来到汇编世界",0
      @@:
        call [MessageBox]
        invoke ExitProcess,0
        END START

    反汇编后:

    00401000 > $  8D05 00304000 lea     eax, dword ptr [403000]          ;  (initial cpu selection)
    00401006   ?  6A 00         push    0
    00401008   ?  6A 00         push    0
    0040100A   ?  50            push    eax
    0040100B   .  6A 00         push    0
    0040100D   ?  74 13         je      short 00401022
    0040100F   ?  75 11         jnz     short 00401022
    00401011   ?  BB B6D3ADC0   mov     ebx, C0ADD3B6
    00401016   ?  B4 B5         mov     ah, 0B5
    00401018   ?  BD BBE3B1E0   mov     ebp, E0B1E3BB
    0040101D   ?  CA C0BD       retf    0BDC0
    00401020   ?  E7 00         out     0, eax
    00401022   ?  E8 07000000   call    <jmp.&user32.MessageBoxA>
    00401027   .  6A 00         push    0                                ; \MessageBoxA
    00401029   ?  E8 06000000   call    <jmp.&kernel32.ExitProcess>
    0040102E   .- FF25 08204000 jmp     dword ptr [<&user32.MessageBoxA>>; \ExitProcess
    00401034   $- FF25 00204000 jmp     dword ptr [<&kernel32.ExitProces>;  kernel32.ExitProcess

    用OD调试的时候感觉到有不习惯的了。

    下面是一个完整的示例:

        ;=================
    ;完整API花指令示例:
        ;=================
        .386
        .Model Flat, StdCall
        Option Casemap :None   ; 不区分大小写(对API与API常数无效)
        ;_____________________________________________________________
        Include windows.inc
        Include user32.inc
        Include kernel32.inc
    
        IncludeLib user32.lib
        IncludeLib kernel32.lib
        .CODE
    START:
        push 0
        push 0
        push offset Welcome
        push 0
        jz @F
        jnz @F
        Welcome db "Welcome",0   
    @@:
        mov eax,[MessageBox+4]
        sub eax,4
        jnz @F
        Welcome1 db "Welcome",0   
    @@:
        call eax
        invoke ExitProcess,0
        END START

    反汇编代码:

    00401000 > $  6A 00         push    0
    00401002   .  6A 00         push    0
    00401004   .  68 0F104000   push    0040100F
    00401009   .  6A 00         push    0
    0040100B   .  74 0A         je      short 00401017
    0040100D   .  75 08         jnz     short 00401017
    0040100F   .  57            push    edi
    00401010   .  65:6C         ins     byte ptr es:[edi], dx
    00401012   .  636F 6D       arpl    word ptr [edi+6D], bp
    00401015      65            db      65                               ;  CHAR 'e'
    00401016      00            db      00
    00401017   .  B8 36104000   mov     eax, 00401036
    0040101C   .  83E8 04       sub     eax, 4
    0040101F   .  75 08         jnz     short 00401029
    00401021   .  57            push    edi
    00401022   .  65:6C         ins     byte ptr es:[edi], dx
    00401024   .  636F 6D       arpl    word ptr [edi+6D], bp
    00401027      65            db      65                               ;  CHAR 'e'
    00401028      00            db      00
    00401029   .  FFD0          call    eax
    0040102B   .  6A 00         push    0                                ; /ExitCode = 0
    0040102D   .  E8 06000000   call    <jmp.&kernel32.ExitProcess>      ; \ExitProcess
    00401032   .- FF25 08204000 jmp     dword ptr [<&user32.MessageBoxA>>;  user32.MessageBoxA
    00401038   .- FF25 00204000 jmp     dword ptr [<&kernel32.ExitProces>;  kernel32.ExitProcess

    惨不忍睹,删除模块分析后

    00401000 >  6A 00           push    0
    00401002    6A 00           push    0
    00401004    68 0F104000     push    0040100F                         ; ASCII "Welcome"
    00401009    6A 00           push    0
    0040100B    74 0A           je      short 00401017
    0040100D    75 08           jnz     short 00401017
    0040100F    57              push    edi
    00401010    65:6C           ins     byte ptr es:[edi], dx
    00401012    636F 6D         arpl    word ptr [edi+6D], bp
    00401015    65:00B8 3610400>add     byte ptr gs:[eax+401036], bh
    0040101C    83E8 04         sub     eax, 4
    0040101F    75 08           jnz     short 00401029
    00401021    57              push    edi
    00401022    65:6C           ins     byte ptr es:[edi], dx
    00401024    636F 6D         arpl    word ptr [edi+6D], bp
    00401027    65:00FF         add     bh, bh
    0040102A    D06A 00         shr     byte ptr [edx], 1
    0040102D    E8 06000000     call    <jmp.&kernel32.ExitProcess>
    00401032  - FF25 08204000   jmp     dword ptr [<&user32.MessageBoxA>>; user32.MessageBoxA
    00401038  - FF25 00204000   jmp     dword ptr [<&kernel32.ExitProces>; kernel32.ExitProcess

    感觉没多大变化,看来,花指令会让人发晕的。

  • 相关阅读:
    java 笔记(6) static关键字
    java 笔记(5)接口,static
    java 笔记(4)抽象类与抽象方法
    java 笔记(3)多态 容易理解
    看穿CSS的定位技术
    揭开浮动布局的秘密(简略版)
    不可不知的CSS盒子模型(简略版)
    初学Java web 项目
    Eclipse快捷键
    JDBC连接数据库
  • 原文地址:https://www.cnblogs.com/tk091/p/2699246.html
Copyright © 2011-2022 走看看