文章作者: Isaiah
具:OllyICE,Lord-PE,ImportREC.
声明:这个脱文几乎就是loveboom的《ASPROTECT2.x脱壳系列之一》的翻版。
好,现在切入正题,我尽可能说的详细一些。有些地方,我还是一知半解,所以可能解释有误,还望高手斧正。
首先,因为街头篮球使用的HackShield系统。HackSield系统的反调试功能很强。
所以,如果让其加载了Hackshield的系统,那么客户端主程序FreeStyle.exe在OD下就跑不起来了.
我没有能力去搞掉hackShield系统,所以我把HackShield的目录改名,让其无法加载HackShield.
然后,可以用OD加载Freestyle.exe,忽略所有异常。看看能不能跑起来。
我这里能够跑起来,运行后加载HackShield的时候,程序会告知无法加载,等待你点一下确定,然后就退出了。
最后提醒一点:如果加载了HackShield用OD调试,好像会引起死机.
不过,这时候程序已经完全从壳里面解了出来.所以脱壳的目的是可以达到的.
用OD加载Freestyle.exe.
会停在这里:
///////////////////////////////////////////////////////////////////////
00401000>/$6801F06E00push006EF001
00401005|.E801000000call0040100B
0040100A\.C3retn
0040100B$C3retn
0040100CE4dbE4
0040100D24db24;CHAR'$'
0040100E2Adb2A;CHAR'*'
...后面全是乱七八糟的数据,不用管.
/////////////////////////////////////////////////////////////////////////////////
!!!:记住隐藏OD.(用HideOD插件)
脱壳的第一步,就是找到OEP.
帮助找到OEP的方法很多,比如ESP定律,2次内存映射断点等等.
这里可以使用这个方法.
先忽略除非法访问内存异常外的所有异常.然后按F9(运行程序).应该会有异常出现按shift+F9忽略.注意记住你忽略了多少次异常后程序开始运行.(可以设置忽略所有异常,清空LOG,然后然程序跑,跑起来后,看LOG数一数异常纪录的个数就能知道有几次异常)(我这是22次,如果没数错~)
然后重新加载.忽略除非法访问内存异常外的所有异常,最后一次异常发生时,给代码段下断点(方法:ALT+M,然后找到freestyle的代码段,选中后按一下F2),然后shift+F9忽略异常.
这时就停在了OEP了:
///////////////////////////////////////////////////////////////////////////
00626777.55pushebp;FreeStyl.0046637E
00626778.8BECmovebp,esp
0062677A.6AFFpush-1
0062677C.6818B16500push0065B118
00626781.68B0B46200push0062B4B0;SE处理程序安装
00626786.64:A10000000>moveax,fs:[0]
0062678C.50pusheax
0062678D.64:892500000>movfs:[0],esp
00626794.83EC58subesp,58
00626797.53pushebx
00626798.56pushesi
00626799.57pushedi
0062679A.8965E8mov[ebp-18],esp
0062679D.FF15B0206500call[6520B0];kernel32.GetVersion
////////////////////////////////////////////////////////////////////////////
记下OEP备以后用:这里是00626777.
好了OEP就找到了.
然后就是IAT了.
看到上面的call[6520B0];kernel32.GetVersion那么就去去006520B0,向上看找找以一大堆00结尾在哪里,在向下看同样找找零结尾在哪里.发现IAT从00652000开始到0065247C结束,而且没有加密.
判断加密的方法,我是去看代码段最后面的一些整齐排列jmp[xxxxxxx]看看有没有被一定数量的相同callxxxxxxxx(xxxxxxxx一般是同一个数)隔开.如果没有,8成是没加密.因为callxxxxxxx就是壳的解密函数.
这个程序没有。而且IAT地址看起来都没有问题:
//////////////////////////////////////////////////////////////////////////////
这个就是IAT:
006520001BC4DC778378DA77F06BDA7700000000能w儀趙餶趙....
0065201026D9186D000000002449370000000000&?m....$I7.....
00652020986EEF778A5AEF77D6E8EF770060EF77榥飛奪飛骤飛.`飛
0065203052D4EF77905BEF77975DEF77495EEF77R燥w怺飛梋飛I^飛
006520407C8BF0771D8EF077B3BFF0772D6CEF77|嬸w庰w晨饂-l飛
0065205060B2F177B885EF77338CEF77FB5EEF77`柴w竻飛3岋w鸮飛
006520604992EF7700000000B3223076A63A3076I掞w....?0v?0v
0065207066553076F3293076825B3076F86F3076fU0v?0v俒0v鴒0v
006520808E4D30762B473076000000005330827C嶮0v+G0v....S0倈
00652090A926827CFB2C827C7C36817C3D04937C?倈?倈|6亅=搢
006520A0D405937C0DE0807C161E807CA2CA817C?搢.鄝||⑹亅
006520B0AB14817CEE1E807C5CE8817C9422827C?亅?|\鑱|?倈
006520C0E1EA817C407A957C5D99807CE0C6807C彡亅@z晐]檧|嗥|
006520D05270827C8BC2857C84E5817C7C2F817CRp倈嬄厊勫亅|/亅
006520E06E9C807C3FFF817C289C807CBDE4817Cn渶|?亅(渶|戒亅
006520F0A92C817C64B6807CF497807CAC92807C?亅d秬|魲|瑨|
006521008603817CFD79937C5935817CE62B817C?亅齳搢Y5亅?亅
006521104399807C2AE8817C0E18807C1990837CC檧|*鑱||悆|
00652120D7EF807CECE9807C66EA807C4EA3807C罪|扉|f陘|N|
0065213093D2807C9497807C4224807C57B3807C撘|敆|B$|W硛|
00652140C1C9807C79E0817C779B807C8D3A867C辽|y鄟|w泙|?唡
00652150B747867C634C817CA197837CAD9C807C稧唡cL亅億瓬|
00652160A19F807C8A18937CED10927C0510927C|?搢?抾抾
006521709072DD00C42F887C66AA807C7B97807C恟??坾f獉|{梹|
006521805C9B857C8D2C817C29B5807C9F0F817C\泤|?亅)祤|?亅
006521903103937C8F0C817C8DB7807C6C94807C1搢?亅嵎|l攢|
006521A0241A807C7609817CC7A0807C5128817C$|v.亅莀|Q(亅
006521B0FCB7807CB2AC807CEDCB817C17A4807C|铂|硭亅|
006521C0DA56827C6B17807C7217817C50F8817C赩倈k|r亅P鴣|
006521D0C09F807CED70837C7ED4807CE312817C罒|韕億~詟|?亅
006521E053C1817CAE94837C80A4807CB98C837CS羴|當億|箤億
006521F058CD807CCBD8817C57BB807CC4CE807CX蛝|素亅W粈|奈|
006522002B2E837C299F807C819A807C149B807C+.億)焵|仛|泙|
006522102929817C1011817C6A48817C782C817C))亅亅jH亅x,亅
0065222023CC817C5F48817C1962827CB39E807C#虂|_H亅b倈碁|
006522302F08817C3797807CF59B807C5097807C/亅7梹|鯖|P梹|
00652240A9CC807C3FDC817C8A2B867C6910817C┨|?軄|?唡i亅
00652250CFC6807CA60D817CED09937C49AA807C掀|?亅?搢I獉|
006522600F2B817C4003937C003C867C00000000+亅@搢.<唡....
00652270609A0010309B00105096001090960010`?0?P?悥.
0065228080910010F0930010C096001080990010?饟.罇.?
0065229020990010A03A0010A03A0010A0900010??.?._?.
006522A0109300104092001000400010E0380010?@?.@.?.
006522B0B0940010A091001010940010509A0010皵._?.?P?
006522C0909A0010B09A0010D099001040970010悮.皻.袡.@?
006522D0809500107096001020970010109B0010?p???
006522E0F09A0010A0400010703B001000100010饸._@.p;...
006522F0F010001040100010B0110010803F0010?.@.?.?.
00652300D03A0010A0390010A0960010F0960010?.?._?.饢.
00652310C03B0010A03E0010303C0010803E0010?.?.0<.>.
00652320404000104040001040400010603E0010@@.@@.@@.`>.
0065233020380010D03A0010D03A0010003B00108.?.?..;.
0065234090380010109A0010309A001000000000?.?0?....
0065235020490F77C24B0F7750480F7795D21177Iw翶wPHw曇w
00652360D9660F77C0480F773B4C0F77A84C0F77賔w繦w;Lw↙w
00652370C3CA1177554C0F770000000085CBD177檬wULw....吽褀
006523809AF3D27760DAD17733B9D177AEB6D177汅襴`谘w3寡w褀
006523901BC0D1779D8FD177EA04D577ADA8D177姥w潖褀?誻褀
006523A0C2D7D177DAC6D37709B6D1771DB6D177伦褀谄觲.堆w堆w
006523B0F68BD1776CC9D177B896D1772413D277鰦褀l裳w笘褀$襴
006523C03E0BD2770DD6D177F9D7D1775D94D177> 襴.盅w褀]斞w
006523D06CBFD1775E02D277A4D8D177E637D277l垦w^襴へ褀?襴
006523E0EADAD177EED4D17741BDD177C6B5D177贲褀钤褀A窖w频褀
006523F01112D27700000000FF19BD77501ABD77襴....絯P絯
00652400BA18BD77000000005B4EB17600000000?絯....[N眝....
00652410662BA271413FA271D44FA27100000000f+A?設....
0065242080E8D36D0000000010AA112170A01121栌m....?!p?!
0065243020A6122120A2112130A1112160A81121?!?!0?!`?!
00652440A0A5112100A5112190B5112170341121_?!.?!惖!p4!
0065245060AC112170AE112100AB1121A0A41121`?!p?!.?!_?!
00652460C03611210000000036EE9A76372A9B76?!....6顨v7*泇
00652470C3FA9A76BA61A0760000000000000000铭歷篴_v........
/////////////////////////////////////////////////////////////////////////////////
好了,知道了IAT从00652000开了,大小为:047C
纪录下来。
现在到了脱壳最困难麻烦的地方了.
大家知道vc的程序,一般OEP后面就是GetVersion后接着就是GetStartInfo.我们看看这个程序的OEP处了代码.
///////////////////////////////////////////////////////////////////////////////////////////////
00626777.55pushebp;FreeStyl.0046637E
00626778.8BECmovebp,esp
0062677A.6AFFpush-1
0062677C.6818B16500push0065B118
00626781.68B0B46200push0062B4B0;SE处理程序安装
00626786.64:A10000000>moveax,fs:[0]
0062678C.50pusheax
0062678D.64:892500000>movfs:[0],esp
00626794.83EC58subesp,58
00626797.53pushebx
00626798.56pushesi
00626799.57pushedi
0062679A.8965E8mov[ebp-18],esp
0062679D.FF15B0206500call[6520B0];kernel32.GetVersion
006267A3.33D2xoredx,edx
006267A5.8AD4movdl,ah
006267A7.89158CA86E00mov[6EA88C],edx
006267AD.8BC8movecx,eax
006267AF.81E1FF000000andecx,0FF
006267B5.890D88A86E00mov[6EA888],ecx
006267BB.C1E108shlecx,8
006267BE.03CAaddecx,edx
006267C0.890D84A86E00mov[6EA884],ecx
006267C6.C1E810shreax,10
006267C9.A380A86E00mov[6EA880],eax
006267CE.6A01push1
006267D0.E83F750000call0062DD14
006267D5.59popecx
006267D6.85C0testeax,eax
006267D8.7508jnzshort006267E2
006267DA.6A1Cpush1C
006267DC.E8C3000000call006268A4
006267E1.59popecx
006267E2>E8E53E0000call0062A6CC
006267E7.85C0testeax,eax
006267E9.7508jnzshort006267F3
006267EB.6A10push10
006267ED.E8B2000000call006268A4
006267F2.59popecx
006267F3>33F6xoresi,esi
006267F5.8975FCmov[ebp-4],esi
006267F8.E8DE6B0000call0062D3DB
006267FD.E8FE979B00call00FE0000;!!!!!!!!!到壳里面去了
00626802.91xchgeax,ecx
00626803.A3D4CD6E00mov[6ECDD4],eax
00626808.E860720000call0062DA6D
0062680D.A370A86E00mov[6EA870],eax
00626812.E809700000call0062D820
00626817.E84B6F0000call0062D767
0062681C.E80E040000call00626C2F
00626821.8975D0mov[ebp-30],esi
00626824.8D45A4leaeax,[ebp-5C]
00626827.50pusheax
00626828.E8D3979B00call00FE0000;!!!!!!!!到壳里面去了
0062682D.C7E8DC6E0>ascii"氰躰",0
0062683200db00
0062683389db89
0062683445db45;CHAR'E'
006268359Cdb9C
后面又是乱七八糟的数据,不用管
///////////////////////////////////////////////////////////////////////////////////////////////
看到了GetVersion了,但是GetStartInfo在哪呢?没有~
但是你应改发现有两个call00FE0000.
给据loveboom的教导,知道这是壳把原来CALLAPI改成了CALLxxxxxxxx,这个callxxxxxxxx会到壳代码里面.
(不同机器上面好像xxxxxxxx都不一样).我这里是00FE0000.
现在就是要修复成CALL正确的API.怎么才能得到这个正确的地址呢.当然只有跟进去看.
不过由于被改了的地方实在太多,人工修复几乎不可能.所以必须写个程序来修复.
这就是Patch.
下面大概讲一下patch的原理.后面会将详细的操作.
patch的方法很多,下面是loveboom提供的方法.
先来整理一下思路,我们要把callxxxxxxxx改称正确的callAPI.
就必须有一张表.里面一一对应记录着callxxxxxxxx的地址->正确的API的地址.
有了这个表,我们就可以快速的把所有callxxxxxxxx改称正确的callapi了.
所以,第一次patch就是为了得到这张表.
怎么得到呢,对于ASPr壳,当进入callxxxxxxxx后,壳会把这个callxxxxxxxx改成正确的callAPI然后跳回原地,就地进入api.
当然这中间有复杂的算法和繁多的花指令.所以想要逆向得到这个正确的API太麻烦.可以借用壳的代码,在它解出来正确的地址的时候我们把它截取,保存下来.
patch的准备工作:
先重新载入freestyle.exe
先来到OEP,找一个callxxxxxxxx(这里是call00FE0000)
因为aspr要把callxxxxxxxx改成正确的所以我们在上面下内存写入断点(这里是在006267FD上面下内存写入断点).
F9运行
断在了这里:
///////////////////////////////////////////////////
00DE5C9B57pushedi
00DE5C9C6A00push0
00DE5C9E8D4DE0leaecx,[ebp-20]
00DE5CA18B45F4moveax,[ebp-C]
00DE5CA48B403Cmoveax,[eax+3C]
00DE5CA78B55FCmovedx,[ebp-4]
00DE5CAAE8D1130000call00DE7080;**********
00DE5CAF8945FCmov[ebp-4],eax
00DE5CB28B45E0moveax,[ebp-20]
00DE5CB58B00moveax,[eax]
00DE5CB7E8D0E6FFFFcall00DE438C
00DE5CBC8BD0movedx,eax
00DE5CBE0255DFadddl,[ebp-21]
00DE5CC18B4DFCmovecx,[ebp-4]
00DE5CC48B45F4moveax,[ebp-C]
00DE5CC7E880040000call00DE614C
00DE5CCC8945FCmov[ebp-4],eax
00DE5CCF8B45F4moveax,[ebp-C]
00DE5CD28B4024moveax,[eax+24]
00DE5CD58B55F4movedx,[ebp-C]
00DE5CD80382E0000000addeax,[edx+E0]
00DE5CDE01451Cadd[ebp+1C],eax
00DE5CE18B45FCmoveax,[ebp-4]
00DE5CE42B451Csubeax,[ebp+1C]
00DE5CE783E805subeax,5
00DE5CEA8B551Cmovedx,[ebp+1C]
00DE5CED42incedx
00DE5CEE8902mov[edx],eax;断在了这里!!!!
00DE5CF0EB01jmpshort00DE5CF3
00DE5CF2E88B45F883call84D6A282
///////////////////////////////////////////////////
向上看,找到:
//////////////////////////////////////////////////////
00DE5C9E8D4DE0leaecx,[ebp-20]
00DE5CA18B45F4moveax,[ebp-C]
00DE5CA48B403Cmoveax,[eax+3C]
00DE5CA78B55FCmovedx,[ebp-4]
00DE5CAAE8D1130000call00DE7080
//////////////////////////////////////////////////////
跟随进入call00DE7080
/////////////////////////////////////////////////////
00DE708055pushebp
00DE70818BECmovebp,esp
00DE708383C4E4addesp,-1C
00DE708653pushebx
00DE708756pushesi
00DE708857pushedi
00DE7089894DF4mov[ebp-C],ecx
00DE708C8955F8mov[ebp-8],edx
00DE708F8945FCmov[ebp-4],eax
00DE709233C0xoreax,eax
00DE70948945F0mov[ebp-10],eax
00DE7097B800070000moveax,700
00DE709CE8A3B4FDFFcall00DC2544;**********
00DE70A18945E4mov[ebp-1C],eax
//////////////////////////////////////////////////////
再跟随进入call00DC2544
///////////////////////////////////////////////////////
00DC254485C0testeax,eax
00DC2546740Ajeshort00DC2552
00DC2548FF151890DE00call[DE9018];***!!!!****
00DC254E09C0oreax,eax
00DC25507401jeshort00DC2553
00DC2552C3retn
//////////////////////////////////////////////////////
看见call[DE9018]了吗?为什么要跟这么深,因为修改这里的代码不会被壳查出来.
这个地方的call[DE9018]我们就能把它改成其他的call从而改变程序的流程.
纪录call[DE9018]的地址,这里是:
00DC2548FF151890DE00call[DE9018]
这个是第一次patch的操作:
重新载入,断GetModuleHandleA(用硬件断点).当第二次断下后.清除硬件断点.F8一路返回,遇见jmp就F4到下一行代码.一会就能看见,如下的代码:
////////////////////////////////////////
00DF15C161popad
00DF15C27508jnzshort00DF15CC
00DF15C4B801000000moveax,1
00DF15C9C20C00retn0C
00DF15CC68DC89DE00push0DE89DC
00DF15D1C3retn
///////////////////////////////////////
retn执行以后,到了
///////////////////////////////////////////
00DE89DC55pushebp;壳的OEP
00DE89DD8BECmovebp,esp
00DE89DF83C4B4addesp,-4C
00DE89E2B8D487DE00moveax,0DE87D4
00DE89E7E850CCFDFFcall00DC563C
00DE89ECE8DBAAFDFFcall00DC34CC
//////////////////////////////////////////
停在了壳的OEP处,搜索如下指令:
MOV[EBP],EAX
PUSH0A
会找到一处:
00DE5F7B894500mov[ebp],eax;在这里下硬件执行断点,断在这里.EIP现在指向这里
00DE5F7E6A0Apush0A
00DE5F80E88FCEFEFFcall00DD2E14
00DE5F858BC8movecx,eax
00DE5F87038BE4000000addecx,[ebx+E4]
然后F9运行,会断在00DE5F7Bmov[ebp],eax;
(不过有时候断不下来,直接就跑飞了,下F2断点反而能断下了,不知道是什么原因,哪位牛人能解释一下.)
断下了后,就开始第一次patch了:
为了方便写程序,就近选个地方写代码,当然要先保存原来的代码,不过OD有撤销修改的功能,就不用专门保存了.
用插件申请一块内存,作为保存上面提到的那张表的空间,有这种功能的插件很多.HideOD也有.我申请到的是01020000
/////////////////////////////////////////////////
00DE5F7BEB43jmp00DE5FC0;注意这里被修改指向我们自己写的代码.EIP还是指向这里
00DE5F7D90nop
00DE5F7E6A0Apush0A
00DE5F80E88FCEFEFFcall00DD2E14
00DE5F858BC8movecx,eax
00DE5F87038BE4000000addecx,[ebx+E4]
00DE5F8D8BD6movedx,esi
00DE5F8F8BC3moveax,ebx
00DE5F91E89EE5FFFFcall00DE4534
00DE5F96FF0C24decdwordptr[esp]
00DE5F9903B3E4000000addesi,[ebx+E4]
00DE5F9F833C2400cmpdwordptr[esp],0
00DE5FA3^0F8755FEFFFFja00DE5DFE
00DE5FA953pushebx;改完,写完代码后这里下F2断点
00DE5FAAE85D000000call00DE600C
00DE5FAF0183EC000000add[ebx+EC],eax
00DE5FB5B001moval,1
00DE5FB783C424addesp,24
00DE5FBA5Dpopebp
00DE5FBB5Fpopedi
00DE5FBC5Epopesi
00DE5FBD5Bpopebx
00DE5FBEC3retn
00DE5FBF90nop
00DE5FC053pushebx;选的这里,最近的地方.开这开始写
00DE5FC151pushecx
00DE5FC2B900415100movecx,01020000;这里数字,填写你想保存这个表的地址.我申请到的地址是01020000,我就保存这
00DE5FC7833900cmpdwordptr[ecx],0
00DE5FCA7506jnzshort00DE5FD2
00DE5FCCC70110415100movdwordptr[ecx],01020010;这里填写保存地址+10h,这里就是01020000h+10h=01020010h
00DE5FD28B19movebx,[ecx]
00DE5FD44Ddecebp
00DE5FD5892Bmov[ebx],ebp
00DE5FD783C304addebx,4
00DE5FDA8919mov[ecx],ebx
00DE5FDC45incebp
00DE5FDD59popecx
00DE5FDE5Bpopebx
00DE5FDF894500mov[ebp],eax
00DE5FE2^EB9Ajmpshort00DE5F7E;这里就写完了
///////////////////////////////////////////////////
写完代码,下好断点.F9运行.停在了
00DE5FA953pushebx
这时把保存的数据复制一份保存备用.我从01020000复制的数据如下:
///////////////////////////////////////////////////////////////////////////////////////////////
3C020401000000000000000000000000898A4800D0D148008AD34800671F4900
06204900202049003920490075204900E320490092214900C42449003EEA4B00
59EB4B00E0C04E0087164F00C94655007A47550088A055003D165600A8165600
C7165600E7165600982A5600BEC65600D2C65600E2C65600E2C7560057C85600
62C85600E0C85600F8C856000BC95600B6CA5600BBDA5800BBDB580007385900
733859009AF75900F5F759002DF859009DBF5A00FCC35A0042D35B0061D35B00
308B5F00368B5F003C8B5F00F2F46000BC066100640F61006B0F610079946100
029A61002E9B6100889B6100B39B6100199C6100449C6100519C61006A9C6100
959C6100A29C6100AF9C6100D69C6100E49D6100F19D6100FE9D6100543D6200
EF3F62002E63620058636200FD676200286862004B686200936C62009A6C6200
5F73620073736200F67362001A74620030746200747462005C79620091796200
A3796200157B620026836200BC83620040846200C38A62000BA7620078A76200
0EC6620084C7620099C7620024C8620090CD6200F5CD620039D46200E4D46200
47D5620055D562008CD5620043D862008CDB6200A9DB620020DC620080DC6200
17DE6200EDDE6200F4DE6200150963005E096300E0136300FC13630014146300
F518630074196300A71A6300C71C63001B1E63004F1E63003F27630086396300
7E3C6300943C6300D53D6300394063002D416300D34163007E486300AB4E6300
D94F63006A55630050586300628F6300838F6300938F6300AE8F630000000000
///////////////////////////////////////////////////////////////////////////////////////////////
然后撤销所有修改,F9继续运行.来到OEP
如果不幸跑飞,也没有关系.反正表已经拿到了.
重新加载freestyle.exe,来到OEP处,停在这里.
第二次patch准备:
要得到两行代码及其地址的信息.
第一个就是上面提到的:
00DC2548FF151890DE00call[DE9018]
这个地址有可能变化,但是几率不大.
第二个有点烦:
用了多态技术,一旦重新加所在地址就会变.不过还好,变化的范围不是很大.
第二个代码是:
00FF00BA9Dpopfd
00FF00BB5Cpopesp
00FF00BCFF6424FCJMPDWORDPTRSS:[ESP-4]
不能直接搜索,因为用了多态技术,可能搜不到.
第一次找这个指令可以这样(以后就直接到附近找,注意识别花指令):
回忆在callxxxxxxxx上,下内存写入断点那里
我们断在了(不记得了就去看看前面):
//////////////////////////////////////////////
00DE5C9B57pushedi
00DE5C9C6A00push0
00DE5C9E8D4DE0leaecx,[ebp-20]
00DE5CA18B45F4moveax,[ebp-C]
00DE5CA48B403Cmoveax,[eax+3C]
00DE5CA78B55FCmovedx,[ebp-4]
00DE5CAAE8D1130000call00DE7080;**********
00DE5CAF8945FCmov[ebp-4],eax
00DE5CB28B45E0moveax,[ebp-20]
00DE5CB58B00moveax,[eax]
00DE5CB7E8D0E6FFFFcall00DE438C
00DE5CBC8BD0movedx,eax
00DE5CBE0255DFadddl,[ebp-21]
00DE5CC18B4DFCmovecx,[ebp-4]
00DE5CC48B45F4moveax,[ebp-C]
00DE5CC7E880040000call00DE614C
00DE5CCC8945FCmov[ebp-4],eax
00DE5CCF8B45F4moveax,[ebp-C]
00DE5CD28B4024moveax,[eax+24]
00DE5CD58B55F4movedx,[ebp-C]
00DE5CD80382E0000000addeax,[edx+E0]
00DE5CDE01451Cadd[ebp+1C],eax
00DE5CE18B45FCmoveax,[ebp-4]
00DE5CE42B451Csubeax,[ebp+1C]
00DE5CE783E805subeax,5
00DE5CEA8B551Cmovedx,[ebp+1C]
00DE5CED42incedx
00DE5CEE8902mov[edx],eax;断在了这里!!!!
00DE5CF0EB01jmpshort00DE5CF3
00DE5CF2E88B45F883call84D6A282
//////////////////////////////////////////////
这个时候用条件跟踪,当遇到POPFD的时候暂停.就能跟到
////////////////////////////////////////////
00FF00BA9Dpopfd
00FF00BB5Cpopesp
00FF00BCFF6424FCJMPDWORDPTRSS:[ESP-4];纪录这行代码
////////////////////////////////////////
下面就是第二次patch:
重新载入,来到OEP,先确定上面提到的两行代码的信息:
直接去00DC2548发现代码没有变:
00DC2548FF151890DE00call[DE9018]
然后去00FF00BC,应该已经变了.
果然JMP[ESP-4]变到了00FF00AE;
信息已经足够了.
开始写代码.
找代码段后面的空白处写patch代码,现在EIP指向OEP
///////////////////////////////////////////////////////////////////////////////////////
0065110060pushad
00651101B910000201movecx,1020010;这里的数填那张表保存的地址+10h
006511068B19movebx,[ecx]
0065110883FB00cmpebx,0
0065110B7415jeshort00651122
0065110DFFE3jmpebx
0065110F8B1508000201movedx,[1020008]
0065111566:C703FF15movwordptr[ebx],15FF
0065111A895302mov[ebx+2],edx
0065111D83C104addecx,4
00651120^EBE4jmpshort00651106
0065112233C0xoreax,eax
00651124B0E8moval,0E8
00651126BF00104000movedi,<模块入口点>
0065112BB900102500movecx,251000;这里填代码段的大小
00651130F2:AErepnescasbyteptres:[edi]
0065113283F900cmpecx,0
00651135743Cjeshort00651173
006511378B1Fmovebx,[edi]
006511398D5C3B04leaebx,[ebx+edi+4]
0065113D81FB00104000cmpebx,<模块入口点>
00651143^72EBjbshort00651130
0065114581FB02106600cmpebx,00661002;这里填代码段结束的地址
0065114B^77E3jashort00651130
0065114D66:813BFF15cmpwordptr[ebx],15FF
00651152^75DCjnzshort00651130
00651154817B0200206>cmpdwordptr[ebx+2],00652000;IAT的起始地址
0065115B^72D3jbshort00651130
0065115D817B0278246>cmpdwordptr[ebx+2],00652478;IAT的结束地址-4
00651164^77CAjashort00651130
0065116666:C703FF25movwordptr[ebx],25FF
0065116B83C704addedi,4
0065116E83E904subecx,4
00651171^EBBDjmpshort00651130
0065117361popad
.......
00651178dd83116500;这里的数字就是下面函数的第一句指令的地址(小头顺序)
........
0065118090nop
0065118190nop
0065118290nop
0065118360pushad
006511848BC2moveax,edx
00651186B980040000movecx,480;IAT的大小+4
0065118BBF00206500movedi,00652000IAT的起始地址
00651190F2:AFrepnescasdwordptres:[edi]
0065119283EF04subedi,4
00651195893D08000201mov[1020008],edi;保存表的地址+8
0065119B61popad
0065119CFF151890DE00call[DE9018];刚才00DC2548FF151890DE00call[DE9018]中被call寻址的地址
006511A2C3retn
006511A390nop
/////////////////////////////////////////////////////////////////////////////////////
这些patch程序都是loveboom所写,根据需要修改相应的数值,如果不清楚有些数是怎么来的,可以去看看上面.和去看看loveboom的文章.
当然,问问别人是最快的解决方式.
然后:
把上面提到的
00DC2548FF151890DE00call[DE9018]
代码改成:
00DC2548FF151890DE00call[651178]
就是让他进入我们的patch代码的第二个函数。
写一段ODScript:
////////////////////////////////////////////////////////////////////////
//fixedaspr2.x
varaddr
start:
run
l1:
cmpeip,00FF00AE;这里的数字是上面提到的jmp[esp-4]的地址,这里是00ff00AE
jnel2
movaddr,esp
subaddr,4
mov[addr],0065110F这个数字是上面patch2代码中jmpebx后面那句的地址,这里是
jmpstart
l2:
ret
/////////////////////////////////////////////////////////////////////////
保存成OD脚本.
然后把EIP从哦OEP改向我们patch代码的第一句,这里是:
0065110060pushad
然后要在上面提到的jmp[esp-4]的地址,这里是00ff00AE上面下硬件执行断点。
其次,在patch结束句,这里是
0065117361popad上面
下F2断点。
最后运行脚本。等待一段时间,脚本运行完毕后,清除掉所有的修改。
dump,修复IAT.
就大功告成了。
PS:
我从看教程到脱壳成功一共用了30小时的时间,分4天。
前几个小时,都是学习PE文件。通过这次脱壳,让我对PE文件有了比较深的认识。原来都是一知半解。
脱壳对我等菜鸟来说是个很艰苦的工程,关键要有毅力和耐心。
现在目标是绕过加载HackShield.