飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 8215|回复: 23

教菜鸟写注册机——实战篇

[复制链接]
  • TA的每日心情
    开心
    2018-2-26 08:32
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    发表于 2006-1-25 20:55:32 | 显示全部楼层 |阅读模式
    教菜鸟写注册机——实战篇

    呵呵,再灌一篇,等再过两天开学就没得灌喽

    前面我们折腾了半天都是在跟CRACKME过不去,可能有人觉得没意思了,这次咱们来个有实际意义的,呵呵,一个发布不久的软件——麻将拼图V1.04,这里来下:
    http://skycn.softreg.com.cn/product...BE-9524013EFADA
    用W32DASM反下,找串式参考“注册失败!”到下面:(分析见后)


    代码:--------------------------------------------------------------------------------
    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402E16(C)
    |
    :00402E3F 8B3D88974000            mov edi, dword ptr [00409788]
    :00402E45 B940000000              mov ecx, 00000040
    :00402E4A 33C0                    xor eax, eax
    :00402E4C 8B6C2414                mov ebp, dword ptr [esp+14]
    :00402E50 F3                      repz
    :00402E51 AB                      stosd
    :00402E52 8B3D7C974000            mov edi, dword ptr [0040977C]
    :00402E58 B940000000              mov ecx, 00000040
    :00402E5D F3                      repz
    :00402E5E AB                      stosd
    :00402E5F 8B0D88974000            mov ecx, dword ptr [00409788]

    * Reference To: USER32.SendDlgItemMessageA, Ord:020Fh
                                      |
    :00402E65 8B1D38714000            mov ebx, dword ptr [00407138]  ;注意
    :00402E6B 51                      push ecx      ;用户名存放地址[409788]
    :00402E6C 6A10                    push 00000010
    :00402E6E 6A0D                    push 0000000D      ;WM_GETTEXT

    * Possible Reference to Dialog: DialogID_0070, CONTROL_ID:03E8, ""
                                      |
    :00402E70 68E8030000              push 000003E8      ;控件ID
    :00402E75 55                      push ebp
    :00402E76 FFD3                    call ebx      ;得到用户名
    :00402E78 8B157C974000            mov edx, dword ptr [0040977C]
    :00402E7E 52                      push edx      ;注册码地址[40977C]
    :00402E7F 6A10                    push 00000010   
    :00402E81 6A0D                    push 0000000D      ;WM_GETTEXT

    * Possible Reference to Dialog: DialogID_0070, CONTROL_ID:03E9, ""
                                      |
    :00402E83 68E9030000              push 000003E9      ;控件ID
    :00402E88 55                      push ebp
    :00402E89 FFD3                    call ebx      ;得到注册码
    :00402E8B A188974000              mov eax, dword ptr [00409788]
    :00402E90 803800                  cmp byte ptr [eax], 00
    :00402E93 0F8438010000            je 00402FD1
    :00402E99 8B0D7C974000            mov ecx, dword ptr [0040977C]
    :00402E9F 803900                  cmp byte ptr [ecx], 00
    :00402EA2 0F8429010000            je 00402FD1
    :00402EA8 50                      push eax      ;压入用户名
    :00402EA9 E822FEFFFF              call 00402CD0      ;关键CALL
    :00402EAE 8B3D7C974000            mov edi, dword ptr [0040977C]  ;假码
    :00402EB4 A188974000              mov eax, dword ptr [00409788]  ;真码
    :00402EB9 83C404                  add esp, 00000004
    :00402EBC 8BF7                    mov esi, edi

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402EDC(C)
    |
    :00402EBE 8A10                    mov dl, byte ptr [eax]
    :00402EC0 8ACA                    mov cl, dl
    :00402EC2 3A16                    cmp dl, byte ptr [esi]
    :00402EC4 751C                    jne 00402EE2
    :00402EC6 84C9                    test cl, cl
    :00402EC8 7414                    je 00402EDE
    :00402ECA 8A5001                  mov dl, byte ptr [eax+01]
    :00402ECD 8ACA                    mov cl, dl
    :00402ECF 3A5601                  cmp dl, byte ptr [esi+01]
    :00402ED2 750E                    jne 00402EE2
    :00402ED4 83C002                  add eax, 00000002
    :00402ED7 83C602                  add esi, 00000002
    :00402EDA 84C9                    test cl, cl
    :00402EDC 75E0                    jne 00402EBE

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402EC8(C)
    |
    :00402EDE 33C0                    xor eax, eax
    :00402EE0 EB05                    jmp 00402EE7

    * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
    |:00402EC4(C), :00402ED2(C)
    |
    :00402EE2 1BC0                    sbb eax, eax
    :00402EE4 83D8FF                  sbb eax, FFFFFFFF

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402EE0(U)
    |
    :00402EE7 85C0                    test eax, eax
    :00402EE9 0F848D000000            je 00402F7C

    * Possible StringData Ref from Data Obj ->"52341546"    ;骗人的
                                      |
    :00402EEF BEA4904000              mov esi, 004090A4
    :00402EF4 8BC7                    mov eax, edi

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402F14(C)
    |
    :00402EF6 8A10                    mov dl, byte ptr [eax]
    :00402EF8 8ACA                    mov cl, dl
    :00402EFA 3A16                    cmp dl, byte ptr [esi]
    :00402EFC 751C                    jne 00402F1A
    :00402EFE 84C9                    test cl, cl
    :00402F00 7414                    je 00402F16
    :00402F02 8A5001                  mov dl, byte ptr [eax+01]
    :00402F05 8ACA                    mov cl, dl
    :00402F07 3A5601                  cmp dl, byte ptr [esi+01]
    :00402F0A 750E                    jne 00402F1A
    :00402F0C 83C002                  add eax, 00000002
    :00402F0F 83C602                  add esi, 00000002
    :00402F12 84C9                    test cl, cl
    :00402F14 75E0                    jne 00402EF6

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402F00(C)
    |
    :00402F16 33C0                    xor eax, eax
    :00402F18 EB05                    jmp 00402F1F

    * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
    |:00402EFC(C), :00402F0A(C)
    |
    :00402F1A 1BC0                    sbb eax, eax
    :00402F1C 83D8FF                  sbb eax, FFFFFFFF

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402F18(U)
    |
    :00402F1F 85C0                    test eax, eax
    :00402F21 7459                    je 00402F7C
    :00402F23 A180974000              mov eax, dword ptr [00409780]
    :00402F28 6A00                    push 00000000
    :00402F2A 83F803                  cmp eax, 00000003

    * Possible StringData Ref from Data Obj ->"用户注册"
                                      |
    :00402F2D 6898904000              push 00409098
    :00402F32 7D23                    jge 00402F57

    * Possible StringData Ref from Data Obj ->"注册码错误!请重新输入!"
                                      |
    :00402F34 687C904000              push 0040907C
    :00402F39 55                      push ebp

    * Reference To: USER32.MessageBoxA, Ord:01BEh
                                      |
    :00402F3A FF1534714000            Call dword ptr [00407134]
    :00402F40 A180974000              mov eax, dword ptr [00409780]
    :00402F45 5F                      pop edi
    :00402F46 40                      inc eax
    :00402F47 5E                      pop esi
    :00402F48 A380974000              mov dword ptr [00409780], eax
    :00402F4D 5D                      pop ebp
    :00402F4E B801000000              mov eax, 00000001
    :00402F53 5B                      pop ebx
    :00402F54 C21000                  ret 0010
    --------------------------------------------------------------------------------

    根据错误错息找串式参考,很容易找到上面这些。然后从这个函数的开头开始分析。

    首先值得一提的是程序取得文本框文本的方法。在这个程序中如果你下GetWindowText,GetDlgItemText这些断点都不能断到,那么它是靠的什么方法呢?我们可以在402E65这一句看到把一个API函数SendDlgItemMessage的地址给了EBX,然后下面两次调用EBX。可以想到这就是取用户名和注册码了,具体说明见下:

    LONG SendDlgItemMessage(

        HWND hDlg,  // 对话框句柄
        int nIDDlgItem,  // 控件的ID
        UINT Msg,  // 要发送的消息
        WPARAM wParam,  // 消息的第一个附加值
        LPARAM lParam   // 消息的第二个附加值
        ;

    对照上面的程序,可以发现它向ID为3E8h即1000的控件(用资源编辑工具可以发现这就是用户名的输入框)发送一个编号为0D的消息,这个消息表示什么呢?在winuser.h里有定义:

    #define WM_SETTEXT    0x000C
    #define WM_GETTEXT    0x000D
    #define WM_GETTEXTLENGTH  0x000E  

    呵呵,不出所料是WM_GETTEXT。再来看WM_GETTEXT的附加值有什么意义

    WM_GETTEXT  
    wParam = (WPARAM) cchTextMax;   // number of characters to copy 得到的字串长度
    lParam = (LPARAM) lpszText;     // address of buffer for text 字串存放的地址

    再看上面的程序就很明显了,第一个CALL的wParam为10,字串长度,lParam为[409788],这是用户名的位置,记好。第二个CALL得到假注册码放在[40977C]。

    很不错的方式,躲开了常见的API,让我想起了DELPHI。

    接下去是判断是否为空。然后把用户名PUSH进了,接着CALL。呵呵~~~~还不快跟进:

    代码:--------------------------------------------------------------------------------
    * Referenced by a CALL at Addresses:
    |:00402EA9   , :004030ED   
    |
    :00402CD0 53                      push ebx
    :00402CD1 56                      push esi
    :00402CD2 57                      push edi
    :00402CD3 8B7C2410                mov edi, dword ptr [esp+10]  ;EDI指向用户名
    :00402CD7 32DB                    xor bl, bl
    :00402CD9 8BCF                    mov ecx, edi
    :00402CDB 8A07                    mov al, byte ptr [edi]
    :00402CDD 84C0                    test al, al
    :00402CDF 740A                    je 00402CEB

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402CE9(C)
    |
    :00402CE1 02D8                    add bl, al      ;各字符累加起来
    :00402CE3 8A4101                  mov al, byte ptr [ecx+01]  ;循环取字符
    :00402CE6 41                      inc ecx      
    :00402CE7 84C0                    test al, al      ;是否取完
    :00402CE9 75F6                    jne 00402CE1      ;这是一个循环
                   
    ;注意参与计算的是AL,BL,即只取累加结果的低8位放在BL

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402CDF(C)
    |
    :00402CEB A178974000???????mov eax, dword ptr [00409778]?
    :00402CF0 33F6??????????xor esi, esi
    :00402CF2 A384974000???????mov dword ptr [00409784], eax
    :00402CF7 A174974000???????mov eax, dword ptr [00409774]
    :00402CFC 85C0??????????test eax, eax
    :00402CFE 7E2D??????????jle 00402D2D

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402D2B(C)
    |
    :00402D00 8A0C3E?????????mov cl, byte ptr [esi+edi]?;EDI指向用户名,ESI裚环变量,取字符
    :00402D03 32CB??????????xor cl, bl???;每次取的字符与上面累加结果BL异或
    :00402D05 51???????????push ecx???;把异或所得结果压入
    :00402D06 E895FFFFFF???????call 00402CA0???;关键CALL,跟进
    {
      :00402CA0 0FBE442404???????movsx eax, byte ptr [esp+04]?;EAX=上面压入的结果
      :00402CA5 030584974000??????add eax, dword ptr [00409784]?;[409784]最初是989681h
      :00402CAB 69C0697DAE42??????imul eax, 42AE7D69
      :00402CB1 0531D40000???????add eax, 0000D431??; D431h=54321
      :00402CB6 A384974000???????mov dword ptr [00409784], eax?;把结果放回,下次计算要用
      :00402CBB C1F810?????????sar eax, 10???;右移10位
      :00402CBE 83E00F?????????and eax, 0000000F??;只取最低4位(见后)
      :00402CC1 C3???????????ret
    }
    :00402D0B 83C404?????????add esp, 00000004
    :00402D0E 88043E?????????mov byte ptr [esi+edi], al?;AL是上面CALL返回的结果
    :00402D11 3C0A??????????cmp al, 0A???
    :00402D13 0FBEC0?????????movsx eax, al
    :00402D16 7D05??????????jge 00402D1D???;如果AL>=0A就跳
    :00402D18 83C030?????????add eax, 00000030??;如果AL<0A就加30h
    :00402D1B EB03??????????jmp 00402D20

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402D16(C)
    |
    :00402D1D 83C041?????????add eax, 00000041??;如果AL>=0A就加41h

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402D1B(U)
    |
    :00402D20 88043E?????????mov byte ptr [esi+edi], al?;把结果放好,这可是最后注册码哟
    :00402D23 A174974000???????mov eax, dword ptr [00409774]?;[409774]是常量8
    :00402D28 46???????????inc esi???;ESI是裚环变量
    :00402D29 3BF0??????????cmp esi, eax???
    :00402D2B 7CD3??????????jl 00402D00???;这里是一个裚环

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00402CFE(C)
    |
    :00402D2D C6043800????????mov byte ptr [eax+edi], 00
    :00402D31 5F???????????pop edi
    :00402D32 5E???????????pop esi
    :00402D33 5B???????????pop ebx
    :00402D34 C3???????????ret
    --------------------------------------------------------------------------------

    先说说关于位操作的事。上面有一个SAR,这个和SHR有一些区别,就在最高位的处理上。我也说不太明白,举个例子 11011100 shr 4 = 00001101 而 11011100 sar 4 = 11111101。不过这里右移10位,我们只取最后4位,所以高10位的变化是影响不到的,可以简单的用右移(>> )来取代。还有要说的就是AND,有一个AND 0000000F,我说是只取最低4位,可能有菜鸟不明白,其实AND只要有一个操作数为0,结果肯定为0,如果一个操作数是1,结果肯定等于另一个操作数。比方说我们如果想“屏蔽”一个八位数的第三四位,只要让它AND 11110011就行了。同理,因为0F=1111,所以AND 0000000F等于只取出了最后面的四位。

    可以发现綺过这个CALL后形成的一个新的字串,仍然放在訽用户名的位置。接下来的代码把它们取出,逐位比较,不等就跳。。。自己看看吧,练习一下,很简单的。

    最后要说的是它还设了个陷阱,后面有一个固定字串"52341546",输入这个会提示成功注册,但其实下次启动又成未注册了。

    整理下思路,先把用户名累加,把结果再和用户名的每位进行一些计算,就得到正确的注册码了。很简单的是不是?

    代码:--------------------------------------------------------------------------------
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    void main()
    {
      char name[20]=;
      char password[20]=;
      unsigned int s=0,k=0,i;

      printf("Please input your name:");
      scanf("%s",name);
      int len=strlen(name);
      for (i=0;i<len;i++)
      {
    ? s+=name;
    ? s%=0x100;??//取低8位
      }
      int LOCAL=0x989681;
      for (i=0;i<8;i++)
      {
    ? k=s^name;
    ? k=(k+LOCAL)*0x42AE7D69+0xD431;
    ? LOCAL=k;
    ? k>>=0x10;??//SAR
    ? k%=0x10;??//取最低4位
    ? if (k>=0xA) k+=0x41;
    ? else k+=0x30;
    ? password=k;
      }
      printf("Your password is : %s\n",password);
      printf("KeyGen by RoBa\nEnjoy Cracking!\n");
    }
    --------------------------------------------------------------------------------

    一个可用的用户名:RoBa
    注册码:0P6N0089

    [ 本帖最后由 wzwgp 于 2006-2-14 09:18 编辑 ]
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2025-1-13 13:43
  • 签到天数: 1992 天

    [LV.Master]伴坛终老

    发表于 2007-8-29 09:45:45 | 显示全部楼层
    学习中。。。。。。。
    沙发呀,高兴
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-11-2 15:48:06 | 显示全部楼层
    怎么没人顶的啊?
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2022-7-9 18:18
  • 签到天数: 12 天

    [LV.3]偶尔看看II

    发表于 2007-11-3 13:49:06 | 显示全部楼层
    兄弟越来越强悍了
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-12-31 10:48:54 | 显示全部楼层
    尽管看不懂 存下来在说
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-12-9 12:34
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2007-12-31 11:32:22 | 显示全部楼层
    还是看不太懂 怎么办
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-12-31 16:45:58 | 显示全部楼层
    哇,不会吧,静态分析程序?不调试也能把算法分析得如何准确,佩服。
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-12-31 20:37:34 | 显示全部楼层
    学习中,不断努力向高手冲刺.
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-1-1 00:54:39 | 显示全部楼层
    学习一下,还是很不错的
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-1-17 17:19:00 | 显示全部楼层
    学习下。。。。。。。。。。
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表