发新话题
打印

[转载]浅谈Armadillo V.3.75 与 V.3.78的保护

[转载]浅谈Armadillo V.3.75 与 V.3.78的保护

信息来源:http://www.pediy.com/bbshtml/BBS6/pediy6906.htm

阔别脱壳已有四年了,没想到Armadillo与ASprotect都变得如此变态,这是四年多来第一篇脱文,有不对的地方,还请各位多加指教,这篇文章只是心得分享.
首先ArmadilloV.3.75与V.3.78最大的不同点是V.3.75是由子进程自行解压而父进程只处理CC,而V.3.78是子进程解压后又会再度加密,然后在执行时产生异常,而由父进程处理异常,处理子进程的解压,所以在父进程在此时的角色变为处理子进程解码与CC。我们主要要处理几个部分:
(1)  得到IAT
(2)  Dump程序与修复IAT
(3)  找OEP
(4)  修复CC
我们分别来谈:
[得到IAT] 想要得到IAT一般是修改Magic Jmp  在 Armadillo中有两处,如下:
00E49C2A  8B0D 74B7E700   MOV ECX,DWORD PTR DS:[E7B774]
00E49C30  89040E        MOV DWORD PTR DS:[ESI+ECX],EAX
00E49C33  A1 74B7E700    MOV EAX,DWORD PTR DS:[E7B774]
00E49C38  391C06        CMP DWORD PTR DS:[ESI+EAX],EBX
00E49C3B  75 16        JNZ SHORT 00E49C53
00E49C3D  8D85 B4FEFFFF   LEA EAX,DWORD PTR SS:[EBP-14C]
00E49C43  50          PUSH EAX
00E49C44  FF15 DC00E700   CALL DWORD PTR DS:[E700DC]          ; KERNEL32.LoadLibraryA
00E49C4A  8B0D 74B7E700   MOV ECX,DWORD PTR DS:[E7B774]
00E49C50  89040E        MOV DWORD PTR DS:[ESI+ECX],EAX
00E49C53  A1 74B7E700    MOV EAX,DWORD PTR DS:[E7B774]
00E49C58  391C06        CMP DWORD PTR DS:[ESI+EAX],EBX
00E49C5B  0F84 32010000   JE 00E49D93                    ;Magic Jmp1



00E76BE8  3985 90C4FFFF   CMP DWORD PTR SS:[EBP-3B70],EAX       ; Armadill.00400000
00E76BEE  75 0F        JNZ SHORT 00E76BFF
00E76BF0  C785 8CC4FFFF 80>MOV DWORD PTR SS:[EBP-3B74],0E85180
00E76BFA  E9 C4000000    JMP 00E76CC3
00E76BFF  83A5 68C2FFFF 00 AND DWORD PTR SS:[EBP-3D98],0
00E76C06  C785 64C2FFFF C0>MOV DWORD PTR SS:[EBP-3D9C],0E857C0
00E76C10  EB 1C        JMP SHORT 00E76C2E
00E76C12  8B85 64C2FFFF   MOV EAX,DWORD PTR SS:[EBP-3D9C]
00E76C18  83C0 0C       ADD EAX,0C
00E76C1B  8985 64C2FFFF   MOV DWORD PTR SS:[EBP-3D9C],EAX
00E76C21  8B85 68C2FFFF   MOV EAX,DWORD PTR SS:[EBP-3D98]
00E76C27  40          INC EAX
00E76C28  8985 68C2FFFF   MOV DWORD PTR SS:[EBP-3D98],EAX
00E76C2E  8B85 64C2FFFF   MOV EAX,DWORD PTR SS:[EBP-3D9C]
00E76C34  8338 00       CMP DWORD PTR DS:[EAX],0
00E76C37  0F84 86000000   JE 00E76CC3                    ;Magic Jmp2
00E76C3D  8B85 64C2FFFF   MOV EAX,DWORD PTR SS:[EBP-3D9C]
00E76C43  8B40 08       MOV EAX,DWORD PTR DS:[EAX+8]
00E76C46  83E0 01       AND EAX,1
00E76C49  85C0         TEST EAX,EAX
00E76C4B  74 25        JE SHORT 00E76C72
00E76C4D  A1 2800E900    MOV EAX,DWORD PTR DS:[E90028]
00E76C52  8B0D 2800E900   MOV ECX,DWORD PTR DS:[E90028]        ; Armadill.004B3310
00E76C58  8B40 30       MOV EAX,DWORD PTR DS:[EAX+30]
00E76C5B  3341 20       XOR EAX,DWORD PTR DS:[ECX+20]
00E76C5E  8B0D 2800E900   MOV ECX,DWORD PTR DS:[E90028]        ; Armadill.004B3310
00E76C64  3341 70       XOR EAX,DWORD PTR DS:[ECX+70]
00

个人觉得第一处比较好。既可得到完整的IAT又可以避开时间的检验,至于如何找到IAT与Dump出IAT,我想大家应该没有问题。
[ Dump出程序与修复IAT ]  在这个步骤,首先你需要一个观念,你必须时时刻刻问自己程序在做什么?为什么这么做?这时IAT乱序已完成,程序在以下的代码段写下CALL的位置.即CALL(Address)

00E67E16  8B85 BCB0FFFF   MOV EAX,DWORD PTR SS:[EBP+FFFFB0BC]
00E67E1C  40          INC EAX
00E67E1D  8985 BCB0FFFF   MOV DWORD PTR SS:[EBP+FFFFB0BC],EAX
00E67E23  8B85 BCB0FFFF   MOV EAX,DWORD PTR SS:[EBP+FFFFB0BC]
00E67E29  8B8D 18C8FFFF   MOV ECX,DWORD PTR SS:[EBP-37E8]
00E67E2F  833C81 00      CMP DWORD PTR DS:[ECX+EAX*4],0
00E67E33  0F84 90000000   JE 00E67EC9
00E67E39  8B85 BCB0FFFF   MOV EAX,DWORD PTR SS:[EBP+FFFFB0BC]
00E67E3F  8B8D 18C8FFFF   MOV ECX,DWORD PTR SS:[EBP-37E8]
00E67E45  8B95 00C7FFFF   MOV EDX,DWORD PTR SS:[EBP-3900]
00E67E4B  031481        ADD EDX,DWORD PTR DS:[ECX+EAX*4]
00E67E4E  8995 ACB0FFFF   MOV DWORD PTR SS:[EBP+FFFFB0AC],EDX
00E67E54  8B85 ACB0FFFF   MOV EAX,DWORD PTR SS:[EBP+FFFFB0AC]
00E67E5A  8B00         MOV EAX,DWORD PTR DS:[EAX]
00E67E5C  8985 A8B0FFFF   MOV DWORD PTR SS:[EBP+FFFFB0A8],EAX
00E67E62  81BD A8B0FFFF 90>CMP DWORD PTR SS:[EBP+FFFFB0A8],90909090
00E67E6C  74 56        JE SHORT 00E67EC4
00E67E6E  8B85 A8B0FFFF   MOV EAX,DWORD PTR SS:[EBP+FFFFB0A8]
00E67E74  2B85 B8B0FFFF   SUB EAX,DWORD PTR SS:[EBP+FFFFB0B8]
00E67E7A  8985 A8B0FFFF   MOV DWORD PTR SS:[EBP+FFFFB0A8],EAX
00E67E80  FFB5 A8B0FFFF   PUSH DWORD PTR SS:[EBP+FFFFB0A8]
00E67E86  8B85 BCB0FFFF   MOV EAX,DWORD PTR SS:[EBP+FFFFB0BC]
00E67E8C  33D2         XOR EDX,EDX
00E67E8E  6A 10        PUSH 10
00E67E90  59          POP ECX
00E67E91  F7F1         DIV ECX
00E67E93  FF1495 7807E700  CALL DWORD PTR DS:[EDX*4+E70778]
00E67E9A  59          POP ECX
00E67E9B  8985 A8B0FFFF   MOV DWORD PTR SS:[EBP+FFFFB0A8],EAX
00E67EA1  8B85 A8B0FFFF   MOV EAX,DWORD PTR SS:[EBP+FFFFB0A8]
00E67EA7  8B8D D8C6FFFF   MOV ECX,DWORD PTR SS:[EBP-3928]
00E67EAD  8D0481        LEA EAX,DWORD PTR DS:[ECX+EAX*4]
00E67EB0  8985 A8B0FFFF   MOV DWORD PTR SS:[EBP+FFFFB0A8],EAX
00E67EB6  8B85 ACB0FFFF   MOV EAX,DWORD PTR SS:[EBP+FFFFB0AC]
00E67EBC  8B8D A8B0FFFF   MOV ECX,DWORD PTR SS:[EBP+FFFFB0A8]
00E67EC2  8908         MOV DWORD PTR DS:[EAX],ECX
00E67EC4  ^E9 4DFFFFFF    JMP 00E67E16

[Address]是指同一个API Armadillo为什么会留下这个最容易被攻击的地方呢?那是因为他的IAT乱序表的地址是动态产生的,它不得不在这个时候写入正确的地址,所以在这个时候他的属性就非得变为可读可写了.嘻嘻!也因此你就能使用Lordpe等工具去Dump出子进程来,这时你可以在Memory中找到IAT乱序表与CALL的位置表,它们是紧连着的.你把它们Dump出来,配合之前得到的IAT你就能修复他,或是直接写入一些代码,让CALL指向你自己的IAT,随便你,在这里你可以为所欲为.

[得到OEP] 在Armadillo中OEP倒有许多方法可找到.你可以He GetCurrenthreadId去找那个CALL EDI V.3.75与V.3.78均同.

[修复CC]:在这个阶段大部分是手工活了,也是最花时间的Armadillo 的  Nanomites保护,其特征代码如下:

0048F1F7  C785 94EBFFFF 00>MOV DWORD PTR SS:[EBP-146C],0
0048F201  6A FF        PUSH -1
0048F203  6A 04        PUSH 4
0048F205  8D95 50ECFFFF   LEA EDX,DWORD PTR SS:[EBP-13B0]
0048F20B  52          PUSH EDX
0048F20C  E8 7F7DFEFF    CALL Armadill.00476F90
0048F211  83C4 0C       ADD ESP,0C
0048F214  8985 68EEFFFF   MOV DWORD PTR SS:[EBP-1198],EAX
0048F21A  8B85 68EEFFFF   MOV EAX,DWORD PTR SS:[EBP-1198]
0048F220  33D2         XOR EDX,EDX
0048F222  B9 10000000    MOV ECX,10
0048F227  F7F1         DIV ECX
0048F229  8995 64EEFFFF   MOV DWORD PTR SS:[EBP-119C],EDX
0048F22F  8B95 50ECFFFF   MOV EDX,DWORD PTR SS:[EBP-13B0]
0048F235  52          PUSH EDX
0048F236  8B85 64EEFFFF   MOV EAX,DWORD PTR SS:[EBP-119C]
0048F23C  FF1485 A8784B00  CALL DWORD PTR DS:[EAX*4+4B78A8]
0048F243  83C4 04       ADD ESP,4
0048F246  8985 94EBFFFF   MOV DWORD PTR SS:[EBP-146C],EAX
0048F24C  C785 90EBFFFF 00>MOV DWORD PTR SS:[EBP-1470],0
0048F256  8B8D 64EEFFFF   MOV ECX,DWORD PTR SS:[EBP-119C]
0048F25C  8B148D 88994B00  MOV EDX,DWORD PTR DS:[ECX*4+4B9988]
0048F263  8995 70EEFFFF   MOV DWORD PTR SS:[EBP-1190],EDX
0048F269  8B85 90EBFFFF   MOV EAX,DWORD PTR SS:[EBP-1470]
0048F26F  3B85 70EEFFFF   CMP EAX,DWORD PTR SS:[EBP-1190]
0048F275  7D 5C        JGE SHORT Armadill.0048F2D3
0048F277  8B85 70EEFFFF   MOV EAX,DWORD PTR SS:[EBP-1190]
0048F27D  2B85 90EBFFFF   SUB EAX,DWORD PTR SS:[EBP-1470]
0048F283  99          CDQ
0048F284  2BC2         SUB EAX,EDX
0048F286  D1F8         SAR EAX,1

至于怎么到这里不用我说了吧!He GetThreadContext在这个部分你需要找到四个表《INT3地址+1表(Armadillo利用这来计算跳转的,记做Table1),跳转类型表(JMP,JZ,JNZ…)记做 Table2,跳的话距离是多少记做Table3,不跳的话距离又是多少记做Table4。为什么需要这四个表呢?举个例子:

            00401D1B    CC    INT3
            00401D1C    56    push ESI
            
我们可以在Armadillo中找到
Table1:00401D1C
Table2:Jmp
Table3:04
Table4: 04
这是个绝对的跳转JMP,但他只跳04Byte这其实是一个NOP怎么说,你看00401D1C+04=00401D20你改为
00401D1B 90 NOP
00401D1C 90 NOP
00401D1D 90 NOP
00401D1E 90 NOP
00401D1F 90  NOP
00401D20 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]

或直接改为:
00401D1B  E900000000  JMP00401D20
00401D20  8B4508    MOV EAX,DWORD PTR SS:[EBP+8]

都必须可实现,或你不放心那可改为:
00401D1B  EB 03    JMP  00401D20
00401D1D  105678    ADC  BYTE  DS:[EST+78],DL
00401D20  8B4508   MOV  EAX,DWORD PTR SS:[EB+8]
也可以,另外还有一些修复技巧,后面再详述.

首先找Table1亦就是发生INT3的下一个地址,它就在上述的0048F205  8D95 50ECFFFF LEA EDX,DWPRO PTR SS:[EBP-13BO]就在[EBP-13BO]中,V.3.75你可以用点击所有的功能表来获得大部分有用的地址.但V.3.78就难了.还有一个方法是使用IDA去反汇编你已Dump出来的程序,IDA就会帮你做记号“Trap to Debugger”利用它你几乎可以得到所有INT3地址,但有许多是用不到的,因为你不会走到那里.你或许会问为什么不用Armadillo的运算表去还原地址呢?旧版的或许可以,但新版的他不只把跳转做成表,也把不是的也加在里面,那就算你能还原它,也不一定是你需要的。
再来就是Table2的处理了,其代码如下:

0048F372  8B85 64EEFFFF   MOV EAX,DWORD PTR SS:[EBP-119C]
0048F378  8B0C85 C8994B00  MOV ECX,DWORD PTR DS:[EAX*4+4B99C8]
0048F37F  8B95 90EBFFFF   MOV EDX,DWORD PTR SS:[EBP-1470]
0048F385  33C0         XOR EAX,EAX
0048F387  8A0411        MOV AL,BYTE PTR DS:[ECX+EDX]
0048F38A  8985 74EBFFFF   MOV DWORD PTR SS:[EBP-148C],EAX
0048F390  8B85 74EBFFFF   MOV EAX,DWORD PTR SS:[EBP-148C]
0048F396  99          CDQ
0048F397  83E2 0F       AND EDX,0F
0048F39A  03C2         ADD EAX,EDX
0048F39C  C1F8 04       SAR EAX,4
0048F39F  8985 7CEBFFFF   MOV DWORD PTR SS:[EBP-1484],EAX
0048F3A5  8B8D 74EBFFFF   MOV ECX,DWORD PTR SS:[EBP-148C]
0048F3AB  81E1 0F000080   AND ECX,8000000F
0048F3B1  79 05        JNS SHORT Armadill.0048F3B8
0048F3B3  49          DEC ECX
0048F3B4  83C9 F0       OR ECX,FFFFFFF0
0048F3B7  41          INC ECX
0048F3B8  898D 78EBFFFF   MOV DWORD PTR SS:[EBP-1488],ECX
0048F3BE  8B95 7CEBFFFF   MOV EDX,DWORD PTR SS:[EBP-1484]
0048F3C4  3B95 78EBFFFF   CMP EDX,DWORD PTR SS:[EBP-1488]
0048F3CA  75 1B        JNZ SHORT Armadill.0048F3E7
0048F3CC  8B85 78EBFFFF   MOV EAX,DWORD PTR SS:[EBP-1488]
0048F3D2  83C0 01       ADD EAX,1
0048F3D5  25 0F000080    AND EAX,8000000F
0048F3DA  79 05        JNS SHORT Armadill.0048F3E1
0048F3DC  48          DEC EAX
0048F3DD  83C8 F0       OR EAX,FFFFFFF0
0048F3E0  40          INC EAX
0048F3E1  8985 78EBFFFF   MOV DWORD PTR SS:[EBP-1488],EAX
0048F3E7  8B8D 74EBFFFF   MOV ECX,DWORD PTR SS:[EBP-148C]
0048F3ED  8B95 7CEBFFFF   MOV EDX,DWORD PTR SS:[EBP-1484]
0048F3F3  8B048D 388F4B00  MOV EAX,DWORD PTR DS:[ECX*4+4B8F38]
0048F3FA  330495 AC324B00  XOR EAX,DWORD PTR DS:[EDX*4+4B32AC]
0048F401  8B8D 78EBFFFF   MOV ECX,DWORD PTR SS:[EBP-1488]
0048F407  33048D AC324B00  XOR EAX,DWORD PTR DS:[ECX*4+4B32AC]
0048F40E  8985 84EBFFFF   MOV DWORD PTR SS:[EBP-147C],EAX
0048F414  8B95 58ECFFFF   MOV EDX,DWORD PTR SS:[EBP-13A8]
0048F41A  81E2 D70F0000   AND EDX,0FD7
0048F420  52          PUSH EDX
0048F421  8B85 74EBFFFF   MOV EAX,DWORD PTR SS:[EBP-148C]
0048F427  0FBE88 A0774B00  MOVSX ECX,BYTE PTR DS:[EAX+4B77A0]
0048F42E  FF148D A8784B00  CALL DWORD PTR DS:[ECX*4+4B78A8]
0048F435  83C4 04       ADD ESP,4
0048F438  8985 88EBFFFF   MOV DWORD PTR SS:[EBP-1478],EAX
0048F43E  8B95 44ECFFFF   MOV EDX,DWORD PTR SS:[EBP-13BC]
0048F444  52          PUSH EDX
0048F445  8B85 88EBFFFF   MOV EAX,DWORD PTR SS:[EBP-1478]
0048F44B  50          PUSH EAX
0048F44C  FF95 84EBFFFF   CALL DWORD PTR SS:[EBP-147C]
0048F452  83C4 08       ADD ESP,8
0048F455  50          PUSH EAX
0048F456  8B8D 74EBFFFF   MOV ECX,DWORD PTR SS:[EBP-148C]
0048F45C  0FBE91 A0774B00  MOVSX EDX,BYTE PTR DS:[ECX+4B77A0]
0048F463  FF1495 E8784B00  CALL DWORD PTR DS:[EDX*4+4B78E8]
0048F46A  83C4 04       ADD ESP,4
0048F46D  8985 80EBFFFF   MOV DWORD PTR SS:[EBP-1480],EAX
0048F473  8B85 80EBFFFF   MOV EAX,DWORD PTR SS:[EBP-1480]
0048F479  83E0 01       AND EAX,1
0048F47C  85C0         TEST EAX,EAX
0048F47E  0F84 AE000000   JE Armadill.0048F532
0048F484  60          PUSHAD
0048F485  33C0         XOR EAX,EAX
0048F487  75 02        JNZ SHORT Armadill.0048F48B
0048F489  EB 15        JMP SHORT Armadill.0048F4A0
0048F48B  EB 33        JMP SHORT Armadill.0048F4C0

这段代码就是利用EFL值与前面运算得出的值做运算,算出子进程是跳或不是跳,意思即0048F47C TEST EAX,EAX;  EAX=1,子进程跳EAX=0子进程不跳,我们利用它来模拟进而得到跳转类型。如何做呢?let’s go!
我们用到的旗标有CF、PF、ZF、SF、OF
     CF=1→1h
     PF=1→4h
     ZF=1→40h
     SF=1→80h
     OF=1→800h

走到0048F420 Push EDX,此时EDX=EFL值,我们把EDX值改为1意即只有CF旗标有作用,结果0048F47C的EAX值为1用笔记下来,再至0048F372重建EIP,如此依序更改为EDX的值,我们发现一个有趣的现象:
EFL=1  EAX=1
EFL=4  EAX=1
EFL=40  EAX=1
EFL=80  EAX=1
EFL=800 EAX=1

意即所有的旗标都无法影响到跳转,它肯定是一个绝对的跳转,意即JMP。

再看下一个例子:           
EFL=1  EAX=0
EFL=4  EAX=0
EFL=40  EAX=1
EFL=80  EAX=0
EFL=800 EAX=0

此时只有零旗标ZF会影响跳转,意即等于零跳转,那就是JZ or JE了

那JNZ呢?如下:           
EFL=1  EAX=1
EFL=4  EAX=1
EFL=40  EAX=0
EFL=80  EAX=1
EFL=800 EAX=1

跟JZ相反,等于零不跳,意即不等于零才会跳

归纳出:
(1)  11111→JMP(EB)                                
(2)  00100→JZ(74)
(3)  11011→JNZ(75)
(4)  00011→JL(7C)  漏掉了许多跳转,这只是告诉你原理,你可以查阅跳转的资料
(5)  00111→JLE(7E) 去编你自己的跳转类型判断表,自由发挥吧!
(6)  11100→JGE(7D)
(7)  10000→JB(72)
(8)  01111→JAE(73)

接下来是Table3其代码如下:

0048F4B0  8B0C8D E8984B00  MOV ECX,DWORD PTR DS:[ECX*4+4B98E8]
0048F4B7  8B85 90EBFFFF   MOV EAX,DWORD PTR SS:[EBP-1470]
0048F4BD  33D2         XOR EDX,EDX
0048F4BF  BE 10000000    MOV ESI,10
0048F4C4  F7F6         DIV ESI
0048F4C6  8B85 90EBFFFF   MOV EAX,DWORD PTR SS:[EBP-1470]
0048F4CC  8B0C81        MOV ECX,DWORD PTR DS:[ECX+EAX*4]
0048F4CF  338C95 8CEEFFFF  XOR ECX,DWORD PTR SS:[EBP+EDX*4-1174]
0048F4D6  8B95 50ECFFFF   MOV EDX,DWORD PTR SS:[EBP-13B0]
0048F4DC  03D1         ADD EDX,ECX
0048F4DE  8995 50ECFFFF   MOV DWORD PTR SS:[EBP-13B0],EDX

走过0048F4CF后这个ECX的值就是我们要的了。

最后是Table4了,其代码如下:

0048F53D  8B85 64EEFFFF   MOV EAX,DWORD PTR SS:[EBP-119C]
0048F543  8B0C85 109A4B00  MOV ECX,DWORD PTR DS:[EAX*4+4B9A10]
0048F54A  8B95 90EBFFFF   MOV EDX,DWORD PTR SS:[EBP-1470]
0048F550  33C0         XOR EAX,EAX
0048F552  8A0411        MOV AL,BYTE PTR DS:[ECX+EDX]
0048F555  8B8D 50ECFFFF   MOV ECX,DWORD PTR SS:[EBP-13B0]
0048F55B  03C8         ADD ECX,EAX
0048F55D  898D 50ECFFFF   MOV DWORD PTR SS:[EBP-13B0],ECX

走过0048F552后这个EAX的值就是我们要的了。
在程序内写入代码,依序去得到想要的Table,然后用它来修复CC,修复CC时注意事项



例1:                             
                        
Table1  00401213
Table2  JZ
Table3  55FFFFFF
Table4  05
改00401212 OF 84 50FFFFFF


例2:                     
Table1  00401213
Table2  JZ
Table3  EFFFFFFF
Table4  01
改00401212  74 EE

例3:                     
Table1  00401213
Table2  JZ
Table3  28
Table4  01
改00401212  74 27

例4:                     
Table1  00401213
Table2  JZ
Table3  B5
Table4  05
改00401212  0F 84 B0000000


[后记]:许久没有脱壳与写脱壳文了,甚至连电脑都很少碰,最近脱了新版本ASprotect 与Armadillo好象又能找到当年的一点感觉,我脱壳总喜欢慢慢的去品尝保护程序带给我的惊喜。脱这些硬壳,需要的是除了知识外,还需要耐心与恒心。最重要的是对脱壳的热爱,希望本文能对你有所帮助。
曾几何时,有人对我说:装B遭雷劈。我说:去你妈的。于是,这个人又对我说:如果再说脏话,上帝会惩罚你的。我说:我操上帝。结论:彪悍的人生不需要上帝。

TOP

发新话题