首页
社区
课程
招聘
[原创]一个程序有两种注册方式(简单)
发表于: 2006-4-28 19:53 8382

[原创]一个程序有两种注册方式(简单)

2006-4-28 19:53
8382

【文章标题】: 一个程序有两种注册方式
【文章作者】: rdsnow[BCG][PYG][D.4s]
【作者邮箱】: [email]rdsnow@163.com[/email]
【作者主页】: http://rdsnow.ys168.com
【作者QQ号】: 83757177
【下载地址】: 主页:http://www.wizissoft.com
【使用工具】: OllyICE
【软件介绍】: 网文×× V4.361
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【文章简介】

这个程序有两种注册方式,但是均比较简单:

1、在程序目录下建立"oem.ini"文件,输入以下内容则可变成 OEM 版

[Common]
Name=成都铁路局基层工会资料管理系统

这也算个最简单的keyfile吧!

2、使用简单算法得到符合条件的注册码注册成个人版:

注册码的形式为:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
下面的注释中给各段取名:szRegCode1-szRegCode2-szRegCode3-szRegCode4-szRegCode5
(其实中间不一定用"-",任何字符都可以通过,只是验证时没有用到这几位,所以用"-"替代了)

算法中使用到了修改了加法常数的 MD5 运算。
--------------------------------------------------------------------------------
【破解过程】

程序在输入注册码后会关闭程序,在重启后验证注册码,输入假码:
98765-56789-54321-12345-ABCDE
监视程序保存注册码,发现假码保存在文件
"C:\Documents and Settings\Administrator\Application Data\CyberArticle\CyberArticle.ini"中:
内容如下:
[UserInfo]
SerialNo=BFIXU-LMFJV-NUENK-GTZYA-PMRSW
Name=rdsnow[BCG][PYG][D.4s]
典型的ini的格式。可以通过字符串"UserInfo"查找关键点下断:

断到这里:
004F366C  |.  51            push ecx
004F366D  |.  BA 1E586600   mov edx,Cyber.0066581E             ;  ASCII "UserInfo"
004F3672  |.  8D45 FC       lea eax,dword ptr ss:[ebp-4]
004F3675  |.  E8 8A611000   call Cyber.005F9804

F8单步跟代码,return 后来到:
0040761A  |.  FF45 EC       inc dword ptr ss:[ebp-14]
0040761D  |.  E8 FEBF0E00   call Cyber.WaGetSN                 ;  读取注册码
00407622  |.  8D55 F8       lea edx,dword ptr ss:[ebp-8]
00407625  |.  52            push edx
00407626  |.  BA 350D6000   mov edx,Cyber.00600D35             ;  ASCII ""
0040762B  |.  8D45 FC       lea eax,dword ptr ss:[ebp-4]
0040762E  |.  E8 D1211F00   call Cyber.005F9804
00407633  |.  FF45 EC       inc dword ptr ss:[ebp-14]
00407636  |.  5A            pop edx
00407637  |.  59            pop ecx
00407638  |.  E8 2F241F00   call Cyber.005F9A6C
0040763D  |.  8D45 F4       lea eax,dword ptr ss:[ebp-C]
00407640  |.  8B00          mov eax,dword ptr ds:[eax]
00407642  |.  E8 ADC00E00   call Cyber.WaDownloadImageFile     ;  关键 Call
00407647  |.  50            push eax                           ;  返回值压栈
………………
(中间有许多Call,用于销毁局部变量,所以就省了)
………………
00407678  |.  59            pop ecx                            ;  弹出返回值
00407679  |.  84C9          test cl,cl
0040767B  |.  74 11         je short Cyber.0040768E            ;  若返回 1 则注册成功
0040767D  |.  33C0          xor eax,eax
0040767F  |.  8B55 D0       mov edx,dword ptr ss:[ebp-30]
00407682  |.  64:8915 00000>mov dword ptr fs:[0],edx
00407689  |.  E9 C4000000   jmp Cyber.00407752

程序有意将关键 Call 和关键 JUMP 拉远距离,不多说了,赶快进去看看吧:
004F3753  |.  50            push eax
004F3754  |.  FF45 8C       inc dword ptr ss:[ebp-74]
004F3757  |.  BA 30586600   mov edx,Cyber.00665830             ;  ASCII "oem.ini"
004F375C  |.  8D45 F0       lea eax,dword ptr ss:[ebp-10]
004F375F  |.  E8 A0601000   call Cyber.005F9804
004F3764  |.  FF45 8C       inc dword ptr ss:[ebp-74]
004F3767  |.  8D55 F0       lea edx,dword ptr ss:[ebp-10]
004F376A  |.  52            push edx
004F376B  |.  8D45 F4       lea eax,dword ptr ss:[ebp-C]
004F376E  |.  E8 ED3CF1FF   call Cyber.00407460
004F3773  |.  FF45 8C       inc dword ptr ss:[ebp-74]
004F3776  |.  E8 F9C5FFFF   call Cyber.WaGetAppPath            ;  获取程序路径
004F377B  |.  8D45 F4       lea eax,dword ptr ss:[ebp-C]
004F377E  |.  5A            pop edx
004F377F  |.  59            pop ecx
004F3780  |.  E8 E7621000   call Cyber.005F9A6C                ;  连接程序路径和"oem.ini"
004F3785  |.  8D45 EC       lea eax,dword ptr ss:[ebp-14]
004F3788  |.  50            push eax
004F3789  |.  BA 3F586600   mov edx,Cyber.0066583F             ;  ASCII "Name"
004F378E  |.  8D45 E4       lea eax,dword ptr ss:[ebp-1C]
004F3791  |.  E8 6E601000   call Cyber.005F9804
004F3796  |.  FF45 8C       inc dword ptr ss:[ebp-74]
004F3799  |.  8D55 E4       lea edx,dword ptr ss:[ebp-1C]
004F379C  |.  52            push edx
004F379D  |.  BA 38586600   mov edx,Cyber.00665838             ;  ASCII "Common"
004F37A2  |.  8D45 E8       lea eax,dword ptr ss:[ebp-18]
004F37A5  |.  E8 5A601000   call Cyber.005F9804
004F37AA  |.  FF45 8C       inc dword ptr ss:[ebp-74]          ; |
004F37AD  |.  8D55 E8       lea edx,dword ptr ss:[ebp-18]      ; |
004F37B0  |.  59            pop ecx                            ; |
004F37B1  |.  58            pop eax                            ; |
004F37B2  |.  E8 A9A4FBFF   call Cyber.WizReadStrFromConfig    ; \读取 oem.ini 内的信息
004F37B7  |.  8D45 DC       lea eax,dword ptr ss:[ebp-24]
004F37BA  |.  50            push eax
004F37BB  |.  BA 45586600   mov edx,Cyber.00665845
004F37C0  |.  8D45 D8       lea eax,dword ptr ss:[ebp-28]
004F37C3  |.  E8 3C601000   call Cyber.005F9804
004F37C8  |.  FF45 8C       inc dword ptr ss:[ebp-74]
004F37CB  |.  8D55 D8       lea edx,dword ptr ss:[ebp-28]
004F37CE  |.  58            pop eax
004F37CF  |.  E8 24631000   call Cyber.005F9AF8                ;  判断是不是 OEM 版

看下程序所在目录根本没有 oem.ini 文件,伪造一个吧,ini格式的文件是最容易伪造的了,根据上面代码文件内容应是:
[Common]
Name=XXXXXXXXXXXXXXXXXXXXXXX

oem.ini 造好后,跟进判断是不是 OEM 版的 Call:
005F9AF8  /$  55            push ebp
005F9AF9  |.  8BEC          mov ebp,esp
005F9AFB  |.  53            push ebx
005F9AF8  /$  55            push ebp
005F9AF9  |.  8BEC          mov ebp,esp
005F9AFB  |.  53            push ebx
005F9AFC  |.  8B00          mov eax,dword ptr ds:[eax]         ;  ASCII "XXXXXXXXXXXXXXXXXXXXXXX"
005F9AFE  |.  8B12          mov edx,dword ptr ds:[edx]         ;  ASCII "成都铁路局基层工会资料管理系统"
005F9B00  |.  E8 3F71FCFF   call Cyber.005C0C44                ;  这个当然是比较字符串了
005F9B05  |.  0F94C0        sete al
005F9B08  |.  83E0 01       and eax,1
005F9B0B  |.  5B            pop ebx
005F9B0C  |.  5D            pop ebp
005F9B0D  \.  C3            retn

赶快将 oem.ini 文件中的XXX换成"成都…………",重启程序,果然变成"成都铁路局基层工会(100套授权)"

不要满足,程序并没有处理我们输入的注册码,关键 Call 直接返回1了,删掉 oem.ini,继续跟:
下面同样有很多 Call 用于销毁局部变量,走了好远,来到:
004F38B6  |.  8D45 FC       lea eax,dword ptr ss:[ebp-4]
004F38B9  |.  E8 1E4EF1FF   call Cyber.004086DC                ;  取得注册码的长度
004F38BE  |.  83F8 1D       cmp eax,1D                         ;  if(strlen(szRegCode)>29) bRegLog=1
004F38C1  |.  0F9FC2        setg dl
004F38C4  |.  83E2 01       and edx,1
004F38C7  |.  8895 6FFFFFFF mov byte ptr ss:[ebp-91],dl        ;  保存 bRegLog
004F38CD  |.  66:C745 80 08>mov word ptr ss:[ebp-80],8
004F38D3  |.  66:C745 80 2C>mov word ptr ss:[ebp-80],2C
004F38D9  |.  8D55 FC       lea edx,dword ptr ss:[ebp-4]
004F38DC  |.  8D45 F8       lea eax,dword ptr ss:[ebp-8]
004F38DF  |.  E8 585F1000   call Cyber.005F983C
004F38E4  |.  FF45 8C       inc dword ptr ss:[ebp-74]
004F38E7  |.  66:C745 80 08>mov word ptr ss:[ebp-80],8
004F38ED  |.  80BD 6FFFFFFF>cmp byte ptr ss:[ebp-91],0
004F38F4  |.  0F84 9E050000 je Cyber.004F3E98                  ;  if( bRegLog==0 ) 跳下去继续验证

bRegLog=1 时,程序没有直接跳向返回 0,作者跟你开了个玩笑,大概过程是这样的:
if(szRegCode==szStr1){
    if(szRegCode==szStr2){
        if(szRegCode==szStr3){
            if(szRegCode==szStr4){
                if(szRegCode==szStr5){
                    if(szRegCode==szStr6){
                        if(szRegCode==szStr7)
                            CheckCode( );
                    }
                }
            }
        }
    }
}
return false;

如果你跟下去,你就会发现上当了:注册码怎么可能同时等于7个不同的字符串呢?即使相等,最后还是去验证注册码。
004F3E98  |> \8D45 F8       lea eax,dword ptr ss:[ebp-8]
004F3E9B  |.  E8 283CF1FF   call Cyber.00407AC8
004F3EA0  |.  50            push eax                           ; /Arg1
004F3EA1  |.  E8 6E000000   call Cyber.004F3F14                ; \CheckCode( )
004F3EA6  |.  59            pop ecx
004F3EA7  |.  84C0          test al,al
004F3EA9  |.  75 33         jnz short Cyber.004F3EDE           ;  if(CheckCode( )==true) return true;
004F3EAB  |.  33C0          xor eax,eax                        ;  return false
………………
004F3EDC  |.  EB 31         jmp short Cyber.004F3F0F           ;  JUMP TO:return false
004F3EDE  |>  B0 01         mov al,1                           ;  return true
………………
004F3F0F  |>  8BE5          mov esp,ebp
004F3F11  |.  5D            pop ebp
004F3F12  \.  C3            retn

CheckCode( )当然是关键了,继续跟进这个关键:
004F3F14  /$  55            push ebp
004F3F15  |.  8BEC          mov ebp,esp
004F3F17  |.  83C4 C4       add esp,-3C
004F3F1A  |.  C645 DE 00    mov byte ptr ss:[ebp-22],0
004F3F1E  |.  6A 05         push 5                             ; /Arg3 = 00000005
004F3F20  |.  FF75 08       push dword ptr ss:[ebp+8]          ; |Arg2
004F3F23  |.  8D45 D4       lea eax,dword ptr ss:[ebp-2C]      ; |
004F3F26  |.  50            push eax                           ; |Arg1
004F3F27  |.  E8 F00C0D00   call Cyber.005C4C1C                ; \取 szRegCode 的第1段 szRegCode1
004F3F2C  |.  83C4 0C       add esp,0C
004F3F2F  |.  6A 05         push 5                             ; /Arg3 = 00000005
004F3F31  |.  8B55 08       mov edx,dword ptr ss:[ebp+8]       ; |
004F3F34  |.  83C2 06       add edx,6                          ; |
004F3F37  |.  52            push edx                           ; |Arg2
004F3F38  |.  8D4D D9       lea ecx,dword ptr ss:[ebp-27]      ; |
004F3F3B  |.  51            push ecx                           ; |Arg1
004F3F3C  |.  E8 DB0C0D00   call Cyber.005C4C1C                ; \取 szRegCode 的第2段 szRegCode2
004F3F41  |.  83C4 0C       add esp,0C
004F3F44  |.  8D45 C4       lea eax,dword ptr ss:[ebp-3C]
004F3F47  |.  50            push eax                           ; /Arg3
004F3F48  |.  6A 0A         push 0A                            ; |Arg2 = 0000000A
004F3F4A  |.  8D55 D4       lea edx,dword ptr ss:[ebp-2C]      ; |
004F3F4D  |.  52            push edx                           ; |Arg1
004F3F4E  |.  E8 812A0000   call Cyber.004F69D4                ; \用szRegCode1 和 szRegCode2 生成 bMd5Result[16]
004F3F53  |.  83C4 0C       add esp,0C
004F3F56  |.  33C9          xor ecx,ecx
004F3F58  |.  894D FC       mov dword ptr ss:[ebp-4],ecx
004F3F5B  |>  8B45 FC       /mov eax,dword ptr ss:[ebp-4]
004F3F5E  |.  33D2          |xor edx,edx
004F3F60  |.  8A5405 C4     |mov dl,byte ptr ss:[ebp+eax-3C]   ;  bMd5Result[i]
004F3F64  |.  8955 F8       |mov dword ptr ss:[ebp-8],edx
004F3F67  |.  8B4D 08       |mov ecx,dword ptr ss:[ebp+8]
004F3F6A  |.  8B45 FC       |mov eax,dword ptr ss:[ebp-4]
004F3F6D  |.  8A5401 0C     |mov dl,byte ptr ds:[ecx+eax+C]    ;  szRegCode3[i]
004F3F71  |.  8855 F7       |mov byte ptr ss:[ebp-9],dl
004F3F74  |.  8B45 F8       |mov eax,dword ptr ss:[ebp-8]
004F3F77  |.  B9 1A000000   |mov ecx,1A                        ;  bMd5Result[i] % 26
004F3F7C  |.  33D2          |xor edx,edx
004F3F7E  |.  F7F1          |div ecx
004F3F80  |.  80C2 41       |add dl,41                         ;  result = bMd5Result[i] % 26 + 0x41
004F3F83  |.  3A55 F7       |cmp dl,byte ptr ss:[ebp-9]
004F3F86  |.  74 07         |je short Cyber.004F3F8F           ;  if (szRegCode3[i]!=result) retrun false
004F3F88  |.  33C0          |xor eax,eax
004F3F8A  |.  E9 8D000000   |jmp Cyber.004F401C
004F3F8F  |>  FF45 FC       |inc dword ptr ss:[ebp-4]
004F3F92  |.  837D FC 05    |cmp dword ptr ss:[ebp-4],5
004F3F96  |.^ 7C C3         \jl short Cyber.004F3F5B
004F3F98  |.  C745 F0 05000>mov dword ptr ss:[ebp-10],5
004F3F9F  |>  8B55 F0       /mov edx,dword ptr ss:[ebp-10]
004F3FA2  |.  33C9          |xor ecx,ecx
004F3FA4  |.  8A4C15 C4     |mov cl,byte ptr ss:[ebp+edx-3C]   ;  bMd5Result[i+5]
004F3FA8  |.  894D EC       |mov dword ptr ss:[ebp-14],ecx
004F3FAB  |.  8B45 08       |mov eax,dword ptr ss:[ebp+8]
004F3FAE  |.  8B55 F0       |mov edx,dword ptr ss:[ebp-10]
004F3FB1  |.  8A4C10 0D     |mov cl,byte ptr ds:[eax+edx+D]    ;  szRegCode4[i]
004F3FB5  |.  884D EB       |mov byte ptr ss:[ebp-15],cl
004F3FB8  |.  8B45 EC       |mov eax,dword ptr ss:[ebp-14]
004F3FBB  |.  B9 1A000000   |mov ecx,1A
004F3FC0  |.  33D2          |xor edx,edx
004F3FC2  |.  F7F1          |div ecx                           ;  bMd5Result[i+5] % 26
004F3FC4  |.  80C2 41       |add dl,41                         ;  result = bMd5Result[i] % 26 + 0x41
004F3FC7  |.  3A55 EB       |cmp dl,byte ptr ss:[ebp-15]
004F3FCA  |.  74 04         |je short Cyber.004F3FD0           ;  if (szRegCode4[0]!=result) retrun false
004F3FCC  |.  33C0          |xor eax,eax
004F3FCE  |.  EB 4C         |jmp short Cyber.004F401C
004F3FD0  |>  FF45 F0       |inc dword ptr ss:[ebp-10]
004F3FD3  |.  837D F0 0A    |cmp dword ptr ss:[ebp-10],0A
004F3FD7  |.^ 7C C6         \jl short Cyber.004F3F9F
004F3FD9  |.  C745 E4 0A000>mov dword ptr ss:[ebp-1C],0A
004F3FE0  |>  8B55 E4       /mov edx,dword ptr ss:[ebp-1C]
004F3FE3  |.  33C9          |xor ecx,ecx
004F3FE5  |.  8A4C15 C4     |mov cl,byte ptr ss:[ebp+edx-3C]   ;  bMd5Result[i+10]
004F3FE9  |.  894D E0       |mov dword ptr ss:[ebp-20],ecx
004F3FEC  |.  8B45 08       |mov eax,dword ptr ss:[ebp+8]
004F3FEF  |.  8B55 E4       |mov edx,dword ptr ss:[ebp-1C]
004F3FF2  |.  8A4C10 0E     |mov cl,byte ptr ds:[eax+edx+E]    ;  szRegCode5[i]
004F3FF6  |.  884D DF       |mov byte ptr ss:[ebp-21],cl
004F3FF9  |.  8B45 E0       |mov eax,dword ptr ss:[ebp-20]
004F3FFC  |.  B9 1A000000   |mov ecx,1A
004F4001  |.  33D2          |xor edx,edx
004F4003  |.  F7F1          |div ecx                           ;  bMd5Result[i+10] % 26
004F4005  |.  80C2 41       |add dl,41                         ;  result = bMd5Result[i+10] % 26 + 0x41
004F4008  |.  3A55 DF       |cmp dl,byte ptr ss:[ebp-21]
004F400B  |.  74 04         |je short Cyber.004F4011           ;  if (szRegCode5[0]!=result) retrun false
004F400D  |.  33C0          |xor eax,eax
004F400F  |.  EB 0B         |jmp short Cyber.004F401C
004F4011  |>  FF45 E4       |inc dword ptr ss:[ebp-1C]
004F4014  |.  837D E4 0F    |cmp dword ptr ss:[ebp-1C],0F
004F4018  |.^ 7C C6         \jl short Cyber.004F3FE0
004F401A  |.  B0 01         mov al,1
004F401C  |>  8BE5          mov esp,ebp
004F401E  |.  5D            pop ebp
004F401F  \.  C3            retn

将bMd5Result[16]中前 15 个 byte 对 26 取余,再加 0x41 就得到组成szRegCode3、4、5 的 15 个字符
程序将 szRegCode1="98765" 和 szRegCode2="56789"连接得到"9876556789"
bMd5Result[16],正是对 "9876556789" 后的字符串MD5运算的结果,跟进

004F3F4E |. E8 812A0000 call Cyber.004F69D4 ; \用szRegCode1 和 szRegCode2 生成 bMd5Result[16]

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

收藏
免费 7
支持
分享
最新回复 (9)
雪    币: 313
活跃值: (250)
能力值: ( LV9,RANK:650 )
在线值:
发帖
回帖
粉丝
2
收藏先,支持
2006-4-28 21:56
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
收藏先,学习
2006-4-28 22:27
0
雪    币: 50
活跃值: (145)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
4
算法挺有意思
2006-4-29 00:05
0
雪    币: 458
活跃值: (36)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
收下了,正在学用VC写东东。谢了。
2006-4-29 01:08
0
雪    币: 203
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
收藏学习了,谢谢
2006-4-29 03:06
0
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
不是还有网络验证吗?!
2006-4-29 09:29
0
雪    币: 333
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wan
8
真的需要耐心啊,强~~~
2006-4-29 11:12
0
雪    币: 175
活跃值: (2531)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
先收藏,学习
2006-4-29 11:15
0
雪    币: 598
活跃值: (282)
能力值: ( LV13,RANK:330 )
在线值:
发帖
回帖
粉丝
10
晕,这两天在看这个,原来已经有两种方式了。

现在它多一种方式,是用windows crypto API,对sn作RSA签名验证,算法的大概流程是用私钥对md5(SN)进行签名(当然由于私钥不知道,对于某个SN,我们也得不到这个签名),然后用公钥对md5(SN)进行签名验证,据说KG是没法写了。

可能作者现在保留了0x1d长度的注册码,以后随着升级可能要取消了吧。。
2006-7-28 17:36
0
游客
登录 | 注册 方可回帖
返回
//