【文章标题】: Happytown's CrackMe_0038.exe 破解笔记
【文章作者】: ylp1332
【作者邮箱】: [email]ylp1332@yahoo.com.cn[/email]
【作者主页】: N/A
【作者QQ号】: N/A
【软件名称】: CrackMe_0038.exe
【软件大小】: 187kB
【下载地址】: 自己搜索下载
【加壳方式】: N/A
【保护方式】: Modified MD5
【编写语言】: VC6
【使用工具】: PEiD,IDA,OllyDBG,UE,VC6
【操作平台】: win32
【软件介绍】: Happytown's CrackMe No.38
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
1、首先用PEiD 0.94检查,用visual c++ 6编译,没有加壳。
2、用PEiD的插件Krypto ANAlyzer检查,没有发现任何加密算法的痕迹。
3、用IDA载入,进行初步的静态分析。
分析结论:
修改过的MD5算法,有4处调用;
使用Windows API GetDlgItemTextA从控件中取得用户名、组织和注册码,
用户名和组织名至少要2个字符长,注册码字符串必须由64个16进制字符组成。
验证过程的反汇编代码如下:
.text:00401000 ; int __cdecl OnCheck(HWND hDlg)
.text:00401000 OnCheck proc near ; CODE XREF: DialogFunc+55p
.text:00401000
.text:00401000 tmp_str2 = byte ptr -2D4h
.text:00401000 var_2CF = byte ptr -2CFh
.text:00401000 var_2CB = dword ptr -2CBh
.text:00401000 var_2C7 = word ptr -2C7h
.text:00401000 var_2C5 = byte ptr -2C5h
.text:00401000 tmp_str1 = dword ptr -2C4h
.text:00401000 var_2BF = dword ptr -2BFh
.text:00401000 var_2BB = dword ptr -2BBh
.text:00401000 var_2B7 = word ptr -2B7h
.text:00401000 var_2B5 = byte ptr -2B5h
.text:00401000 tmp_str0 = byte ptr -2B4h
.text:00401000 var_2AF = dword ptr -2AFh
.text:00401000 var_2AB = dword ptr -2ABh
.text:00401000 var_2A7 = word ptr -2A7h
.text:00401000 var_2A5 = byte ptr -2A5h
.text:00401000 hash_context = dword ptr -2A4h
.text:00401000 tmp_str3 = byte ptr -284h
.text:00401000 tmp_str4 = byte ptr -27Eh
.text:00401000 serbytes0 = dword ptr -278h
.text:00401000 serbytes1 = dword ptr -268h
.text:00401000 Name = byte ptr -258h
.text:00401000 Group = byte ptr -190h
.text:00401000 Serial = dword ptr -0C8h
.text:00401000 hDlg = dword ptr 4
.text:00401000
.text:00401000 sub esp, 2D4h
.text:00401006 push ebx
.text:00401007 push esi
.text:00401008 push edi
.text:00401009 xor ebx, ebx
.text:0040100B mov ecx, 49
.text:00401010 xor eax, eax
.text:00401012 lea edi, [esp+89h]
.text:00401019 mov [esp+2E0h+Name], bl
.text:00401020 rep stosd
.text:00401022 stosw
.text:00401024 stosb
.text:00401025 mov ecx, 49
.text:0040102A xor eax, eax
.text:0040102C lea edi, [esp+151h]
.text:00401033 mov [esp+2E0h+Group], bl
.text:0040103A rep stosd
.text:0040103C stosw
.text:0040103E stosb
.text:0040103F mov ecx, 49
.text:00401044 xor eax, eax
.text:00401046 lea edi, [esp+2E0h+Serial+1]
.text:0040104D mov byte ptr [esp+2E0h+Serial], bl
.text:00401054 rep stosd
.text:00401056 stosw
.text:00401058 stosb
.text:00401059 xor eax, eax
.text:0040105B mov esi, [esp+2E0h+hDlg]
.text:00401062 mov [esp+2Dh], eax
.text:00401066 xor ecx, ecx
.text:00401068 mov [esp+2E0h+var_2AF], eax
.text:0040106C xor edx, edx
.text:0040106E mov [esp+2E0h+var_2AB], eax
.text:00401072 mov edi, ds:GetDlgItemTextA
.text:00401078 mov [esp+2E0h+var_2A7], ax
.text:0040107D mov [esp+2E0h+tmp_str1+1], ecx
.text:00401081 mov [esp+0Dh], edx
.text:00401085 mov [esp+2E0h+var_2A5], al
.text:00401089 mov [esp+2E0h+var_2BF], ecx
.text:0040108D mov dword ptr [esp+2E0h+var_2CF], edx
.text:00401091 lea eax, [esp+2E0h+Name]
.text:00401098 mov [esp+2E0h+var_2BB], ecx
.text:0040109C mov [esp+2E0h+var_2CB], edx
.text:004010A0 push 0C9h ; nMaxCount
.text:004010A5 push eax ; lpString
.text:004010A6 mov [esp+2E8h+var_2B7], cx
.text:004010AB mov [esp+2E8h+var_2C7], dx
.text:004010B0 push 3EDh ; nIDDlgItem
.text:004010B5 push esi ; hDlg
.text:004010B6 mov [esp+2F0h+tmp_str0], bl
.text:004010BA mov byte ptr [esp+2F0h+tmp_str1], bl
.text:004010BE mov [esp+2F0h+var_2B5], cl
.text:004010C2 mov [esp+2F0h+tmp_str2], bl
.text:004010C6 mov [esp+2F0h+var_2C5], dl
.text:004010CA call edi ; GetDlgItemTextA
.text:004010CC cmp eax, 2 ; 用户名至少2个字符
.text:004010CF jnb short loc_4010DD
.text:004010D1 pop edi
.text:004010D2 pop esi
.text:004010D3 xor eax, eax
.text:004010D5 pop ebx
.text:004010D6 add esp, 2D4h
.text:004010DC retn
.text:004010DD ; ---------------------------------------------------------------------------
.text:004010DD
.text:004010DD loc_4010DD: ; CODE XREF: OnCheck+CFj
.text:004010DD lea ecx, [esp+2E0h+Group]
.text:004010E4 push 0C9h ; nMaxCount
.text:004010E9 push ecx ; lpString
.text:004010EA push 3EEh ; nIDDlgItem
.text:004010EF push esi ; hDlg
.text:004010F0 call edi ; GetDlgItemTextA
.text:004010F2 cmp eax, 2 ; 组织名至少2个字符
.text:004010F5 jnb short loc_401103
.text:004010F7 pop edi
.text:004010F8 pop esi
.text:004010F9 xor eax, eax
.text:004010FB pop ebx
.text:004010FC add esp, 2D4h
.text:00401102 retn
.text:00401103 ; ---------------------------------------------------------------------------
.text:00401103
.text:00401103 loc_401103: ; CODE XREF: OnCheck+F5j
.text:00401103 lea edx, [esp+2E0h+Serial]
.text:0040110A push 0C9h ; nMaxCount
.text:0040110F push edx ; lpString
.text:00401110 push 3EFh ; nIDDlgItem
.text:00401115 push esi ; hDlg
.text:00401116 call edi ; GetDlgItemTextA
.text:00401118 test eax, eax ; 注册码不能为空
.text:0040111A jnz short loc_401126
.text:0040111C pop edi
.text:0040111D pop esi
.text:0040111E pop ebx
.text:0040111F add esp, 2D4h
.text:00401125 retn
.text:00401126 ; ---------------------------------------------------------------------------
.text:00401126
.text:00401126 loc_401126: ; CODE XREF: OnCheck+11Aj
.text:00401126 lea edi, [esp+2E0h+Serial]
.text:0040112D or ecx, 0FFFFFFFFh
.text:00401130 xor eax, eax
.text:00401132 repne scasb
.text:00401134 not ecx
.text:00401136 dec ecx
.text:00401137 cmp ecx, 64
.text:0040113A jz short loc_401146 ; 注册码长度必须是64个字符
.text:0040113C pop edi
.text:0040113D pop esi
.text:0040113E pop ebx
.text:0040113F add esp, 2D4h
.text:00401145 retn
.text:00401146 ; ---------------------------------------------------------------------------
.text:00401146
.text:00401146 loc_401146: ; CODE XREF: OnCheck+13Aj
.text:00401146 lea eax, [esp+2E0h+hash_context]
.text:0040114A push ebp
.text:0040114B push eax ; ctx
.text:0040114C call hash_init
.text:00401151 lea edi, [esp+2E8h+Name]
.text:00401158 or ecx, 0FFFFFFFFh
.text:0040115B xor eax, eax
.text:0040115D lea edx, [esp+2E8h+hash_context]
.text:00401161 repne scasb
.text:00401163 not ecx
.text:00401165 dec ecx
.text:00401166 push ecx ; len
.text:00401167 lea ecx, [esp+2ECh+Name]
.text:0040116E push ecx ; cstr
.text:0040116F push edx ; ctx
.text:00401170 call hash_update
.text:00401175 lea eax, [esp+2F4h+hash_context]
.text:00401179 lea ecx, [esp+2F4h+tmp_str0]
.text:0040117D push eax ; ctx
.text:0040117E push ecx ; cstr
.text:0040117F call hash_final
.text:00401184 lea edx, [esp+2FCh+hash_context]
.text:00401188 push edx ; ctx
.text:00401189 call hash_init
.text:0040118E lea edi, [esp+300h+Group]
.text:00401195 or ecx, 0FFFFFFFFh
.text:00401198 xor eax, eax
.text:0040119A repne scasb
.text:0040119C not ecx
.text:0040119E dec ecx
.text:0040119F lea eax, [esp+300h+Group]
.text:004011A6 push ecx ; len
.text:004011A7 lea ecx, [esp+304h+hash_context]
.text:004011AB push eax ; cstr
.text:004011AC push ecx ; ctx
.text:004011AD call hash_update
.text:004011B2 lea edx, [esp+30Ch+hash_context]
.text:004011B6 lea eax, [esp+30Ch+tmp_str1]
.text:004011BA push edx ; ctx
.text:004011BB push eax ; cstr
.text:004011BC call hash_final
.text:004011C1 lea ecx, [esp+314h+hash_context]
.text:004011C5 push ecx ; ctx
.text:004011C6 call hash_init
.text:004011CB lea edx, [esp+318h+Group]
.text:004011D2 push edx ; char *
.text:004011D3 call __strrev
.text:004011D8 mov edi, eax
.text:004011DA or ecx, 0FFFFFFFFh
.text:004011DD xor eax, eax
.text:004011DF lea edx, [esp+31Ch+Name]
.text:004011E6 repne scasb
.text:004011E8 not ecx
.text:004011EA sub edi, ecx
.text:004011EC mov esi, edi
.text:004011EE mov ebp, ecx
.text:004011F0 mov edi, edx
.text:004011F2 or ecx, 0FFFFFFFFh
.text:004011F5 repne scasb
.text:004011F7 mov ecx, ebp
.text:004011F9 dec edi
.text:004011FA shr ecx, 2
.text:004011FD rep movsd
.text:004011FF mov ecx, ebp
.text:00401201 and ecx, 3
.text:00401204 rep movsb
.text:00401206 lea edi, [esp+31Ch+Name]
.text:0040120D or ecx, 0FFFFFFFFh
.text:00401210 repne scasb
.text:00401212 not ecx
.text:00401214 dec ecx
.text:00401215 lea eax, [esp+31Ch+Name]
.text:0040121C push ecx ; len
.text:0040121D lea ecx, [esp+320h+hash_context]
.text:00401221 push eax ; cstr
.text:00401222 push ecx ; ctx
.text:00401223 call hash_update
.text:00401228 add esp, 44h
.text:0040122B lea edx, [esp+2E4h+hash_context]
.text:0040122F lea eax, [esp+2E4h+tmp_str2]
.text:00401233 push edx ; ctx
.text:00401234 push eax ; cstr
.text:00401235 call hash_final
.text:0040123A lea ecx, [esp+2ECh+tmp_str2]
.text:0040123E push 6 ; size_t
.text:00401240 lea edx, [esp+2F0h+tmp_str3]
.text:00401244 push ecx ; char *
.text:00401245 push edx ; char *
.text:00401246 call _strncpy
.text:0040124B lea eax, [esp+2Ah]
.text:0040124F push 6 ; size_t
.text:00401251 lea ecx, [esp+2FCh+tmp_str4]
.text:00401255 push eax ; char *
.text:00401256 push ecx ; char *
.text:00401257 call _strncpy
.text:0040125C lea edi, [esp+304h+Serial]
.text:00401263 or ecx, 0FFFFFFFFh
.text:00401266 xor eax, eax
.text:00401268 lea edx, [esp+304h+serbytes0]
.text:0040126F repne scasb
.text:00401271 not ecx
.text:00401273 dec ecx
.text:00401274 push edx
.text:00401275 lea eax, [esp+308h+Serial]
.text:0040127C push ecx
.text:0040127D push eax
.text:0040127E call sub_4014E0 ; 关键函数1:检查注册码长度是否是偶数,注册码是否全是16进制字符,
.text:0040127E ; 然后将注册码字符串串转换为字节串
.text:00401283 add esp, 2Ch
.text:00401286 test eax, eax
.text:00401288 pop ebp
.text:00401289 jnz short loc_401295
.text:0040128B pop edi
.text:0040128C pop esi
.text:0040128D pop ebx
.text:0040128E add esp, 2D4h
.text:00401294 retn
.text:00401295 ; ---------------------------------------------------------------------------
.text:00401295
.text:00401295 loc_401295: ; CODE XREF: OnCheck+289j
.text:00401295 xor eax, eax ; eax = 0
.text:00401297
.text:00401297 loc_401297: ; CODE XREF: OnCheck+2DAj
.text:00401297 lea esi, [eax+1] ; for(int i=0; i<3; i++)
.text:0040129A and eax, 80000001h
.text:0040129F jns short loc_4012A6
.text:004012A1 dec eax
.text:004012A2 or eax, 0FFFFFFFEh
.text:004012A5 inc eax
.text:004012A6
.text:004012A6 loc_4012A6: ; CODE XREF: OnCheck+29Fj
.text:004012A6 mov ecx, esi
.text:004012A8 and ecx, 80000001h
.text:004012AE jns short loc_4012B5
.text:004012B0 dec ecx
.text:004012B1 or ecx, 0FFFFFFFEh
.text:004012B4 inc ecx
.text:004012B5
.text:004012B5 loc_4012B5: ; CODE XREF: OnCheck+2AEj
.text:004012B5 shl ecx, 4
.text:004012B8 lea edx, [esp+ecx+2E0h+serbytes0]
.text:004012BC lea ecx, [eax+eax*2]
.text:004012BF shl eax, 4
.text:004012C2 push edx ; s3
.text:004012C3 lea edx, [esp+ecx*2+2E4h+tmp_str3]
.text:004012C7 lea eax, [esp+eax+2E4h+serbytes0]
.text:004012CB push edx ; s2
.text:004012CC push eax ; s1
.text:004012CD call sub_401320 ; 关键函数2
.text:004012D2 mov eax, esi
.text:004012D4 add esp, 0Ch
.text:004012D7 cmp eax, 3
.text:004012DA jl short loc_401297
.text:004012DC mov ecx, 4
.text:004012E1 lea edi, [esp+2E0h+tmp_str0] ; 比较注册码前16个字符
.text:004012E5 lea esi, [esp+2E0h+serbytes0]
.text:004012E9 xor edx, edx
.text:004012EB repe cmpsd
.text:004012ED jz short loc_4012FB
.text:004012EF pop edi
.text:004012F0 pop esi
.text:004012F1 xor eax, eax
.text:004012F3 pop ebx
.text:004012F4 add esp, 2D4h
.text:004012FA retn
.text:004012FB ; ---------------------------------------------------------------------------
.text:004012FB
.text:004012FB loc_4012FB: ; CODE XREF: OnCheck+2EDj
.text:004012FB mov ecx, 4
.text:00401300 lea edi, [esp+2E0h+tmp_str1] ; 比较注册码后16个字符
.text:00401304 lea esi, [esp+2E0h+serbytes1]
.text:00401308 xor eax, eax
.text:0040130A repe cmpsd
.text:0040130C pop edi
.text:0040130D pop esi
.text:0040130E setz al
.text:00401311 pop ebx
.text:00401312 add esp, 2D4h
.text:00401318 retn
.text:00401318 OnCheck endp
.text:00401318
.text:00401318 ; ---------------------------------------------------------------------------
.text:00401319 align 10h
.text:00401320
.text:00401320 ; =============== S U B R O U T I N E =======================================
.text:00401320
.text:00401320
.text:00401320 ; int __cdecl sub_401320(char *s1,char *s2,char *s3)
.text:00401320 sub_401320 proc near ; CODE XREF: OnCheck+2CDp
.text:00401320
.text:00401320 var_50 = dword ptr -50h
.text:00401320 var_4B = dword ptr -4Bh
.text:00401320 var_47 = dword ptr -47h
.text:00401320 var_43 = word ptr -43h
.text:00401320 var_41 = byte ptr -41h
.text:00401320 var_40 = byte ptr -40h
.text:00401320 hash_context2 = dword ptr -20h
.text:00401320 s1 = dword ptr 4
.text:00401320 s2 = dword ptr 8
.text:00401320 s3 = dword ptr 0Ch
.text:00401320
.text:00401320 sub esp, 50h
.text:00401323 push ebx
.text:00401324 push esi
.text:00401325 push edi
.text:00401326 xor dl, dl
.text:00401328 mov ecx, 7
.text:0040132D xor eax, eax
.text:0040132F lea edi, [esp+1Dh]
.text:00401333 mov [esp+5Ch+var_40], dl
.text:00401337 rep stosd
.text:00401339 stosw
.text:0040133B mov ecx, [esp+5Ch+s1]
.text:0040133F mov byte ptr [esp+5Ch+var_50], dl
.text:00401343 stosb
.text:00401344 xor eax, eax
.text:00401346 push 16 ; size_t
.text:00401348 mov [esp+60h+var_50+1], eax
.text:0040134C lea edx, [esp+60h+var_40]
.text:00401350 mov [esp+60h+var_4B], eax
.text:00401354 push ecx ; char *
.text:00401355 mov [esp+64h+var_47], eax
.text:00401359 push edx ; char *
.text:0040135A mov [esp+68h+var_43], ax
.text:0040135F mov [esp+68h+var_41], al
.text:00401363 call _strncpy
.text:00401368 mov eax, [esp+68h+s2]
.text:0040136C push 6 ; size_t
.text:0040136E lea ecx, [esp+6Ch+var_40]
.text:00401372 push eax ; char *
.text:00401373 push ecx ; char *
.text:00401374 call _strncat
.text:00401379 lea edx, [esp+74h+hash_context2]
.text:0040137D push edx ; ctx
.text:0040137E call hash_init
.text:00401383 lea eax, [esp+78h+var_40]
.text:00401387 push 32 ; len
.text:00401389 lea ecx, [esp+7Ch+hash_context2]
.text:0040138D push eax ; cstr
.text:0040138E push ecx ; ctx
.text:0040138F call hash_update
.text:00401394 lea edx, [esp+84h+hash_context2]
.text:00401398 lea eax, [esp+84h+var_50]
.text:0040139C push edx ; ctx
.text:0040139D push eax ; cstr
.text:0040139E call hash_final
.text:004013A3 mov eax, [esp+8Ch+s3]
.text:004013AA lea ecx, [esp+8Ch+var_50]
.text:004013AE add esp, 30h
.text:004013B1 sub ecx, eax
.text:004013B3 mov esi, 16
.text:004013B8
.text:004013B8 loc_4013B8: ; CODE XREF: sub_401320+A3j
.text:004013B8 mov dl, [ecx+eax]
.text:004013BB mov bl, [eax]
.text:004013BD xor bl, dl
.text:004013BF mov [eax], bl
.text:004013C1 inc eax
.text:004013C2 dec esi
.text:004013C3 jnz short loc_4013B8
.text:004013C5 pop edi
.text:004013C6 pop esi
.text:004013C7 pop ebx
.text:004013C8 add esp, 50h
.text:004013CB retn
.text:004013CB sub_401320 endp
.text:004013CB
注册码验证过程:
1、将用户名、组织、以及用户名和组织的逆串连接起来的字符串分别进行hash运算,得到以下4个字符串。
s0 = hash(name); s1 = hash(group); s2 = hash(name+ rev(group)); s3 = s2的前12个字符。
2、检查注册码是否是由64个16进制字符组成,先将它转化为大写,然后将它转化为由32个字节组成的字节串。
ser_code = str2bytes(serial);
3、调用函数sub_401320对s3和ser_code进行操作,要调用3次,主要操作是按字节进行异或。
sub_401320( ser_code, s3, ser_code + 16 );
sub_401320( ser_code + 16, s3 + 6, ser_code );
sub_401320( ser_code, s3, ser_code + 16 );
4、对最后得到的ser_code,如果其前16个字节与s0相同,且后16个字节与s1相同,则注册成功。
函数void sub_401320( char *s1, char *s2, char *s3 )的操作很简单,取s1的前16个字节和s2的前6个字节,
进行hash运算,将得到的字符串与s3按字节异或,结果保存到s3中。
由于异或2次就还原了,所以连续以同样的参数调用sub_401320两次,将不改变s3的值。
可以看出整个验证过程还是比较简单的。
生成注册码的过程:
1、将用户名、组织、以及用户名和组织的逆串连接起来的字符串分别进行hash运算,得到以下4个字符串。
s0 = hash(name); s1 = hash(group); s2 = hash(name+ rev(group)); s3 = s2的前12个字符。
2、将s0和s1连接起来,构成注册码的初始值,其中s0和s1都是16字节,注册码是32字节。
ser_code = s0 + s1;
3、按与验证过程相反的顺序调用函数sub_401320对s3和ser_code进行操作,要调用3次。
sub_401320( ser_code, tmp_str3, ser_code + 16 );
sub_401320( ser_code + 16, tmp_str3 + 6, ser_code );
sub_401320( ser_code, tmp_str3, ser_code + 16 );
4、将得到的注册码ser_code串转化为其16进制字符串,此即为最终的注册码,长度为64字节。
修改过的hash算法还原比较困难,直接从IDA中提取汇编代码更省事。
对于与MD5非常类似的hash算法,提取汇编代码的技术已经很成熟,有很多帖子已经详细讲过了,这里就不赘述。
以下是一组正确的注册码:
name: ylp1332
group: abcdefg
serial: F7C2C090A074CA0D093842B2D482CF5140E5DAFA3C9E6CAC483830FF4C78FD90
以下是keygen的主要代码,不含hash算法的汇编代码。
在visual c++ 6 with sp6 下编译通过。
/* keygen.c 注册机源码 */
#include <stdio.h>
#include <string.h>
#define MAXLEN 49
#define HASH_DIGEST_SIZE 16
typedef unsigned long uint32;
typedef struct {
uint32 state[4];
uint32 count[2];
unsigned char buffer[64];
} hash_context;
void hash_init( hash_context *ctx );
void hash_update( hash_context *ctx, unsigned char *cstr, unsigned int len );
void hash_final( unsigned char *cstr, hash_context *ctx );
void bytes2str( unsigned char *in, unsigned int len, unsigned char *out )
{
unsigned int i, x, y;
for( i=0; i<len; i++)
{
y = in[i] >> 4;
y += 0x30;
if( y > 0x39 ) y += 0x07;
x = in[i] & 0x0F;
x += 0x30;
if( x > 0x39 ) x += 0x07;
out[ i << 1 ] = y;
out[ (i << 1) + 1 ] = x;
}
out[ len << 1 ] = 0x00;
}
void sub_401320( char *s1, char *s2, char *s3 )
{
int i;
char buf[ MAXLEN ] = {0};
char out[ MAXLEN ] = {0};
hash_context hash_ctx;
strncpy( buf, s1, 16 );
strncat( buf, s2, 6 );
hash_init( &hash_ctx );
hash_update( &hash_ctx, buf, 32 );
hash_final( out, &hash_ctx );
for( i=0; i<16; i++) s3[i] ^= out[i];
}
int main(int argc, char **argv)
{
char usr_name[ MAXLEN ] = {0};
char grp_name[ MAXLEN ] = {0};
char ser_code[ MAXLEN ] = {0};
char tmp_str0[ MAXLEN ] = {0};
char tmp_str1[ MAXLEN ] = {0};
char tmp_str2[ MAXLEN ] = {0};
char tmp_str3[ MAXLEN ] = {0};
char buf[ MAXLEN ] = {0};
char serial[ MAXLEN*2 ] = {0};
hash_context hash_ctx;
// Your Name here, at least 2 chars !
strcpy( usr_name, "ylp1332" );
// Your Group here, at least 2 chars !
strcpy( grp_name, "abcdefg" );
printf(" name: %s\n", usr_name );
printf(" group: %s\n", grp_name );
hash_init( &hash_ctx );
hash_update( &hash_ctx, usr_name, strlen(usr_name) );
hash_final( tmp_str0, &hash_ctx );
hash_init( &hash_ctx );
hash_update( &hash_ctx, grp_name, strlen(grp_name) );
hash_final( tmp_str1, &hash_ctx );
strcpy( buf, usr_name );
strcat( buf, _strrev(grp_name));
hash_init( &hash_ctx );
hash_update( &hash_ctx, buf, strlen(buf) );
hash_final( tmp_str2, &hash_ctx );
strncpy( tmp_str3, tmp_str2, 12 );
strncpy( ser_code, tmp_str0, 16 );
strncpy( ser_code + 16, tmp_str1, 16 );
sub_401320( ser_code, tmp_str3, ser_code + 16 );
sub_401320( ser_code + 16, tmp_str3 + 6, ser_code );
sub_401320( ser_code, tmp_str3, ser_code + 16 );
bytes2str( ser_code, 32, serial );
printf(" serial: %s\n", serial );
return 0;
}
--------------------------------------------------------------------------------
【经验总结】
静态分析与动态调试相结合。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2006年12月17日 4:23:56
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)