首页
社区
课程
招聘
[原创]COM Explorer 注册分析.
发表于: 2008-8-9 21:34 7197

[原创]COM Explorer 注册分析.

2008-8-9 21:34
7197

目标软件 :comexp
版本 :2.0

软件地址 :http://www.4dev.com/com/index.htm  

谨以此献给和我一样的菜鸟们。高手略过。

第一次写破解文章,不足之处请多多指教,希望同大家一起进步!

comexp od加载后,下getwindowtexta 很容易 找导 关键判断的地方;

00408B90  /$  6A FF         push    -1                               ;  注册核心程序
00408B92  |.  68 88B64400   push    0044B688                         ;  SE 处理程序安装
00408B97  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
00408B9D  |.  50            push    eax
00408B9E  |.  64:8925 00000>mov     dword ptr fs:[0], esp
00408BA5  |.  83EC 08       sub     esp, 8
00408BA8  |.  57            push    edi
00408BA9  |.  BF 68994600   mov     edi, 00469968                    ;  输入的用户名
00408BAE  |.  83C9 FF       or      ecx, FFFFFFFF
00408BB1  |.  33C0          xor     eax, eax
00408BB3  |.  F2:AE         repne   scas byte ptr es:[edi]
00408BB5  |.  F7D1          not     ecx
00408BB7  |.  49            dec     ecx
00408BB8  |.  83F9 08       cmp     ecx, 8
00408BBB  |.  894C24 08     mov     dword ptr [esp+8], ecx           ;  判断用户名长度要大于8
00408BBF  |.  7D 10         jge     short 00408BD1
00408BC1  |.  5F            pop     edi
00408BC2  |.  8B4C24 08     mov     ecx, dword ptr [esp+8]
00408BC6  |.  64:890D 00000>mov     dword ptr fs:[0], ecx
00408BCD  |.  83C4 14       add     esp, 14
00408BD0  |.  C3            retn
00408BD1  |>  53            push    ebx
00408BD2  |.  55            push    ebp
00408BD3  |.  56            push    esi
00408BD4  |.  68 68994600   push    00469968                         ;  用户名
00408BD9  |.  E8 24300200   call    <__strlwr>
00408BDE  |.  83C4 04       add     esp, 4
00408BE1  |.  8D4C24 10     lea     ecx, dword ptr [esp+10]
00408BE5  |.  68 FC404600   push    004640FC                         ;  6769- ;注册码的开始部分,好像是一个常量,
00408BEA  |.  E8 52630200   call    0042EF41                         ;大概是表示软件的系列吧
00408BEF  |.  33F6          xor     esi, esi
00408BF1  |.  897424 20     mov     dword ptr [esp+20], esi
00408BF5  |>  8B2D 483E4600 /mov     ebp, dword ptr [463E48]         ;  查表串,一个固定串0123456789
00408BFB  |.  83C9 FF       |or      ecx, FFFFFFFF
00408BFE  |.  8BFD          |mov     edi, ebp
00408C00  |.  33C0          |xor     eax, eax
00408C02  |.  F2:AE         |repne   scas byte ptr es:[edi]
00408C04  |.  F7D1          |not     ecx
00408C06  |.  49            |dec     ecx                             ;  取固定串长度;可能是为了以后变化查表串准备的
00408C07  |.  8BC6          |mov     eax, esi                        ;  第几位
00408C09  |.  33D2          |xor     edx, edx
00408C0B  |.  8BFD          |mov     edi, ebp
00408C0D  |.  F7F1          |div     ecx                             ;  /串长度 如果s所取位数大于串长度转化
00408C0F  |.  8B4C24 14     |mov     ecx, dword ptr [esp+14]         ;  用户名长度
00408C13  |.  8BC6          |mov     eax, esi
00408C15  |.  0FBE1C2A      |movsx   ebx, byte ptr [edx+ebp]         ;  edx 查表
00408C19  |.  33D2          |xor     edx, edx
00408C1B  |.  F7F1          |div     ecx                             ;  /用户名长度
00408C1D  |.  0FBE82 689946>|movsx   eax, byte ptr [edx+469968]      ;  依次取用户名
00408C24  |.  8D1440        |lea     edx, dword ptr [eax+eax*2]      ;  edx= eax*3
00408C27  |.  8D0490        |lea     eax, dword ptr [eax+edx*4]      ;  eax=eax+eax*12
00408C2A  |.  8BD6          |mov     edx, esi                        ;  取得用户名asc码*13 ;第一步
00408C2C  |.  0FAFD6        |imul    edx, esi
00408C2F  |.  0FAFD6        |imul    edx, esi
00408C32  |.  0FAFD1        |imul    edx, ecx                        ;  当前位数3次方后 *用户名的总位数
00408C35  |.  03D8          |add     ebx, eax                        ;  +串中对应位置字符的asc值 ;第二步
00408C37  |.  83C9 FF       |or      ecx, FFFFFFFF
00408C3A  |.  33C0          |xor     eax, eax
00408C3C  |.  03DA          |add     ebx, edx                        ;  前两步 结果做和
00408C3E  |.  F2:AE         |repne   scas byte ptr es:[edi]
00408C40  |.  F7D1          |not     ecx
00408C42  |.  49            |dec     ecx
00408C43  |.  8BC3          |mov     eax, ebx
00408C45  |.  33D2          |xor     edx, edx
00408C47  |.  F7F1          |div     ecx                             ;  计算结果除以串长度
00408C49  |.  8D4C24 10     |lea     ecx, dword ptr [esp+10]
00408C4D  |.  8A042A        |mov     al, byte ptr [edx+ebp]          ;  余数 edx,在串中取edx位置的字符作为相应位置的注册码
00408C50  |.  50            |push    eax
00408C51  |.  E8 34660200   |call    0042F28A                        ;  ????????????
00408C56  |.  85F6          |test    esi, esi
00408C58  |.  74 1D         |je      short 00408C77
00408C5A  |.  8BC6          |mov     eax, esi
00408C5C  |.  33D2          |xor     edx, edx
00408C5E  |.  B9 03000000   |mov     ecx, 3
00408C63  |.  F7F1          |div     ecx
00408C65  |.  85D2          |test    edx, edx
00408C67  |.  75 0E         |jnz     short 00408C77
00408C69  |.  68 F8404600   |push    004640F8                        ;  -
00408C6E  |.  8D4C24 14     |lea     ecx, dword ptr [esp+14]
00408C72  |.  E8 EC650200   |call    0042F263
00408C77  |>  46            |inc     esi
00408C78  |.  83FE 09       |cmp     esi, 9
00408C7B  |.^ 0F82 74FFFFFF \jb      00408BF5
00408C81  |.  8B5424 10     mov     edx, dword ptr [esp+10]          ;  生成检查串;明码比较
00408C85      68 689A4600   push    00469A68                         ;   这里可以爆破
00408C8A  |.  52            push    edx                              
00408C8B  |.  E8 EF350100   call    <__mbscmp>
00408C90  |.  83C4 08       add     esp, 8
00408C93  |.  8D4C24 10     lea     ecx, dword ptr [esp+10]
00408C97  |.  85C0          test    eax, eax
00408C99  |.  0F94C0        sete    al
00408C9C  |.  25 FF000000   and     eax, 0FF
00408CA1  |.  C74424 20 FFF>mov     dword ptr [esp+20], -1
00408CA9  |.  8BF0          mov     esi, eax                         ;  关键返回;也可以爆破
00408CAB  |.  E8 23620200   call    0042EED3
00408CB0  |.  8B4C24 18     mov     ecx, dword ptr [esp+18]
00408CB4  |.  8BC6          mov     eax, esi
00408CB6  |.  5E            pop     esi
00408CB7  |.  5D            pop     ebp
00408CB8  |.  5B            pop     ebx
00408CB9  |.  5F            pop     edi
00408CBA  |.  64:890D 00000>mov     dword ptr fs:[0], ecx
00408CC1  |.  83C4 14       add     esp, 14
00408CC4  \.  C3            retn

       很简单的一个小程序,作者注册保护上没下什么功夫,才让我这样的菜鸟找到机会,
也从中学到了点东西,和大家共享
                 两个经常遇到的 汇编指令序列的含义:
          1)经过优化的 算术指令
00408C24  |.  8D1440        |lea     edx, dword ptr [eax+eax*2]      ;  edx= eax*3
00408C27  |.  8D0490        |lea     eax, dword ptr [eax+edx*4]      ;  eax=eax+eax*12
          以前对这样的指令总是不明白,后来经老大们提示 终于明白了,就是经过编译器优化的算术指令
          2)
                            |mov     edi, ebp
00408C00  |.  33C0          |xor     eax, eax
00408C02  |.  F2:AE         |repne   scas byte ptr es:[edi]
00408C04  |.  F7D1          |not     ecx
00408C06  |.  49            |dec     ecx

         这样的指令序列 多数是获得串的长度。

随手写了一个delphi 的 注册

procedure TForm1.Button1Click(Sender: TObject);
var
  namestr, password: string;
  conststr: string;
  i, j, k, l, m: integer;
  tempchar: char;
begin
  conststr := '0123456789';
  setlength(password, 10);
  namestr := edit1.Text;
  j := length(namestr);

  if j > 8 then
    begin
      for i := 1 to 9 do
        begin
          tempchar := namestr[i];
          k := ord(tempchar);
          l := (k * 13 + (i - 1) * (i - 1) * (i - 1) * j + ord(conststr[i])) mod 10;
          password[i] := conststr[l + 1];

        end;

      edit2.Text := '6769-' + copy(password, 1, 4) + '-' + copy(password, 5, 3) + '-' + copy(password, 8, 2);
    end
  else
    showmessage('用户名长度要大于8位');
end;


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 350
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
先坐沙发,再慢慢练习.
2008-8-9 21:57
0
雪    币: 350
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
刚跟了一遍.再谢谢一下楼主.

00408BA9  |.  BF 68994600   mov     edi, 00469968         ;用户名地址送EDI
00408BAE  |.  83C9 FF       or      ecx, FFFFFFFF                 ;设置ECX当计数器
00408BB1  |.  33C0          xor     eax, eax      
00408BB3  |.  F2:AE         repne   scas byte ptr es:[edi]   ;重复按每字节扫描用户名,直到0结尾.
00408BB5  |.  F7D1          not     ecx                                 ;得到的计数值取反
00408BB7  |.  49            dec     ecx                                  ; -1

其中这个计数器的使用方法还没太清楚,全置F,然后扫描一个就减1, 扫描到0不知道是不是也减1,
然后取反,怎么还要减1.    反正最后得到的是字符个数.
2008-8-9 23:27
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
4
不减1 你会连 00 也算进去
repne   scas byte ptr es:[edi] 等于这样:

_Next:
        if ecx==0 then _Exit
        ecx--
        edi++
        cmp byte[edi--], AL
        jne _Next
_Exit:
2008-8-9 23:35
0
雪    币: 2056
活跃值: (13)
能力值: ( LV13,RANK:250 )
在线值:
发帖
回帖
粉丝
5
感谢LZ的分析,为方便更多需要的人,我弄了个C格式的出来。如下:

//注意:用户名长度必须大于8.
BOOL GetSerailNum(char *pszUserName, char *pszSerialNum)
{
    static char szMixKey[] = "0123456789"; //KEY变换序列
    int nNameLen, nMixLen, nIndex;

    lstrcpy(pszSerialNum, "6769-"); //KEY固定开头
    pszUserName = strlwr(pszUserName);
    nNameLen = strlen(pszUserName);
    nMixLen = strlen(szMixKey);
    for (nIndex = 0; nIndex < 9; nIndex++) //只在后面再加上9位KEY
    {
        int nKey1 = szMixKey[nIndex % nMixLen];
        int nKey2 = pszUserName[nIndex % nNameLen] * 13;
        int nKey3 = (nIndex*nIndex*nIndex) * nNameLen;
        int nKey4 = nKey1 + nKey2 + nKey3;

        char szSrc[2] = { 0, 0 };
        szSrc[0] = szMixKey[nKey4 % nMixLen];
        lstrcat(pszSerialNum, szSrc);
        
        if (nIndex != 0 && (nIndex % 3) == 0)
        {
            lstrcat(pszSerialNum, "-"); //加分隔符
        }        
    }
   
    return TRUE;
}

举例:
User name: chinachina
Serial number: 6769-5151-306-06
2008-8-10 20:59
0
雪    币: 359
活跃值: (435)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
6
不错,非常感谢各位的付出,努力学习中
2008-8-10 21:10
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
7
LZ顺手写的Delphi算法还真是顺手啊,不用自己爆破了
试了一下COM Explorer,感觉还不错。就是它一旦运行,就会在dll和ocx的右键菜单中加4个打开项。我比较喜欢干净的右键菜单,于是patch了一下程序:

1. 去除DLL/OCX右键菜单中的注册等选项:
给访问注册表的API下断点,找到添加右键菜单的函数位置。
004189C0 6A FF PUSH -1
-> 直接改成ret指令,跳过函数执行(或者改jmp)。
004189C0 C2 0C00 RETN 0C


2. 去除ocx图标(运行后ocx图标也变成它的图标了,太难看了
跟踪下来,发现这样改最快:
004191A9 |. 41 INC ECX
004191AA |. 51 PUSH ECX ; /BufSize
004191AB |. 50 PUSH EAX ; |Buffer
004191AC |. 6A 01 PUSH 1 ; |ValueType = REG_SZ
004191AE |. 6A 00 PUSH 0 ; |Reserved = 0
004191B0 |. 6A 00 PUSH 0 ; |ValueName = NULL
004191B2 |. 52 PUSH EDX ; |hKey
004191B3 |. FF15 10004500 CALL DWORD PTR DS:[<&ADVAPI32.RegSetValu>; \RegSetValueExA->

改这里
004191A9 |. 6A 00 PUSH 0 ; /BufSize

这样一来,由于 BufSize = 0 导致RegSetValueExA写入失败。


用WinHex比较修改前后的文件,有如下5处改变:
189C0: 6A C2
189C1: FF 0C
189C2: 68 00
191A9: 41 6A
191AA: 51 00
2008-10-4 21:51
0
雪    币: 267
活跃值: (24)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
8
刚下载了,给传上来保存起,汉化版的包含注册机。 HB_comx20_zcn.rar
上传的附件:
2010-1-12 20:30
0
游客
登录 | 注册 方可回帖
返回
//