注册机编写器说明文件
2007-01-12 20:11:38 来源:WEB开发网这个注册机编写器以前一直是我自己为写注册机而编写的,通过它只要略有汇编基础很快就能写出一个注册机。而不需要再过多的了解程序的指令算法。 整个程序体实际上只是我用汇编写的一个模板。所以大家也可以在其中自定义自己的界面和提示信息。可以用VC++或BC++等资源编辑工具自行修改key1.res资源文件,但请不要修改它们对应的ID号。
在目录目录 EXAMPLE 下有一个例子程序,主要用来举例说明这个程序的使用(我先假设自己并不太懂Win32汇编)。
通过动态调试或反汇编例子程序可以得到以下注册码的计算过程:
xxxx:00401077 CALL GetCommandLineA
xxxx:0040107C CMP BYTE PTR [EAX],22
xxxx:0040107F JNZ 401082
xxxx:00401081 INC EAX
xxxx:00401082 MOV CX,WORD PTR [EAX]
xxxx:00401085 MOV WORD PTR [0040306C],CX
xxxx:0040108C MOV WORD PTR [0040306E],5C
xxxx:00401095 PUSH 0
xxxx:00401097 PUSH 0
xxxx:00401099 PUSH 0
xxxx:0040109B PUSH 0
xxxx:0040109D PUSH DWORD 00403058
xxxx:004010A2 PUSH 0
xxxx:004010A4 PUSH 0
xxxx:004010A6 PUSH DWORD 0040306C
xxxx:004010AB CALL GetVolumeInformationA
………… …………
………… …………
xxxx:0040111E MOV EAX,1
xxxx:00401123 CPUID
xxxx:00401125 MOV ECX,DWORD PTR [00403058]
xxxx:0040112B XOR EDX,EDX
xxxx:0040112D MUL ECX
xxxx:0040112F ADD EAX,EDX
xxxx:00401131 PUSH EAX
xxxx:00401132 PUSH DWORD 0040303E ; 在这里下D 40303E可以看到数据窗口中显示为“%1X”
xxxx:00401137 PUSH DWORD 0040305C
xxxx:0040113C CALL wsprintfA
对于以上的指令并不需要过多的了解它在干什么,只要将其中的每个地址改成一个变量地址的声明,然后再原封不动的抄到注册机编写器的代码窗口中即可。
这是写好的声明:
a1 dd 0 | ; 这是一个双字的内存空间,对应于上面的403058。 ;(因为40109D处的指令是DWORD 403058,所以用dd,如果是WORD就用dw,如果是BYTE就用db) |
a2 dd 0 | ; 对应于上面的40306C |
a3 db "%1X",0 | ; 对应于上面的40303E指向的字符串 |
a4 db 20 dup (0) | ; 这是20个字节的内存空间,用来存放输出的注册码,对应于上面的40305C |
这是写好的程序代码:
CALL GetCommandLineA CMP BYTE PTR [EAX],22h | ; 后面加h表示是十六进制 |
JNZ n1 | |
INC EAX | |
n1: | |
MOV CX,WORD PTR [EAX] | |
MOV WORD PTR a2,CX | |
MOV WORD PTR a2+2,5Ch | |
PUSH 0 | |
PUSH 0 | |
PUSH 0 | |
PUSH 0 | |
LEA EAX,a1 | ; 令EAX指向a1 |
PUSH EAX | |
PUSH 0 | |
PUSH 0 | |
LEA EAX,a2 | |
PUSH EAX | ; 令EAX指向a2 |
CALL GetVolumeInformationA | ; 当然这几条语句也可以直接写成 invoke GetVolumeInformationA,addr a2,0,0,addr a1,0,0,0,0 的形式 |
MOV EAX,1 | |
CPUID | |
MOV ECX,a1 | |
XOR EDX,EDX | |
MUL ECX | |
ADD EAX,EDX | |
PUSH EAX | |
LEA EAX,a3 | ; 令EAX指向a3,也就是指向字符“%1X”。 |
PUSH EAX | |
LEA EAX,a4 | |
PUSH EAX | |
CALL wsprintfA | |
LEA EAX,a4 | ; 令EAX指向a4。因为程序最后显示的就是EAX寄存器所指向的内存地址的数据。 |
输入如:
可以看到这与上面的反汇编代码基本相同。点击编译就可以很容易的得到一个注册机了。
生成的注册机如下图所示(这只是我写的外观,你也可以自行修改):
需要说明的是因为这只是我写的一个模板,所以我也在程序中使用了几个变量。
请不要再重复声明:hCursorHandle、hInstance、hIcon、hTempEbp、hInput、hMode以免出错。
还有就是你一定要在指令结束时令EAX指向正确的注册码地址。
这种算注册码的方法不是直接从用户所输入的序列号来计算注册码的,所以并不适用于所有情况。有时我们可能需要根据用户所填入的序列号来计算注册码。考虑到这种情况所以我在程序初使时令EAX指向第一个编辑框(也就是输入序列号的窗口)收到用户输入的数据,令EBX指向第二个编辑框收到用户输入的数据,令ECX指向第三个编辑框收到用户输入的数据。你如果要对用户输入的序列号或用户名等信息进行操作,那么可以就对EAX、EBX、ECX进行操作。
下面的代码是本例根据用户所填入的序列号来计算注册码的方法:
MOV ECX,EAX | ; EAX指向用户输入的八位序列号,现在暂将它移动到ECX寄存器 |
XOR EBX,EBX | ; 以下是一段典型的将内存中的ASCII码转换为十六进制代码。 |
n1: | |
MOVZX EAX,BYTE PTR [ECX] | |
OR AL,AL | |
JZ n3 | |
CMP AL,3Ah | |
JC n2 | |
SUB AL,7 | |
n2: | |
SUB AL,30h | |
SHL EBX,4 | |
ADD EBX,EAX | |
INC ECX | |
JMP n1 | |
n3: | ; 我想以上的一段代码应该懂汇编就能写的出(如果不是很明白,那么你对我编写好的注册机用TRW调试一次就知道了)。 |
PUSH EBX | ; 最后的十六进制结果都保存在寄存器EBX中 ; 将EBX入栈,这是为了将EBX寄存器的数据保存起来。因为经过CPUID这个指令后EBX的值将被修改。然后后面就和上面一样照抄程序中的指令。以下计算注册码的方法很简短。但在实际的破解过程中,程序的算法可能会相当复杂。这就需要你通过调试或反汇编将关键的运算指令都找出来,再写进来。 |
MOV EAX,1 | |
CPUID | |
POP ECX | ; 恢复EBX的值到ECX寄存器 |
XOR EDX,EDX | |
MUL ECX | |
ADD EAX,EDX | |
PUSH EAX | |
LEA EAX,a3 | ; 令EAX指向a3,也就是指向字符“%1X”。 |
PUSH EAX | |
LEA EAX,a4 | |
PUSH EAX | |
CALL wsprintfA | |
LEA EAX,a4 | ; 令EAX指向a4。因为程序最后显示的就是EAX寄存器所指向的内存地址的数据。 |
分别是采用方案二和方案三编译后的窗口界面:
如果你不采用这种方法编写那么也可以使用程序中的另一个功能“另类注册机”。它和CrackCode2000一样,也是通过拦截程序指令并显示出注册码。 我之所以再写一个是因为以前的CrackCode2000提供的拦截选项非常有限,而且也不对宽字符串(一般出现在VB程序中用00将ASCII码分隔开)提供支持,还有一个毛病是在有些程序中会出现莫名的非法操作或无法获得注册码的情况(就好比这个例子程序)。 另外它的界面也太简陋了,只是一个消息框。所以我用汇编写了这个另类注册机非常小巧,它最多可以设置99个断点(其实可以更多,但好象没这个必要),以及在每个断点处中断多少次,如下图所示:
对于以上界面的说明:
⑴、程序名称和中断地址的设置,这个我想用不着多说,会调试的人都懂。中断次数,即指在该位置连续中断多少次。第一字节,就是将当前设置的中断位置处反汇编后的第一个字节(可通过在调试窗口中输入code on看到)。指令长度就是当前中断位置反汇编后的长度。
⑵、获取注册码的方式上需要说明一下,我是这样考虑的:寄存器方式-因为注册码可能是会放在寄存器中比较,并且可能经过十进制或十六进制的转换,所以就提供了一个寄存器方式及十进制或十六进制的选项。
⑶、内存方式-是指:如设置为EDX,即指注册码保存在EDX所指向的内存地址中(而不是寄存器里)。
⑷、偏移地址-这就是说:比如注册码是在eax+64的位置,那么现在就可以在偏移地址处填入64(如果是eax-64,就填入-64)。
⑸、地址指针-但是如果eax+64处的值是123456,而123456里的值又是654321,654321所指向的地址才是注册码所在呢,有位网友向我提出了这个问题,所以加入了一个“地址指针”(不知这种情况该怎么形容,只好用这个词了),现在你就可以根据自己的需要进行设置了。比如说如果你要从654321里取注册码,就不要选择地址指针;如果你要从123456里取注册码就选择地址指针,并将其值设置为1;如果你要从eax+64里取注册码就选择地址指针,并将其值设置为2。有了这个功能以后就可以尽量避免使用直接内存地址。因为Win2000/XP对内存的分配与Win98不同,直接指定内存地址很容易出错。
⑹、经过加壳-现在许多程序都用aspack、upx等工具进行了压缩,这个功能就是针对这类程序。
⑺、修改内存主要是对于一些需要经过修改内存中的数据后,才会出现注册窗口或才能正常注册的程序。
⑻、如果生成的注册机出现错误,你可以在制作前点击全部重置,将所有数据置零。
⑼、配置方案是让你可以对每一次的设置进行保存,免得日后不记得了,又得到处找资料。
⑽、在左边窗口处也设置保存注册码信息,是因为程序可能对注册码分次进行比较。
可以自定义在弹出的对话框中将显示的主页、邮件、窗口标题和启动提示,还可以自定义图标如下图所示:
生成的注册机有三个可选界面
需要说明的一点是这个对话框只在拦截成功的时候出现。
除此之外还有一个制作破解补丁的附加工具,制作界面如图所示。
这是完成界面。
最后一个功能就是内存补丁,用于对某些有自校验功能,或经过压缩后很难脱壳的程序。
更多精彩
赞助商链接