首页
社区
课程
招聘
[原创]ErShu's CrackMe分析 附 注册机
发表于: 2013-1-19 02:09 8594

[原创]ErShu's CrackMe分析 附 注册机

2013-1-19 02:09
8594

【文章标题】: 【原创】ErShu's CrackMe 分析 附注册机
【文章作者】: lifestill
【作者邮箱】: zhong_sf@sina.com
【软件名称】: LErShu's Keygenme
【附件下载】: Crack Me.rar

最近因为考试 ,实在无聊 , 基本上的同学都放假了 ,就差我了, 还得考试   
因此 ,心情感觉十分压抑 , 只好找个CrackMe 让自己淡定......:

转入正题, 这个CrackMe 很简单 ,根据szAccount(用户名)计算serial ,计算分三步:

step1. 一个循环 根据szAccount 按一定规则计算出三个 下文 待用结果 值, 分别是Ebp ,Ebx ,nTmp14(即esp+0x14 ,只是给它个名字,便于操作) .这三个中间值将在下文中用到

step2.  通过4个循环 , 每个循环5次 ,每个循环使用一个 上个step1中计算三个中间值,外加 VolumeNumber (经过了简单的改变) ,  每个循环将相应的中间值经过计算计算出5个字符, 这分别的5个字符组成一个长为20个字符的字符串, 这个就是 serial 的中间值 szSerialTmp

step3. 在这一步中将step2中 szSerialTmp ,因为在step2中 组建的20个字符不一定都为可 视的字符 ,那么在这一步中就是将这20个字符经过一定的计算转化为可视的字符,若原来为可视的字符 则不改变它.

整个过程就是如此, 简单吧, 在这,还有个简单心得想和大家分享下 ,就是将一大段代码分模块 ,在每个模块中明确 这个模块的的目的是最重要的, 即这一段代码的输出值, 并且这个输出值将在后文中用到. 这个值就是我们所要关注的.其它的一些变量可能都是辅助于得到这个输出值. 这样在分析每段代码时目的就很确了, 整个过程也就更加明了了. 是吧, 不知道这样说对不对啊.

下面我们来看代码吧:

1.入口点,bp MessageBoxA 或 bp GetWindowTextA ,经过几步回溯之后便可很容易来到程序入口:

00401590   .  6A FF         push -0x1
00401592   .  68 381E4000   push Crack_Me.00401E38                   ;  SE 处理程序安装
00401597   .  64:A1 0000000>mov eax,dword ptr fs:[0]
0040159D   .  50            push eax
0040159E   .  64:8925 00000>mov dword ptr fs:[0],esp
004015A5   .  51            push ecx
004015A6   .  56            push esi
004015A7   .  8BF1          mov esi,ecx
004015A9   .  6A 01         push 0x1
004015AB   .  E8 6A050000   call <jmp.&MFC42.#6334>                  ;  这是MFC.UpdateData() ,在里层 间接调用GetWindowTextA
004015B0   .  8B4E 60       mov ecx,dword ptr ds:[esi+0x60]
004015B3   .  8D46 60       lea eax,dword ptr ds:[esi+0x60]
004015B6   .  8B51 F8       mov edx,dword ptr ds:[ecx-0x8]
004015B9   .  85D2          test edx,edx
004015BB   .  75 20         jnz XCrack_Me.004015DD
004015BD   .  6A 00         push 0x0
004015BF   .  6A 00         push 0x0
004015C1   .  68 38304000   push Crack_Me.00403038                   ;  ASCII "User Name is empty!"
004015C6   .  8BCE          mov ecx,esi
004015C8   .  E8 47050000   call <jmp.&MFC42.#4224>
004015CD   .  5E            pop esi
004015CE   .  8B4C24 04     mov ecx,dword ptr ss:[esp+0x4]
004015D2   .  64:890D 00000>mov dword ptr fs:[0],ecx
004015D9   .  83C4 10       add esp,0x10
004015DC   .  C3            retn
004015DD   >  8D5424 04     lea edx,dword ptr ss:[esp+0x4]
004015E1   .  50            push eax
004015E2   .  52            push edx
004015E3   .  8BCE          mov ecx,esi
004015E5   .  E8 66000000   call Crack_Me.00401650                   ;  _CalcSerial(...) 所有都计算在里面,F7跟进
004015EA   .  8B46 64       mov eax,dword ptr ds:[esi+0x64]
004015ED   .  C74424 10 000>mov dword ptr ss:[esp+0x10],0x0          ;  _CalcSerial(..) 之后马上与输入的假码比较_mbscmp
004015F5   .  50            push eax                                 ; /s2
004015F6   .  8B4424 08     mov eax,dword ptr ss:[esp+0x8]           ; |
004015FA   .  50            push eax                                 ; |s1
004015FB   .  FF15 C8214000 call dword ptr ds:[<&MSVCRT._mbscmp>]    ; \_mbscmp
00401601   .  83C4 08       add esp,0x8
00401604   .  85C0          test eax,eax
00401606   .  6A 00         push 0x0
00401608   .  6A 00         push 0x0
0040160A   .  75 0E         jnz XCrack_Me.0040161A
0040160C   .  68 28304000   push Crack_Me.00403028                   ;  ASCII "Great! pf! pf!"
00401611   .  8BCE          mov ecx,esi
00401613   .  E8 FC040000   call <jmp.&MFC42.#4224>                  ;  MFC.MessageBox("Crack Success")
00401618   .  EB 15         jmp XCrack_Me.0040162F
0040161A   >  68 20304000   push Crack_Me.00403020                   ;  ASCII "fail!"
0040161F   .  8BCE          mov ecx,esi
00401621   .  E8 EE040000   call <jmp.&MFC42.#4224>                  ;  MFC.MessageBox("Crack Failed")
00401626   .  6A 00         push 0x0
00401628   .  8BCE          mov ecx,esi
0040162A   .  E8 EB040000   call <jmp.&MFC42.#6334>
0040162F   >  8D4C24 04     lea ecx,dword ptr ss:[esp+0x4]
00401633   .  C74424 10 FFF>mov dword ptr ss:[esp+0x10],-0x1
0040163B   .  E8 C0030000   call <jmp.&MFC42.#800>
00401640   .  8B4C24 08     mov ecx,dword ptr ss:[esp+0x8]
00401644   .  5E            pop esi
00401645   .  64:890D 00000>mov dword ptr fs:[0],ecx
0040164C   .  83C4 10       add esp,0x10
0040164F   .  C3            retn

2.通过上面代码应该很清楚这步要做什么了, 没错, F7跟进 _CalcSerial(....) ,这个函数包含上面提到的所有step ,我们慢慢 分开来看:

2.1 这是初始化工作, 在这步中 ,最主要是得到了 VolumeNumber,

00401590   .  6A FF         push -0x1
00401592   .  68 381E4000   push Crack_Me.00401E38                   ;  SE 处理程序安装
00401597   .  64:A1 0000000>mov eax,dword ptr fs:[0]
0040159D   .  50            push eax
0040159E   .  64:8925 00000>mov dword ptr fs:[0],esp
004015A5   .  51            push ecx
004015A6   .  56            push esi
004015A7   .  8BF1          mov esi,ecx
004015A9   .  6A 01         push 0x1
004015AB   .  E8 6A050000   call <jmp.&MFC42.#6334>                  ;  这是MFC.UpdateData() ,在里层 间接调用GetWindowTextA
004015B0   .  8B4E 60       mov ecx,dword ptr ds:[esi+0x60]
004015B3   .  8D46 60       lea eax,dword ptr ds:[esi+0x60]
004015B6   .  8B51 F8       mov edx,dword ptr ds:[ecx-0x8]
004015B9   .  85D2          test edx,edx
004015BB   .  75 20         jnz XCrack_Me.004015DD
004015BD   .  6A 00         push 0x0
004015BF   .  6A 00         push 0x0
004015C1   .  68 38304000   push Crack_Me.00403038                   ;  ASCII "User Name is empty!"
004015C6   .  8BCE          mov ecx,esi
004015C8   .  E8 47050000   call <jmp.&MFC42.#4224>
004015CD   .  5E            pop esi
004015CE   .  8B4C24 04     mov ecx,dword ptr ss:[esp+0x4]
004015D2   .  64:890D 00000>mov dword ptr fs:[0],ecx
004015D9   .  83C4 10       add esp,0x10
004015DC   .  C3            retn
004015DD   >  8D5424 04     lea edx,dword ptr ss:[esp+0x4]
004015E1   .  50            push eax
004015E2   .  52            push edx
004015E3   .  8BCE          mov ecx,esi
004015E5   .  E8 66000000   call Crack_Me.00401650                   ;  _CalcSerial(...) 所有都计算在里面,F7跟进
004015EA   .  8B46 64       mov eax,dword ptr ds:[esi+0x64]
004015ED   .  C74424 10 000>mov dword ptr ss:[esp+0x10],0x0          ;  _CalcSerial(..) 之后马上与输入的假码比较_mbscmp
004015F5   .  50            push eax                                 ; /s2
004015F6   .  8B4424 08     mov eax,dword ptr ss:[esp+0x8]           ; |
004015FA   .  50            push eax                                 ; |s1
004015FB   .  FF15 C8214000 call dword ptr ds:[<&MSVCRT._mbscmp>]    ; \_mbscmp
00401601   .  83C4 08       add esp,0x8
00401604   .  85C0          test eax,eax
00401606   .  6A 00         push 0x0
00401608   .  6A 00         push 0x0
0040160A   .  75 0E         jnz XCrack_Me.0040161A
0040160C   .  68 28304000   push Crack_Me.00403028                   ;  ASCII "Great! pf! pf!"
00401611   .  8BCE          mov ecx,esi
00401613   .  E8 FC040000   call <jmp.&MFC42.#4224>                  ;  MFC.MessageBox("Crack Success")
00401618   .  EB 15         jmp XCrack_Me.0040162F
0040161A   >  68 20304000   push Crack_Me.00403020                   ;  ASCII "fail!"
0040161F   .  8BCE          mov ecx,esi
00401621   .  E8 EE040000   call <jmp.&MFC42.#4224>                  ;  MFC.MessageBox("Crack Failed")
00401626   .  6A 00         push 0x0
00401628   .  8BCE          mov ecx,esi
0040162A   .  E8 EB040000   call <jmp.&MFC42.#6334>
0040162F   >  8D4C24 04     lea ecx,dword ptr ss:[esp+0x4]
00401633   .  C74424 10 FFF>mov dword ptr ss:[esp+0x10],-0x1
0040163B   .  E8 C0030000   call <jmp.&MFC42.#800>
00401640   .  8B4C24 08     mov ecx,dword ptr ss:[esp+0x8]
00401644   .  5E            pop esi
00401645   .  64:890D 00000>mov dword ptr fs:[0],ecx
0040164C   .  83C4 10       add esp,0x10
0040164F   .  C3            retn
00401650  /$  6A FF         push -0x1                                ;  --------------
00401652  |.  68 6F1E4000   push Crack_Me.00401E6F                   ;  SE 处理程序安装
00401657  |.  64:A1 0000000>mov eax,dword ptr fs:[0]
0040165D  |.  50            push eax
0040165E  |.  64:8925 00000>mov dword ptr fs:[0],esp
00401665  |.  83EC 34       sub esp,0x34
00401668  |.  33C0          xor eax,eax
0040166A  |.  53            push ebx
0040166B  |.  894424 21     mov dword ptr ss:[esp+0x21],eax
0040166F  |.  55            push ebp
00401670  |.  894424 29     mov dword ptr ss:[esp+0x29],eax
00401674  |.  56            push esi                                 ;  一系列初始化 ,不必在此纠结
00401675  |.  894424 31     mov dword ptr ss:[esp+0x31],eax
00401679  |.  33DB          xor ebx,ebx
0040167B  |.  894424 35     mov dword ptr ss:[esp+0x35],eax
0040167F  |.  57            push edi
00401680  |.  8D4C24 18     lea ecx,dword ptr ss:[esp+0x18]
00401684  |.  895C24 20     mov dword ptr ss:[esp+0x20],ebx
00401688  |.  885C24 2C     mov byte ptr ss:[esp+0x2C],bl
0040168C  |.  894424 3D     mov dword ptr ss:[esp+0x3D],eax          ;  --------------
00401690  |.  E8 55040000   call <jmp.&MFC42.#540>                   ;  CString()
00401695  |.  6A 0A         push 0xA                                 ; /pFileSystemNameSize = 0000000A
00401697  |.  53            push ebx                                 ; |pFileSystemNameBuffer
00401698  |.  53            push ebx                                 ; |pFileSystemFlags
00401699  |.  8D4C24 1C     lea ecx,dword ptr ss:[esp+0x1C]          ; |
0040169D  |.  53            push ebx                                 ; |pMaxFilenameLength
0040169E  |.  51            push ecx                                 ; |pVolumeSerialNumber
0040169F  |.  6A 0C         push 0xC                                 ; |MaxVolumeNameSize = C (12.)
004016A1  |.  BE 01000000   mov esi,0x1                              ; |
004016A6  |.  53            push ebx                                 ; |VolumeNameBuffer
004016A7  |.  68 50304000   push Crack_Me.00403050                   ; |RootPathName = "C:\"
004016AC  |.  897424 6C     mov dword ptr ss:[esp+0x6C],esi          ; |
004016B0  |.  895C24 34     mov dword ptr ss:[esp+0x34],ebx          ; |
004016B4  |.  33ED          xor ebp,ebp                              ; |这个函数主要是要得到 VolumeNumber ,其余不必理会
004016B6  |.  895C24 30     mov dword ptr ss:[esp+0x30],ebx          ; |
004016BA  |.  FF15 00204000 call dword ptr ds:[<&KERNEL32.GetVolumeI>; \GetVolumeInformationA
004016C0  |.  8B4424 10     mov eax,dword ptr ss:[esp+0x10]          ;  eax = VolumeNumber
004016C4  |.  8B5424 58     mov edx,dword ptr ss:[esp+0x58]
004016C8  |.  35 26038319   xor eax,0x19830326                       ;  eax = VolumeSerialNumber xor 0x19830326
004016CD  |.  83C9 FF       or ecx,0xFFFFFFFF
004016D0  |.  8B12          mov edx,dword ptr ds:[edx]               ;  edx = szAcctount 即你输入的用户名
004016D2  |.  894424 10     mov dword ptr ss:[esp+0x10],eax
004016D6  |.  8BFA          mov edi,edx
004016D8  |.  33C0          xor eax,eax
004016DA  |.  F2:AE         repne scas byte ptr es:[edi]
004016DC  |.  F7D1          not ecx
004016DE  |.  49            dec ecx
004016DF  |.  895424 1C     mov dword ptr ss:[esp+0x1C],edx
004016E3  |.  8BF9          mov edi,ecx                              ;  edi = nAcctLen  即用户名长度

2.2 这步就是上面提到的step1了,具体见step1:

004016ED  |.  897424 58     mov dword ptr ss:[esp+0x58],esi          ;  nTmp58 = esi
004016F1  |.  0F8C AF000000 jl Crack_Me.004017A6                     ;  while (esi-1 < AcctLen)
004016F7      DD05 30254000 fld qword ptr ds:[0x402530]              ;  {
004016FD  |.  EB 04         jmp XCrack_Me.00401703
004016FF  |>  8B5424 1C     /mov edx,dword ptr ss:[esp+0x1C]
00401703  |>  8A5C32 FF      mov bl,byte ptr ds:[edx+esi-0x1]        ;     bl = szAcct[esi-1]
00401707  |.  DB4424 58     |fild dword ptr ss:[esp+0x58]
0040170B  |.  0FBEC3        |movsx eax,bl
0040170E  |.  DD5C24 24     |fstp qword ptr ss:[esp+0x24]            ;     nTmp24 = nTmp58  其实二者都等于 esi
00401712  |.  894424 58     |mov dword ptr ss:[esp+0x58],eax
00401716  |.  DB4424 58     |fild dword ptr ss:[esp+0x58]
0040171A  |.  0FBECB        |movsx ecx,bl                            ;  这个while 循环 的计算结果放在 ebx ,ebp
0040171D  |.  D9FA          |fsqrt                                   ;  nTmp14(即esp+0x14) 三个变量中 ,后面将用这3个值
0040171F  |.  0FAFCE        |imul ecx,esi
00401722  |.  DC4C24 24     |fmul qword ptr ss:[esp+0x24]
00401726  |.  DC05 28254000 |fadd qword ptr ds:[0x402528]            ;     sto = sqrt(szAcct[esi-1]) * nTmp24 + 1.0
0040172C  |.  0FAFCE        |imul ecx,esi
0040172F  |.  894C24 58     |mov dword ptr ss:[esp+0x58],ecx
00401733  |.  DB4424 58     |fild dword ptr ss:[esp+0x58]
00401737  |.  DEC9          |fmulp st(1),st                          ;     sto *= szAcct[esi-1] * esi * esi
00401739      D8C1          fadd st,st(1)                            ;     sto += st1
0040173B  |.  E8 36040000   |call <jmp.&MSVCRT._ftol>
00401740  |.  99            |cdq
00401741  |.  DDD8          |fstp st
00401743  |.  B9 A0860100   |mov ecx,0x186A0
00401748  |.  F7F9          |idiv ecx                                ;  1.计算 nTmp14
0040174A  |.  895424 14     |mov dword ptr ss:[esp+0x14],edx         ;  nTmp14 = ftol(st0) % 0x186A0
0040174E  |.  0FBED3        |movsx edx,bl
00401751  |.  895424 58     |mov dword ptr ss:[esp+0x58],edx
00401755  |.  DB4424 58     |fild dword ptr ss:[esp+0x58]
00401759  |.  DD05 20254000 |fld qword ptr ds:[0x402520]
0040175F  |.  E8 0C040000   |call <jmp.&MSVCRT._CIpow>
00401764  |.  DC4C24 24     |fmul qword ptr ss:[esp+0x24]            ;  sto = szAcct[esi-1]^2 * nTmp24   其实 nTmp == esi
00401768  |.  E8 09040000   |call <jmp.&MSVCRT._ftol>                ;  eax =_ftol(sto) + esi * ebp
0040176D  |.  DB4424 14     |fild dword ptr ss:[esp+0x14]
00401771  |.  8BCE          |mov ecx,esi
00401773  |.  0FAFCD        |imul ecx,ebp
00401776  |.  D9C0          |fld st                                  ;  st1 = sto
00401778  |.  D9FA          |fsqrt                                   ;  sto = sqrt(nTmp14)
0040177A  |.  03C1          |add eax,ecx
0040177C  |.  B9 A0860100   |mov ecx,0x186A0
00401781  |.  99            |cdq
00401782  |.  F7F9          |idiv ecx                                ;  2.计算 ebp
00401784  |.  8BEA          |mov ebp,edx                             ;  ebp = eax % 0x186A0
00401786  |.  E8 EB030000   |call <jmp.&MSVCRT._ftol>
0040178B  |.  03C5          |add eax,ebp                             ;  eax = _ftol(sto) + ebp
0040178D  |.  B9 A0860100   |mov ecx,0x186A0
00401792  |.  99            |cdq
00401793  |.  F7F9          |idiv ecx
00401795  |.  46            |inc esi
00401796  |.  3BF7          |cmp esi,edi
00401798  |.  897424 58     |mov dword ptr ss:[esp+0x58],esi         ;  3.计算 ebx             nTmp58 = esi
0040179C  |.  8BDA          |mov ebx,edx                             ;  ebx = (_ftol(st0)+ebp) % 0x186A0
0040179E  |.^ 0F8E 5BFFFFFF \jle Crack_Me.004016FF                   ;  }
004017A4  |.  DDD8          fstp st

很明确,在这步中得到了三个输出值 Ebp ,Ebx ,nTmp14(esp+0x14) , 对应的C语言代码如下:

        //step1 : _Calc nEbp ,nEbx ,nTmp14
        for (i = 1 ;i <= lstrlen(szAcct) ;i++)
        {
                st0 = (sqrt(szAcct[i-1]) * i + 1.0);
                st0 = st0 * (szAcct[i-1]*i*i) + st1;

                FtoInt = st0;
                nTmp14 = FtoInt % 0x186A0;

                FtoInt = st0 = szAcct[i-1]*szAcct[i-1]*i;
                FtoInt += (nEbp*i);
                nEbp = FtoInt % 0x186A0;

                st1 = st0 = nTmp14;
                FtoInt = sqrt(st0) + nEbp;
                nEbx = FtoInt % 0x186A0;
        }

2.3 这是step2部分的代码具体实现 ,同样,详细见step2:

004017A6  |> \33C0          xor eax,eax                              ;  while (eax < 5)   结果放于 Buf2c 中
004017A8  |>  8BD0          /mov edx,eax                             ;  {
004017AA  |.  8B4C24 14     |mov ecx,dword ptr ss:[esp+0x14]
004017AE  |.  0FAFD0        |imul edx,eax
004017B1  |.  0FAFD0        |imul edx,eax
004017B4  |.  8D540A 1F     |lea edx,dword ptr ds:[edx+ecx+0x1F]
004017B8  |.  81E2 7F000080 |and edx,0x8000007F                      ;  edx = (eax^3 + nTmp14 + 0x1F) & 0x8000007F
004017BE  |.  79 05         |jns XCrack_Me.004017C5                  ;  if (edx < 0)
004017C0  |.  4A            |dec edx                                 ;       edx-- ;edx |= 0xFFFFFF80 ;edx++
004017C1  |.  83CA 80       |or edx,0xFFFFFF80
004017C4  |.  42            |inc edx
004017C5  |>  885404 2C     |mov byte ptr ss:[esp+eax+0x2C],dl       ;  Buf2c[eax] = dl
004017C9  |.  40            |inc eax
004017CA  |.  83F8 05       |cmp eax,0x5
004017CD  |.^ 7C D9         \jl XCrack_Me.004017A8                   ;  }
004017CF  |.  B8 05000000   mov eax,0x5                              ;  while (eax < 0xA)   结果继续放于 Buf2c 中
004017D4  |>  8BC8          /mov ecx,eax                             ;  {
004017D6  |.  0FAFC8        |imul ecx,eax
004017D9  |.  0FAFC8        |imul ecx,eax
004017DC  |.  8D5429 1F     |lea edx,dword ptr ds:[ecx+ebp+0x1F]
004017E0  |.  81E2 7F000080 |and edx,0x8000007F                      ;  edx = (eax^3 + ebp + 0x1F) & 0x8000007F
004017E6  |.  79 05         |jns XCrack_Me.004017ED                  ;  if (edx < 0)
004017E8  |.  4A            |dec edx                                 ;       edx-- ;edx |= 0xFFFFFF80 ;edx++
004017E9  |.  83CA 80       |or edx,0xFFFFFF80
004017EC  |.  42            |inc edx
004017ED  |>  885404 2C     |mov byte ptr ss:[esp+eax+0x2C],dl       ;  Buf2c[eax] = dl
004017F1  |.  40            |inc eax
004017F2  |.  83F8 0A       |cmp eax,0xA
004017F5  |.^ 7C DD         \jl XCrack_Me.004017D4                   ;  }
004017F7  |.  B8 0A000000   mov eax,0xA
004017FC  |>  8BC8          /mov ecx,eax                             ;  while (eax < 0xA)   结果继续放于 Buf2c 中
004017FE  |.  0FAFC8        |imul ecx,eax                            ;  {
00401801  |.  0FAFC8        |imul ecx,eax
00401804  |.  8D5419 1F     |lea edx,dword ptr ds:[ecx+ebx+0x1F]
00401808  |.  81E2 7F000080 |and edx,0x8000007F                      ;  edx = (eax^3 + ebx + 0x1F) & 0x8000007F
0040180E  |.  79 05         |jns XCrack_Me.00401815                  ;  if (edx < 0)
00401810  |.  4A            |dec edx                                 ;       edx-- ;edx |= 0xFFFFFF80 ;edx++
00401811  |.  83CA 80       |or edx,0xFFFFFF80
00401814  |.  42            |inc edx
00401815  |>  885404 2C     |mov byte ptr ss:[esp+eax+0x2C],dl       ;  Buf2c[eax] = dl
00401819  |.  40            |inc eax
0040181A  |.  83F8 0F       |cmp eax,0xF
0040181D  |.^ 7C DD         \jl XCrack_Me.004017FC                   ;  }
0040181F  |.  B8 0F000000   mov eax,0xF
00401824  |>  8BC8          /mov ecx,eax                             ;  while (eax < 0xA)   结果继续放于 Buf2c 中
00401826  |.  8B5424 10     |mov edx,dword ptr ss:[esp+0x10]
0040182A  |.  0FAFC8        |imul ecx,eax
0040182D  |.  0FAFC8        |imul ecx,eax
00401830  |.  8D4C11 1F     |lea ecx,dword ptr ds:[ecx+edx+0x1F]
00401834  |.  81E1 7F000080 |and ecx,0x8000007F                      ;  ecx = (eax^3 + VolumeNumber + 0x1F) & 0x8000007F
0040183A  |.  79 05         |jns XCrack_Me.00401841                  ;  if (ecx < 0)
0040183C  |.  49            |dec ecx                                 ;       edx-- ;edx |= 0xFFFFFF80 ;edx++
0040183D  |.  83C9 80       |or ecx,0xFFFFFF80
00401840  |.  41            |inc ecx
00401841  |>  884C04 2C     |mov byte ptr ss:[esp+eax+0x2C],cl       ;  Buf2c[eax] = cl
00401845  |.  40            |inc eax
00401846  |.  83F8 14       |cmp eax,0x14
00401849  |.^ 7C D9         \jl XCrack_Me.00401824                   ;  }
0040184B  |.  33D2          xor edx,edx

同样 ,对应的C代码也附上:

        char szSerial[100] = {0};

        //step2: Construct string
        _CstStr(0 ,szSerial ,nTmp14);
        _CstStr(5 ,szSerial ,nEbp);
        _CstStr(10 ,szSerial ,nEbx);
        _CstStr(15 ,szSerial ,nVoSerial);

void _CstStr(
        int ndexStart,
        char* lpBuf,
        int nKey
        )
{
        int nTmp = 0;
        for (int i = 0 ;i < 0x5 ;i++ ,ndexStart++)
        {
                nTmp = ndexStart*ndexStart*ndexStart + nKey + 0x1F;
                nTmp &= 0x8000007F;
                if (nTmp < 0)
                {
                        nTmp--;
                        nTmp |= 0xFFFFFF80;
                        nTmp++;
                }
                lpBuf[ndexStart] = nTmp;
        }
}

2.4 最后就是字符转化工作了, 如step3 所述:

0040184D  |.  33C9          xor ecx,ecx                              ;  while (ecx < 0x8c)
0040184F  |>  8A4414 2C     /mov al,byte ptr ss:[esp+edx+0x2C]       ;  {
00401853  |.  3C 30         |cmp al,0x30                             ;  al = byte Buf2c[edx]
00401855  |.  7C 04         |jl XCrack_Me.0040185B
00401857  |.  3C 39         |cmp al,0x39
00401859  |.  7E 29         |jle XCrack_Me.00401884
0040185B  |>  3C 41         |cmp al,0x41                             ;  这个循环旨在将 Buf2c 中所有字节转化数字或字母
0040185D  |.  7C 04         |jl XCrack_Me.00401863
0040185F  |.  3C 5A         |cmp al,0x5A
00401861  |.  7E 21         |jle XCrack_Me.00401884
00401863  |>  3C 61         |cmp al,0x61
00401865  |.  7C 04         |jl XCrack_Me.0040186B
00401867  |.  3C 7A         |cmp al,0x7A                             ;  if (al 不是数字 或 字母)
00401869  |.  7E 19         |jle XCrack_Me.00401884                  ;  {
0040186B  |>  0FBEC0        |movsx eax,al                            ;     while (al == 数字 或 字母)
0040186E  |.  8D4408 1F     |lea eax,dword ptr ds:[eax+ecx+0x1F]     ;     {
00401872  |.  25 7F000080   |and eax,0x8000007F                      ;          eax = (al + ecx + 0x1F) & 0x8000007F
00401877  |.  79 05         |jns XCrack_Me.0040187E                  ;          Buf2c[edx] = al
00401879  |.  48            |dec eax                                 ;     }
0040187A  |.  83C8 80       |or eax,0xFFFFFF80
0040187D  |.  40            |inc eax
0040187E  |>  884414 2C     |mov byte ptr ss:[esp+edx+0x2C],al
00401882  |.^ EB CB         |jmp XCrack_Me.0040184F                  ;  }
00401884  |>  83C1 07       |add ecx,0x7
00401887  |.  42            |inc edx
00401888  |.  81F9 8C000000 |cmp ecx,0x8C
0040188E  |.^ 7C BF         \jl XCrack_Me.0040184F                   ;  }
00401890  |.  8D4C24 2C     lea ecx,dword ptr ss:[esp+0x2C]
00401894  |.  8D5424 18     lea edx,dword ptr ss:[esp+0x18]
00401898  |.  51            push ecx
00401899  |.  68 4C304000   push Crack_Me.0040304C                   ;  ASCII "%s"
0040189E  |.  52            push edx
0040189F  |.  E8 82020000   call <jmp.&MFC42.#2818>                  ;  str.Format()
004018A4  |.  83C4 0C       add esp,0xC
004018A7  |>  8B7424 54     mov esi,dword ptr ss:[esp+0x54]
004018AB  |.  8D4424 18     lea eax,dword ptr ss:[esp+0x18]
004018AF  |.  50            push eax
004018B0  |.  8BCE          mov ecx,esi
004018B2  |.  E8 69020000   call <jmp.&MFC42.#535>                   ;  Cstring(&str)
004018B7  |.  C74424 20 010>mov dword ptr ss:[esp+0x20],0x1
004018BF  |.  8D4C24 18     lea ecx,dword ptr ss:[esp+0x18]
004018C3  |.  C64424 4C 00  mov byte ptr ss:[esp+0x4C],0x0
004018C8  |.  E8 33010000   call <jmp.&MFC42.#800>                   ;  ~Cstring
004018CD  |.  8B4C24 44     mov ecx,dword ptr ss:[esp+0x44]
004018D1  |.  8BC6          mov eax,esi                              ;  eax = szSerial
004018D3  |.  5F            pop edi
004018D4  |.  5E            pop esi
004018D5  |.  5D            pop ebp
004018D6  |.  5B            pop ebx
004018D7  |.  64:890D 00000>mov dword ptr fs:[0],ecx
004018DE  |.  83C4 40       add esp,0x40
004018E1  \.  C2 0800       retn 0x8

如下便是对应的C代码咯:

        char szChar = 0;
        for (i = 0 ,j = 0 ;i < 20 ;i++ ,j += 0x7)
        {
                szChar = szSerial[i];
                while (szChar < 0x30 || (szChar>0x39 && szChar<0x41) ||
                          (szChar>0x5A && szChar < 0x61) || szChar > 0x7A)
                {
                        szChar = (szChar+j+0x1F) & 0x8000007F;
                        if (szChar < 0)
                        {
                                szChar--;
                                szChar &= 0xFFFFFF80;
                                szChar++;
                        }
                        szSerial[i] = szChar;
                }
        }

3. 经过上面的step就得到了真正的serial, 下面是完整的注册机代码:

#include <stdio.h>
#include <math.h>
#include <windows.h>

void _CstStr(
        int ndexStart,
        char* lpBuf,
        int nKey
        )
{
        int nTmp = 0;
        for (int i = 0 ;i < 0x5 ;i++ ,ndexStart++)
        {
                nTmp = ndexStart*ndexStart*ndexStart + nKey + 0x1F;
                nTmp &= 0x8000007F;
                if (nTmp < 0)
                {
                        nTmp--;
                        nTmp |= 0xFFFFFF80;
                        nTmp++;
                }
                lpBuf[ndexStart] = nTmp;
        }
}

int main()
{
        unsigned long nVoSerial = 0;
        GetVolumeInformation("C:\\" ,NULL ,0 ,&nVoSerial ,NULL ,0 ,NULL ,0);
        nVoSerial ^= 0x19830326;
       
        char szAcct[50] = {0};
        printf("Enter Account: ");
        scanf("%s" ,szAcct);

        double st0 ,st1 = 0;
        int i ,j ,FtoInt ,nTmp14 ,nEbx ,nEbp = 0;

        //step1 : _Calc nEbp ,nEbx ,nTmp14
        for (i = 1 ;i <= lstrlen(szAcct) ;i++)
        {
                st0 = (sqrt(szAcct[i-1]) * i + 1.0);
                st0 = st0 * (szAcct[i-1]*i*i) + st1;

                FtoInt = st0;
                nTmp14 = FtoInt % 0x186A0;

                FtoInt = st0 = szAcct[i-1]*szAcct[i-1]*i;
                FtoInt += (nEbp*i);
                nEbp = FtoInt % 0x186A0;

                st1 = st0 = nTmp14;
                FtoInt = sqrt(st0) + nEbp;
                nEbx = FtoInt % 0x186A0;
        }

        char szSerial[100] = {0};

        //step2: Construct string
        _CstStr(0 ,szSerial ,nTmp14);
        _CstStr(5 ,szSerial ,nEbp);
        _CstStr(10 ,szSerial ,nEbx);
        _CstStr(15 ,szSerial ,nVoSerial);

        //step3: modify if the byte of szSerial
        //not char or number
        char szChar = 0;
        for (i = 0 ,j = 0 ;i < 20 ;i++ ,j += 0x7)
        {
                szChar = szSerial[i];
                while (szChar < 0x30 || (szChar>0x39 && szChar<0x41) ||
                          (szChar>0x5A && szChar < 0x61) || szChar > 0x7A)
                {
                        szChar = (szChar+j+0x1F) & 0x8000007F;
                        if (szChar < 0)
                        {
                                szChar--;
                                szChar &= 0xFFFFFF80;
                                szChar++;
                        }
                        szSerial[i] = szChar;
                }
        }

        return printf("Serial: %s\n" ,szSerial);
}



晚安,  各位朋友们


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 6
支持
分享
最新回复 (13)
雪    币: 47147
活跃值: (20425)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
这么晚还学习,分析的不错,但得注意身体~
2013-1-19 09:30
0
雪    币: 97697
活跃值: (200799)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
3
Thanks for share.
2013-1-19 09:35
0
雪    币: 778
活跃值: (208)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
4
我还因为坛主会说,这么晚还学习,分析的不错,给你个精华吧
2013-1-19 09:47
0
雪    币: 50
活跃值: (43)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
已经是精华了...Thanks!
2013-1-19 10:06
0
雪    币: 1042
活跃值: (500)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
LZ怎么跟我头像雷同...
2013-1-19 10:28
0
雪    币: 159
活跃值: (40)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
额,看来LZ境界高啊,我无聊的时候就DOTA2去了,- -
2013-1-19 10:54
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
8
哈哈,明显LZ的注册日期比你早,你模仿他的。。
2013-1-19 10:59
0
雪    币: 260
活跃值: (249)
能力值: ( LV12,RANK:350 )
在线值:
发帖
回帖
粉丝
9
其实我是昨晚才换上它的.
2013-1-19 11:19
0
雪    币: 1042
活跃值: (500)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
=,= 这个头像我很早就用了.
2013-1-19 13:10
0
雪    币: 1643
活跃值: (101)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我真以为是你了
2013-1-19 16:15
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
什么东西有成就感,自然就玩什么东西,DOTA2让你有成就感啊,而楼主逆向算法有成就感
2013-1-21 09:23
0
雪    币: 104
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
难度系数还可以,不错,观赏下。
2013-1-23 22:54
0
雪    币: 1318
活跃值: (149)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
Thanks for share.
2013-1-24 21:08
0
游客
登录 | 注册 方可回帖
返回
//