回 帖 发 新 帖 刷新版面

主题:[原创]用c语言计算一个软件的注册码

【破解作者】 shiter
【作者邮箱】 shiter_2000@163.com
【作者主页】 http://shiter.programfan.com
【使用工具】 OD WINDASM98 VS.NET
【破解平台】 WinXP
【软件名称】 echap511.exe
【下载地址】 下载
【软件简介】 这个是一个CRACKME
【软件大小】 4k
【加壳方式】 无
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】


00401041  /. 55             PUSH EBP
00401042  |. 8BEC           MOV EBP,ESP
00401044  |. 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]
00401047  |. A3 54304000    MOV DWORD PTR DS:[403054],EAX
0040104C  |. 8B45 0C        MOV EAX,DWORD PTR SS:[EBP+C]
0040104F  |. 3D 10010000    CMP EAX,110
00401054  |. 75 1A          JNZ SHORT echap511.00401070
00401056  |. 68 B80B0000    PUSH 0BB8                                ; /ControlID = BB8 (3000.)
0040105B  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
0040105E  |. E8 19010000    CALL <JMP.&USER32.GetDlgItem>            ; \GetDlgItem
00401063  |. A3 58304000    MOV DWORD PTR DS:[403058],EAX
00401068  |. 50             PUSH EAX                                 ; /hWnd
00401069  |. E8 1A010000    CALL <JMP.&USER32.SetFocus>              ; \SetFocus
0040106E  |. EB 50          JMP SHORT echap511.004010C0
00401070  |> 83F8 10        CMP EAX,10
00401073  |. 75 0C          JNZ SHORT echap511.00401081
00401075  |. 6A 00          PUSH 0                                   ; /Result = 0
00401077  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
0040107A  |. E8 F7000000    CALL <JMP.&USER32.EndDialog>             ; \EndDialog
0040107F  |. EB 3F          JMP SHORT echap511.004010C0
00401081  |> 3D 11010000    CMP EAX,111
00401086  |. 75 2F          JNZ SHORT echap511.004010B7
00401088  |. 8B45 10        MOV EAX,DWORD PTR SS:[EBP+10]
0040108B  |. 66:3D B90B     CMP AX,0BB9
0040108F  |. 75 2F          JNZ SHORT echap511.004010C0
00401091  |. C1E8 10        SHR EAX,10
00401094  |. 66:0BC0        OR AX,AX
00401097  |. 75 1C          JNZ SHORT echap511.004010B5
00401099  |. 6A 0A          PUSH 0A                                  ; /Count = A (10.)
0040109B  |. 68 44304000    PUSH echap511.00403044                   ; |Buffer = echap511.00403044  字符变量地址为00403044
004010A0  |. 68 B80B0000    PUSH 0BB8                                ; |ControlID = BB8 (3000.)
004010A5  |. FF35 54304000  PUSH DWORD PTR DS:[403054]               ; |hWnd = NULL
004010AB  |. E8 D2000000    CALL <JMP.&USER32.GetDlgItemTextA>       ; \GetDlgItemTextA
004010B0  |. E8 14000000    CALL echap511.004010C9
004010B5  |> EB 09          JMP SHORT echap511.004010C0
004010B7  |> B8 00000000    MOV EAX,0
004010BC  |. C9             LEAVE
004010BD  |. C2 1000        RETN 10
004010C0  |> B8 01000000    MOV EAX,1
004010C5  |. C9             LEAVE
004010C6  \. C2 1000        RETN 10
004010C9  /$ 56             PUSH ESI
004010CA  |. 57             PUSH EDI
004010CB  |. 51             PUSH ECX
004010CC  |. 33F6           XOR ESI,ESI
004010CE  |. 33FF           XOR EDI,EDI
004010D0  |. B9 08000000    MOV ECX,8                                    ECX=8  充当循环变量
004010D5  |. BE 44304000    MOV ESI,echap511.00403044                    ESI="shitersh"  是我自己输入的注册码ASCII=73 68 69 74 65 72 73 68
004010DA  |> 8036 32        /XOR BYTE PTR DS:[ESI],32                   /将我输入的"shitersh"的ASCII码每个字节与0x32进行异或
004010DD  |. 46             |INC ESI                                    |
004010DE  |.^E2 FA          \LOOPD SHORT echap511.004010DA              \一共循环8次,循环结果为41 5A 5B 46 57 40 41 5A
004010E0  |. BE 44304000    MOV ESI,echap511.00403044                    令ESI=41 5A 5B 46 57 40 41 5A
004010E5  |. B9 04000000    MOV ECX,4                                    ECX=4  充当循环变量
004010EA  |> 8A06           /MOV AL,BYTE PTR DS:[ESI]                   /AL和BL分别取41 5A 5B 46 57 40 41 5A中的相邻的前后两个字节
004010EC  |. 8A5E 01        |MOV BL,BYTE PTR DS:[ESI+1]                 |即 (AL=41 BL=5A)(AL=5B BL=46)...
004010EF  |. 32C3           |XOR AL,BL                                  |AL 与 BL异或
004010F1  |. 8887 4C304000  |MOV BYTE PTR DS:[EDI+40304C],AL            |将异或结果放入0040304C+EDI地址
004010F7  |. 83C6 02        |ADD ESI,2                                  |ESI地址当然要加2
004010FA  |. 47             |INC EDI                                    |EDI地址加1
004010FB  |.^E2 ED          \LOOPD SHORT echap511.004010EA              \一共循环4次,循环结果为1B 1D 17 1B
004010FD  |. BE 4C304000    MOV ESI,echap511.0040304C                    令ESI=1B 1D 17 1B
00401102  |. 8A06           MOV AL,BYTE PTR DS:[ESI]
00401104  |. 8A5E 01        MOV BL,BYTE PTR DS:[ESI+1]                   这几行的意思就是将1B 1D 17 1B按顺序将第一字节和第二字节异或
00401107  |. 32C3           XOR AL,BL                                    将第三和第四字节异或,最后再将分别异或后的两个结果进行异或
00401109  |. 8A5E 02        MOV BL,BYTE PTR DS:[ESI+2]                   
0040110C  |. 8A4E 03        MOV CL,BYTE PTR DS:[ESI+3]
0040110F  |. 32D9           XOR BL,CL
00401111  |. 32C3           XOR AL,BL                                    得到结果是AL=0xA
00401113  |. B9 08000000    MOV ECX,8                                    ECX=8  充当循环变量
00401118  |. BE 44304000    MOV ESI,echap511.00403044                    令ESI=41 5A 5B 46 57 40 41 5A
0040111D  |> 3006           /XOR BYTE PTR DS:[ESI],AL                    将41 5A 5B 46 57 40 41 5A中的每个字节与0xA
0040111F  |. 46             |INC ESI
00401120  |.^E2 FB          \LOOPD SHORT echap511.0040111D               一共循环8次 循环结果为4B 50 51 4C 5D 4A 5B 50
00401122  |. B9 08000000    MOV ECX,8                                    ECX=8  充当循环变量
00401127  |. BE 44304000    MOV ESI,echap511.00403044                    令ESI=4B 50 51 4C 5D 4A 5B 50
0040112C  |. BF 08304000    MOV EDI,echap511.00403008                    令EDI=71 18 59 1B 79 42 45 4C   这个系统内定的注册码
00401131  |> 8A06           /MOV AL,BYTE PTR DS:[ESI]                    /以下这几句的意思就是将ESI和EDI所指向的两组数据足个字节的比较
00401133  |. 3A07           |CMP AL,BYTE PTR DS:[EDI]                    |
00401135  |. 75 1D          |JNZ SHORT echap511.00401154                 |如果有一位不相同就跳转向死亡。
00401137  |. 46             |INC ESI                                     |
00401138  |. 47             |INC EDI                                     |好了到了这里就算是分析完了吧!
00401139  |.^E2 F6          \LOOPD SHORT echap511.00401131               \
0040113B  |. 6A 40          PUSH 40                                  ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040113D  |. 68 35304000    PUSH echap511.00403035                   ; |Title = "Crackme 1.0"
00401142  |. 68 10304000    PUSH echap511.00403010                   ; |Text = "Good Work Cracker"
00401147  |. FF35 54304000  PUSH DWORD PTR DS:[403054]               ; |hOwner = NULL
0040114D  |. E8 3C000000    CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
00401152  |. EB 17          JMP SHORT echap511.0040116B
00401154  |> 6A 30          PUSH 30                                  ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401156  |. 68 35304000    PUSH echap511.00403035                   ; |Title = "Crackme 1.0"
0040115B  |. 68 22304000    PUSH echap511.00403022                   ; |Text = "Bad Serial, Sorry!"
00401160  |. FF35 54304000  PUSH DWORD PTR DS:[403054]               ; |hOwner = NULL
00401166  |. E8 23000000    CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
0040116B  |> 5F             POP EDI
0040116C  |. 5E             POP ESI
0040116D  |. 59             POP ECX
0040116E  \. C3             RETN
0040116F     CC             INT3

--------------------------------------------------------------------------------

回复列表 (共9个回复)

沙发

【破解总结】


这个程序是很简单的
思路就是
假设我输入的是"shitersh"
ASCII:           73 68 69 74 65 72 73 68
与0x32异或后     41 5A 5B 46 57 40 41 5A
                  \ /   \ /   \ /   \ /
然后相临两为异或   1B    1D    17    1B
                     \   /       \   /
然后在相临异或         6           C
                          \     /
然后在异或                   A

然后将          41 5A 5B 46 57 40 41 5A  与  A 进行异或

得到            4B 50 51 4C 5D 4A 5B 50

而真正程序需要得到的是71 18 59 1B 79 42 45 4C
假设有X这个数值它的取值范围为0~0xFF
所以就需要将71 18 59 1B 79 42 45 4C先与X异或
而这个X又等于71 18 59 1B 79 42 45 4C先与X异或的结果再依照以上分析的方式进行异或后的值

X=F((71 18 59 1B 79 42 45 4C) XOR X)

用手算挺麻烦

写个程序让电脑来算算
--------------------------------------------------------------------------------
【算法注册机】


// vcstd1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "conio.h"

int _tmain(int argc, _TCHAR* argv[])
{
  int sn[]  = {0x71,0x18,0x59,0x1b,0x79,0x42,0x45,0x4c};
  int sn1[8];
  int sn2[4];
  int sn3[2];
  int keysn = 0x0;
  
  for(int i = 0x0; i <= 0xff; i++)
  {
    for(int j = 0; j < 8; j++)
      sn1[j] = sn[j] ^ i;

    for(int j = 0,k = 0; j < 8; j+=2,k++)
      sn2[k] = sn1[j] ^ sn1[j+1];
    sn3[0] = sn2[0] ^ sn2[1];
    sn3[1] = sn2[2] ^ sn2[3];
    keysn  = sn3[0] ^ sn3[1];

    if(keysn == i)
    {
      for(int j = 0; j < 8; j++)
      {
        sn1[j] = sn[j] ^ keysn;
        sn1[j] = sn1[j] ^0x32;
        printf("%c",sn1[j]);
      }
    getch();
    }
  }
  return 0;
}

--------------------------------------------------------------------------------
【爆破地址】



00401135  |. 75 1D          |JNZ SHORT echap511.00401154  
--------------------------------------------------------------------------------
【用户名、密码】


结果为Z3r0Ring 此为注册码

在对程序的编写的时候满以为我会得到好几组注册码
结果只有一组,然后就对我的程序进行调试发现
71 18 59 1B 79 42 45 4C不论与什么数字异或后,然后依照前面分析的方式进行异或后得到的那个X的值都是固定的0x19
然后还对其他的八个字节的这类进行测试,发现得到的都是固定数字

所以我就得到了一个结论
凡是8个字节的一组ASCII码依照以上方式异或,得到的结果都是一样的

如果知道了这个结论的话,那这个计算方式就简单多了...
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!

板凳

与0x32异或后     41 5A 5B 46 57 40 41 5A
                  \ /   \ /   \ /   \ /
然后相临两为异或   1B    1D    17    1B
                     \   /       \   /
然后在相临异或         6           C
                          \     /
然后在异或                   A
/////////////////////////////
上面分析得到
A=41^5A^5B^...^5A
设该校验码为ZX



/////////////////////////////
然后将          41 5A 5B 46 57 40 41 5A  与  A 进行异或
                
得到            4B 50 51 4C 5D 4A 5B 50
/////////////////////////////
设2个16进制数字串为x[8],y[8],就是说
x[8]=41 5A 5B 46 57 40 41 5A
y[8]=4B 50 51 4C 5D 4A 4B 50

得到y[]=x[]^ZX

ZY=y[0]^y[1]^...^y[7]
  =x[0]^x[1]^...^x[7]^ZX^Zx...^ZX  //共8个ZX
  =ZX

就是说你要找得那个X得值只要把
sn[]  = {0x71,0x18,0x59,0x1b,0x79,0x42,0x45,0x4c};
从头异或到尾就得到了,完全不用像你那么麻烦

不一定需要8个,只要是偶数个,ZY==ZX的,呵呵

3 楼

什么软件的这么小?

4 楼

非常感谢2楼的兄弟的指点.
让我茅塞顿开啊
我得到这个时候就没有仔细算过,只是顺着上面反汇编的思路写了了事.

5 楼

晕`~
这是汇编..

6 楼

我不会写汇编程序
只会点反汇编
哈哈

7 楼

看汇编程序让人吐血~

8 楼

因为看了要吐血,所以我们才要更加的学好C语言啊!

9 楼


我学了那么久的c了
真的看不懂!

我来回复

您尚未登录,请登录后再回复。点此登录或注册