zoukankan      html  css  js  c++  java
  • 简单加密壳代码分析

    00438450 >  55              PUSH EBP
    00438451    8BEC            MOV EBP,ESP
    00438453    83EC 0C         SUB ESP,0xC
    //第一个call观察发现没有参数,返回值eax也没被使用,可知这个call没有参数也没有返回值,
    //即在C语言 == void fun(void),enter进去观察。(注释1-CALL 004383A0)
    00438456    E8 45FFFFFF     CALL 02.004383A0                         ; 初始化函数地址
    0043845B    A1 40804300     MOV EAX,DWORD PTR DS:[0x438040]         ; 获取映像基址
    00438460    0305 44804300   ADD EAX,DWORD PTR DS:[0x438044]         ; 获取代码RVA
    //根据后面的函数猜测到这之前应该是初始化数据。

    00438466    8945 F8         MOV DWORD PTR SS:[EBP-0x8],EAX
    00438469    C745 FC 0000000>MOV DWORD PTR SS:[EBP-0x4],0x0
    00438470    8D4D FC         LEA ECX,DWORD PTR SS:[EBP-0x4]
    00438473    51              PUSH ECX
    00438474    6A 40           PUSH 0x40
    00438476    8B15 4C804300   MOV EDX,DWORD PTR DS:[0x43804C]
    //修改的地址是代码段基址
    0043847C    52              PUSH EDX
    0043847D    8B45 F8         MOV EAX,DWORD PTR SS:[EBP-0x8]
    00438480    50              PUSH EAX
    //这里看到一个VirtualProtct函数,说明可能要修改页属性,推测这之上几行代码都是它的参数。
    00438481    FF15 C0924300   CALL DWORD PTR DS:[0x4392C0]             ; DS:[004392C0]=764750AB (kernel32.VirtualProtect)
    00438487    E8 04FEFFFF     CALL 02.00438290
    0043848C    8D4D FC         LEA ECX,DWORD PTR SS:[EBP-0x4]
    0043848F    51              PUSH ECX
    00438490    8B55 FC         MOV EDX,DWORD PTR SS:[EBP-0x4]
    00438493    52              PUSH EDX
    00438494    A1 4C804300     MOV EAX,DWORD PTR DS:[0x43804C]
    00438499    50              PUSH EAX
    0043849A    8B4D F8         MOV ECX,DWORD PTR SS:[EBP-0x8]
    0043849D    51              PUSH ECX
    //果不期然这里还有一个VirtualProtect,这个应该是恢复页属性。
    //因为第一个VirtualProtect修改代码段基址,所以监视它,然后步过到这,发现代码被修改了。
    //而这两个函数中间只有call 00438290可能修改,enter进去(注释2-call 00438290)
    0043849E    FF15 C0924300   CALL DWORD PTR DS:[0x4392C0]             ; DS:[004392C0]=764750AB (kernel32.VirtualProtect)

    //这里开始是messagebox
    004384A4    6A 04           PUSH 0x4
    004384A6    68 2C814300     PUSH 02.0043812C                         ; ASCII "Hello 15PB"
    004384AB    68 38814300     PUSH 02.00438138                         ; ASCII "欢迎使用免费加壳程序,是否运行主程序?"
    004384B0    6A 00           PUSH 0x0
    004384B2    FF15 BC924300   CALL DWORD PTR DS:[0x4392BC]             ; user32.MessageBoxA
    004384B8    8945 F4         MOV DWORD PTR SS:[EBP-0xC],EAX
    004384BB    837D F4 06      CMP DWORD PTR SS:[EBP-0xC],0x6           ; 判断返回是否yes
    004384BF    75 0B           JNZ SHORT 02.004384CC
    //这里是messagebox结束

    004384C1    E8 1A000000     CALL 02.004384E0

    //这里进入就是OEP(注释3-OEP图)了,然而在这里的时候发现IAT被加密了(注释4-IAT加密图)
    //然后这中间只有前面这个call 004384E0可能加密。enter进入(注释5-CALL 004384E0)
    004384C6  - FF25 3C804300   JMP DWORD PTR DS:[0x43803C]             ; OEP入口
    004384CC    6A 00           PUSH 0x0
    004384CE    FF15 B8924300   CALL DWORD PTR DS:[0x4392B8]             ; kernel32.ExitProcess
    004384D4    8BE5            MOV ESP,EBP
    004384D6    5D              POP EBP
    004384D7    C3              RETN

    注释1-CALL 004383A0

    //发现函数中有操作fs寄存器的代码,访问Fs寄存器的一般是访问线程TEB以及PEB结构,再加上获取kernel32基址的话需要访问PEB结构中的模块链表。由以上对PEB和FS寄存器的了解,可知这段代码多半是kernel32基址。往下看会看到熟悉的函数。观察步过前跟步过后的参数推测这个是个初始化函数的地址。
    004383A0    55              PUSH EBP
    004383A1    8BEC            MOV EBP,ESP
    004383A3    51              PUSH ECX
    004383A4    56              PUSH ESI
    004383A5    C745 FC 0000000>MOV DWORD PTR SS:[EBP-0x4],0x0
    004383AC    50              PUSH EAX
    004383AD    64:A1 30000000  MOV EAX,DWORD PTR FS:[0x30]             ; 获取PEB
    004383B3    8B40 0C         MOV EAX,DWORD PTR DS:[EAX+0xC]
    004383B6    8B40 1C         MOV EAX,DWORD PTR DS:[EAX+0x1C]
    004383B9    8B00            MOV EAX,DWORD PTR DS:[EAX]
    004383BB    8B00            MOV EAX,DWORD PTR DS:[EAX]
    004383BD    8B40 08         MOV EAX,DWORD PTR DS:[EAX+0x8]
    004383C0    8945 FC         MOV DWORD PTR SS:[EBP-0x4],EAX
    004383C3    58              POP EAX
    004383C4    8B75 FC         MOV ESI,DWORD PTR SS:[EBP-0x4]
    004383C7    E8 F4FEFFFF     CALL 02.004382C0
    004383CC    68 C4804300     PUSH 02.004380C4                         ; ASCII "LoadLibraryA"
    004383D1    56              PUSH ESI
    004383D2    A3 CC924300     MOV DWORD PTR DS:[0x4392CC],EAX
    004383D7    FFD0            CALL EAX
    004383D9    68 D4804300     PUSH 02.004380D4                         ; ASCII "GetModuleHandleA"
    004383DE    56              PUSH ESI
    004383DF    A3 C8924300     MOV DWORD PTR DS:[0x4392C8],EAX
    004383E4    FF15 CC924300   CALL DWORD PTR DS:[0x4392CC]
    004383EA    68 E8804300     PUSH 02.004380E8                         ; ASCII "VirtualProtect"
    004383EF    56              PUSH ESI
    004383F0    A3 C4924300     MOV DWORD PTR DS:[0x4392C4],EAX
    004383F5    FF15 CC924300   CALL DWORD PTR DS:[0x4392CC]
    004383FB    68 F8804300     PUSH 02.004380F8                         ; ASCII "user32.dll"
    00438400    A3 C0924300     MOV DWORD PTR DS:[0x4392C0],EAX
    00438405    FF15 C8924300   CALL DWORD PTR DS:[0x4392C8]
    0043840B    68 04814300     PUSH 02.00438104                         ; ASCII "MessageBoxA"
    00438410    50              PUSH EAX
    00438411    FF15 CC924300   CALL DWORD PTR DS:[0x4392CC]
    00438417    68 10814300     PUSH 02.00438110                         ; ASCII "ExitProcess"
    0043841C    56              PUSH ESI
    0043841D    A3 BC924300     MOV DWORD PTR DS:[0x4392BC],EAX
    00438422    FF15 CC924300   CALL DWORD PTR DS:[0x4392CC]
    00438428    68 1C814300     PUSH 02.0043811C                         ; ASCII "VirtualAlloc"
    0043842D    56              PUSH ESI
    0043842E    A3 B8924300     MOV DWORD PTR DS:[0x4392B8],EAX
    00438433    FF15 CC924300   CALL DWORD PTR DS:[0x4392CC]
    00438439    A3 B4924300     MOV DWORD PTR DS:[0x4392B4],EAX
    0043843E    5E              POP ESI
    0043843F    8BE5            MOV ESP,EBP
    00438441    5D              POP EBP
    00438442    C3              RETN

    最后

    00438439 A3 B4924300 MOV DWORD PTR DS:[0x4392B4],EAX

    数据窗口跟随,发现初始化了一些函数

    1564729714614[4]

    注释2-call 00438290

    //明显有一行代码是异或,显而易见这个call的功能就是解密代码段
    00438290    8B0D 44804300   MOV ECX,DWORD PTR DS:[0x438044]         ; 获取代码段RVA
    00438296    33C0            XOR EAX,EAX
    00438298    030D 40804300   ADD ECX,DWORD PTR DS:[0x438040]         ; 代码段基址=代码段RVA+映像基址
    0043829E    3905 4C804300   CMP DWORD PTR DS:[0x43804C],EAX         ; 代码段长度
    004382A4    76 17           JBE SHORT 02.004382BD
    004382A6    EB 08           JMP SHORT 02.004382B0
    004382A8    8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
    004382AF    90              NOP
    004382B0    803408 15       XOR BYTE PTR DS:[EAX+ECX],0x15           ; 代码段基址+偏移异或代码
    004382B4    40              INC EAX
    004382B5    3B05 4C804300   CMP EAX,DWORD PTR DS:[0x43804C]
    004382BB  ^ 72 F3           JB SHORT 02.004382B0
    004382BD    C3              RETN

    注释3-OEP图

    1564730529962[4]

    注释4-IAT加密图

    1564730515519[4]

    注释5-CALL 004384E0

    //IAT填充,需要先获取函数地址,于是在GetProcAddress下断,找到它,然后跟踪它分析,发现,有一行代码对它的返回值异或,之后将这个值保存在局部变量,紧接申请一个内存,将局部缓冲区的一块原本准备好的内容+刚刚加密的值宝贝走,然后填充到IAT地址。
    004385B9    FF15 CC924300   CALL DWORD PTR DS:[0x4392CC]             ; kernel32.GetProcAddress
    004385BF    6A 40           PUSH 0x40
    004385C1    68 00300000     PUSH 0x3000
    004385C6    6A 20           PUSH 0x20
    004385C8    35 15151515     XOR EAX,0x15151515                       ; 修改IAT函数
    004385CD    6A 00           PUSH 0x0
    004385CF    8945 DB         MOV DWORD PTR SS:[EBP-0x25],EAX         ; 保存加密之后的iat函数
    004385D2    FF15 B4924300   CALL DWORD PTR DS:[0x4392B4]             ; kernel32.VirtualAlloc
    004385D8    F30F6F45 D0     MOVDQU XMM0,DQWORD PTR SS:[EBP-0x30]     ; 移位64位到数据到mm0
    004385DD    8B55 CC         MOV EDX,DWORD PTR SS:[EBP-0x34]
    004385E0    F30F7F00        MOVDQU DQWORD PTR DS:[EAX],XMM0         ; 赋值给申请的空间
    004385E4    F30F6F45 E0     MOVDQU XMM0,DQWORD PTR SS:[EBP-0x20]
    004385E9    F30F7F40 10     MOVDQU DQWORD PTR DS:[EAX+0x10],XMM0
    004385EE    8907            MOV DWORD PTR DS:[EDI],EAX               ; 将函数压入堆栈
    004385F0    8B4E 04         MOV ECX,DWORD PTR DS:[ESI+0x4]
    004385F3    83C6 04         ADD ESI,0x4
    004385F6    8BFE            MOV EDI,ESI
    004385F8    85C9            TEST ECX,ECX

    1564735088148[4]

  • 相关阅读:
    修改表的定义
    DataFrame.groupby()函数
    有限差分法
    Python之pandas库
    类:实验2家中的电视
    函数:使用函数指针操作函数
    函数:函数操作结构体通过按值传递以及按址传递,使用动态内存
    函数:使用数组名作为函数参数进行操作
    函数:使用递归实现阶乘
    函数:通过按值传递及传递结构地址操作结构
  • 原文地址:https://www.cnblogs.com/ltyandy/p/11289565.html
Copyright © 2011-2022 走看看