好友
阅读权限10
听众
最后登录1970-1-1
|
脱壳过程
脱壳方法:esp定律+内存镜象
OD载入
004070D4 > /EB 01 jmp short 004070D7;载入后停在这里,单步f8两次
004070D6 |68 60E80000 push0E860
004070DB0000add byte ptr [eax], al
004070DD8B1C24mov ebx, dword ptr [esp]
004070E083C3 12 add ebx, 12
004070E3812B E8B10600 sub dword ptr [ebx], 6B1E8
004070E9FE4B FD dec byte ptr [ebx-3]
------------------------------
004070D760pushad
004070D8E8 00000000 call004070DD ;单步f8两次后停在这里,用esp定律
004070DD8B1C24mov ebx, dword ptr [esp]
004070E083C3 12 add ebx, 12
004070E3812B E8B10600 sub dword ptr [ebx], 6B1E8
004070E9FE4B FD dec byte ptr [ebx-3]
004070EC822C24 17 sub byte ptr [esp], 17
------------------------------
shift+f9后来到这里
00408CB5F7D2not edx ; esp定律后停在这里
00408CB739C2cmp edx, eax
00408CB9F7C0 74E7F921 testeax, 21F9E774
00408CBF0FACC2 48 shrdedx, eax, 48
00408CC30FBDC8bsr ecx, eax
00408CC6C7C2 2431C7CD mov edx, CDC73124
00408CCC85C0testeax, eax
------------------------------
esp定律断下后,alt+m 在00401000断下f2断点f9运行
004017488B0D 20314000 mov ecx, dword ptr [403120] ; 内存镜象后停在这里,向上翻看
0040174E8908mov dword ptr [eax], ecx
00401750FF15 88214000 calldword ptr [402188] ; msvcrt.__p__commode
004017568B0D 1C314000 mov ecx, dword ptr [40311C]
0040175C8908mov dword ptr [eax], ecx
0040175EA1 84214000 mov eax, dword ptr [402184]
------------------------------
向上翻看发现大量的空字节,这些代码被抽取了
004016FECCint3
004016FFCCint3
004017000000add byte ptr [eax], al
004017020000add byte ptr [eax], al
004017040000add byte ptr [eax], al
004017060000add byte ptr [eax], al
004017080000add byte ptr [eax], al
0040170A0000add byte ptr [eax], al
0040170C0000add byte ptr [eax], al
0040170E0000add byte ptr [eax], al
004017100000add byte ptr [eax], al
004017120000add byte ptr [eax], al
004017140000add byte ptr [eax], al
004017160000add byte ptr [eax], al
004017180000add byte ptr [eax], al
0040171A0000add byte ptr [eax], al
0040171C0000add byte ptr [eax], al
0040171E0000add byte ptr [eax], al
004017200000add byte ptr [eax], al
004017220000add byte ptr [eax], al
004017240000add byte ptr [eax], al
004017260000add byte ptr [eax], al
004017280000add byte ptr [eax], al
0040172A0000add byte ptr [eax], al
0040172C0000add byte ptr [eax], al
0040172E0000add byte ptr [eax], al
004017300000add byte ptr [eax], al
004017320000add byte ptr [eax], al
004017340000add byte ptr [eax], al
004017360000add byte ptr [eax], al
004017380000add byte ptr [eax], al
0040173A0000add byte ptr [eax], al
0040173C0000add byte ptr [eax], al
0040173E0000add byte ptr [eax], al
004017400000add byte ptr [eax], al
004017420000add byte ptr [eax], al
004017440000add byte ptr [eax], al
004017460000add byte ptr [eax], al
004017488B0D 20314000 mov ecx, dword ptr [403120] ; 这里是被STOLEN CODE后的伪OEP
0040174E8908mov dword ptr [eax], ecx
00401750FF15 88214000 calldword ptr [402188] ; msvcrt.__p__commode
004017568B0D 1C314000 mov ecx, dword ptr [40311C]
0040175C8908mov dword ptr [eax], ecx
--------------------------------
看寄存器显示的函数是vc的函数,可以断定是个vc++的程序
EAX 77C3185C offset msvcrt._fmode;这里显示了是vc的程序
ECX 00000002
EDX B3BD4ACD
EBX 00000000
ESP 0012FF3C
EBP 0012FFC0
ESI FFFFFFFF
EDI 7C930738 ntdll.7C930738
EIP 00401748 UnPackMe.00401748
--------------------------------
我们寻找一个vc++的程序来对比下vc++程序的入口吧,随手找了个vc++写的《PYG破解计算器》的程序看看OEP的样子
,留做寻找偷窃代码比较之用。
00403831 >/$55pushebp;破解计算器的程序入口特征
00403832|.8BECmov ebp, esp
00403834|.6A FF push-1
00403836|.68 F0624000 push004062F0
0040383B|.68 A44C4000 push00404CA4 ;SE 处理程序安装
00403840|.64:A1 0000000>mov eax, dword ptr fs:[0]
00403846|.50pusheax
00403847|.64:8925 00000>mov dword ptr fs:[0], esp
0040384E|.83EC 58 sub esp, 58
00403851|.53pushebx
00403852|.56pushesi
00403853|.57pushedi
00403854|.8965 E8 mov dword ptr [ebp-18], esp
00403857|.FF15 48604000 calldword ptr [<&KERNEL32.GetVersion>;kernel32.GetVersion
0040385D|.33D2xor edx, edx
0040385F|.8AD4mov dl, ah
00403861|.8915 6C8A4000 mov dword ptr [408A6C], edx
00403867|.8BC8mov ecx, eax
00403869|.81E1 FF000000 and ecx, 0FF
0040386F|.890D 688A4000 mov dword ptr [408A68], ecx
00403875|.C1E1 08 shl ecx, 8
00403878|.03CAadd ecx, edx
-----------------------------------------
下面我们试试寻找被偷窃的代码,ctrl+f2重新载入程序,esp定律断下后,我们f8单步跟踪来分析代码
00408CB461popad
00408CB5F7D2not edx ; esp定律后停在这里了,f8跟
00408CB739C2cmp edx, eax
00408CB9F7C0 74E7F921 testeax, 21F9E774
00408CBF0FACC2 48 shrdedx, eax, 48
00408CC30FBDC8bsr ecx, eax
00408CC6C7C2 2431C7CD mov edx, CDC73124
00408CCC85C0testeax, eax
00408CCE0FBAEA 31 bts edx, 31
00408CD2F7D2not edx
00408CD4F7C1 25C4A65C testecx, 5CA6C425
00408CDA3BD0cmp edx, eax
00408CDC0FABC2bts edx, eax
00408CDFEB 01 jmp short 00408CE2
00408CE1DD???; 未知命令
00408CE20FAFC8imulecx, eax
00408CE549dec ecx
00408CE60FCAbswap edx
00408CE8B9 0A07CDFD mov ecx, FDCD070A
00408CED0BC8orecx, eax
00408CEF31C2xor edx, eax
00408CF18D0D 945D734C lea ecx, dword ptr [4C735D94]
00408CF7D1E9shr ecx, 1
00408CF94Adec edx
00408CFABA CD4ABDB3 mov edx, B3BD4ACD
00408CFFD1D9rcr ecx, 1
00408D010BD0oredx, eax
00408D03F7C1 2063B688 testecx, 88B66320
00408D0955pushebp ;程序来到这里发现了我们被偷的第一句代码
00408D0AEB 01 jmp short 00408D0D;下面这一系列的jmp就是对偷窃的代码进行解码
00408D0C3D 8BECEB01 cmp eax, 1EBEC8B
00408D112Fdas
00408D126A FF push-1;
00408D14EB 01 jmp short 00408D17
00408D160C 68 oral, 68
00408D188890 BF01812C mov byte ptr [eax+2C8101BF], dl
00408D1E24 88 and al, 88
00408D206B7F 01 68imuledi, dword ptr [edi+1], 68
00408D24EDineax, dx
00408D258824EEmov byte ptr [esi+ebp*8], ah
00408D28810424 998F1B12 add dword ptr [esp], 121B8F99
00408D2F64:A1 00000000mov eax, dword ptr fs:[0]
00408D35EB 01 jmp short 00408D38
00408D37CEinto
00408D3850pusheax
00408D39EB 01 jmp short 00408D3C
00408D3B4Cdec esp
00408D3C64:8925 0000000>mov dword ptr fs:[0], esp
00408D43EB 01 jmp short 00408D46
00408D45CD 83 int 83
00408D47ECinal, dx
00408D4868 EB01EA53 push53EA01EB
00408D4DEB 01 jmp short 00408D50
00408D4F26:56 pushesi
00408D51EB 01 jmp short 00408D54
00408D53E6 57 out 57, al
00408D55EB 01 jmp short 00408D58
00408D57B8 8965E8EB mov eax, EBE86589
00408D5C0125 33DBEB01 add dword ptr [1EBDB33], esp
00408D62ADlodsdword ptr [esi]
00408D63895D FC mov dword ptr [ebp-4], ebx
00408D66EB 01 jmp short 00408D69
00408D6824 6A and al, 6A
00408D6A02EBadd ch, bl
00408D6C0134FFadd dword ptr [edi+edi*8], esi
00408D6F15 90214000 adc eax, 00402190
00408D74EB 01 jmp short 00408D77
00408D76B2 59 mov dl, 59
00408D78EB 01 jmp short 00408D7B
00408D7AC8 830D2C enter 0D83, 2C
00408D7E3140 00 xor dword ptr [eax], eax
00408D81FFEBjmp far ebx; 非法使用寄存器
00408D83013C83add dword ptr [ebx+eax*4], edi
00408D860D 30314000 oreax, 403130
00408D8BFFEBjmp far ebx; 非法使用寄存器
00408D8D0151 FF add dword ptr [ecx-1], edx
00408D9015 8C214000 adc eax, 0040218C
00408D95EB 01 jmp short 00408D98 ;这是解码后的最后一个jmp了,它jmp到那个跳往
oep的地址了
00408D97A5movsdword ptr es:[edi], dword ptr [e>
00408D98- E9 AB89FFFF jmp 00401748 ;到这里一个远跳,就跳到刚找到的伪OEP了
-------------------------------------
偷窃的代码,就是从上面的第一句,将每次jmp后所跳到的位置的代码都复制出来就是被偷窃的代码了,复制如下:
00408D0955pushebp
00408D0D8BECmov ebp, esp
00408D126A FF push-1
00408D1768 8890BF01 push1BF9088
00408D1C812C24 886B7F01 sub dword ptr [esp], 17F6B88
00408D2368 ED8824EE pushEE2488ED
00408D28810424 998F1B12 add dword ptr [esp], 121B8F99
00408D2F64:A1 00000000mov eax, dword ptr fs:[0]
00408D3850pusheax
00408D3C64:8925 0000000>mov dword ptr fs:[0], esp
00408D4683EC 68 sub esp, 68
00408D4C53pushebx
00408D5056pushesi
00408D5457pushedi; ntdll.7C930738
00408D588965 E8 mov dword ptr [ebp-18], esp
00408D5E33DBxor ebx, ebx
00408D63895D FC mov dword ptr [ebp-4], ebx
00408D696A 02 push2
00408D6EFF15 90214000 calldword ptr [402190] ; msvcrt.__set_app_type
00408D7759pop ecx
00408D7B830D 2C314000 F>ordword ptr [40312C], FFFFFFFF
00408D85830D 30314000 F>ordword ptr [403130], FFFFFFFF
00408D8FFF15 8C214000 calldword ptr [40218C] ; msvcrt.__p__fmode
-----------------------------------
好了上面的代码复制完了,和我们刚才找的程序对比一下,这时发现00408D17到00408D28压栈的地址还没解码,如何
寻找这两句就是完整找回偷窃代码的关键了
-----------------------------------
两句的解码方法
第一句:
00408D1768 8890BF01 push1BF9088;程序将1BF9088值压入堆栈
00408D1C812C24 886B7F01 sub dword ptr [esp], 17F6B88;运行到这里将刚压入堆栈中的值减去
17F6B88这个值并放回堆栈中,这时堆栈窗中观察0012FFB8 1BF9088运算后变成了0012FFB8 00402500
UnPackMe.00402500,这时观察堆栈窗口中的00402500就是这句解码出来的真正要压入堆栈中的值,那么这句被偷的
代码我们就得到了:push 00402500
----------------
第二句:
00408D2368 ED8824EE pushEE2488ED ;方法和上面类似,程序将EE2488ED值压入堆栈
00408D28810424 998F1B12 add dword ptr [esp], 121B8F99 ;这里是将堆栈中的值加上121B8F99后再放会
堆栈,堆栈窗中的值的变化:
由0012FFB4 EE2488ED
变成0012FFB4 00401886jmp 到 msvcrt._except_handler3
这样我们就得到了解码后的第二句了:push 00401886
---------------------------------------
整理后的代码:
pushebp
mov ebp, esp
push-1
push 00402500
push 00401886
mov eax, dword ptr fs:[0]
pusheax
mov dword ptr fs:[0], esp
sub esp, 68
pushebx
pushesi
pushedi
mov dword ptr [ebp-18], esp
xor ebx, ebx
mov dword ptr [ebp-4], ebx
push2
calldword ptr [402190]
pop ecx
dword ptr [40312C], FFFFFFFF
dword ptr [403130], FFFFFFFF
calldword ptr [40218C]
-----------------------------
根据代码长度从
004017000000add byte ptr [eax], al
处开始修复回去,并且长度正好,此时我们在00401700处新建EIP
-----------------------------
下面就要开始脱壳了,LodePE脱壳,ImportREC载入修复,所有指针有效,抓取程序,运行成功,查壳为Microsoft
Visual C++ 6.0
总结下,此壳共偷取了72个字节的代码,此次脱壳虽然将偷窃代码全部找回修补成功,脱壳后程序能够运行,但是点
击按钮确无法连上网站,估计程序还有暗桩未完全修复,先交作业先,再检查到底是哪里出错了。 |
|