这种算注册码的方法不是直接从用户所输入的序列号来计算注册码的,所以并不适用于所有情况。有时我们可能需要根据用户所填入的序列号来计算注册码。考虑到这种情况所以我在程序初使时令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提供的拦截选项非常有限,而且也不对Wide格式(出现在VB程序中用00将ASCII码分隔开)提供支持,还有一个毛病是在有些程序中会出现莫名的非法操作或无法获得注册码的情况(就好比这个例子程序)。 另外它的界面也太简陋了,只是一个消息框。所以我用汇编写了这个另类注册机非常小巧,它最多可以设置100个断点(其实可以更多,但好象没这个必要),以及在每个断点处中断多少次,如下图所示:

上一页 1 2 3 4 下一页