【文章标题】: 知道算法了,可是不知道怎么写注册机 - URL Browser 1.45
【文章作者】: Suyana
【作者邮箱】: Suyasha@163.com
【作者QQ号】: 517949855(请注明来自看雪论坛)
【软件名称】: URL Browser 1.45
【使用工具】: OD,DeDe
【作者声明】: 我只是一只小菜鸟,失误之处难免,敬望诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
软件用Delphi编写,用DeDe分析。软件的注册是在"关于"里的,在DeDe中找到"输入注册码"的例程(LbButton1Click)。用DeDe反汇编,看一下这段代码,并没有计算注册码的代码。但用到了Timer。所以来到Timer1Timer的例程002DCDE0。
来到002DCDE0,看一下DeDe给出的注释,这段代码里只有:
002DCE0C E89B20FDFF call 002AEEAC
是程序自己的函数,其它的都是Delphi的函数。所以进入这个函数,来到:
002AEEAC 55 push ebp
这段代码里也只有一个自定义函数,看其它的注释也觉得不像计算注册码的代码,所以再进入这
个call,来到:
002AEF2C 55 push ebp
...
002AEFA5 8B45FC mov eax, [ebp-$04]
* Reference to: system.@LStrLen:Integer;
|
002AEFA8 E88B51F5FF call 00204138
002AEFAD 3B4350 cmp eax, [ebx+$50] ;用户名位数 > 23 跳
002AEFB0 7F19 jnle 002AEFCB ;跳到注册失败
002AEFB2 8B45FC mov eax, [ebp-$04]
* Reference to: system.@LStrLen:Integer;
|
002AEFB5 E87E51F5FF call 00204138
002AEFBA 3B4354 cmp eax, [ebx+$54] ;用户名位数 < 3 跳
002AEFBD 7C0C jl 002AEFCB ;跳到注册失败
002AEFBF 8B450C mov eax, [ebp+$0C]
* Reference to: system.@LStrLen:Integer;
|
002AEFC2 E87151F5FF call 00204138
002AEFC7 85C0 test eax, eax
002AEFC9 7504 jnz 002AEFCF
002AEFCB 33DB xor ebx, ebx
002AEFCD EB6B jmp 002AF03A
002AEFCF 8D55F4 lea edx, [ebp-$0C]
002AEFD2 8B450C mov eax, [ebp+$0C]
* Reference to: sysutils.UpperCase(AnsiString):AnsiString;
|
002AEFD5 E84AA6F5FF call 00209624 ;注册码转成大写
002AEFDA 8B55F4 mov edx, [ebp-$0C]
002AEFDD 8D450C lea eax, [ebp+$0C]
* Reference to: system.@LStrLAsg;
|
002AEFE0 E86B4FF5FF call 00203F50
002AEFE5 8D4DF0 lea ecx, [ebp-$10]
002AEFE8 8B55FC mov edx, [ebp-$04]
002AEFEB 8BC3 mov eax, ebx
* Reference to : TRegwareII._PROC_002AE9B4()
|
002AEFED E8C2F9FFFF call 002AE9B4 ;计算注册码
002AEFF2 8B45F0 mov eax, [ebp-$10] ;真注册码
002AEFF5 8B550C mov edx, [ebp+$0C] ;假注册码
* Reference to: sysutils.CompareText(AnsiString;AnsiString):Integer;
|
002AEFF8 E8BFA6F5FF call 002096BC ;比较注册码。很明
002AEFFD 85C0 test eax, eax ;显,上面的自定义
002AEFFF 7404 jz 002AF005 ;函数就是计算注册码
002AF001 33DB xor ebx, ebx
进入002AEFED E8C2F9FFFF call 002AE9B4
002AE9B4 push ebp
...
002AE9E2 mov eax, [ebp-4]
002AE9E5 call 00204138
002AE9EA cmp eax, [esi+50]
002AE9ED jg short 002AE9FC
002AE9EF mov eax, [ebp-4]
002AE9F2 call 00204138 ; 判断用户名长度,和上面的一样
002AE9F7 cmp eax, [esi+54]
002AE9FA jge short 002AEA08 ; 要跳
...
002AEAC2 call 00204138 ; system.@LStrLen:Integer;
002AEAC7 mov ebx, eax ; ebx=注册码的长度
002AEAC9 jmp short 002AEAFC
002AEACB /mov eax, [ebp-4] ; 指向用户名
002AEACE |mov al, [eax+ebx-1] ; 倒数第n个用户名的ASCII
002AEAD2 |and eax, 0FF ; 和上面的mov指令合起来就是mov eax,[eax+ebx-1]
002AEAD7 |xor edx, edx
002AEAD9 |push edx ; Arg2=0
002AEADA |push eax ; 用户名的ASCII
002AEADB |mov eax, [ebp-20] ; [ebp-20] = C2EAE0FE
002AEADE |mov edx, [ebp-1C] ; [ebp-1C] = 72B02A98
002AEAE1 |call 002073C1 ; system.@_llmod,Delphi里的函数,不知道是干什么的,eax的值转成10连接在一起后转成16进制(填充0到12位)后就是注册码了。
002AEAE6 |push edx ; /Arg2
002AEAE7 |push eax ; |Arg1
002AEAE8 |lea eax, [ebp-34] ; |
002AEAEB |call 00209A4C ; \sysutils.IntToStr(Int64):AnsiString;
002AEAF0 |mov edx, [ebp-34]
002AEAF3 |lea eax, [ebp-C]
002AEAF6 |call 00204140 ; system.@LStrCat;
002AEAFB |dec ebx
002AEAFC |mov eax, [ebp-4]
002AEAFF |call 00204138 ; system.@LStrLen:Integer;
002AEB04 |sub eax, 6
002AEB07 |cmp ebx, eax
002AEB09 |jl short 002AEB0F ; < 跳转
002AEB0B |test ebx, ebx ; 用户名倒数第n位
002AEB0D \jg short 002AEACB ; 大于0循环
002AEB0F lea edx, [ebp-8]
002AEB12 mov eax, [ebp-C]
002AEB15 call 00205FB8 ; system.@ValInt64
002AEB1A mov [ebp-18], eax ; 转成16进制,这就是注册码了
002AEB1D mov [ebp-14], edx
现在可以写注册机了,算法就是把寄存器设为:
eax=C2EAE0FE
edx=72B02A98
用户名的ascii码作第一参数(ebx),0作第二参数(ecx),进行system.@_llmod运算。
可是偶不知道system.@_llmod是干什么的。
好在这个函数不长,直接抄下来就可以了。
注册机还没有写出来,因为不懂得怎样转成16进制(11位的10进制转成16进制的喔!)
6 5Ah 6 65h 19h 2Dh
69061012545 -> 就是这个,要转成16进制,用Windows的计算器就可以转,但不知怎么写,谁能教偶?
0010145B6C41 ->注册码
------------------------------------------------------------------
文章写于2007-08-12
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课