首页
服装论坛t.vhao.net
专栏
课程

[原创]一个自写IAT加密壳的详细分析(含脱壳脚本)

2019-5-12 19:36 1018

[原创]一个自写IAT加密壳的详细分析(含脱壳脚本)

2019-5-12 19:36
1018

目次

概述

壳比较简单,但倒是我在15pb学到的第二个壳。详细分析一下,照样能学到很多器械,如今这里将壳中的重点和难点在这里分析一下,并详细演示脱壳的思路,最后给出了OD的脱壳脚本。欲望能对一些刚入门的同窗一些赞助

知恩莫忘本,这这里要特别感激一下15bp薛师长教员和其他师长教员的循循善诱。

由于本壳属于课件资本,是以未经师长教员许可,就不在这发了。

1. 功能

代码段加密,弹框提示,IAT加密

2. 难点

须要手动修复IAT,由于API被加密,且请求内存空间来保存解密的shellocode,并把内存空间首地址填充到IAT

3. 壳的流程

  1. 获得API的地址
  2. 修改内存属性
  3. 代码段解密
  4. 弹框提示
  5. 填充IAT表

    API地址获得到加密,然后开辟内存保存解密的shellocode,填充IAT表为shellcode 的地址

  6. 跳到原始OEP
    图片描述

壳代码反汇编分析

1. 获得壳代码所须要的API地址

  1. 经过过程FS[30]取得kernel32.dll的基地址
  2. 遍历kernel32.dll的导出表取得GetProAddress的地址
  3. 经过过程GetProcAddress取得LoadLibrary的地址
  4. LoadLibrary加载user32.dll
  5. 经过过程GetProcAddress取得其他API的地址
    Messagebox
    ExitPorcess
    GetMoudleHandleA
    VirtualProtect
    VirtualAlloc
    图片描述

2. 代码段解密:

图片描述

3. IAT解密与填充

  1. 经过过程INT取得模块名和导入API地址
  2. 对API地址停止异或加密

  3. 取得解密shellcode
    图片描述

  4. VirtualAlloc开辟内存用来存放shellcode
  5. 将请求的内存地址填充到IAT

下面汇编代码注释中给出了解释,假设有不明白或许解答不到位的可以鄙人面留言

004384E0    53              PUSH EBX
004384E1    8BDC            MOV EBX,ESP
004384E3    83EC 08         SUB ESP,0x8
004384E6    83E4 F0         AND ESP,0xFFFFFFF0
004384E9    83C4 04         ADD ESP,0x4
004384EC    55              PUSH EBP
004384ED    8B6B 04         MOV EBP,DWORD PTR DS:[EBX+0x4]
004384F0    896C24 04       MOV DWORD PTR SS:[ESP+0x4],EBP
004384F4    8BEC            MOV EBP,ESP
004384F6    83EC 48         SUB ESP,0x48
004384F9    A1 20804300     MOV EAX,DWORD PTR DS:[0x438020]
004384FE    33C5            XOR EAX,EBP
00438500    8945 FC         MOV DWORD PTR SS:[EBP-0x4],EAX
00438503    56              PUSH ESI
00438504    8B35 40804300   MOV ESI,DWORD PTR DS:[0x438040]          ; 02-hello.00400000
0043850A    8D45 C8         LEA EAX,DWORD PTR SS:[EBP-0x38]
0043850D    57              PUSH EDI
0043850E    8B3D 54804300   MOV EDI,DWORD PTR DS:[0x438054]
00438514    50              PUSH EAX
00438515    A1 5C804300     MOV EAX,DWORD PTR DS:[0x43805C]
0043851A    6A 40           PUSH 0x40
0043851C    FF35 60804300   PUSH DWORD PTR DS:[0x438060]
00438522    03C6            ADD EAX,ESI
00438524    8975 CC         MOV DWORD PTR SS:[EBP-0x34],ESI
00438527    50              PUSH EAX
00438528    C745 C8 0000000>MOV DWORD PTR SS:[EBP-0x38],0x0
0043852F    FF15 C0924300   CALL DWORD PTR DS:[0x4392C0]             ; VirtualProtect  422000 rwe
00438535    833C37 00       CMP DWORD PTR DS:[EDI+ESI],0x0
00438539    0F84 D7000000   JE 02-hello.00438616
0043853F    8B55 CC         MOV EDX,DWORD PTR SS:[EBP-0x34]
00438542    83C6 10         ADD ESI,0x10
00438545    03F7            ADD ESI,EDI
00438547    8975 C4         MOV DWORD PTR SS:[EBP-0x3C],ESI
0043854A    8D9B 00000000   LEA EBX,DWORD PTR DS:[EBX]
00438550    8B46 FC         MOV EAX,DWORD PTR DS:[ESI-0x4]           ; 遍历INT的模块
00438553    03C2            ADD EAX,EDX
00438555    50              PUSH EAX
00438556    FF15 C8924300   CALL DWORD PTR DS:[0x4392C8]             ; LoadLibraryA加载模块地址
0043855C    8B3E            MOV EDI,DWORD PTR DS:[ESI]
0043855E    8B55 CC         MOV EDX,DWORD PTR SS:[EBP-0x34]
00438561    03FA            ADD EDI,EDX
00438563    8945 C0         MOV DWORD PTR SS:[EBP-0x40],EAX
00438566    8B0F            MOV ECX,DWORD PTR DS:[EDI]
00438568    85C9            TEST ECX,ECX
0043856A    0F84 93000000   JE 02-hello.00438603
00438570    8BF7            MOV ESI,EDI
00438572    8B07            MOV EAX,DWORD PTR DS:[EDI]               ; 遍历模块的api
00438574    83C0 02         ADD EAX,0x2
00438577    85C9            TEST ECX,ECX
00438579    78 75           JS SHORT 02-hello.004385F0
0043857B    03C2            ADD EAX,EDX
0043857D    C745 D0 E801000>MOV DWORD PTR SS:[EBP-0x30],0x1E8
00438584    50              PUSH EAX
00438585    FF75 C0         PUSH DWORD PTR SS:[EBP-0x40]
00438588    C745 D4 00E958E>MOV DWORD PTR SS:[EBP-0x2C],0xEB58E900   ; 这是一段解密IAT的shellcode
0043858F    66:C745 D8 01E8 MOV WORD PTR SS:[EBP-0x28],0xE801
00438595    C645 DA B8      MOV BYTE PTR SS:[EBP-0x26],0xB8
00438599    C745 DF EB01153>MOV DWORD PTR SS:[EBP-0x21],0x351501EB
004385A0    C745 E3 1515151>MOV DWORD PTR SS:[EBP-0x1D],0x15151515
004385A7    C745 E7 EB01FF5>MOV DWORD PTR SS:[EBP-0x19],0x50FF01EB
004385AE    C745 EB EB02FF1>MOV DWORD PTR SS:[EBP-0x15],0x15FF02EB
004385B5    C645 EF C3      MOV BYTE PTR SS:[EBP-0x11],0xC3
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          ; 将地址保存到部分变量[ebp-0x25]
004385D2    FF15 B4924300   CALL DWORD PTR DS:[0x4392B4]             ; kernel32.VirtualAlloc
004385D8    F30F6F45 D0     MOVDQU XMM0,DQWORD PTR SS:[EBP-0x30]
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               ; 将api地址保存到iat中
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
004385FA  ^ 0F85 72FFFFFF   JNZ 02-hello.00438572
00438600    8B75 C4         MOV ESI,DWORD PTR SS:[EBP-0x3C]
00438603    83C6 14         ADD ESI,0x14
00438606    8975 C4         MOV DWORD PTR SS:[EBP-0x3C],ESI
00438609    837E F0 00      CMP DWORD PTR DS:[ESI-0x10],0x0
0043860D  ^ 0F85 3DFFFFFF   JNZ 02-hello.00438550
00438613    8B75 CC         MOV ESI,DWORD PTR SS:[EBP-0x34]
00438616    8D45 C8         LEA EAX,DWORD PTR SS:[EBP-0x38]
00438619    50              PUSH EAX
0043861A    FF75 C8         PUSH DWORD PTR SS:[EBP-0x38]
0043861D    A1 5C804300     MOV EAX,DWORD PTR DS:[0x43805C]
00438622    FF35 60804300   PUSH DWORD PTR DS:[0x438060]
00438628    03C6            ADD EAX,ESI
0043862A    50              PUSH EAX
0043862B    FF15 C0924300   CALL DWORD PTR DS:[0x4392C0]             ; kernel32.VirtualProtect
00438631    8B4D FC         MOV ECX,DWORD PTR SS:[EBP-0x4]
00438634    5F              POP EDI
00438635    33CD            XOR ECX,EBP
00438637    5E              POP ESI
00438638    E8 07000000     CALL 02-hello.00438644
0043863D    8BE5            MOV ESP,EBP
0043863F    5D              POP EBP
00438640    8BE3            MOV ESP,EBX
00438642    5B              POP EBX
00438643    C3              RETN

脱壳思路与步调:

手动脱壳

1. 找到OEP

由于代码简单,可以用单步或许特点搜刮法来找到OEP

2. 修复IAT

  1. 检查IAT发明和正常的IAT表不一样
    图片描述
    图片描述

  2. 在IAT表的内存下硬件写入断点,看哪个处所开端写入IAT表
    图片描述
    图片描述

  3. 找到填充IAT表的地位后,看高低反汇编代码是怎样填充的
    发明填充的是请求内存空间的首地址,这个地址里存的是一段异或解密的shellcode

    图片描述

  4. 那我们找到真实的api地址然后填充到IAT表
    图片描述

3. Dump

图片描述

4. ImportREC修复导入表

图片描述

5. 转储到刚才dump出来的文件中

写脱壳脚本

为了复习OD的脚本,固然本壳简单,写脚本也当作复习了,脚本怎样写的就不说了,注释曾经很详细

// 1. 定义变量
VAR dwWriteIATAddr // 填充IAT地址的下一行地址
VAR dwGetAPIAddr // 获得到了API地址下一行地址
VAR dwOEP // 原始OEP
VAR dwTmp // 临时变量

// 2. 初始化变量
MOV dwOEP, 00409486
MOV dwWriteIATAddr,4385f0
MOV dwGetAPIAddr, 4385bf

// 3. 清除一切断点
BPHWC
BPMC
BC

// 4. 设置断点
BPHWS dwWriteIATAddr, "x"
BPHWS dwGetAPIAddr, "x"
BPHWS dwOEP, "x"

// 5. 轮回断定
LOOP0:
RUN

CMP eip,dwGetAPIAddr
JNZ NEXT1
MOV dwTmp,eax
JMP LOOP0
NEXT1:
CMP eip,dwWriteIATAddr
JNZ NEXT3
MOV [edi],dwTmp
JMP LOOP0         
NEXT3:
CMP eip,dwOEP
JNZ LOOP0
MSG "达到OEP!"

由于自己程度无限,个中缺乏的地方,还请多多指教,多谢!



[推荐]看雪企服平台,供给安然分析、定制项目开辟、APP等级保护、渗透渗出测试等安然办事!

最后于 2019-5-13 18:24 被lcdxsun编辑 ,缘由: 标题和内容更贴切
上一主题 下一主题
最新答复 (4)
泪落晨光 2019-5-13 10:03
2
0
楼主太强了,能不克不及把demo也上传一下
大年夜锅炖鲲 2019-5-13 17:38
3
0
66666
xingbing 2019-5-15 22:49
4
0
太强大年夜了,进修。
lcdxsun 1 2019-5-16 17:54
5
0
本来想每条指令都写上注释的,然则这个壳的汇编其实简单,感到没有须要,重要的是思路,壳代码的履行思路与脱壳思路,比如壳代码是若何找到API地址的,IAT是若何修复的等等
旅客
登录 | 注册 方可回帖
前往