算法分析:我也分析下,练练手,好久没有学习了。
1。bp rtcMidCharVar
2。假设注册名:12345,注册码987654321
3。一直观察内存[EBP-28]的内容,因为在后面的分析中发现要用到它。
第一个循环将注册名的ASCII码累加->X
第二个循环将注册码的ASCII码累加->Y
Z=X+Y;
[EBP-28]=X+Y,按我输入的注册名和注册码得到2DC
4。到这里时,只用到注册名和注册码的前3位进行运算。
注册名的第2位ASCII码*注册码的第2位ASCII码,->A
注册名的第1位ASCII码*注册码的第3位ASCII码,->B
注册名的第3位ASCII码*注册码的第1位ASCII码, ->C
A+B+C+Z=40C9就注册成功!
如下:
00405B95 mov eax, dword ptr [ebp-34] ; "987654321"假注册码
00405B98 mov ecx, dword ptr [ebp-64] ; "12345" 假注册名
00405B9B mov dx, word ptr [eax+2] ; "8"
00405B9F mov di, word ptr [eax+4] ; "7"
00405BA3 imul dx, word ptr [ecx+2] ; ASCII码相乘,"8"*"2",即38H*32H=AF0
00405BA8 jo 00405EF5
00405BAE imul di, word ptr [ecx] ; "1"*"7",即31H*37H=A87H
00405BB2 jo 00405EF5
00405BB8 movsx edi, di
00405BBB add edi, dword ptr [ebp-28] ; A87+2DC=D63H
00405BBE mov cx, word ptr [ecx+4]
00405BC2 movsx edx, dx
00405BC5 jo 00405EF5
00405BCB add edx, edi ; AF0H+D63H=1853H
00405BCD jo 00405EF5
00405BD3 imul cx, word ptr [eax] ; "3"*"9",即31H*39H=B5BH
00405BD7 jo 00405EF5
00405BDD movsx eax, cx
00405BE0 add edx, eax ; B58H+1853H=23AEH
00405BE2 jo 00405EF5
00405BE8 mov eax, edx
00405BEA test eax, eax
00405BEC mov dword ptr [ebp-28], eax
00405BEF je 00405D1B
00405BF5 mov ecx, dword ptr [esi]
00405BF7 cmp eax, 40C9 ; eax=23AE,关键比较:EAX要等于40C9就OK
00405BFC push esi
00405BFD jnz short 00405C7A ; 不转走就成功!
5。注册机
分析方程组{x1+x2+...=X; y1+y2+....=Y; x1*y3+x2*y2+x3*y1+X+Y=40C9}
注册名:111注册码:llldd&
注册名:111注册码:iiiddddddX
打开看雪主页
注册机有多种写法,其中之一:固定注册码前3位y1y2y3的值,如都是111,222,mmm......
运行通过,正常.
#include "stdio.h"
#include "conio.h"
#include<string.h>
main()
{ char a[10];
int x=0,y=0,z=0; /*y用于确定注册码的前3位固定值*/
long key=16585 ; /*最终值等于0x40C9就注册成功*/
int i;
int maxcode=127;
int mincode=33; /*小于33或大于126就无法显示注册码的ASCII值*/
int remainder;
int last,count; /*记录剩余注册码的个数及最后一位注册码*/
char regcode[10];
printf("enter name\n");
scanf("%s",&a);
for(i=0;i<strlen(a);i++) /*注册名的ASCII码累加*/
x=x+a[i];
printf(" %x \n",x);
try:if(mincode==maxcode)
goto quit;
for(i=0,y=0,z=0;i<3;i++) /*注册码的ASCII码累加。确定注册码的前3位,同一个值*/
y=y+mincode;
for(i=0;i<3;i++) /*在这个循环中,注册名、码只用了前3位*/
z=z+a[i]*mincode;
remainder=key-x-y-z;
printf(" %x ",remainder);
if(remainder/3<mincode||remainder/6>=maxcode) /*小于33或大于126就无法显示ASCII值*/
{ printf(" error %c ",y/3);
mincode++;/*尝试下一个ASCII码*/
goto try;
}
quit:
printf(" \nfinal:(%c) %x = %d ",mincode,remainder,remainder); /*分配剩余注册 码,除开前3位后的ASCII码值*/
/*有多种处理方法,现举例子,用100取余*/
last=remainder%100 ;/*最后一个注册码值。100是字符d的ASCII码*/
count=remainder/100; /*中间注册码的个数*/
printf("\n (%c) %d %c \n",mincode,count,last);
regcode[0]=mincode;regcode[1]=mincode;regcode[2]=mincode;
for(i=3;i<count+3;i++)
regcode[i]=100;
regcode[i]=last; regcode[i+1]='\0';
printf("\nThe code is %s",®code);
getch();
}
作者:看雪论坛.thatsme.