- UID
- 5199
注册时间2005-12-14
阅读权限10
最后登录1970-1-1
周游历练
该用户从未签到
|
楼主 |
发表于 2005-12-15 01:57:12
|
显示全部楼层
在0103708C处下断,shift+f9一次中断,断下后在code段下断,断下后可以看到OEP了:
00569594 55 PUSH EBP ; OEP
00569595 8BEC MOV EBP, ESP
00569597 83C4 F0 ADD ESP, -10
到了OEP处后,像前面的文章一样,找到保存相关地方:
01022544 85C0 TEST EAX, EAX
01022546 > 74 0A JE SHORT 01022552
01022548 FF15 18900401 CALL DWORD PTR DS:[1049018] ;这里改成我们自己的代码
0102254E 09C0 OR EAX, EAX
01022550 74 01 JE SHORT 01022553
......
012800A0 9D POPFD
012800A1 5C POP ESP
012800A2 FF6424 FC JMP DWORD PTR SS:[ESP-4] ;这里设置硬件断点用于写上我们自己的代码
012800A6 54 PUSH ESP
因为这个程序里的IAT是部分加密处理过的,所以相对来说处理会麻烦一点,这个要靠自己去想怎么去解决,我的处理方法比较麻烦。可能有更好的方法,我现在还没有想到:-(.再写上一段代码和一段脚本,然后运行脚本就可以了:
________________________-相关代码_________________________________
005695D0 . 60 PUSHAD
005695D1 . B9 10916400 MOV ECX, 00649110 ; 调用call address的位置
005695D6 > 8339 00 CMP DWORD PTR DS:[ECX], 0
005695D9 . 74 17 JE SHORT 005695F2
005695DB . 8B19 MOV EBX, DWORD PTR DS:[ECX] ; ntdll.7C92E64E
005695DD .- FFE3 JMP EBX ; 跳去执行原call
005695DF . 66:C703 FF15 MOV WORD PTR DS:[EBX], 15FF ; 改写成call [addr]
005695E4 . 8B15 08916400 MOV EDX, DWORD PTR DS:[649108] ; <&comdlg32.ChooseColorA>
005695EA . 8953 02 MOV DWORD PTR DS:[EBX+2], EDX ; ntdll.KiFastSystemCallRet
005695ED . 83C1 04 ADD ECX, 4
005695F0 .^ EB E4 JMP SHORT 005695D6
005695F2 > 33C0 XOR EAX, EAX ; 修复为jmp [addr]的部分
005695F4 . B9 CC951600 MOV ECX, 1695CC
005695F9 . BF 00104000 MOV EDI, 00401000
005695FE > B0 E8 MOV AL, 0E8
00569600 > F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00569602 . 83F9 00 CMP ECX, 0
00569605 . 74 2C JE SHORT 00569633
00569607 . 8B1F MOV EBX, DWORD PTR DS:[EDI]
00569609 . 8D5C3B 04 LEA EBX, DWORD PTR DS:[EBX+EDI+4]
0056960D . 81FB 00104000 CMP EBX, 00401000
00569613 .^ 72 EB JB SHORT 00569600
00569615 . 81FB C7955600 CMP EBX, 005695C7 ; 判断是否符合修复条件
0056961B .^ 77 E3 JA SHORT 00569600
0056961D . 66:8B03 MOV AX, WORD PTR DS:[EBX]
00569620 . 66:3D FF15 CMP AX, 15FF
00569624 . 75 0B JNZ SHORT 00569631
00569626 . 66:C703 FF25 MOV WORD PTR DS:[EBX], 25FF
0056962B . 83C7 04 ADD EDI, 4
0056962E . 83E9 04 SUB ECX, 4
00569631 >^ EB CB JMP SHORT 005695FE
00569633 > 61 POPAD
00569634 . 90 NOP
00569635 . 90 NOP
00569636 . 90 NOP
00569637 . 90 NOP
00569638 . 90 NOP
00569639 . 90 NOP
0056963A . 90 NOP
0056963B . 90 NOP
0056963C . 90 NOP
0056963D . 90 NOP
0056963E . 90 NOP
0056963F . 90 NOP
00569640 . 48965600 DD dumped_.00569648
00569644 00 DB 00
00569645 00 DB 00
00569646 00 DB 00
00569647 00 DB 00
00569648 90 NOP
00569649 . 60 PUSHAD
0056964A . BD 00916400 MOV EBP, 00649100
0056964F . 90 NOP
00569650 . 8B4D 04 MOV ECX, DWORD PTR SS:[EBP+4]
00569653 . 0BC9 OR ECX, ECX
00569655 . 75 18 JNZ SHORT 0056966F ; 这里修复和上两篇有所不同,这篇里的iat是加密处理过的
00569657 . B9 C4E05700 MOV ECX, <&kernel32.GetFileType> ; 对于修复加密的输入表,我采用脚本+代码的方式
0056965C . 8911 MOV DWORD PTR DS:[ECX], EDX ; 来修复输入表
0056965E . 894D 08 MOV DWORD PTR SS:[EBP+8], ECX
00569661 . 83C1 04 ADD ECX, 4
00569664 . 894D 04 MOV DWORD PTR SS:[EBP+4], ECX
00569667 . 90 NOP
00569668 . 90 NOP
00569669 . 90 NOP
0056966A . 90 NOP
0056966B . 90 NOP
0056966C . 90 NOP
0056966D . EB 45 JMP SHORT 005696B4
0056966F > 8BF1 MOV ESI, ECX
00569671 . 81E9 C4E05700 SUB ECX, <&kernel32.GetFileType>
00569677 . C1E9 02 SHR ECX, 2
0056967A . 8BC2 MOV EAX, EDX ; ntdll.KiFastSystemCallRet
0056967C . BF C4E05700 MOV EDI, <&kernel32.GetFileType>
00569681 . F2:AF REPNE SCAS DWORD PTR ES:[EDI]
00569683 . 0BC9 OR ECX, ECX
00569685 . 74 08 JE SHORT 0056968F
00569687 . 83EF 04 SUB EDI, 4
0056968A . 897D 08 MOV DWORD PTR SS:[EBP+8], EDI ; ntdll.7C930738
0056968D . EB 25 JMP SHORT 005696B4
0056968F > 90 NOP
00569690 90 NOP ; 写好脚本和这里的代码后,先在这里下f2断
00569691 . 90 NOP ; 用于脚本判断是否为相同的DLL
00569692 . 90 NOP
00569693 . 90 NOP
00569694 . 90 NOP
00569695 . 0BD2 OR EDX, EDX ; 通过脚本判断是否为相同的DLL,如果相同edx=0不同edx=1
00569697 . 75 0D JNZ SHORT 005696A6
00569699 . 8906 MOV DWORD PTR DS:[ESI], EAX
0056969B . 8975 08 MOV DWORD PTR SS:[EBP+8], ESI
0056969E . 83C6 04 ADD ESI, 4
005696A1 . 8975 04 MOV DWORD PTR SS:[EBP+4], ESI
005696A4 . EB 0E JMP SHORT 005696B4
005696A6 > 83C6 04 ADD ESI, 4
005696A9 . 8906 MOV DWORD PTR DS:[ESI], EAX
005696AB . 8975 08 MOV DWORD PTR SS:[EBP+8], ESI
005696AE . 83C6 04 ADD ESI, 4
005696B1 . 8975 04 MOV DWORD PTR SS:[EBP+4], ESI
005696B4 > 61 POPAD
005696B5 . FF15 18900401 CALL DWORD PTR DS:[1049018] ; 执行原壳的代码
005696BB . C3 RETN
_____________________END_____________________________________
____________________相关脚本_________________________________
//fix1
var dll1
var dllnow
var addr
start:
run
l1:
cmp eip,569690 //跳去处理是否为同一DLL
je l2
cmp eip,0012800c5 //判断是否为jmp [esp-4]处
je l6
ret
l2:
gn edx
mov dllnow,$RESULT_1
cmp dll1,0
jne l3
mov dll1,dllnow
l3:
cmp dll1,dllnow
jne l4
mov edx,0
jmp l5
l4:
mov dll1,dllnow
mov edx,1
l5:
sto
jmp start
l6:
mov addr,esp
sub addr,4
mov [addr],5695df //修改eip
jmp start
_____________________END_____________________________________
写好了上面的东西,运行脚本,用importrec修复输入表时,有一个是GetProcAddress:
00407784 - FF25 28B45700 JMP DWORD PTR DS:[57B428]
把这个API修复好,其它无效的直接cut掉,分两次就可以把iat获取并修复好。
修复好程序并不能够运行的。通过运行发现下面的地方,就是检测是否被壳的相关地址:
0055B03B . E8 7498FDFF CALL 005348B4 ; CreateFileA
0055B040 3D A66D0D00 CMP EAX, 0D6DA6 ; 判断文件大小?
0055B045 0F8E 8B000000 JLE 0055B0D6 ; 如果小于或等于则跳,正常这里是跳的
因为考虑到处理反脱壳检测可能会比较麻烦,所以我直接改CreateFileA为原来没有脱壳的文件名,这样就可以通过检测,操作好后,还有一个段被抽在程序里,直接用lordpe添加段进去。这样子程序就可以运行了,不过可惜的,按菜单功能的时间还是会异常退出:-(,唉不脱了,再脱真的是脱皮而不是脱壳了。 |
|