【作者】
by hkfans --> 转载请注明作者,谢谢!
【脱后感想】
总共花了3个多月的业余时间来分析themida.. 到现在我大概只剩半条命了。。。 真TMD的累! 脱壳不是人干的活啊。。眼睛快瞎了。精神也有点不大正常。。哎。。累! 再次膜拜写壳的人!
【感谢】
仅以此文感谢偶像softworm,要不是他的天书【真的是天书,分析的太透彻了】,我现在估计还是苦苦挣扎在VM的汪洋大海之中..
【思路】
脱壳脱到最后发现其实就是做4件事,anti 解码 IAT OEP到达 (大牛都参透了这个道理了 :) 最后一个算不算一件事情啊?^_^)
所以下面就按照这四个部分来分析themida..
【附件】
本篇文章, NOTEPAD样本 以及简单的IAT还原的脚本
tmd1.2.0.1.rar
【其他】
代码太多了。我就不全部贴出来了。。只贴出这四部分的内容, 还有很多的准备工作的代码我就不贴出出来了。。
准备工作包括:
1. 一开始外壳分配内存来存储VM的vmContext, oneByteOpcodeTable, twoByteOpcodeTable 以及所有HANDLE的代码.. themida对VirtualAlloc的调用超级多 。。。
2. 在VM用LoadLibrary加载kernel32.dll user32.dll advapi32.dll 在VM中获取CreateFileA ReadFile CloseFile VirtualAlloc
等API函数,然后利用ReadFile映射kernel32.dll user32.dll advapi32.dll, 这样以后基本上所有的API函数地址都是镜像地址,非真实的API函数地址..
3. 创建用于解码外壳自身代码的线程,外壳经常是主线程和支线程交替解码,特别特别多的这样的代码。。真正有用的代码其实不多。大多数都是
垃圾代码和这样解码外壳自身代码的代码。。
【最后】
可能有很多东西我漏掉分析。。有些地方自己还没有搞清楚。。。比如调用ZwQuerySystemInformation存储了一些信息之后,但是后面好像没有跟到利用这些信息的代码
还有运行时间的检测,前面有看到保存时间,但后面又没有跟到检测时间的代码。。。<估计是VM跟丢了>
下面进入正题:
=======================================================================================================================================================
【第一部分: anti】
[说明]
themida 1.2.0.1 的anti-debug 的手段有: <好像还有很多我没有看到的样子。:)>
OutputDebugStringA ---> 针对OD的BUG, 具体为什么我还没有细细研究..
CreateFileA --> 检查是否使用SoftIce
FindWindowA ---> 查找是否有Filemon RegMon 之类的软件
【详细代码】
1. 使用OutputDebugStringA对付存在BUG的OD
// 先获取OutputDebugStringA 在镜像中的地址
011D0555 8D85 7937AA09 lea eax, dword ptr [011D079C]
011D0688 8D85 711DAA09 lea eax, dword ptr [011CED94]
011D068E 0F8E 12000000 jle 011D06A6
011D0696 899D 451C9E09 mov dword ptr [0110EC68], ebx
011D06A6 FFD0 call eax ; call 011CED94 调用函数获取 OutputDebugStringA在镜像中的内存地址
0106 13 01 011D1A10 push [context.register]
0107 07 02 011D19F4 mov [addr_context.register], context.esp
0108 23 01 011D1A1E Sub [addr_context.register], 00000004
0109 30 01 011D19CA pop [context.register] (4 bytes)
0110 34 02 011D19E6 push [addr_context.register]
0111 2D 00 011D1A02 pop [addr_context.esp] (4 bytes)
0112 13 00 011D19D8 load context.register, 07C61104
0113 36 00 011D1A2C mov [addr_context.register], context.esp
0114 23 01 011D1A9C Sub [addr_context.register], 00000004
0115 11 00 011D1A8E push [addr_context.register]
0116 2D 00 011D1A56 pop [addr_context.esp] (4 bytes)
0117 20 00 011D1A72 push 011D1AB8
0118 39 01 011D1A3A mov [addr_context.register], context.esp
0119 0A 02 011D1A80 pop [context.register] (4 bytes)
0120 1A 01 011D1A64 mov [addr_context.register], context.ebp
0121 3B 00 011D1A48 Add [addr_context.register], 099E2B09
0122 11 02 011D1AAA call [context.register] ; call 0098A14C (OutputDebugStringA)
0037 00 011F70F4 push 00000000
0038 1A 01 011F713A mov [addr_context.register], context.esp
0039 17 00 011F7102 Sub [addr_context.register], 00000004
0040 30 01 011F712C pop [context.register] (4 bytes)
0041 1F 01 011F7148 push [addr_context.register]
0042 0A 02 011F7110 pop [addr_context.esp] (4 bytes) ; push 0
0043 13 00 011F711E load context.register, 07AA8B2C
0044 36 00 011F7156 mov [addr_context.register], context.ebp
0045 3B 00 011F7172 Add [addr_context.register], 09AC932E
0046 34 02 011F7164 push [addr_context.register]
0047 07 02 011F718E mov [addr_context.register], addr_context.eax
0048 14 02 011F7180 pop [context.register] (4 bytes) ; lea eax, dword ptr [ebp+09AC932E]
0049 36 00 011F719C mov [addr_context.register], addr_context.eax
0050 20 00 011F71D4 push [context.register]
0051 39 01 011F71FE mov [addr_context.register], context.esp
0052 08 00 011F71F0 Sub [addr_context.register], 00000004
0053 30 01 011F71C6 pop [context.register] (4 bytes)
0054 32 01 011F71B8 push [addr_context.register]
0055 30 01 011F71E2 pop [addr_context.esp] (4 bytes) ; push eax
0056 1C 02 011F71AA load context.register, 0A831D62
0057 36 00 011F720C mov [addr_context.register], context.esp
0058 23 01 011F728A Sub [addr_context.register], 00000004
0059 13 01 011F7244 push [addr_context.register]
0060 2D 00 011F7260 pop [addr_context.esp] (4 bytes)
0061 20 00 011F727C push 011F7298
0062 39 01 011F7298 mov [addr_context.register], context.esp
0063 30 01 011F721A pop [context.register] (4 bytes)
0064 1A 01 011F7252 mov [addr_context.register], context.ebp ; call 0A676E1 --> FindWindowA
0065 3B 00 011F7236 Add [addr_context.register], 099E0055
0066 29 00 011F7228 call [context.register] ; call dword ptr [ebp+099E0055]
0067 02 011F72A6 mov [addr_context.register], addr_context.eax
0068 11 00 011F72B4 push [context.register]
0069 07 02 011F72DE mov [addr_context.register], addr_context.eax
0070 13 01 011F72C2 push [context.register]
0071 3B 01 011F72D0 Test [esp+4], [esp] (4 bytes) ; test eax, eax
0072 3A 00 011F72EC jnz 011F7500
0007 3C 02 011F72FA mov [addr_context.register], context.ebp
0008 3B 00 011F7316 Add [addr_context.register], 09AC933B
0009 32 01 011F7340 push [addr_context.register]
0010 36 00 011F7324 mov [addr_context.register], addr_context.eax
0011 30 01 011F7308 pop [context.register] (4 bytes) ; lea eax, dword ptr [ebp+09AC933B]
0012 1C 02 011F7332 load context.register, 0AAE8C69
0013 1A 01 011F734E mov [addr_context.register], addr_context.eax
0014 11 00 011F7386 push [context.register]
0015 1A 01 011F735C mov [addr_context.register], context.esp
0016 08 00 011F7378 Sub [addr_context.register], 00000004
0017 2D 00 011F736A pop [context.register] (4 bytes)
0018 20 00 011F7394 push [addr_context.register]
0019 30 01 011F73A2 pop [addr_context.esp] (4 bytes) ; push eax
0020 34 02 011F73B0 push 00000000
0021 07 02 011F73BE mov [addr_context.register], context.esp
0022 23 01 011F73DA Sub [addr_context.register], 00000004
0023 0A 02 011F73E8 pop [context.register] (4 bytes)
0024 13 01 011F73CC push [addr_context.register]
0025 14 02 011F73F6 pop [addr_context.esp] (4 bytes) ; push 0
0026 07 02 011F7404 mov [addr_context.register], context.esp
0027 23 01 011F742E Sub [addr_context.register], 00000004
0028 34 02 011F7412 push [addr_context.register]
0029 2D 00 011F744A pop [addr_context.esp] (4 bytes)
0030 11 00 011F7466 push 011F7490
0031 07 02 011F7482 mov [addr_context.register], context.esp
0032 30 01 011F7458 pop [context.register] (4 bytes)
0033 07 02 011F7474 mov [addr_context.register], context.ebp
0034 3B 00 011F7420 Add [addr_context.register], 099E0055
0035 25 00 011F743C call [context.register] ; call FindWindowA
0112 00 011F939D push 00000000
0113 36 00 011F93C7 mov [addr_context.register], context.esp
0114 23 01 011F93AB Sub [addr_context.register], 00000004
0115 30 01 011F93D5 pop [context.register] (4 bytes)
0116 20 00 011F93B9 push [addr_context.register]
0117 14 02 011F93E3 pop [addr_context.esp] (4 bytes)
0118 39 01 011F93F1 mov [addr_context.register], context.ebp
0119 35 01 011F941B Add [addr_context.register], 09ACB5F0
0120 11 00 011F940D push [addr_context.register]
0121 1A 01 011F9437 mov [addr_context.register], addr_context.eax
0122 0A 02 011F9429 pop [context.register] (4 bytes)
0123 13 00 011F93FF load context.register, 006D7A4E
0124 39 01 011F9445 mov [addr_context.register], addr_context.eax
0125 32 01 011F9453 push [context.register]
0126 39 01 011F946F mov [addr_context.register], context.esp
0127 23 01 011F9461 Sub [addr_context.register], 00000004
0128 14 02 011F9499 pop [context.register] (4 bytes)
0129 13 01 011F948B push [addr_context.register]
0130 2D 00 011F947D pop [addr_context.esp] (4 bytes)
0131 13 00 011F94A7 load context.register, 0BA7DD87
0132 07 02 011F94B5 mov [addr_context.register], context.esp
0133 17 00 011F9533 Sub [addr_context.register], 00000004
0134 1F 01 011F94C3 push [addr_context.register]
0135 14 02 011F94ED pop [addr_context.esp] (4 bytes)
0136 11 00 011F94DF push 011F9541
0137 1A 01 011F94D1 mov [addr_context.register], context.esp
0138 0A 02 011F9517 pop [context.register] (4 bytes)
0139 1A 01 011F9509 mov [addr_context.register], context.ebp
0140 3B 00 011F9525 Add [addr_context.register], 099E0055
0141 29 00 011F94FB call [context.register] ; call FindWindowA
0142 02 011F9541 mov [addr_context.register], addr_context.eax
0143 34 02 011F954F push [context.register]
0144 39 01 011F9579 mov [addr_context.register], addr_context.eax
0145 1F 01 011F956B push [context.register]
0146 3B 01 011F955D Test [esp+4], [esp] (4 bytes)
0147 38 00 011F9587 jnz 011F97B7
0007 3C 02 011F9595 mov [addr_context.register], context.ebp
0008 35 01 011F95BF Add [addr_context.register], 09ACB5FC
0009 34 02 011F95DB push [addr_context.register]
0010 36 00 011F95A3 mov [addr_context.register], addr_context.eax
0011 0A 02 011F95CD pop [context.register] (4 bytes)
0012 1C 02 011F95B1 load context.register, 09463DEA
0013 36 00 011F95E9 mov [addr_context.register], addr_context.eax
0014 32 01 011F9613 push [context.register]
0015 39 01 011F963D mov [addr_context.register], context.esp
0016 23 01 011F9605 Sub [addr_context.register], 00000004
0017 2D 00 011F9621 pop [context.register] (4 bytes)
0018 32 01 011F95F7 push [addr_context.register]
0019 2D 00 011F962F pop [addr_context.esp] (4 bytes)
0020 13 00 011F964B load context.register, 0CA35115
0021 34 02 011F9659 push 00000000
0022 07 02 011F9675 mov [addr_context.register], context.esp
0023 23 01 011F9691 Sub [addr_context.register], 00000004
0024 30 01 011F969F pop [context.register] (4 bytes)
0025 32 01 011F9683 push [addr_context.register]
0026 0A 02 011F9667 pop [addr_context.esp] (4 bytes)
0027 1A 01 011F96AD mov [addr_context.register], context.esp
0028 08 00 011F96C9 Sub [addr_context.register], 00000004
0029 20 00 011F96E5 push [addr_context.register]
0030 2D 00 011F9701 pop [addr_context.esp] (4 bytes)
0031 11 00 011F96BB push 011F9739
0032 07 02 011F970F mov [addr_context.register], context.esp
0033 30 01 011F9739 pop [context.register] (4 bytes)
0034 36 00 011F96D7 mov [addr_context.register], context.ebp
0035 35 01 011F971D Add [addr_context.register], 099E0055
0036 3A 00 011F972B call [context.register] ; call FindWindowA
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!