• 标 题:[原创]ARM标准加壳实例脱壳
  • 作 者:lordor
  • 时 间:004-08-15,01:15
  • 链 接:http://bbs.pediy.com

作者:lordor
目的:脱壳记念。

对象:神圣纪事1.66C程序
加壳:Armadillo 3.00a - 3.61 -> Silicon Realms Toolworks
说明:单进程标准加壳




用od载入程序,来到这里
sacred.<M>PUSHAD  ==>这里
0184C001  CALL sacred.0184C006
0184C006  POP EBP
0184C007  PUSH EAX
0184C008  PUSH ECX
0184C009  JMP SHORT sacred.0184C01A
0184C00B  MOV ECX,EBB80FEB

一、来到OEP
arm加壳查找OEP比较简单:

alt+m打开内存窗口
在401000下内存断点


F9运行后,会出现如下的异常
0184FDCB  PREFIX LOCK:                             ; Superfluous prefix  ==>异常
0184FDCC  ???                                      ; Unknown command
0184FDCE  ENTER 3360,0C9

shift+f9后运行,经过两次异常后(中间会有NAG提示),就会停在OEP处
00747128  PUSH EBP      ==>停在这里,这就是OEP
00747129  MOV EBP,ESP
0074712B  PUSH -1
0074712D  PUSH sacred.00774908
00747132  PUSH sacred.0074735C                                        ; JMP to msvcrt._except_handler3
00747137  MOV EAX,DWORD PTR FS:[0]
0074713D  PUSH EAX
0074713E  MOV DWORD PTR FS:[0],ESP
00747145  SUB ESP,68
00747148  PUSH EBX
00747149  PUSH ESI
0074714A  PUSH EDI
0074714B  MOV DWORD PTR SS:[EBP-18],ESP
0074714E  XOR EBX,EBX
00747150  MOV DWORD PTR SS:[EBP-4],EBX
00747153  PUSH 2
00747155  CALL DWORD PTR DS:[76C328]                                  ; msvcrt.__set_app_type
0074715B  POP ECX
0074715C  OR DWORD PTR DS:[17EA988],FFFFFFFF
00747163  OR DWORD PTR DS:[17EA98C],FFFFFFFF
0074716A  CALL DWORD PTR DS:[76C2C0]                                  ; msvcrt.__p__fmode
00747170  MOV ECX,DWORD PTR DS:[17EA43C]



二、查找IAT

继续上一步,先不要动OD,打开ucfir16f程序,在OEP处输入:00747128-400000=347128
通过ImportREC会得到IAT的RAV:0036BFFC,大小:000008E0,让ImportREC查找会得到很多无效的指针

IAT的位置是:0036BFFC+400000=76BFFC
在OD的命令行处输入d 76BFFC会看到IAT表,如下
0076BFFC  00 00 00 00 0C 16 E4 77  .....鋡
0076C004  7B 96 3C 00 7E 17 E4 77  {?.~鋡
0076C00C  BC 1B E4 77 EA 1B E4 77  ?鋡?鋡
0076C014  1E A7 3C 00 E3 A4 E4 77  ?.悚鋡
0076C01C  79 BA E4 77 4E DB E4 77  y轰wN垆w


三、查找Magic jump,避开IAT加密
继续上一步,在OD中选中0076BFFC处的四个字节及下四个字节,下两个硬件断点,然后CTRL+F2重新运行程序,记得在401000处下内存断点,F9

后,通过异常,第一次停在硬件断点处,再一次F9,来到这里

003E17F4  ADD ESP,14
003E17F7  XOR EAX,EAX
003E17F9  JMP 003E27A8
003E17FE  MOV EAX,DWORD PTR SS:[EBP-13E0]
003E1804  CMP EAX,DWORD PTR SS:[EBP-1394]
003E180A  JNB SHORT 003E1829
003E180C  MOV EAX,DWORD PTR SS:[EBP-13E0]
003E1812  MOV ECX,DWORD PTR SS:[EBP-197C]  ==>这个是函数指针
003E1818  MOV DWORD PTR DS:[EAX],ECX    ==>指针这里写入到IAT
003E181A  MOV EAX,DWORD PTR SS:[EBP-13E0]        ==>这里
003E1820  ADD EAX,4
003E1823  MOV DWORD PTR SS:[EBP-13E0],EAX
003E1829  JMP 003E1564        ==>这里往上跳
003E182E  CMP DWORD PTR SS:[EBP-150C],0
003E1835  JNZ 003E18C5


单步走到003E1829  JMP 003E1564往上跳,来到这里
003E1551  MOV EAX,DWORD PTR SS:[EBP-14E4]
003E1557  ADD EAX,DWORD PTR SS:[EBP-1754]
003E155D  PUSH EAX
003E155E  CALL DWORD PTR DS:[3E8134]                                  ; kernel32.VirtualProtect
003E1564  PUSH 1        ==>来到这里
003E1566  POP EAX
003E1567  TEST EAX,EAX
003E1569  JE 003E182E
003E156F  AND WORD PTR SS:[EBP-1978],0
003E1577  AND DWORD PTR SS:[EBP-1980],0
003E157E  AND DWORD PTR SS:[EBP-197C],0
003E1585  MOV EAX,DWORD PTR SS:[EBP-137C]
003E158B  MOVSX EAX,BYTE PTR DS:[EAX]
003E158E  TEST EAX,EAX
003E1590  JNZ SHORT 003E15D6
003E1592  LEA ECX,DWORD PTR SS:[EBP-13BC]
003E1598  CALL 003C1040
003E159D  MOVZX EAX,AL
003E15A0  CDQ
003E15A1  PUSH 14
003E15A3  POP ECX
003E15A4  IDIV ECX
003E15A6  MOV EAX,DWORD PTR SS:[EBP-13E0]
003E15AC  MOV ECX,DWORD PTR SS:[EBP+EDX*4-155C]
003E15B3  MOV DWORD PTR DS:[EAX],ECX
003E15B5  MOV EAX,DWORD PTR SS:[EBP-13E0]
003E15BB  ADD EAX,4
003E15BE  MOV DWORD PTR SS:[EBP-13E0],EAX
003E15C4  MOV EAX,DWORD PTR SS:[EBP-137C]
003E15CA  INC EAX
003E15CB  MOV DWORD PTR SS:[EBP-137C],EAX
003E15D1  JMP 003E182E
003E15D6  MOV EAX,DWORD PTR SS:[EBP-137C]    ==>可以看到函数名
003E15DC  MOVZX EAX,BYTE PTR DS:[EAX]
003E15DF  CMP EAX,0FF
003E15E4  JNZ 003E1674          ==>是否还有函数名
003E15EA  MOV EAX,DWORD PTR SS:[EBP-137C]
003E15F0  INC EAX
003E15F1  MOV DWORD PTR SS:[EBP-137C],EAX
003E15F7  MOV EAX,DWORD PTR SS:[EBP-137C]
003E15FD  MOV AX,WORD PTR DS:[EAX]
003E1600  MOV WORD PTR SS:[EBP-1978],AX
003E1607  MOV EAX,DWORD PTR SS:[EBP-137C]
003E160D  INC EAX
003E160E  INC EAX
003E160F  MOV DWORD PTR SS:[EBP-137C],EAX
003E1615  CMP DWORD PTR SS:[EBP-1748],0
003E161C  JE SHORT 003E166F
003E161E  MOV EAX,DWORD PTR SS:[EBP-1748]
003E1624  MOV DWORD PTR SS:[EBP-1984],EAX
003E162A  JMP SHORT 003E163B
003E162C  MOV EAX,DWORD PTR SS:[EBP-1984]
003E1632  ADD EAX,0C
003E1635  MOV DWORD PTR SS:[EBP-1984],EAX
003E163B  MOV EAX,DWORD PTR SS:[EBP-1984]
003E1641  CMP DWORD PTR DS:[EAX+8],0
003E1645  JE SHORT 003E166F
003E1647  MOVZX EAX,WORD PTR SS:[EBP-1978]
003E164E  MOV ECX,DWORD PTR SS:[EBP-1984]
003E1654  MOVZX ECX,WORD PTR DS:[ECX+4]
003E1658  CMP EAX,ECX
003E165A  JNZ SHORT 003E166D
003E165C  MOV EAX,DWORD PTR SS:[EBP-1984]
003E1662  MOV EAX,DWORD PTR DS:[EAX+8]
003E1665  MOV DWORD PTR SS:[EBP-197C],EAX
003E166B  JMP SHORT 003E166F
003E166D  JMP SHORT 003E162C
003E166F  JMP 003E1711
003E1674  MOV EAX,DWORD PTR SS:[EBP-137C]
003E167A  MOV DWORD PTR SS:[EBP-1980],EAX
003E1680  PUSH 0
003E1682  PUSH DWORD PTR SS:[EBP-137C]
003E1688  CALL DWORD PTR DS:[3E82C8]                                  ; msvcrt.strchr
003E168E  POP ECX
003E168F  POP ECX
003E1690  INC EAX
003E1691  MOV DWORD PTR SS:[EBP-137C],EAX
003E1697  CMP DWORD PTR SS:[EBP-1748],0
003E169E  JE SHORT 003E1711
003E16A0  MOV EAX,DWORD PTR SS:[EBP-1748]
003E16A6  MOV DWORD PTR SS:[EBP-1988],EAX
003E16AC  JMP SHORT 003E16BD
003E16AE  MOV EAX,DWORD PTR SS:[EBP-1988]        -----------------------
003E16B4  ADD EAX,0C                         |
003E16B7  MOV DWORD PTR SS:[EBP-1988],EAX                   |  
003E16BD  MOV EAX,DWORD PTR SS:[EBP-1988]
003E16C3  CMP DWORD PTR DS:[EAX+8],0    ==>要避开加密,只要把[EAX+8]内容清空
003E16C7  JE SHORT 003E1711      ==>这里就是magic jump,因只有这里才能跳出这个循环
003E16C9  PUSH 100
003E16CE  LEA EAX,DWORD PTR SS:[EBP-1A88]
003E16D4  PUSH EAX
003E16D5  MOV EAX,DWORD PTR SS:[EBP-1988]
003E16DB  PUSH DWORD PTR DS:[EAX]
003E16DD  CALL 003C5FD0
003E16E2  ADD ESP,0C
003E16E5  LEA EAX,DWORD PTR SS:[EBP-1A88]
003E16EB  PUSH EAX
003E16EC  PUSH DWORD PTR SS:[EBP-1980]
003E16F2  CALL DWORD PTR DS:[3E8334]                                  ; msvcrt._stricmp
003E16F8  POP ECX
003E16F9  POP ECX
003E16FA  TEST EAX,EAX
003E16FC  JNZ SHORT 003E170F
003E16FE  MOV EAX,DWORD PTR SS:[EBP-1988]
003E1704  MOV EAX,DWORD PTR DS:[EAX+8]                   |    
003E1707  MOV DWORD PTR SS:[EBP-197C],EAX                 |
003E170D  JMP SHORT 003E1711
003E170F  JMP SHORT 003E16AE            ----------------------------
003E1711  CMP DWORD PTR SS:[EBP-197C],0
003E1718  JNZ SHORT 003E1759
003E171A  MOVZX EAX,WORD PTR SS:[EBP-1978]
003E1721  TEST EAX,EAX
003E1723  JE SHORT 003E1734
003E1725  MOVZX EAX,WORD PTR SS:[EBP-1978]
003E172C  MOV DWORD PTR SS:[EBP-2E38],EAX
003E1732  JMP SHORT 003E1740
003E1734  MOV EAX,DWORD PTR SS:[EBP-1980]
003E173A  MOV DWORD PTR SS:[EBP-2E38],EAX
003E1740  PUSH DWORD PTR SS:[EBP-2E38]
003E1746  PUSH DWORD PTR SS:[EBP-1744]
003E174C  CALL 003C7E40
003E1751  POP ECX
003E1752  POP ECX
003E1753  MOV DWORD PTR SS:[EBP-197C],EAX
003E1759  CMP DWORD PTR SS:[EBP-197C],0
003E1760  JNZ 003E17FE
003E1766  MOVZX EAX,WORD PTR SS:[EBP-1978]
003E176D  TEST EAX,EAX
003E176F  JE SHORT 003E17C5
003E1771  CALL DWORD PTR DS:[3E80D4]                                  ; ntdll.RtlGetLastWin32Error
003E1777  CMP EAX,32
003E177A  JNZ SHORT 003E1788
003E177C  MOV DWORD PTR SS:[EBP-197C],3C7E35
003E1786  JMP SHORT 003E17C3
003E1788  MOV EAX,DWORD PTR SS:[EBP+8]
003E178B  MOV EAX,DWORD PTR DS:[EAX]
003E178D  MOV DWORD PTR DS:[EAX],3
003E1793  CALL DWORD PTR DS:[3E80D4]                                  ; ntdll.RtlGetLastWin32Error
003E1799  PUSH EAX
003E179A  MOVZX EAX,WORD PTR SS:[EBP-1978]
003E17A1  PUSH EAX
003E17A2  PUSH DWORD PTR SS:[EBP-1860]
003E17A8  PUSH 3EE510                                                 ; ASCII "File "%s", ordinal %d (error %d)"
003E17AD  MOV EAX,DWORD PTR SS:[EBP+8]
003E17B0  PUSH DWORD PTR DS:[EAX+4]
003E17B3  CALL DWORD PTR DS:[3E82C4]                                  ; msvcrt.sprintf
003E17B9  ADD ESP,14
003E17BC  XOR EAX,EAX
003E17BE  JMP 003E27A8
003E17C3  JMP SHORT 003E17FE
003E17C5  MOV EAX,DWORD PTR SS:[EBP+8]
003E17C8  MOV EAX,DWORD PTR DS:[EAX]
003E17CA  MOV DWORD PTR DS:[EAX],3
003E17D0  CALL DWORD PTR DS:[3E80D4]                                  ; ntdll.RtlGetLastWin32Error
003E17D6  PUSH EAX
003E17D7  PUSH DWORD PTR SS:[EBP-1980]
003E17DD  PUSH DWORD PTR SS:[EBP-1860]
003E17E3  PUSH 3EE4EC                                                 ; ASCII "File "%s", function "%s" (error %d)"
003E17E8  MOV EAX,DWORD PTR SS:[EBP+8]
003E17EB  PUSH DWORD PTR DS:[EAX+4]
003E17EE  CALL DWORD PTR DS:[3E82C4]                                  ; msvcrt.sprintf
003E17F4  ADD ESP,14
003E17F7  XOR EAX,EAX
003E17F9  JMP 003E27A8
003E17FE  MOV EAX,DWORD PTR SS:[EBP-13E0]
003E1804  CMP EAX,DWORD PTR SS:[EBP-1394]
003E180A  JNB SHORT 003E1829
003E180C  MOV EAX,DWORD PTR SS:[EBP-13E0]
003E1812  MOV ECX,DWORD PTR SS:[EBP-197C]
003E1818  MOV DWORD PTR DS:[EAX],ECX
003E181A  MOV EAX,DWORD PTR SS:[EBP-13E0]
003E1820  ADD EAX,4
003E1823  MOV DWORD PTR SS:[EBP-13E0],EAX
003E1829  JMP 003E1564
003E182E  CMP DWORD PTR SS:[EBP-150C],0
003E1835  JNZ 003E18C5
003E1835  JNZ 003E18C5
003E183B  MOVZX EAX,BYTE PTR SS:[EBP-1750]
003E1842  TEST EAX,EAX
003E1844  JE SHORT 003E18C5
003E1846  PUSH 0
003E1848  MOV EAX,DWORD PTR SS:[EBP-174C]
003E184E  SHL EAX,2
003E1851  PUSH EAX
003E1852  MOV EAX,DWORD PTR SS:[EBP-14E4]
003E1858  ADD EAX,DWORD PTR SS:[EBP-1754]
003E185E  PUSH EAX
003E185F  CALL 003E319C
003E1864  ADD ESP,0C
003E1867  MOV EAX,DWORD PTR SS:[EBP-174C]
003E186D  SHL EAX,2
003E1870  PUSH EAX
003E1871  PUSH DWORD PTR SS:[EBP-138C]
003E1877  MOV EAX,DWORD PTR SS:[EBP-14E4]
003E187D  ADD EAX,DWORD PTR SS:[EBP-1754]
003E1883  PUSH EAX
003E1884  CALL 003E76F4                                               ; JMP to msvcrt.memcpy
003E1889  ADD ESP,0C
003E188C  PUSH 1
003E188E  MOV EAX,DWORD PTR SS:[EBP-174C]
003E1894  SHL EAX,2
003E1897  PUSH EAX
003E1898  MOV EAX,DWORD PTR SS:[EBP-14E4]
003E189E  ADD EAX,DWORD PTR SS:[EBP-1754]
003E18A4  PUSH EAX
003E18A5  CALL 003E319C
003E18AA  ADD ESP,0C
003E18AD  MOV EAX,DWORD PTR SS:[EBP-138C]
003E18B3  MOV DWORD PTR SS:[EBP-2C04],EAX
003E18B9  PUSH DWORD PTR SS:[EBP-2C04]
003E18BF  CALL 003E76EE                                               ; JMP to msvcrt.??3@YAXPAX@Z
003E18C4  POP ECX
003E18C5  CMP DWORD PTR SS:[EBP-150C],0
003E18CC  JNZ SHORT 003E18F8
003E18CE  LEA EAX,DWORD PTR SS:[EBP-1758]
003E18D4  PUSH EAX
003E18D5  PUSH DWORD PTR SS:[EBP-1758]
003E18DB  MOV EAX,DWORD PTR SS:[EBP-174C]
003E18E1  SHL EAX,2
003E18E4  PUSH EAX
003E18E5  MOV EAX,DWORD PTR SS:[EBP-14E4]
003E18EB  ADD EAX,DWORD PTR SS:[EBP-1754]
003E18F1  PUSH EAX
003E18F2  CALL DWORD PTR DS:[3E8134]                                  ; kernel32.VirtualProtect
003E18F8  JMP 003E1181            ===>这里往上形成大循环,反复载入dll文件
003E18FD  MOV EAX,DWORD PTR SS:[EBP-1500]
003E1903  MOV DWORD PTR SS:[EBP-2C08],EAX


先取消所以的硬件断点,再在003E16C3  CMP DWORD PTR DS:[EAX+8],0  处下执行断点,再CTRL+F2重新运行程序,来到003E16C3处后把

[eax+8]处的内容清空,再在401000处下内存断点,并去掉硬件断点,F9运行,会到OEP处
00747116  JMP DWORD PTR DS:[76C3B8]                                   ; msvcrt.printf
0074711C  JMP DWORD PTR DS:[76C340]                                   ; msvcrt.qsort
00747122  JMP DWORD PTR DS:[76C434]                                   ; msvcrt._CIasin
00747128  PUSH EBP    ==>到这里了
00747129  MOV EBP,ESP
0074712B  PUSH -1
0074712D  PUSH sacred.00774908
00747132  PUSH sacred.0074735C                                        ; JMP to msvcrt._except_handler3


先用LORDPE工具DUMP下这个程序,再打开ImportREC1.6,查找IAT,只有17个指针无效,CUT掉即可,FIXDUMP


四、最后修复
这样脱壳后,程序可以正常运行了,并且没有NAG提示了,过瘾吧。不过在点击联网按键时程序会非常操作,看来还有一些IAT指针没修复。
用OD载入脱壳后的程序,会发现
0068248E    6A 00           PUSH 0
00682490    6A 00           PUSH 0
00682492    6A 00           PUSH 0
00682494    68 18FF8300     PUSH dumped_.0083FF18                    ; ASCII "Software\Microsoft\DirectPlay8

\Applications\{3DA76BB1-F64B-4CD6-8C90-34EDFD369D25}"
00682499    68 01000080     PUSH 80000001
0068249E    FF15 0CC27600   CALL DWORD PTR DS:[76C20C]    ==>这个指针为0,所以出错
006824A4    85C0            TEST EAX,EAX
006824A6    0F85 38040000   JNZ dumped_.006828E4
006824AC    55              PUSH EBP
006824AD    57              PUSH EDI
006824AE    898424 40010000 MOV DWORD PTR SS:[ESP+140],EAX


好了,再用OD载入加壳的程序,并在76C20C处下硬件断点,来到这里处理IAT的地方(请看上面的方法)
003E180C  MOV EAX,DWORD PTR SS:[EBP-13E0]
003E1812  MOV ECX,DWORD PTR SS:[EBP-197C]
003E1818  MOV DWORD PTR DS:[EAX],ECX
003E181A  MOV EAX,DWORD PTR SS:[EBP-13E0]                    ==>停在这里
003E1820  ADD EAX,4
003E1823  MOV DWORD PTR SS:[EBP-13E0],EAX
003E1829  JMP 003E1564

由于程序在加密IAT时会留下函数名,看看EDX处是什么,对,就是函数名:RegCreateKeyExA。
可以知76C20C处应该是RegCreateKeyExA的地址,用我写的小工具:DirAPI,找到地址为77DA27D6

其它的步骤都是相同的,只是在ImportREC中把76C20C的指针修正为RegCreateKeyExA函数名即可。CUT掉其除的16个无效地址。

到此,联网的功能也正常的运行了。



总结:
写完了,好累,不知大家有没有看明白,像ARM这些加密壳关键是处理加密IAT的地方,希望对初学者修复IAT加密有参考价值

再次感谢写ARM教程的所以大侠!


by lordor
欢迎访问小站:http://lordor.freelinuxhost.com


04.08.15 深夜