飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3710|回复: 4

[转贴] Armadillo SMC 破解教程

[复制链接]
  • TA的每日心情

    2021-3-15 02:34
  • 签到天数: 347 天

    [LV.8]以坛为家I

    发表于 2010-12-3 10:43:13 | 显示全部楼层 |阅读模式
    以《硕思闪客精灵 企业版》为例子。PEiD载入,看区段,显然是Armadillo,现在用Armadillo Find Protector看一下有啥保护:
    <- 02-12-2010 18:17:59 - [2.0] ->

    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几个地址:

        [0x4468E4]->0x37

        [0x446738]->0x179E9

        [0x44673C]->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 [0xC2C34C]               ;  这里就保存着dll的基址

    00BC40F4   |.  50               push    eax

    00BC40F5   |.  FF15 50C3C200    call    dword ptr [0xC2C350]                    ;  call DLL 入口

    00BC40FB   |.  85C0             test    eax, eax

    00BC40FD   |.  75 11            jnz     short 00BC4110
    复制代码

    既然在00BC40EF从0xC2C34C处取出dll的基址,就一定有另外一个地方把dll的基址写入0xC2C34C。所以我们搜索常量,可以到这里:
    00BC4D3A    .  A3 4CC3C200      mov     dword ptr [0xC2C34C], eax

    00BC4D3F       8B45 08          mov     eax, dword ptr [ebp+0x8]

    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 [0x28B924C]                   ; kernel32.OutputDebugStringA

    0287D832     C705 6C4A8D02 A4F7>mov     dword ptr [0x28D4A6C], 0x28BF7A4

    0287D83C     8B0D 1C938D02      mov     ecx, dword ptr [0x28D931C]              ; SWFDecom.00C1C4E0

    0287D842     8B15 1C938D02      mov     edx, dword ptr [0x28D931C]              ; SWFDecom.00C1C4E0

    0287D848     A1 1C938D02        mov     eax, dword ptr [0x28D931C]

    0287D84D     8B40 78            mov     eax, dword ptr [eax+0x78]

    0287D850     3342 58            xor     eax, dword ptr [edx+0x58]

    0287D853     3341 2C            xor     eax, dword ptr [ecx+0x2C]

    0287D856     3345 F0            xor     eax, dword ptr [ebp-0x10]               ; ***********
    复制代码

    注意0287D856,输入dd ebp-0x10,看数据窗口:
    0012F308  13388778

    0012F30C  48963C67

    0012F310  F76562B1

    0012F314  10181326

    0012F318  00000000

    0012F31C  720DAEB2
    复制代码

    这五个值就是原始文件的校验值,只要我们在这里恢复文件校验,就可以任意的修改文件了。
       
    接下来是找一找代码解压的时机,这里是跟他们学的,劫持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 [esp+0x2C]               ; 取出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 [eax+0xB924C], 00C0B032       ; Hook OutputDebugStringA

    00C0B021     C780 54910B00 64B0C>mov     dword ptr [eax+0xB9154], 00C0B064       ; Hook VirtualProtect

    00C0B02B     8B45 08             mov     eax, dword ptr [ebp+0x8]                ; 恢复原来的代码

    00C0B02E     8BE5                mov     esp, ebp

    00C0B030     5D                  pop     ebp

    00C0B031     C3                  retn

    00C0B032     8B0424              mov     eax, dword ptr [esp]                    ; 调用OutputDebugStringA流程会到这里,首先取出返回地址

    00C0B035     8178 1E 33425833    cmp     dword ptr [eax+0x1E], 0x33584233        ; 然后判断是不是到校验的地方

    00C0B03C     75 23               jnz     short 00C0B061

    00C0B03E     C745 F0 B2AE0D72    mov     dword ptr [ebp-0x10], 0x720DAEB2        ; 如果是,就恢复校验值

    00C0B045     C745 E8 26131810    mov     dword ptr [ebp-0x18], 0x10181326

    00C0B04C     C745 E4 B16265F7    mov     dword ptr [ebp-0x1C], 0xF76562B1

    00C0B053     C745 E0 673C9648    mov     dword ptr [ebp-0x20], 0x48963C67

    00C0B05A     C745 DC 78873813    mov     dword ptr [ebp-0x24], 0x13388778

    00C0B061     C2 0400             retn    0x4                                     ; OutputDebugStringA只是一个反调试,返回就好

    00C0B064     C74424 0C 40000000  mov     dword ptr [esp+0xC], 0x40               ; 这里是Hook VirtualProtect,我们修改属性为可读可写可执行。

    00C0B06C     803D E3684400 00    cmp     byte ptr [0x4468E3], 0x0                ; 判断是否解压完毕

    00C0B073     74 1B               je      short <jmp.&KERNEL32.VirtualProtect>

    00C0B075     C605 E4684400 37    mov     byte ptr [0x4468E4], 0x37               ; 开始补代码

    00C0B07C     C705 38674400 E9790>mov     dword ptr [0x446738], 0x179E9

    00C0B086     C705 3C674400 0090E>mov     dword ptr [0x44673C], 0xDE89000

    00C0B090   - FF25 6CB0C100       jmp     dword ptr [<&KERNEL32.VirtualProtect>]  ; kernel32.VirtualProtect,继续执行。
    复制代码

    其实原来的SMC代码比较麻烦,昨天晚上洗澡的时候突然觉悟了,其实可以写的更简单的。
       
    谢谢观赏。

    转自 CjwNull
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    昨天 20:04
  • 签到天数: 1975 天

    [LV.Master]伴坛终老

    发表于 2010-12-3 12:53:56 | 显示全部楼层
    高手就是不一样, 我看完了还没有明白
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2011-1-20 18:41:50 | 显示全部楼层
    学习一下
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2023-1-16 21:41
  • 签到天数: 39 天

    [LV.5]常住居民I

    发表于 2014-2-10 09:53:30 | 显示全部楼层
    学习了,感谢。
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2014-6-3 20:29:53 | 显示全部楼层
    支持飘云阁!
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表