<< 自己记录......... Category: 黑客技术文章 我搜集的好东西 >>
壳 自己记录2.......    [ 2009-05-02 8:10:39 PM | Author: kyo327 | From: Original ]
脱壳tmd.
先跑脚本判断一下版本。 然后改nooby的脚本。
themida & wl iat repair by nooby
tmd_iat.osc
-------------------------------------------------------
gmemi eip,MEMORYBASE
msg $RESULT

// FIRST TMD/WL SECTION IN THE TARGET
mov tmdbase, 008b5000 //把这里改一下。

然后跑脚本。
跑完后 停在这。
/*408358*/ PUSH EBX
/*408359*/ MOV EBX,EAX
/*40835B*/ XOR EAX,EAX
/*40835D*/ MOV DWORD PTR DS:[76A0CC],EAX
/*408362*/ PUSH 0
-----------------------------------------
dump后,上uif.选上 fix directly imports---->start---->
接着上ImportREC
oep===8358 rva和大小 在uif里找。然后修复转储即可了。
---------------------------------------------------------------------

偷代码了 还得修复。
http://www.unpack.cn/viewthread.php?tid=22871
这个是delphi的修复 好像很麻烦
----------------------------------------------------------------------------------------------------------------------------------------
脱 ASProtect 1.2x - 1.3x [Registered] -> Alexey Solodovnikov 用下面这个脚本。
Aspr2.XX_unpacker_v1.15SC.osc
先配置一下。用odbgScript1.65跑一遍,会提示有偷代码,其实已经补好了。并dump一个de_xxxx.exe.然后根据日志用ImportREC修复一下即可。
-----------------------------------------------------------------------------------------------------------
自己下的ACProtect v1.09g加壳玩下
加的是vc6.0的程序。peid查看是AntiCrack Protector 1.0x -> RISCO Software Inc.
OEP很好找。
代码段---PE段---代码段下内存访问断就到了。
不过到了后有点偷代码,好在偷的不多,顺便补上就可以了。
004016A2 68 D8504000 PUSH CrackMe.004050D8
004016A7 68 00274000 PUSH CrackMe.00402700
004016AC 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
004016B2 50 PUSH EAX
004016B3 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
004016BA 83EC 58 SUB ESP,58
004016BD 53 PUSH EBX

可根据堆栈中的值来补代码。所补的代码如下
push ebp
mov ebp,esp
push -1


当然IAT也加密了。老方法,dd 405000 内存写入断
可以到这里/*4173D3*/ MOV DWORD PTR DS:[EDI],EAX

就是eax覆盖了。单步跟踪一下可以知道正确的iat是从这得到的
/*417319*/ CALL DWORD PTR SS:[EBP+41C268] //这里得到的 这是GetProcaddress
/*41731F*/ CMP EBX,DWORD PTR SS:[EBP+404028] //这里改为jmp 4173D3

那么把下面的改成jmp 4173D3应该是可行的。
那就试试吧
he 417319
改完到oep后记得把偷代码补上就可以dumpfix了。
完了后发现不能运行。原来还有code replace
0040F0FB - FF25 04701500 JMP DWORD PTR DS:[157004]
0040F101 - FF25 08701500 JMP DWORD PTR DS:[157008]
0040F107 - FF25 0C701500 JMP DWORD PTR DS:[15700C]
0040F10D - FF25 10701500 JMP DWORD PTR DS:[157010]
0040F113 - FF25 14701500 JMP DWORD PTR DS:[157014]
0040F119 - FF25 18701500 JMP DWORD PTR DS:[157018]
---------------------------------华丽的分割线--------------------------------------
code replace的修复。
进行到这时我本来已经懒得去修复了。想把157004的区段给补上,虽然是拙劣的方式,但对于我这个菜鸟,
我以为首先能脱壳后正常运行起来是主要的。
可这是个低于00400000的地址,直接补区段是不行的。我试过在刚载入程序时首先申请低于400000地址的方法。
无奈对于这个壳好象不是很管用。因为我发现他是用GolbalAlloc来申请内存的。
具体为什么不行我还未弄明白。
怎么办呢,硬着头皮来修复code replace吧,也好锻炼下自己。

我点进一个JMP DWORD PTR DS:[157004]看了下。
原来正确的代码在这
00157FA6 8B55 08 MOV EDX,DWORD PTR SS:[EBP+8]
00157FA9 33C9 XOR ECX,ECX
00157FAB C3 RET

一共6个字节,中间并没有什么花指令。还算温柔了。
而0040F0FB这里的JMP DWORD PTR DS:[157004]也是6个字节。
我就想,如果能把0040F0FB处的6个字节替换成正确的字节码不就OK了吗?

思路通了就开始干吧。
对0040F0FB进行内存写入断点吧。
断到这里了
00411D8B 66:C707 FF25 MOV WORD PTR DS:[EDI],25FF
00411D90 8947 02 MOV DWORD PTR DS:[EDI+2],EAX
00411D93 83C7 06 ADD EDI,6
00411D96 83C0 04 ADD EAX,4
00411D99 ^ E2 F0 LOOPD SHORT CrackMe.00411D8B

ds:[edi]中的代码此时正被替换为JMP DWORD PTR DS:[157004]这个样子。
从MOV WORD PTR DS:[EDI],25FF这句可以明显看出来。

可ds:[edi]中现在是什么东西呢?
经过我分析,发现ds:[edi]中的代码xor 了0xe0就变成正确的机器码了。
从这里可以分析出来的。

/*411D5F*/ MOV ECX,1770
/*411D64*/ LODS BYTE PTR DS:[ESI]
/*411D65*/ XOR AL,BL
/*411D67*/ STOS BYTE PTR ES:[EDI]

那么这就好办了。开始patch代码。
00411D8B MOV WORD PTR DS:[EDI],25FF
从这里开始。首先这句改为jmp 429669
也就是跳到一个无用的地方吧。
然后在下面写如下代码
xor byte ptr ds:[edi],bl
xor byte ptr ds:[edi+1],bl
xor byte ptr ds:[edi+2],bl
xor byte ptr ds:[edi+3],bl
xor byte ptr ds:[edi+4],bl
xor byte ptr ds:[edi+5],bl
jmp 00411D93 //最后再跳回来

好了,这样patch代码就完了。
重新来过,把按前面所说的跳过iat加密,patch下代码,再补上那偷掉了一点代码。
就可以dumpfix了。
当然,很顺利运行成功。

//后记
这个壳对于我这个初学者感到还是有挑战性的。不过我很高兴我能独立解决,没有看其他的教程。
这点我感到很欣慰。另外就是脱壳确实挺好玩的,不管是老壳还是新壳,在暂时找不到其他娱乐方式的时候找点
老壳脱脱也能带给自己快乐的。



[ Edited by kyo327 at 2010-09-03 2:43:54 PM ]

Comments RSS Feed http://www.kyospace.com/feedcomm.asp?logID=320

Quote kyo327 Posted at 2009-05-03 5:49:04 PM
ASProtect 1.2 / 1.2c-> Alexey Solodovnikov

可能是最早的asprotect的壳了吧
我今天下载后自己加了壳试了试
的确挺简单的.

用最后一次异常法来到最后一次异常处后,再用代码段内存访问断点就到OEP了.

这时,IAT是加密的.
dd 405000内存写入断点可来到这里
/*92F4D0*/ CALL 0092F0EC
/*92F4D5*/ CALL 0092F358
/*92F4DA*/ MOV EDX,DWORD PTR DS:[EDI]
/*92F4DC*/ MOV DWORD PTR DS:[EDX],EAX //这里eax是错误的IAT

但是过了/*92F4D0*/ CALL 0092F0EC后eax是正确的IAT
那么nop掉/*92F4D5*/ CALL 0092F358这句应该是可以的.

不过还是有校验.
nop完顺便 hr 92F4D5再f9后 发现IAT已经填充完了.
这时候还等什么 马上dumpfix吧
完了后发现还有一个指针是错的,剪切掉后能正常运行,呵呵到这就over了.


Quote kyo327 Posted at 2010-09-03 11:41:58 PM
【文章标题】: Delphi程序脱TMD修复OEP
【文章作者】: wuqing1501
--------------------------------------------------------------------------------
【详细过程】


首先查壳

Themida/WinLicense V1.8.X-V2.X -> Oreans Technologies * Sign.By.fly * 20080131 *

OD载入

009E0014 X> B8 00000000 mov eax,0 ; OD载入后停在这里
009E0019 60 pushad
009E001A 0BC0 or eax,eax
009E001C 74 68 je short XX.009E0086
009E001E E8 00000000 call XX.009E0023
009E0023 58 pop eax
009E0024 05 53000000 add eax,53
009E0029 8038 E9 cmp byte ptr ds:[eax],0E9
009E002C 75 13 jnz short XX.009E0041
009E002E 61 popad
009E002F EB 45 jmp short XX.009E0076
009E0031 DB2D 37009E00 fld tbyte ptr ds:[9E0037]
009E0037 FFFF ??? ; 未知命令
009E0039 FFFF ??? ; 未知命令
009E003B FFFF ??? ; 未知命令
009E003D FFFF ??? ; 未知命令
009E003F 3D 40E80000 cmp eax,0E840


很明显的TMD入口

好了我们使用这个脚本跑吧

TMDScript-1.9.1+_1.0 final_修正集成版.osc

OD载入脚本 运行完后停在这里


004061E4 53 push ebx ; 脚本运行完 停在这里
004061E5 8BD8 mov ebx,eax
004061E7 33C0 xor eax,eax
004061E9 A3 A0104B00 mov dword ptr ds:[4B10A0],eax
004061EE 6A 00 push 0
004061F0 E8 2BFFFFFF call XX.00406120 ; jmp 到 kernel32.GetModuleHandleA
004061F5 A3 68464B00 mov dword ptr ds:[4B4668],eax
004061FA A1 68464B00 mov eax,dword ptr ds:[4B4668]
004061FF A3 AC104B00 mov dword ptr ds:[4B10AC],eax
00406204 33C0 xor eax,eax
00406206 A3 B0104B00 mov dword ptr ds:[4B10B0],eax
0040620B 33C0 xor eax,eax
0040620D A3 B4104B00 mov dword ptr ds:[4B10B4],eax
00406212 E8 C1FFFFFF call XX.004061D8
00406217 BA A8104B00 mov edx,XX.004B10A8
0040621C 8BC3 mov eax,ebx
0040621E E8 D1DBFFFF call XX.00403DF4
00406223 5B pop ebx
00406224 C3 retn

这个就是程序的第一个CALL

此时 EAX的值为004B09D0

有这些我们可以写出OEP的前几句

push ebp
mov ebp,esp
add esp,-10
mov eax,004B09D0//第一个call时 EAX的值
call 004061E4//第一个CALL的地址

好了 我们按 F8 一直运行到

00406224 C3 retn

此时记下寄存器的数值

EAX 00000000
ECX 0012FF70
EDX 0012FF88
EBX 0012FF9C
ESP 0012FF80
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C

然后继续按F8将进入到TMD的VM中

00C2AD4A 68 E266860C push 0C8666E2


然后再按F8几次 走过第一个JMP后 在CODE段 00401000处F2断点,F9运行 然后再在在CODE段 00401000处F2断点再运行 直到停在第二个CALL内

00478CE0 53 push ebx ; 第二个CALL
00478CE1 A1 64304B00 mov eax,dword ptr ds:[4B3064]
00478CE6 8338 00 cmp dword ptr ds:[eax],0
00478CE9 74 0A je short XX.00478CF5
00478CEB 8B1D 64304B00 mov ebx,dword ptr ds:[4B3064] ; XX.004B4044
00478CF1 8B1B mov ebx,dword ptr ds:[ebx]
00478CF3 FFD3 call ebx
00478CF5 5B pop ebx
00478CF6 C3 retn

此时我们记下第二个CALL的地址 和寄存器的内容

EAX 03181804
ECX 0012FF70
EDX 0012FF88
EBX 0012FF9C
ESP 0012FF80
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C

然后我们与第一次记录的寄存器比较,发现只有EAX发生了变化 ,我们按CTRL+B搜索二进制 04 18 18 03 找到了地址004B1484,这时我们可以补充OEP为

push ebp
mov ebp,esp
add esp,-10
mov eax,004B09D0//第一个call时 EAX的值
call 004061E4//第一个CALL的地址
mov eax,dword ptr ds:[4B1484]//如果找不到的话可以直接写成mov eax,004B1484
mov eax,dword ptr ds:[eax]
CALL 00478CE0


然后我们继续按F8直到走完第二个CALL

00478CF6 C3 retn

此时我们再记录下寄存器的数据

EAX 00000001
ECX 76AB67F0 ole32.76AB67F0
EDX 76AB67F0 ole32.76AB67F0
EBX 0012FF9C
ESP 0012FF80
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C

然后我们继续安装上面的步骤执行 直到程序运行到第三个CALL

00406428 55 push ebp ; 第三个call
00406429 8BEC mov ebp,esp
0040642B 8B45 10 mov eax,dword ptr ss:[ebp+10]
0040642E 50 push eax
0040642F 837D 0C 01 cmp dword ptr ss:[ebp+C],1
00406433 1BC0 sbb eax,eax
00406435 40 inc eax
00406436 83E0 7F and eax,7F
00406439 50 push eax
0040643A 8B45 08 mov eax,dword ptr ss:[ebp+8]
0040643D 50 push eax
0040643E E8 DDFFFFFF call XX.00406420 ; jmp 到 kernel32.createMutexA
00406443 5D pop ebp
00406444 C2 0C00 retn 0C

此时我们记下 第三个CALL的地址和寄存器的数据

EAX 00000001
ECX 76AB67F0 ole32.76AB67F0
EDX 76AB67F0 ole32.76AB67F0
EBX 0012FF9C
ESP 0012FF74
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C
此时寄存器与我们上次记录的数据相比 只有ESP发生了变换 变化值为:0012FF74-0012FF80=-c 这时我们可以修复OEP为

push ebp
mov ebp,esp
add esp,-10
mov eax,004B09D0//第一个call时 EAX的值
call 004061E4//第一个CALL的地址
mov eax,dword ptr ds:[4B1484]//如果找不到的话可以直接写成mov eax,004B1484
mov eax,dword ptr ds:[eax]
CALL 00478CE0
add esp,-c
call 00406428

然后我们继续F8做完第三个CALL 记下寄存器的数据

EAX 00000208
ECX 0012FEF8
EDX 7C92E514 ntdll.KiFastSystemCallRet
EBX 0012FF9C
ESP 0012FF74
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C

然后继续按F8走到VM中,然后和上面一样继续CODE段下断点,直到程序停在非VM 中,中间遇到 012214DE F3:A4 rep movs byte ptr es:[edi],byte ptr d> 这样的可以 F7一次,然后再F8一次走过去,然后继续下断点运



运行几次后发现程序停在了这里


004B0E50 E8 D356F5FF call XX.00406528 ; jmp 到 ntdll.RtlGetLastWin32Error 最后停在这里了
004B0E55 3D B7000000 cmp eax,0B7
004B0E5A 75 10 jnz short XX.004B0E6C
004B0E5C A1 48534B00 mov eax,dword ptr ds:[4B5348]
004B0E61 50 push eax
004B0E62 E8 9955F5FF call XX.00406400 ; jmp 到 kernel32.CloseHandle
004B0E67 E9 C2000000 jmp XX.004B0F2E
004B0E6C A1 78314B00 mov eax,dword ptr ds:[4B3178]

走到这里我们可以直到已经运行到程序的部分了,这里就是OEP的附近了

此时我们记下寄存器中的数据

EAX 00000208
ECX 0012FEF8
EDX 7C92E514 ntdll.KiFastSystemCallRet
EBX 0012FF9C
ESP 0012FF84
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C

此时与上面的寄存器比较一下 还是只有 ESP发生变化 变化值为 0012FF84-0012FF74=10

好了我们可以把OEP修复为

push ebp
mov ebp,esp
add esp,-10
mov eax,004B09D0//第一个call时 EAX的值
call 004061E4//第一个CALL的地址
mov eax,dword ptr ds:[4B1484]//如果找不到的话可以直接写成mov eax,004B1484
mov eax,dword ptr ds:[eax]
CALL 00478CE0
add esp,-c
call 00406428
add esp,10

这样我们就找到了所有被VM的的OEP了,其实整个过程就是 看每次寄存器那些数据发生了变化 我们把相应的变化写出来就可以了

此时我们分析一下数据 看看OEP的具体位置在哪里?

根据Delphi程序的入口 OEP一般位于

0044CA7C . \4C364200 dd delphi7.0042364C
0044CA80 . ACC64400 dd delphi7.0044C6AC
0044CA84 . 50C64400 dd delphi7.0044C650
0044CA88 . 88C84400 dd delphi7.0044C888
0044CA8C . 58C84400 dd delphi7.0044C858
0044CA90 00 db 00
0044CA91 00 db 00
0044CA92 00 db 00
0044CA93 00 db 00
0044CA94 . 90C84400 dd delphi7.0044C890//根据Delphi程序的入口 OEP一般位于这个下面

看我们分析后的代码



004B0E02 ? 4A dec edx
004B0E03 ? 00CC add ah,cl
004B0E05 ? F7 ??? ; 未知命令
004B0E06 ? 4A dec edx
004B0E07 ? 00A0 094B0064 add byte ptr ds:[eax+64004B09],ah
004B0E0D ? 094B 00 or dword ptr ds:[ebx],ecx
004B0E10 00 db 00
004B0E11 00 db 00
004B0E12 00 db 00
004B0E13 00 db 00
004B0E14 A8094B00 dd XX.004B09A8
004B0E18 77 db 77 ; CHAR 'w'
004B0E19 3D db 3D ; CHAR '='
004B0E1A D6 db D6

那我们的OEP地址应该就是004B0E18 了

好我们把我们修复好的代码从这里开始写上去 发现写好后


004B0E50 E8 D356F5FF call XX.00406528这个代码与我们写的代码之间还有些数据,我们可以直接用个跳转跳到这里也可以直接把中间的代码都NOP掉,我就直接NOP掉了

好了 到了这里我们的工作基本上就算完成了

修复好的OEP

55 8B EC 83 C4 F0 B8 D0 09 4B 00 E8 BC 53 F5 FF A1 84 14 4B 00 8B 00 E8 AC 7E FC FF 83 C4 F4 E8 EC 55 F5 FF 83 C4 10 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90

恩 在004B0E18 新建EIP吧,

然后用LordPE DUMP出来,再用ImportREC修复一下就可以了,看看怎么样软件运行了吧!


Post Comment
Topic Locked or You don't have the Permission. No Comment Allowed.
Here is kyo's blog © 2004-2005 
Processed in 0.093750 second(s)