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之间的代码就是解压缩,在解压缩之前,先将寄存器状态保存到栈,解压缩结束之后在从栈中读取,恢复寄存器状态,从而运行真正的代码。
    所以手动脱壳,关键在于找到 解压结束,程序开始的瞬间。
  • 相关阅读:
    PAT A1094 The Largest Generation (25 分)——树的bfs遍历
    PAT A1055 The World's Richest (25 分)——排序
    PAT A1052 Linked List Sorting (25 分)——链表,排序
    PAT A1076 Forwards on Weibo (30 分)——图的bfs
    辅导员
    辅导员面试
    C程序设计
    Excel VBA 基本概念
    Excel函数
    导入excel表的数据到数据库ssh
  • 原文地址:https://www.cnblogs.com/lsh123/p/7859255.html
Copyright © 2011-2022 走看看