您的位置:首页 > 其它

Diablo 2oo2’s CrackMe 2 算法分析

2005-06-19 13:58 597 查看
【目 标】:Diablo 2oo2’s CrackMe 2
【工 具】:IDA 4.7
【任 务】:算法分析
【操作平台】:Windows 2003 server
【作 者】: LOVEBOOM[DFCG][FCG][US]
【相关链接】: 见附件
【简要说明】: 用IDA再分析一篇简单的算法。
【详细过程】:
因为CRACKME是用masm写的,所以非常方便分析的。这次目标用yoda加了壳,怎么脱壳我就不说了,很简单的。脱壳后,用IDA分析一下结果就出来了:
code:00401028 DialogFunc: ; DATA XREF: start+Eocode:00401028 push ebpcode:00401029 mov ebp, espcode:0040102B cmp dword ptr [ebp+0Ch], 111hcode:00401032 jnz loc_401245code:00401038 mov eax, [ebp+10h] ; CASE EAX==WM_COMMANDcode:0040103B cmp ax, 65hcode:0040103F jnz loc_40125Dcode:00401045 pusha ; CASE AX==IDC_BTN_CHECKREGcode:00401046 mov byte ptr ds:UCASE_Buffer, 53h ; "SJKAZBVTECGIDFNG"code:0040104D mov byte ptr ds:UCASE_Buffer+1, 4Ahcode:00401054 mov byte ptr ds:UCASE_Buffer+2, 4Bhcode:0040105B mov byte ptr ds:UCASE_Buffer+3, 41hcode:00401062 mov byte ptr ds:UCASE_Buffer+4, 5Ahcode:00401069 mov byte ptr ds:UCASE_Buffer+5, 42hcode:00401070 mov byte ptr ds:UCASE_Buffer+6, 56hcode:00401077 mov byte ptr ds:UCASE_Buffer+7, 54hcode:0040107E mov byte ptr ds:UCASE_Buffer+8, 45hcode:00401085 mov byte ptr ds:UCASE_Buffer+9, 43hcode:0040108C mov byte ptr ds:UCASE_Buffer+0Ah, 47hcode:00401093 mov byte ptr ds:UCASE_Buffer+0Bh, 49hcode:0040109A mov byte ptr ds:UCASE_Buffer+0Ch, 44hcode:004010A1 mov byte ptr ds:UCASE_Buffer+0Dh, 46hcode:004010A8 mov byte ptr ds:UCASE_Buffer+0Eh, 4Ehcode:004010AF mov byte ptr ds:UCASE_Buffer+0Fh, 47h ; 准备获取注册码code:004010B6 push 28h ; nMaxCountcode:004010B8 push offset SN_Buffer ; lpStringcode:004010BD push 68h ; nIDDlgItemcode:004010BF push dword ptr [ebp+8] ; hDlgcode:004010C2 call GetDlgItemTextA ; 获取注册码code:004010C7 cmp eax, 10hcode:004010CA jnz short Reg_Failed ; 比较注册码,如果注册码长度不是10h则overcode:004010CC push 28h ; nMaxCountcode:004010CE push offset SzName_Buffer ; lpStringcode:004010D3 push 67h ; nIDDlgItemcode:004010D5 push dword ptr [ebp+8] ; hDlgcode:004010D8 call GetDlgItemTextA ; 获取用户名code:004010DD test eax, eaxcode:004010DF jz short loc_401101code:004010E1 cmp eax, 8 ; 用户名长度不能大于8code:004010E4 jg short loc_401115code:004010E6 cmp eax, 1 ; 如果用户名小于1则提示,问题提示,后面的提示最少2位,这里判断却是不为空就算过关了code:004010E9 jl short loc_4010EDcode:004010EB jmp short @UCASE ; 这里实际就是一个转为大写的函数。code:004010EB ; 如果小于'A'则加20h,相加后值还是小于'A'则把字符转为'F'code:004010EB ; 如果大于'Z'则减20h(就是转为大写),运算值大于'Z'则字符转为'G'code:004010EB ; 运算值小于'A',则把字符转为'S'code:004010ED ; ----------------------------------------------------------------------------code:004010EDcode:004010ED loc_4010ED: ; CODE XREF: code:004010E9jcode:004010ED push offset aNameMustBeAtLe ; lpStringcode:004010F2 push 68h ; nIDDlgItemcode:004010F4 push dword ptr [ebp+8] ; hDlgcode:004010F7 call SetDlgItemTextA ; 显示错误信息 code:004010FC jmp loc_401242code:00401101 ; ----------------------------------------------------------------------------code:00401101code:00401101 loc_401101: ; CODE XREF: code:004010DFjcode:00401101 push offset aEnterAName ; lpStringcode:00401106 push 68h ; nIDDlgItemcode:00401108 push dword ptr [ebp+8] ; hDlgcode:0040110B call SetDlgItemTextAcode:00401110 jmp loc_401242code:00401115 ; ----------------------------------------------------------------------------code:00401115code:00401115 loc_401115: ; CODE XREF: code:004010E4jcode:00401115 push offset aNameIsTooLong ; lpStringcode:0040111A push 68h ; nIDDlgItemcode:0040111C push dword ptr [ebp+8] ; hDlgcode:0040111F call SetDlgItemTextAcode:00401124 jmp loc_401242code:00401129 ; ----------------------------------------------------------------------------code:00401129code:00401129 Reg_Failed: ; CODE XREF: code:004010CAjcode:00401129 ; code:0040120Fj ...code:00401129 push offset String ; lpStringcode:0040112E push 68h ; nIDDlgItemcode:00401130 push dword ptr [ebp+8] ; hDlgcode:00401133 call SetDlgItemTextAcode:00401138 jmp loc_401242code:0040113Dcode:0040113D ; ************** S U B R O U T I N E *****************************************code:0040113Dcode:0040113D ; 这里实际就是一个转为大写的函数。code:0040113D ; 如果小于'A'则加20h,相加后值还是小于'A'则把字符转为'F'code:0040113D ; 如果大于'Z'则减20h(就是转为大写),运算值大于'Z'则字符转为'G'code:0040113D ; 运算值小于'A',则把字符转为'S'code:0040113Dcode:0040113D @UCASE proc near ; CODE XREF: code:004010EBjcode:0040113D xor ebx, ebxcode:0040113F xor ecx, ecx ; 初始化相关寄存器code:00401141 xor edx, edxcode:00401143 xor edi, edicode:00401145 xor esi, esicode:00401147code:00401147 loc_401147: ; CODE XREF: @UCASE+47jcode:00401147 mov bl, ds:SzName_Buffer[ecx]code:0040114D cmp bl, 41h ; 如果用户名小于'A'则跳去加20hcode:00401150 jl short ADD_20hcode:00401152code:00401152 loc_401152: ; CODE XREF: @UCASE:loc_401163jcode:00401152 cmp bl, 5Ah ; 如果用户名大于'Z'则跳去减20h,也就是uCASEcode:00401155 jg short UPCASEcode:00401157code:00401157 loc_401157: ; CODE XREF: @UCASE:loc_401176jcode:00401157 jmp short loc_401178code:00401159 ; ----------------------------------------------------------------------------code:00401159code:00401159 ADD_20h: ; CODE XREF: @UCASE+13jcode:00401159 add bl, 20hcode:0040115C cmp bl, 41h ; 如果+20后还是小于41则直接置BL为46H('F')code:0040115F jge short loc_401163code:00401161 mov bl, 46hcode:00401163code:00401163 loc_401163: ; CODE XREF: @UCASE+22jcode:00401163 jmp short loc_401152 ; 如果用户名大于'Z'则跳去减20h,也就是uCASEcode:00401165 ; ----------------------------------------------------------------------------code:00401165code:00401165 UPCASE: ; CODE XREF: @UCASE+18jcode:00401165 sub bl, 20hcode:00401168 cmp bl, 5Ah ; 如果-20小于或等于则跳code:0040116B jle short loc_40116F ; 如果减后小于'A'则改为'S'code:0040116D mov bl, 47h ; 如果-20后还是大于'Z'则把BL改为'D'code:0040116Fcode:0040116F loc_40116F: ; CODE XREF: @UCASE+2Ejcode:0040116F cmp bl, 41h ; 如果减后小于'A'则改为'S'code:00401172 jge short loc_401176code:00401174 mov bl, 53hcode:00401176code:00401176 loc_401176: ; CODE XREF: @UCASE+35jcode:00401176 jmp short loc_401157code:00401178 ; ----------------------------------------------------------------------------code:00401178code:00401178 loc_401178: ; CODE XREF: @UCASE:loc_401157jcode:00401178 mov byte ptr ds:UCASE_Buffer[edx], bl ; "SJKAZBVTECGIDFNG"code:0040117E add edx, 2 ; 每次加2,替换原有的数据,偶数替换code:00401181 inc ecxcode:00401182 cmp ecx, eaxcode:00401184 jnz short loc_401147code:00401184 @UCASE endpcode:00401184code:00401186 xor ecx, ecx ; 初始化相关寄存器code:00401188 xor edx, edxcode:0040118A xor ebx, ebxcode:0040118Ccode:0040118C Lp_Sum_value: ; CODE XREF: code:00401198jcode:0040118C mov bl, byte ptr ds:UCASE_Buffer[ecx] ; 取出转为大写后字符code:00401192 add edx, ebx ; 计算大写替换后字符串的和sumValuecode:00401194 inc ecxcode:00401195 cmp ecx, 10hcode:00401198 jnz short Lp_Sum_value ; 取出转为大写后字符code:0040119A imul eax, 0FFh ; 用户名长度乘以0FFh的值key1code:004011A0 imul edx, eax ; 再用key1乘以sumValue,设为imulvaluecode:004011A3 xor edx, 0ACEBDFABh ; 用imulValue 异或常数0ACEBDFABH的值设为XorValuecode:004011A9 bswap edx ; 计算出的xorValue反转code:004011AB push edxcode:004011AC push offset szLx ; "%lX"code:004011B1 push offset sz_save_fmstr ; 转换后的十六进制值输出为字符串code:004011B6 call wsprintfAcode:004011BB add esp, 0Chcode:004011BE xor ebx, ebxcode:004011C0 xor ecx, ecxcode:004011C2code:004011C2 loc_4011C2: ; CODE XREF: code:004011DCjcode:004011C2 mov bl, ds:sz_save_fmstr[ecx]code:004011C8 cmp bl, 3Ah ; 比较值是否小于':'code:004011CB jl short jl3a ; 如果值小于':'则加11hcode:004011CD jmp short loc_4011D8code:004011CF ; ----------------------------------------------------------------------------code:004011CFcode:004011CF jl3a: ; CODE XREF: code:004011CBjcode:004011CF add bl, 11h ; 如果值小于':'则加11hcode:004011D2 mov ds:sz_save_fmstr[ecx], blcode:004011D8code:004011D8 loc_4011D8: ; CODE XREF: code:004011CDjcode:004011D8 inc ecxcode:004011D9 cmp ecx, 8code:004011DC jnz short loc_4011C2 ; 循环判断替换code:004011DE xor ebx, ebxcode:004011E0 xor ecx, ecxcode:004011E2 xor edx, edxcode:004011E4code:004011E4 loc_4011E4: ; CODE XREF: code:004011F7jcode:004011E4 mov bl, ds:sz_save_fmstr[ecx] ; 再次取出运算后的值code:004011EA mov byte ptr ds:(UCASE_Buffer+1)[edx], bl ; 奇数替换字符code:004011F0 add edx, 2code:004011F3 inc ecxcode:004011F4 cmp edx, 10hcode:004011F7 jnz short loc_4011E4 ; 再次取出运算后的值code:004011F9 xor ebx, ebxcode:004011FB xor ecx, ecxcode:004011FD xor edx, edxcode:004011FF xor eax, eaxcode:00401201code:00401201 Loop_Compare_Data: ; CODE XREF: code:00401231jcode:00401201 mov bl, ds:SN_Buffer[edx] ; 取出假码code:00401207 mov al, byte ptr ds:UCASE_Buffer[edx] ; 取出真码code:0040120D xor eax, ebxcode:0040120F jnz Reg_Failed ; 如果不相等则overcode:00401215 mov bl, ds:byte_4030C9[edx]code:0040121B mov al, byte ptr ds:(UCASE_Buffer+1)[edx]code:00401221 add al, 5 ; 比较真注册码的偶数位-5是否等于假码的偶数位code:00401223 cmp bl, alcode:00401225 jnz Reg_Failedcode:0040122B add edx, 2code:0040122E cmp edx, 10hcode:00401231 jnz short Loop_Compare_Data ; 取出假码code:00401233 push offset aThankYouForYou ; lpStringcode:00401238 push 68h ; nIDDlgItemcode:0040123A push dword ptr [ebp+8] ; hDlgcode:0040123D call SetDlgItemTextA ; 显示正确信息code:00401242code:00401242 loc_401242: ; CODE XREF: code:004010FCjcode:00401242 ; code:00401110j ...code:00401242 popacode:00401243 jmp short loc_401257code:00401245 ; ----------------------------------------------------------------------------

算法总结: 又抓了个软杮子, 算法也是非常这简单的,先把注册名转为大写,然后替换固定字符串里奇数位的字符,s1,然后把s1的值累加s2,s2*0ff*用户名长度key1,key1再异或固定值0ACEBDFABh结果保存为key2,key2的每一位比较是否小于’:’,小于则加上11h,然后再加上5,结果替换固定字符串里偶数位的字符。 [align=left]Greetz:[/align][align=left] Fly.Jingulong,yock,tDasm.David.hexer,hmimys,ahao.UFO(brother).alan(sister).all of my friends and you![/align][align=left] [/align][align=left]By loveboom[DFCG][FCG][US][/align][align=left]http://blog.csdn.net/bmd2chen[/align][align=left]Email:loveboom#163.com[/align][align=center]Date:2005-6-13 14:32[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: