zoukankan      html  css  js  c++  java
  • 05 初识加壳脱壳

     (很久以前的学习记录,放到博客上来)
     
    1.IsDebuggerPresent()函数(CheckRemoteDebuggerPresent())
        确定调用进程是否由用户模式的调试器调试.


    #include "stdafx.h"
    #include<windows.h>
    #include<stdio.h>
     
    int main()
    {
    if (IsDebuggerPresent())
    {
    printf("Debugger! ");
    }
    else
    {
    printf("no debugger ");
    }
     
        return 0;
    }

    VS2015中运行:

    图片 


    ollydbg中运行:

     图片

     

    --------------------------------------------------------------------------------------------------
    2.加壳与脱壳

    源代码如下:

    #include "stdafx.h"
    #include <Windows.h>
    #include <stdio.h>
     
    int main(int argc, char *argv[])
    {
    if (argc < 2) {
    fprintf(stderr, "$packed.exe <password> ");
    return 1;
    }
    if (IsDebuggerPresent()) {
     
    printf("on debugger ");
    return -1;
    }
    else {
     
    if (strcmp(argv[1], "unpacking") == 0) {
    printf("correct! ");
    }
    else {
    printf("auth error ");
    return -1;
    }
    }
    getchar();
    return 0;

    }

    exe文件(未加壳)拖到IDA中反汇编:
     

    .text:00411830 ; int __cdecl main(int argc, char **argv)
    .text:00411830 _main           proc near               ; CODE XREF: j__mainj
    .text:00411830
    .text:00411830 var_C0          = byte ptr -0C0h
    .text:00411830 argc            = dword ptr  8
    .text:00411830 argv            = dword ptr  0Ch
    .text:00411830
    .text:00411830                 push    ebp
    .text:00411831                 mov     ebp, esp
    .text:00411833                 sub     esp, 0C0h
    .text:00411839                 push    ebx
    .text:0041183A                 push    esi
    .text:0041183B                 push    edi
    .text:0041183C                 lea     edi, [ebp+var_C0]
    .text:00411842                 mov     ecx, 30h
    .text:00411847                 mov     eax, 0CCCCCCCCh
    .text:0041184C                 rep stosd
    .text:0041184E                 cmp     [ebp+argc], 2
    .text:00411852                 jge     short loc_41187D
    .text:00411854                 push    offset _Format  ; "$packed.exe <password> "
    .text:00411859                 mov     esi, esp
    .text:0041185B                 push    2
    .text:0041185D                 call    ds:__imp____acrt_iob_func
    .text:00411863                 add     esp, 4
    .text:00411866                 cmp     esi, esp
    .text:00411868                 call    j___RTC_CheckEsp
    .text:0041186D                 push    eax             ; _Stream
    .text:0041186E                 call    j__fprintf
    .text:00411873                 add     esp, 8
    .text:00411876                 mov     eax, 1
    .text:0041187B                 jmp     short loc_4118F6
    .text:0041187D ; ---------------------------------------------------------------------------
    .text:0041187D
    .text:0041187D loc_41187D:                             ; CODE XREF: _main+22j
    .text:0041187D                 mov     esi, esp
    .text:0041187F                 call    ds:__imp__IsDebuggerPresent@0 ; IsDebuggerPresent()
    .text:00411885                 cmp     esi, esp
    .text:00411887                 call    j___RTC_CheckEsp
    .text:0041188C                 test    eax, eax
    .text:0041188E                 jz      short loc_4118A4
    .text:00411890                 push    offset aOnDebugger ; "on debugger "
    .text:00411895                 call    j__printf
    .text:0041189A                 add     esp, 4
    .text:0041189D                 or      eax, 0FFFFFFFFh
    .text:004118A0                 jmp     short loc_4118F6
    .text:004118A2 ; ---------------------------------------------------------------------------
    .text:004118A2                 jmp     short loc_4118E5
    .text:004118A4 ; ---------------------------------------------------------------------------
    .text:004118A4
    .text:004118A4 loc_4118A4:                             ; CODE XREF: _main+5Ej
    .text:004118A4                 push    offset Str2     ; "unpacking"
    .text:004118A9                 mov     eax, 4
    .text:004118AE                 shl     eax, 0
    .text:004118B1                 mov     ecx, [ebp+argv]
    .text:004118B4                 mov     edx, [ecx+eax]
    .text:004118B7                 push    edx             ; Str1
    .text:004118B8                 call    j__strcmp
    .text:004118BD                 add     esp, 8
    .text:004118C0                 test    eax, eax
    .text:004118C2                 jnz     short loc_4118D3
    .text:004118C4                 push    offset aCorrect ; "correct! "
    .text:004118C9                 call    j__printf
    .text:004118CE                 add     esp, 4
    .text:004118D1                 jmp     short loc_4118E5
    .text:004118D3 ; ---------------------------------------------------------------------------
    .text:004118D3
    .text:004118D3 loc_4118D3:                             ; CODE XREF: _main+92j
    .text:004118D3                 push    offset aAuthError ; "auth error "
    .text:004118D8                 call    j__printf
    .text:004118DD                 add     esp, 4
    .text:004118E0                 or      eax, 0FFFFFFFFh
    .text:004118E3                 jmp     short loc_4118F6
    .text:004118E5 ; ---------------------------------------------------------------------------
    .text:004118E5
    .text:004118E5 loc_4118E5:                             ; CODE XREF: _main+72j
    .text:004118E5                                         ; _main+A1j
    .text:004118E5                 mov     esi, esp
    .text:004118E7                 call    ds:__imp__getchar
    .text:004118ED                 cmp     esi, esp
    .text:004118EF                 call    j___RTC_CheckEsp
    .text:004118F4                 xor     eax, eax
    .text:004118F6
    .text:004118F6 loc_4118F6:                             ; CODE XREF: _main+4Bj
    .text:004118F6                                         ; _main+70j ...
    .text:004118F6                 pop     edi
    .text:004118F7                 pop     esi
    .text:004118F8                 pop     ebx
    .text:004118F9                 add     esp, 0C0h
    .text:004118FF                 cmp     ebp, esp
    .text:00411901                 call    j___RTC_CheckEsp
    .text:00411906                 mov     esp, ebp
    .text:00411908                 pop     ebp
    .text:00411909                 retn

    .text:00411909 _main           endp 

    这段汇编代码开起来简明清晰。 


    接下来用UPX为exe文件加壳(用cmd命令行执行的时候被“拒绝访问”了,最后直接拿exe文件往upx.exe里拖,压缩成功了): 

    压缩过的exe文件在IDA中的流程视图:

    图片

    图片
     

    里面的代码也变成这样的了(截取) :

    UPX1:004204C0 ; ---------------------------------------------------------------------------
    UPX1:004204C2                 align 8
    UPX1:004204C8
    UPX1:004204C8 loc_4204C8:                             ; CODE XREF: start:loc_4204D9j
    UPX1:004204C8                 mov     al, [esi]
    UPX1:004204CA                 inc     esi
    UPX1:004204CB                 mov     [edi], al
    UPX1:004204CD                 inc     edi
    UPX1:004204CE
    UPX1:004204CE loc_4204CE:                             ; CODE XREF: start+B6j
    UPX1:004204CE                                         ; start+CDj
    UPX1:004204CE                 add     ebx, ebx
    UPX1:004204D0                 jnz     short loc_4204D9
    UPX1:004204D2
    UPX1:004204D2 loc_4204D2:                             ; CODE XREF: start+10j
    UPX1:004204D2                 mov     ebx, [esi]
    UPX1:004204D4                 sub     esi, 0FFFFFFFCh
    UPX1:004204D7                 adc     ebx, ebx
    UPX1:004204D9
    UPX1:004204D9 loc_4204D9:                             ; CODE XREF: start+20j
    UPX1:004204D9                 jb      short loc_4204C8
    UPX1:004204DB                 mov     eax, 1
    UPX1:004204E0
    UPX1:004204E0 loc_4204E0:                             ; CODE XREF: start+3Fj
    UPX1:004204E0                                         ; start+4Aj
    UPX1:004204E0                 add     ebx, ebx
    UPX1:004204E2                 jnz     short loc_4204EB
    UPX1:004204E4                 mov     ebx, [esi]
    UPX1:004204E6                 sub     esi, 0FFFFFFFCh
    UPX1:004204E9                 adc     ebx, ebx
    UPX1:004204EB
    UPX1:004204EB loc_4204EB:                             ; CODE XREF: start+32j
    UPX1:004204EB                 adc     eax, eax
    UPX1:004204ED                 add     ebx, ebx
    UPX1:004204EF                 jnb     short loc_4204E0
    UPX1:004204F1                 jnz     short loc_4204FC
    UPX1:004204F3                 mov     ebx, [esi]
    UPX1:004204F5                 sub     esi, 0FFFFFFFCh
    UPX1:004204F8                 adc     ebx, ebx
    UPX1:004204FA                 jnb     short loc_4204E0

     (现在想要去解压缩,因为upx命令行输入总是被拒绝访问,解决无果,无奈发现好像存在带有窗口界面的upx,按百度排序的第一个下载——全是一群流氓,捆绑一堆软件安装,百度流氓头子!最后下载的upx还总是error,最后在360上查了下,发现360竟然有这款软件,UPX Easy GUI,今天感谢360的良心!)

    Depreess脱壳后的exe文件不如原来那样清晰直观了:
    流程试图:

    图片

    反汇编代码(截取): 
    .text:0041104B ; [00000005 BYTES: COLLAPSED FUNCTION start. PRESS CTRL-NUMPAD+ TO EXPAND]
    .text:00411050 ; [00000005 BYTES: COLLAPSED FUNCTION j_wcscpy_s. PRESS CTRL-NUMPAD+ TO EXPAND]
    .text:00411055 ; ---------------------------------------------------------------------------
    .text:00411055                 jmp     sub_414E40
    .text:0041105A
    .text:0041105A ; =============== S U B R O U T I N E =======================================
    .text:0041105A
    .text:0041105A ; Attributes: thunk
    .text:0041105A
    .text:0041105A sub_41105A      proc near               ; CODE XREF: .text:00411C1Ap
    .text:0041105A                                         ; .text:00411C4Ap
    .text:0041105A                 jmp     sub_411BF0
    .text:0041105A sub_41105A      endp
    .text:0041105A
    .text:0041105F
    .text:0041105F ; =============== S U B R O U T I N E =======================================
    .text:0041105F
    .text:0041105F ; Attributes: thunk
    .text:0041105F
    .text:0041105F sub_41105F      proc near               ; CODE XREF: .text:00411CA1p
    .text:0041105F                                         ; .text:00411CC5p ...
    .text:0041105F                 jmp     sub_413650
    .text:0041105F sub_41105F      endp
    .text:0041105F
    .text:00411064
    .text:00411064 ; =============== S U B R O U T I N E =======================================
    .text:00411064
    .text:00411064 ; Attributes: thunk
    .text:00411064
    .text:00411064 sub_411064      proc near               ; CODE XREF: sub_412D00+6p
    .text:00411064                                         ; .text:00412D63p ...
    .text:00411064                 jmp     sub_414820
    .text:00411064 sub_411064      endp
    .text:00411064
    .text:00411069
    .text:00411069 ; =============== S U B R O U T I N E =======================================
    .text:00411069
    .text:00411069 ; Attributes: thunk
    .text:00411069
    .text:00411069 sub_411069      proc near               ; CODE XREF: sub_411BA0+1Ap
    .text:00411069                 jmp     sub_4123C0
    .text:00411069 sub_411069      endp
    .text:00411069 

    --------------------------------------------------------------------------------------------------------
    3.尝试手动脱壳
     
    在ollydbg中打开upx加壳过的exe文件,开头是这样的:

    00FC03F0 > $ 60             PUSHAD
    00FC03F1   . BE 00E0FB00    MOV ESI,Pack.00FBE000
    00FC03F6   . 8DBE 0030FEFF  LEA EDI,DWORD PTR DS:[ESI+FFFE3000]
    00FC03FC   . 57             PUSH EDI
    00FC03FD   . 83CD FF        OR EBP,FFFFFFFF
    00FC0400   > EB 10          JMP SHORT Pack.00FC0412

    首先PUSHAD将所有寄存器的值复制都栈中,F8单步执行,不远处进入了一个人循环:
    (PUSHAD指令在堆栈中按顺序压入下列寄存器:EAX,ECX,EDX,EBX,ESP,EBP,ESI和EDI.
    POPAD指令则是PUSHAD指令的逆操作。POPAD指令按照与上面相反的顺序依次弹出寄存器的值。
    顺序为 EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX.)


    00FC0408   > 8A06           MOV AL,BYTE PTR DS:[ESI]
    00FC040A   . 46             INC ESI
    00FC040B   . 8807           MOV BYTE PTR DS:[EDI],AL
    00FC040D   . 47             INC EDI
    00FC040E   > 01DB           ADD EBX,EBX
    00FC0410   . 75 07          JNZ SHORT Pack.00FC0419
    00FC0412   > 8B1E           MOV EBX,DWORD PTR DS:[ESI]
    00FC0414   . 83EE FC        SUB ESI,-4
    00FC0417   . 11DB           ADC EBX,EBX
    00FC0419   >^72 ED          JB SHORT Pack.00FC0408

    这里的逻辑就是从esi中向edi中拷贝数据,
    还可以从窗口中看到edi的地址是从00FC03F0开始的。

    向下找到 POPAD命令,F2设置断点,F9执行到断点处。

     00FC056B   . 61             POPAD
     00FC056C   . 8D4424 80      LEA EAX,DWORD PTR SS:[ESP-80]
     00FC0570   > 6A 00          PUSH 0
     00FC0572   . 39C4           CMP ESP,EAX
     00FC0574   .^75 FA          JNZ SHORT Pack.00FC0570
     00FC0576   . 83EC 80        SUB ESP,-80
     00FC0579   .-E9 CD0AFFFF    JMP Pack.00FB104B

    执行到JMP Pack.00FB104B,
    跳转到了:
    00FB104B   E9 50100000      JMP Pack.00FB20A0
    00FB1050   E9 553D0000      JMP Pack.00FB4DAA                        ; JMP to ucrtbase.wcscpy_s
     
     
    这时打开菜单栏上Plug_in   >   OllyDump   >   Dump debugged process,进行脱壳,但是......多歧路今安在啊!总是无法读内存,显示“Bad DOS Signature”,我也很无奈,尚未解决。
    图片

    按道理, pushad和popad之间的代码就是解压缩,在解压缩之前,先将寄存器状态保存到栈,解压缩结束之后在从栈中读取,恢复寄存器状态,从而运行真正的代码。
    所以手动脱壳,关键在于找到 解压结束,程序开始的瞬间。
  • 相关阅读:
    2020软件工程作业04(2.0)
    2020软件工程作业03
    软件工程作业02
    2020软件工程作业02
    2020软件工程作业01
    2020软件工程个人作业06——软件工程实践总结作业
    2020软件工程作业05
    2020软件工程作业00——问题清单
    2020软件工程作业04
    2020软件工程作业02
  • 原文地址:https://www.cnblogs.com/lsh123/p/7859255.html
Copyright © 2011-2022 走看看