ps520 发表于 2010-2-22 16:13

小解Game:分析下海风的Game0.22

因为LCG貌似没有Game的资源,于是海风那个shell我就放附件里了
附件同时附上本次分析过程所使用的TeSt.exe
节省体积,没放图标~
------------------------------------------------------------------------------------------
Game是风月哥哥Anti劫持的一个作品

lpk之类的补丁很流行
所以做了一个小东西,专门anti lpk之类的dll劫持补丁
Only a game,不对你的什么负责
为了不让木马拿去用,所以不压缩
不支持dll加壳,因为加dll没意义,直接加exe就行了
BTW:不会做界面,界面很丑,不会写壳,拿shoooo的壳改了改
Thanks to shoooo
by 海风月影
2008.04.28

由于Fx_LpK的黑马表现,所以昨天和风月聊了会天。
后来我在自己系统测试时发现Anti失效了,一时郁闷了,就脱了壳。
现在来一起研究下这个代码吧*(应该可以移植到我的保护模块吧~)
-------------------------------------------------------------------------------------
加个test.exe,OD载入

00404AFE >6A 00         push    0x0
00404B00    60            pushad
00404B01    54            push    esp
00404B02    E8 25FFFFFF   call    00404A2C


代码很可爱,我们是要分析这个壳的功能,而不是说要单一的脱,所以我们不用ESP定律了。
近call F7进入。


00404A2C    55            push    ebp
00404A2D    8BEC            mov   ebp, esp
00404A2F    51            push    ecx
00404A30    51            push    ecx
00404A31    53            push    ebx
00404A32    56            push    esi
00404A33    57            push    edi
00404A34    E8 FAFEFFFF   call    00404933
00404A39    BE 7C4C4000   mov   esi, 00404C7C                  ; ASCII "ntdll.dll"
00404A3E    56            push    esi
00404A3F    8BF8            mov   edi, eax
00404A41    FF15 144C4000   call    dword ptr [<&KERNEL32.LoadLibrar>; kernel32.LoadLibraryA
00404A47    85C0            test    eax, eax
00404A49    75 11         jnz   short 00404A5C
00404A4B    68 A7484000   push    004048A7
00404A50    68 6C4C4000   push    00404C6C                         ; ASCII "LoadLibraryExW"
00404A55    68 5C4C4000   push    00404C5C                         ; ASCII "kernel32.dll"
00404A5A    EB 0B         jmp   short 00404A67
00404A5C    68 C1474000   push    004047C1
00404A61    68 504C4000   push    00404C50                         ; ASCII "LdrLoadDll"
00404A66    56            push    esi
00404A67    E8 72FAFFFF   call    004044DE
00404A6C    A3 00564000   mov   dword ptr , eax
00404A71    8B77 3C         mov   esi, dword ptr
00404A74    8B1D 084C4000   mov   ebx, dword ptr [<&KERNEL32.Virtu>; kernel32.VirtualProtect


一般的代码不会出现这些东西吖,那么这是怎么回事呢?
我很郁闷,于是请教师兄。


很显然
他在模拟Kernel32的某函数
既然是模拟函数,那么我们就进去看看吧!
第一个call,请教师兄,是C库函数。直接无视
为了避免漏掉什么地方
在时候确认海风哥哥用了HookApi以后,我参考了下自己的Hook源码

.版本 2

.如果真 (pFunAddress ≠ 0)
返回 (真)
.如果真结束
hLibModule = LoadLibraryA (动态链接库路径)
.如果真 (hLibModule = 0)
返回 (假)
.如果真结束
pFunAddress = GetProcAddress (hLibModule, 欲截获的函数名) ' 获取API函数地址
.如果真 (pFunAddress = 0)
FreeLibrary (hLibModule)
返回 (假)
.如果真结束
.如果真 (VirtualProtect (pFunAddress, 5, #PAGE_EXECUTE_READWRITE, dwOldProtect) = 假)
FreeLibrary (hLibModule)
返回 (假)
.如果真结束
pData = 指针到字节集 (pFunAddress, 5) ' 保存API入口前5个字节
写到内存 ({ 233 } + 到字节集 (到整数 (新函数地址 - (pFunAddress + 5))), pFunAddress, 5) ' 修改API入口前5字节
pData = pData + { 233, 0, 0, 0, 0 }
addrData = 取字节集变量数据地址 (pData, pData, 0)
写到内存 (到整数 (pFunAddress + 5 - (addrData + 10)), addrData + 6, 4)
FreeLibrary (hLibModule)
返回 (真)

关注下Api吧:
LoadLibraryA (动态链接库路径)
VirtualProtect
跟我们的代码比较:
00404A41    FF15 144C4000   call    dword ptr [<&KERNEL32.LoadLibrar>; kernel32.LoadLibraryA
00404A47    85C0            test    eax, eax
00404A49    75 11         jnz   short 00404A5C
00404A4B    68 A7484000   push    004048A7
00404A50    68 6C4C4000   push    00404C6C                         ; ASCII "LoadLibraryExW"
00404A55    68 5C4C4000   push    00404C5C                         ; ASCII "kernel32.dll"
00404A5A    EB 0B         jmp   short 00404A67
00404A5C    68 C1474000   push    004047C1
00404A61    68 504C4000   push    00404C50                         ; ASCII "LdrLoadDll"
00404A66    56            push    esi
00404A67    E8 72FAFFFF   call    004044DE
00404A6C    A3 00564000   mov   dword ptr , eax
00404A71    8B77 3C         mov   esi, dword ptr
00404A74    8B1D 084C4000   mov   ebx, dword ptr [<&KERNEL32.Virtu>; kernel32.VirtualProtect
由此确认,这段代码是在HookApi。
HookApi,这就挂了,因为Api给Hook了,用户不从你那装载了。555
不过我也想到了一个小突破方法:
kernel32.LoadLibraryA
这个就是突破方法
因为海风哥哥直接用Kernel32的LoadLibraryA,所以可以写个Kernel32劫持……
我也不知道我的想法是否正确,请各位指正。
仔细看了会,原来海风哥哥用了两手准备……彻底膜拜
继续下走……
省略代码……
00404AE8    E8 5EFEFFFF   call    0040494B
这个Call不知道干嘛的,执行倒用了点时间
咱也进去看看
数据窗口看到这些内容:
0012FF5C   004000E0ASCII "PE"
0012FF60   7C801AD4kernel32.VirtualProtect
0012FF64   00400000dddddd.00400000
0012FF68   004000E0ASCII "PE"
0012FF6C   00404ADDRETURN to dddddd.00404ADD
0012FF70   00400000dddddd.00400000
貌似是修改内存属性
到底干嘛呢?
004049BC    FF15 144C4000   call    dword ptr [<&KERNEL32.LoadLibrar>; kernel32.LoadLibraryA
原来是在装载库?

004049D0    8D45 F8         lea   eax, dword ptr
004049D3    50            push    eax
004049D4    6A 04         push    0x4
004049D6    6A 04         push    0x4
004049D8    56            push    esi
004049D9    FF15 084C4000   call    dword ptr [<&KERNEL32.VirtualPro>; kernel32.VirtualProtect
004049DF    8B03            mov   eax, dword ptr
004049E1    85C0            test    eax, eax
004049E3    79 07         jns   short 004049EC
004049E5    25 FFFF0000   and   eax, 0xFFFF
004049EA    EB 05         jmp   short 004049F1
004049EC    03C7            add   eax, edi
004049EE    83C0 02         add   eax, 0x2
004049F1    50            push    eax
004049F2    FF75 FC         push    dword ptr
004049F5    FF15 104C4000   call    dword ptr [<&KERNEL32.GetProcAdd>; kernel32.GetProcAddress
004049FB    8906            mov   dword ptr , eax
004049FD    8D45 F8         lea   eax, dword ptr
00404A00    50            push    eax
00404A01    FF75 F8         push    dword ptr
00404A04    6A 04         push    0x4
00404A06    56            push    esi
00404A07    FF15 084C4000   call    dword ptr [<&KERNEL32.VirtualPro>; kernel32.VirtualProtect
00404A0D    83C6 04         add   esi, 0x4
00404A10    83C3 04         add   ebx, 0x4
00404A13    833B 00         cmp   dword ptr , 0x0
00404A16^ 75 B8         jnz   short 004049D0



释放你的小宇宙,请教师兄,这段是填充IAT啊~~~~~~
但是没见找system32这个字符串啊
心里不爽
于是数据窗口上翻
0012FD04   0012FCB0UNICODE "INDOWS\system32"
小宇宙原来已经飞了……
当我们完成这段代码的执行,从Retn出来时,发现程序已经到了OEP了。

004010D0    E8 BBFFFFFF   call    00401090
004010D5    E8 69FFFFFF   call    00401043
004010DA    33C0            xor   eax, eax
004010DC    C3            retn
004010DD    90            nop
004010DE    90            nop
004010DF    90            nop
004010E0    E8 BBFFFFFF   call    004010A0
004010E5    8B4424 04       mov   eax, dword ptr
004010E9    50            push    eax
004010EA    FF15 04204000   call    dword ptr              ; kernel32.ExitProcess
004010F0    C3            retn



这时候Dump出来吧~
执行一下,铛。
错误了,看下原因:
应用程序正常初始化(0xc0000005)失败。

原来还要修复啊~
插播段广告:

女:我是你的什么?
男:你是我的OEP啊?
女:原来我只是个入口点啊?
男:这样,我就可以扒光了……
广告之后,依然精彩。
拿出ImportREC。
因为没抽OEP(感谢风哥这个程序写得不是很复杂)
所以自动查找就可以了
获取函数,啥都OK了。
修复~
执行程序,发现正常啦!~
==============================================
总结下这个壳的执行模式:
启动后转入call里,Hook ntdll.dll里的LdrLoadDll
由壳段模拟LdrLoadDll
模拟的方法是用LoadLibraryA
如果失败就用LoadLibraryEx (?这个不是很明确,因为跳过去了。)
查了下百度,发现的确是这样的
模拟完了以后貌似壳就没干什么事了
后面就交由系统加载支持库啥的
当然,由于壳段执行最早,所以啥库都没装载
貌似还手工装载了下kernel32啥的
不懂了,直接跳过~

执行原程序,用XueTr看了下钩子,代码执行完了以后钩子仍然存在
问了下师兄这是为啥
他笑了:“图省事呗~”
嘿嘿,的确有可能哟~~~~~~~
--------------------------------------------------------------------------------------
至此,我们已经成功分析了一个重要功能:Anti-Dll马甲
我们仔细看了这段代码,发现,原来我们不能仿照这个写个保护模块
为什么?
因为这个必须靠壳在第一时间挂钩函数,如果用易语言的模块写,再怎么快也不能第一时间挂钩
如果错过了初始时间,库都装载完了,Hook也就么意思了。
--------------------------------------------------------------------------------------
感谢:
LCG、UpK、CCTV
特别感谢:
啊cr、yangjt
------------------------------------------------------------------------------
Download:

小糊涂虫 发表于 2010-2-22 16:22

那段的广告说的很经典:lol~~~~~~~~

ps520 发表于 2010-2-22 16:56

这帖子未必就这么沉了?

jiaofu999 发表于 2010-2-22 17:29

顶下,不错的文章。

Hmily 发表于 2010-2-22 17:29

分析的不错,加精鼓励,继续努力!

coolszy 发表于 2010-2-22 17:35

看看不懂哦,继续加油修炼中

ps520 发表于 2010-2-22 18:36

分析的不错,加精鼓励,继续努力!
Hmily 发表于 2010-2-22 17:29 http://www.52pojie.cn/images/common/back.gif


这个算今年的LCG作业么……

ps520 发表于 2010-2-24 00:15

这个帖子居然真的沉了……

gry8686 发表于 2010-2-24 00:27

进来学习一下,支持楼主

Cicanc 发表于 2010-4-9 20:16

真是的。太可惜了、
怎么能让这样的帖子沉了呢?
页: [1] 2
查看完整版本: 小解Game:分析下海风的Game0.22