Armadillo SMC 破解教程
以《硕思闪客精灵 企业版》为例子。PEiD载入,看区段,显然是Armadillo,现在用Armadillo Find Protector看一下有啥保护:<- 02-12-2010 18:17:59 - ->
G:\Program Files\SourceTec\SWFDecompiler_2.exe
Protected Armadillo
<-Find Protect
Protection system (Professional)
<Protection Options>
Standard protection or Minimum protection
Import Table Elimination
Strategic Code Splicing
<Backup Key Options>
Variable Backup Keys
<Compression Options>
Minimal/Fastest Compression
<Other Options>
Disable Monitoring Thread
<-Find Version
Version 7.00 26-10-2009
<- Elapsed Time 00h 00m 00s 453ms ->
复制代码
似乎是单进程的,那就好办了。果断SMC之。
我们先找到要爆破的地方,这个地方是lkou版主告诉我的,我自己没调试出来(!-_-)。在程序运行起来之后,需要Patch几个地址:
->0x37
->0x179E9
->0xDE89000
复制代码
试一试,在入口点的时候patch掉这几处的代码果然可以变成了正版。lkou版主说他用了不到十分钟就搞掉了……我硬是没调出来。
下面有必要知道一些Armadillo的特点,Armadillo的壳主要是在一个ArmAccess.dll里边,外壳加载的时候首先调用VirtualAlloc分配一段内存,然后模拟PE加载器把DLL加载进去,然后把流程转移到DLL里,DLL完成主要的流程。DLL大概会做一点事情就是,首先是进行文件校验,然后处理IAT,最后解压代码啥的啥的。
SMC的流程是这样的:在DLL加载完毕后劫持流程,因为我们修改了文件,所以要绕过文件校验。之后是在壳解压原始代码之后进行Patch,相当于内存补丁。
所以,我们需要在三个地方插入代码:加载DLL完毕的时候,壳自校验的时候,原始代码解压完毕的时候。
首先说一下如何找DLL加载完毕的时机,OD载入程序,搜索字符串“SetFunctionAddresses”,会找到这里:
00BC40EB |> \6A 00 push 0x0
00BC40ED |.6A 01 push 0x1
00BC40EF |.A1 4CC3C200 mov eax, dword ptr ;这里就保存着dll的基址
00BC40F4 |.50 push eax
00BC40F5 |.FF15 50C3C200 call dword ptr ;call DLL 入口
00BC40FB |.85C0 test eax, eax
00BC40FD |.75 11 jnz short 00BC4110
复制代码
既然在00BC40EF从0xC2C34C处取出dll的基址,就一定有另外一个地方把dll的基址写入0xC2C34C。所以我们搜索常量,可以到这里:
00BC4D3A .A3 4CC3C200 mov dword ptr , eax
00BC4D3F 8B45 08 mov eax, dword ptr
00BC4D42 8BE5 mov esp, ebp
00BC4D44 .5D pop ebp
00BC4D45 .C3 retn
复制代码
很显然,这个时候把DLL的代码解压完毕,并把基址保存到了0xC2C34C里。我一般选择在00BC4D3F处SMC,这样可以更简单,而且不用考虑重定位。SMC代码里面eax就是基址了。记下00BC4D3F,作为第一处Patch的地址。
下面我们来找原始的文件校验值,bp OutputDebugStringA,运行两次之后返回,代码是这样的:
0287D82C FF15 4C928B02 call dword ptr ; kernel32.OutputDebugStringA
0287D832 C705 6C4A8D02 A4F7>mov dword ptr , 0x28BF7A4
0287D83C 8B0D 1C938D02 mov ecx, dword ptr ; SWFDecom.00C1C4E0
0287D842 8B15 1C938D02 mov edx, dword ptr ; SWFDecom.00C1C4E0
0287D848 A1 1C938D02 mov eax, dword ptr
0287D84D 8B40 78 mov eax, dword ptr
0287D850 3342 58 xor eax, dword ptr
0287D853 3341 2C xor eax, dword ptr
0287D856 3345 F0 xor eax, dword ptr ; ***********
复制代码
注意0287D856,输入dd ebp-0x10,看数据窗口:
0012F30813388778
0012F30C48963C67
0012F310F76562B1
0012F31410181326
0012F31800000000
0012F31C720DAEB2
复制代码
这五个值就是原始文件的校验值,只要我们在这里恢复文件校验,就可以任意的修改文件了。
接下来是找一找代码解压的时机,这里是跟他们学的,劫持VirtualProtect然后判断对应地址的数据是不是0就可以了。大家看代码就好了。
下面开始SMC。先让00BC4D3F处的代码跳到我们的SMC代码:
00BC4D3F - E9 BC620400 jmp 00C0B000 ;跳到00C0B000
复制代码
在00C0B000处补上代码:
00C0B000 60 pushad ; 保存寄存器
00C0B001 54 push esp ; 分配一个栈空间
00C0B002 54 push esp ; 修改内存保护
00C0B003 6A 40 push 0x40 ; 可读可写可执行
00C0B005 68 00A00F00 push 0xFA000 ; buffer的大小
00C0B00A 8B4424 2C mov eax, dword ptr ; 取出dll基址
00C0B00E 50 push eax ; 修改dll的属性
00C0B00F FF15 6CB0C100 call dword ptr [<&KERNEL32.VirtualProtect>]; kernel32.VirtualProtect
00C0B015 58 pop eax
00C0B016 61 popad ; 堆栈平衡
00C0B017 C780 4C920B00 32B0C>mov dword ptr , 00C0B032 ; Hook OutputDebugStringA
00C0B021 C780 54910B00 64B0C>mov dword ptr , 00C0B064 ; Hook VirtualProtect
00C0B02B 8B45 08 mov eax, dword ptr ; 恢复原来的代码
00C0B02E 8BE5 mov esp, ebp
00C0B030 5D pop ebp
00C0B031 C3 retn
00C0B032 8B0424 mov eax, dword ptr ; 调用OutputDebugStringA流程会到这里,首先取出返回地址
00C0B035 8178 1E 33425833 cmp dword ptr , 0x33584233 ; 然后判断是不是到校验的地方
00C0B03C 75 23 jnz short 00C0B061
00C0B03E C745 F0 B2AE0D72 mov dword ptr , 0x720DAEB2 ; 如果是,就恢复校验值
00C0B045 C745 E8 26131810 mov dword ptr , 0x10181326
00C0B04C C745 E4 B16265F7 mov dword ptr , 0xF76562B1
00C0B053 C745 E0 673C9648 mov dword ptr , 0x48963C67
00C0B05A C745 DC 78873813 mov dword ptr , 0x13388778
00C0B061 C2 0400 retn 0x4 ; OutputDebugStringA只是一个反调试,返回就好
00C0B064 C74424 0C 40000000mov dword ptr , 0x40 ; 这里是Hook VirtualProtect,我们修改属性为可读可写可执行。
00C0B06C 803D E3684400 00 cmp byte ptr , 0x0 ; 判断是否解压完毕
00C0B073 74 1B je short <jmp.&KERNEL32.VirtualProtect>
00C0B075 C605 E4684400 37 mov byte ptr , 0x37 ; 开始补代码
00C0B07C C705 38674400 E9790>mov dword ptr , 0x179E9
00C0B086 C705 3C674400 0090E>mov dword ptr , 0xDE89000
00C0B090 - FF25 6CB0C100 jmp dword ptr [<&KERNEL32.VirtualProtect>]; kernel32.VirtualProtect,继续执行。
复制代码
其实原来的SMC代码比较麻烦,昨天晚上洗澡的时候突然觉悟了,其实可以写的更简单的。
谢谢观赏。
转自 CjwNull 高手就是不一样, 我看完了还没有明白 学习一下 学习了,感谢。 支持飘云阁!
页:
[1]