邪恶八进制信息安全团队技术讨论组's Archiver

pub!1c 2006-1-23 11:00

[转载][MFC]某英语复读软件简单算法

<P>文章作者: killl</P>
<P><FONT face=宋体>【破文标题】某英语复读软件MFC简单算法<BR>【破文作者】KiLlL<BR>【破解时间】2006-01-2123:25<BR>【破解声明】仅为技术交流之用!<BR>【破解过程】<BR><BR>很好的复读软件,这里仅做算法分析。名字省去了。<BR><BR>MFC,没有壳,很方便。机器码的生成用到了dll,那个dll是aspack压缩的。<BR><BR>根据错误提示的对话框很容易定位到下面:<BR><BR><BR>0041A88F.E8BC7AFFFFcall00412350//关键call<BR>0041A894.84C0testal,al<BR>0041A896.53pushebx<BR>0041A897.6858A84200push0042A858<BR>0041A89C.752Djnzshort0041A8CB//注册成功<BR><BR>开始直接爆破00412350,让al返回值为1,结果发现有暗桩,某些功能在使用时还是有提示,索性跟进去看看:<BR><BR>0041235051pushecx<BR>0041235153pushebx<BR>0041235255pushebp<BR>00412353|.56pushesi<BR>00412354|.57pushedi<BR>00412355|.8BE9movebp,ecx<BR>00412357|.E874110000call004134D0<BR>0041235C|.8BCDmovecx,ebp<BR>0041235E|.E85D110000call004134C0<BR>00412363|.8BCDmovecx,ebp<BR>00412365|.E8F60A0000call00412E60<BR>0041236A|.8B4514moveax,[arg.4]<BR>0041236D|.8D7D14leaedi,[arg.4]<BR>00412370|.8378F808cmpdwordptrds:[eax-8],8;注册码8位<BR>004123747408jeshort0041237E<BR>004123765Fpopedi<BR>004123775Epopesi<BR>004123785Dpopebp<BR>00412379|.32C0xoral,al<BR>0041237B|.5Bpopebx<BR>0041237C|.59popecx<BR>0041237D|.C3retn<BR>0041237E|>8BCFmovecx,edi<BR>00412380|.E88DCD0000call<jmp.&MFC42.#4202_CString::MakeLower><BR>00412385|.8B7518movesi,[arg.5];我的机器码"46674926D"<BR>00412388|.8B3Fmovedi,dwordptrds:[edi];假码12345678<BR>0041238A|.0FBE4605movsxeax,byteptrds:[esi+5];机器码第六位9<BR>0041238E|.0FBE16movsxedx,byteptrds:[esi];机器码第一位4<BR>00412391|.8D0C40leaecx,dwordptrds:[eax+eax*2];39*3=AB<BR>00412394|.8D0488leaeax,dwordptrds:[eax+ecx*4];eax=eax+AB*4<BR>00412397|.8BCAmovecx,edx;34<BR>00412399|.C1E105shlecx,5;ecx=ecx*2^5<BR>0041239C|.03CAaddecx,edx;ecx=680+34<BR>0041239E|.8D0C49leaecx,dwordptrds:[ecx+ecx*2];ecx=ecx*36b4*3=141c<BR>004123A1|.8D144Aleaedx,dwordptrds:[edx+ecx*2];edx+=ecx*2286c<BR>004123A4|.B924000000movecx,24<BR>004123A9|.03C2addeax,edx;eax+=edx2e5+286c<BR>004123AB|.33D2xoredx,edx<BR>004123AD|.F7F1divecx;2b51/24<BR>004123AF|.0FBE0Fmovsxecx,byteptrds:[edi];注册码第一位<BR>004123B2|.8D41D0leaeax,dwordptrds:[ecx-30];Switch(cases30..7A)<BR>004123B5|.83F84Acmpeax,4A;ascii-30<BR>004123B8|.0F8734010000ja004124F2<BR>004123BE|.33DBxorebx,ebx<BR>004123C0|.8A98302A4100movbl,byteptrds:[eax+412A30];查表<BR>004123C6|.FF249D9C294100jmpdwordptrds:[ebx*4+41299C]<BR>004123CD|>B813000000moveax,13;Case31('1')ofswitch004123B2<BR>004123D2|.E920010000jmp004124F7<BR>004123D7|>B802000000moveax,2;Case32('2')ofswitch004123B2<BR>004123DC|.E916010000jmp004124F7<BR>004123E1|>B801000000moveax,1;Case33('3')ofswitch004123B2<BR>004123E6|.E90C010000jmp004124F7<BR>004123EB|>B807000000moveax,7;Case34('4')ofswitch004123B2<BR>004123F0|.E902010000jmp004124F7<BR>004123F5|>B822000000moveax,22;Case35('5')ofswitch004123B2<BR>004123FA|.E9F8000000jmp004124F7<BR>004123FF|>B805000000moveax,5;Case36('6')ofswitch004123B2<BR>00412404|.E9EE000000jmp004124F7<BR>00412409|>B804000000moveax,4;Case37('7')ofswitch004123B2<BR>0041240E|.E9E4000000jmp004124F7<BR>00412413|>B810000000moveax,10;Case38('8')ofswitch004123B2<BR>00412418|.E9DA000000jmp004124F7<BR>0041241D|>33C0xoreax,eax;Case39('9')ofswitch004123B2<BR>0041241F|.E9D3000000jmp004124F7<BR>00412424|>B811000000moveax,11;Case30('0')ofswitch004123B2<BR>00412429|.E9C9000000jmp004124F7<BR>0041242E|>B81C000000moveax,1C;Case61('a')ofswitch004123B2<BR>00412433|.E9BF000000jmp004124F7<BR>00412438|>B80C000000moveax,0C;Case62('b')ofswitch004123B2<BR>0041243D|.E9B5000000jmp004124F7<BR>00412442|>B814000000moveax,14;Case63('c')ofswitch004123B2<BR>00412447|.E9AB000000jmp004124F7<BR>0041244C|>B80E000000moveax,0E;Case64('d')ofswitch004123B2<BR>00412451|.E9A1000000jmp004124F7<BR>00412456|>B80D000000moveax,0D;Case65('e')ofswitch004123B2<BR>0041245B|.E997000000jmp004124F7<BR>00412460|>B808000000moveax,8;Case66('f')ofswitch004123B2<BR>00412465|.E98D000000jmp004124F7<BR>0041246A|>B809000000moveax,9;Case67('g')ofswitch004123B2<BR>0041246F|.E983000000jmp004124F7<BR>00412474|>B812000000moveax,12;Case68('h')ofswitch004123B2<BR>00412479|.EB7Cjmpshort004124F7<BR>0041247B|>B803000000moveax,3;Case69('i')ofswitch004123B2<BR>00412480|.EB75jmpshort004124F7<BR>00412482|>B80F000000moveax,0F;Case6A('j')ofswitch004123B2<BR>00412487|.EB6Ejmpshort004124F7<BR>00412489|>B815000000moveax,15;Case6B('k')ofswitch004123B2<BR>0041248E|.EB67jmpshort004124F7<BR>00412490|>B81B000000moveax,1B;Case6C('l')ofswitch004123B2<BR>00412495|.EB60jmpshort004124F7<BR>00412497|>B818000000moveax,18;Case6D('m')ofswitch004123B2<BR>0041249C|.EB59jmpshort004124F7<BR>0041249E|>B817000000moveax,17;Case6E('n')ofswitch004123B2<BR>004124A3|.EB52jmpshort004124F7<BR>004124A5|>B821000000moveax,21;Case6F('o')ofswitch004123B2<BR>004124AA|.EB4Bjmpshort004124F7<BR>004124AC|>B81A000000moveax,1A;Case70('p')ofswitch004123B2<BR>004124B1|.EB44jmpshort004124F7<BR>004124B3|>B816000000moveax,16;Case72('r')ofswitch004123B2<BR>004124B8|.EB3Djmpshort004124F7<BR>004124BA|>B81D000000moveax,1D;Case73('s')ofswitch004123B2<BR>004124BF|.EB36jmpshort004124F7<BR>004124C1|>B81E000000moveax,1E;Case74('t')ofswitch004123B2<BR>004124C6|.EB2Fjmpshort004124F7<BR>004124C8|>B823000000moveax,23;Case75('u')ofswitch004123B2<BR>004124CD|.EB28jmpshort004124F7<BR>004124CF|>B820000000moveax,20;Case76('v')ofswitch004123B2<BR>004124D4|.EB21jmpshort004124F7<BR>004124D6|>B819000000moveax,19;Case77('w')ofswitch004123B2<BR>004124DB|.EB1Ajmpshort004124F7<BR>004124DD|>B806000000moveax,6;Case78('x')ofswitch004123B2<BR>004124E2|.EB13jmpshort004124F7<BR>004124E4|>B81F000000moveax,1F;Case79('y')ofswitch004123B2<BR>004124E9|.EB0Cjmpshort004124F7<BR>004124EB|>B80A000000moveax,0A;Case7A('z')ofswitch004123B2<BR>004124F0|.EB05jmpshort004124F7<BR>004124F2|>B80B000000moveax,0B;Defaultcaseofswitch004123B2<BR>004124F7|>3BD0cmpedx,eax<BR>004124F9|.740Cjeshort00412507<BR>004124FB|.5Fpopedi<BR>004124FC|.C6450F10movbyteptrss:[ebp+F],10<BR>00412500|.5Epopesi<BR>00412501|.5Dpopebp<BR>00412502|.32C0xoral,al<BR>00412504|.5Bpopebx<BR>00412505|.59popecx<BR>00412506|.C3retn<BR><BR><BR>这里首先验证注册码位数,然后逐位验证。验证时没有出现真正的注册码,而是通过假码第一位跟第六位运行后得到一个数字,再利用假码第一位查表得到另外一个数字,比较这两个数字,相等则继续,否则注册失败。<BR><BR>注意movbyteptrss:[ebp+F],10这句,成功了是movbyteptrss:[ebp+F],13,这里估计是个暗桩。有兴趣下个读断点试试。<BR><BR>给出vb的注册机源码,对比程序代码很容易看:<BR><BR>str="1234567890abcdefghijklmnoprstuvwxyz{"<BR>str1="130201072205041000111c0c140e0d080912030f151b1817211a161d1e232019061f0a0b"<BR><BR>eax=Asc(Mid$(mc,6,1))<BR>edx=Asc(Mid$(mc,1,1))<BR>ecx=eax*3<BR>eax=eax+ecx*4<BR>ecx=edx<BR>ecx=ecx*2^5<BR>ecx=ecx+edx<BR>ecx=ecx*3<BR>edx=edx+ecx*2<BR>ecx=&H24<BR>eax=eax+edx<BR>edx=eaxModecx<BR><BR><BR>Fori=1ToLen(str1)-1Step2<BR>IfRight$("00"&Hex$(edx),2)=UCase$(Mid$(str1,i,2))Then<BR>Tmp=Mid$(str,i\2+1,1)<BR>ExitFor<BR>EndIf<BR>Next<BR><BR>IfTmp=""ThenTmp="{"<BR><BR>后面的7位计算方法与之类似。有几个地方要注意:<BR><BR>004128E8|.C6450C01movbyteptrss:[ebp+C],1;1<BR><BR>00412941|.C6450D01movbyteptrss:[ebp+D],1;2<BR><BR>0041298E|.C6450F13movbyteptrss:[ebp+F],13;3<BR><BR><BR>【破解心得】<BR>有了mfc的Lib文件,mfc的函数一目了然,所以很容易看清注册流程。该软件的思路不错,在关键call里面设置了其他返回数据,因此不能采取在函数开始直接返回al值的方法来爆破,但是还是很容易找到关键点。注册成功后结果保存在注册表内。<BR><BR>关于利用dll取得机器码的方法不是很可靠,简单编写一个dll就可以一码多用了。</FONT><BR></P>

页: [1]
© 1999-2008 EvilOctal Security Team