acafeel 发表于 2007-11-10 16:12:10

翱文中华灯谜大全1.1注册算法分析

翱文中华灯谜大全1.1注册算法分析

灯谜是我国特有的一种文明高雅的文字游戏,也是民间文学花园里一枝色彩诱人、异香扑鼻的奇葩。它曲折别致,变化多端,寓意奥妙,耐人寻味。猜灯谜既可启发思维,锻炼智协,也可使人增长知识,增加学习能协,提高文学修养,享受生活情趣。翱文《中华灯谜大全》就是您开启智慧之门极好助手之一。

软件特点:
1、软件界面友好,操作简单。详尽的使用帮助,使您能够在很短的时间内就熟悉本套软件。
2、数据库容量多的惊人的灯谜、谜目丰富全面的灯谜,让您充分地享受到海量般的充实。
3、新的灯谜源源不断增加之中,您可以从软件主页下载新的灯谜,并导入到您本地的软件中。
4、您可以增加、修改、删除和管理本软件的灯谜库。当然,您可以添加自己创造的灯谜到数据库中。
5、灯谜数据库查询方便、快速,多条件过滤与排序让您从浩瀚的数据资源中马上检索出您所需要的信息。
6、您可以分类、分作者、分时间或随机出灯谜,来进行猜灯谜的智慧挑战。
7、灯谜辞海和射虎必备更是猜谜者了解灯谜知识和丰富个人内涵的极好帮手



软件在未注册的状态下,每次启动和退出时都会弹出一个NAG提示对话框;先打开注册窗口,输入注册名:aCaFeeL,输入注册码:12345678,点击[完成注册]按钮,程序提示注册失败;确定软件为delphi编写并用了tElock 0.98b1 -> tE!加壳,将其脱壳之后,用od载入,按F9键运行程序后,再打开注册窗口,再次输入上面的测试注册名和测试注册码后,下断点: BP MessageBoxA,然后点击[完成注册]按钮,此时程序被中断下来,顺着被中断的地方向上查看,发现错误信息是从 006403AD 处跳转过来的,于是来到这里后,发现如下的代码:

》》》》》》
(省略...)
00640339|.8D55 F8               lea   edx, dword ptr
0064033C|.8B83 28030000         mov   eax, dword ptr
00640342|.E8 A597E2FF             call    b.00469AEC
00640347|.8B45 F8               mov   eax, dword ptr     ;注册名 -》 eax
0064034A|.8D55 FC               lea   edx, dword ptr
0064034D|.E8 E69ADCFF             call    b.00409E38
00640352|.837D FC 00            cmp   dword ptr , 0      ;注册名是否为空
00640356|.74 1F                   je      short b.00640377          ;为空,跳走
00640358|.8D55 F0               lea   edx, dword ptr
0064035B|.8B83 2C030000         mov   eax, dword ptr
00640361|.E8 8697E2FF             call    b.00469AEC
00640366|.8B45 F0               mov   eax, dword ptr    ;注册码 -》 eax
00640369|.8D55 F4               lea   edx, dword ptr
0064036C|.E8 C79ADCFF             call    b.00409E38
00640371|.837D F4 00            cmp   dword ptr , 0      ;注册码是否为空
00640375      75 1E                   jnz   short b.00640395          ;不为空,跳走
00640377|>6A 10                   push    10
00640379|.68 58046400             push    b.00640458                ;ASCII "Fail"
0064037E|.68 60046400             push    b.00640460
00640383|.8BC3                  mov   eax, ebx
00640385|.E8 E2FFE2FF             call    b.0047036C
0064038A|.50                      push    eax                     ; |hOwner
0064038B|.E8 BC82DCFF             call    b.0040864C                ; \MessageBoxA
00640390|.E9 83000000             jmp   b.00640418
00640395|>8D55 EC               lea   edx, dword ptr
00640398|.8B83 2C030000         mov   eax, dword ptr
0064039E|.E8 4997E2FF             call    b.00469AEC
006403A3|.8B45 EC               mov   eax, dword ptr    ;注册码
006403A6|.E8 B5A0EAFF             call    b.004EA460                ;决定al的值,F7进入
006403AB|.84C0                  test    al, al
006403AD|.74 50                   je      short b.006403FF          ;关键跳转,不跳成功
006403AF|.8D55 E8               lea   edx, dword ptr
(省略...)
》》》》》》



从上面可知道,要分析算法,需要进入 006403A6 地址的:

006403A6|.E8 B5A0EAFF             call    b.004EA460

在这里再用F2键下断,用OD重新载入程序后,F9键运行,再次重复上面的步骤,便断在了这里,按F7建进入该子程序后:

》》》》》》
004EA460   $55                      push    ebp                     ;注册算法开始
004EA461   .8BEC                  mov   ebp, esp
004EA463   .33C9                  xor   ecx, ecx
004EA465   .51                      push    ecx
004EA466   .51                      push    ecx
004EA467   .51                      push    ecx
004EA468   .51                      push    ecx
004EA469   .51                      push    ecx
004EA46A   .51                      push    ecx
004EA46B   .51                      push    ecx
004EA46C   .53                      push    ebx
004EA46D   .56                      push    esi
004EA46E   .57                      push    edi
004EA46F   .8945 FC               mov   dword ptr , eax
004EA472   .8B45 FC               mov   eax, dword ptr
004EA475   .E8 6AB2F1FF             call    b.004056E4
004EA47A   .33C0                  xor   eax, eax
004EA47C   .55                      push    ebp
004EA47D   .68 AFA54E00             push    b.004EA5AF
004EA482   .64:FF30               push    dword ptr fs:
004EA485   .64:8920               mov   dword ptr fs:, esp
004EA488   .B3 01                   mov   bl, 1
004EA48A   .33D2                  xor   edx, edx
004EA48C   .55                      push    ebp
004EA48D   .68 88A54E00             push    b.004EA588
004EA492   .64:FF32               push    dword ptr fs:
004EA495   .64:8922               mov   dword ptr fs:, esp
004EA498   .8B45 FC               mov   eax, dword ptr
004EA49B   .E8 54B0F1FF             call    b.004054F4                ;得到注册码长度 -》 eax
004EA4A0   .83F8 1E               cmp   eax, 1E                   ;与 $1E(30) 比较
004EA4A3   .74 02                   je      short b.004EA4A7          ;相等,跳走
004EA4A5   .33DB                  xor   ebx, ebx
004EA4A7   >8D45 F8               lea   eax, dword ptr
004EA4AA   .50                      push    eax
004EA4AB   .B9 01000000             mov   ecx, 1                  ;ecx := 1;
004EA4B0   .BA 04000000             mov   edx, 4                  ;edx := 4;
004EA4B5   .8B45 FC               mov   eax, dword ptr     ;eax := 注册码;
004EA4B8   .E8 97B2F1FF             call    b.00405754                ;//取注册码第4个字符
004EA4BD   .8B45 F8               mov   eax, dword ptr     ;-》 eax
004EA4C0   .BA C8A54E00             mov   edx, b.004EA5C8         ;内存窗口中 Ctrl+G 键,输入地址004EA5C8,定位得到'1'字符
004EA4C5   .E8 76B1F1FF             call    b.00405640                ;//比较
004EA4CA      75 4A                   jnz   short b.004EA516          ;不相等,跳走
004EA4CC   .8D45 F4               lea   eax, dword ptr
004EA4CF   .50                      push    eax
004EA4D0   .B9 01000000             mov   ecx, 1                  ;ecx := 1;
004EA4D5   .BA 0C000000             mov   edx, 0C                   ;edx := 12;
004EA4DA   .8B45 FC               mov   eax, dword ptr     ;eax := 注册码;
004EA4DD   .E8 72B2F1FF             call    b.00405754                ;//取注册码第12个字符
004EA4E2   .8B45 F4               mov   eax, dword ptr     ;-》 eax
004EA4E5   .BA D4A54E00             mov   edx, b.004EA5D4         ;内存窗口中 Ctrl+G 键,输入地址004EA5D4,定位得到'L'字符
004EA4EA   .E8 51B1F1FF             call    b.00405640                ;//比较
004EA4EF   .75 25                   jnz   short b.004EA516          ;不相等,跳走
004EA4F1   .8D45 F0               lea   eax, dword ptr
004EA4F4   .50                      push    eax
004EA4F5   .B9 01000000             mov   ecx, 1                  ;ecx := 1;
004EA4FA   .BA 14000000             mov   edx, 14                   ;edx := 20;
004EA4FF   .8B45 FC               mov   eax, dword ptr     ;eax := 注册码;
004EA502   .E8 4DB2F1FF             call    b.00405754                ;//取注册码第20个字符
004EA507   .8B45 F0               mov   eax, dword ptr    ;-》 eax
004EA50A   .BA E0A54E00             mov   edx, b.004EA5E0         ;内存窗口中 Ctrl+G 键,输入地址004EA5E0,定位得到'R'字符
004EA50F   .E8 2CB1F1FF             call    b.00405640                ;//比较
004EA514   .74 02                   je      short b.004EA518          ;相等,跳走
004EA516   >33DB                  xor   ebx, ebx
004EA518   >8D45 EC               lea   eax, dword ptr
004EA51B   .50                      push    eax
004EA51C   .B9 01000000             mov   ecx, 1                  ;ecx := 1;
004EA521   .BA 0B000000             mov   edx, 0B                   ;edx := 11;
004EA526   .8B45 FC               mov   eax, dword ptr     ;eax := 注册码;
004EA529   .E8 26B2F1FF             call    b.00405754                ;//取注册码第11个字符
004EA52E   .8B45 EC               mov   eax, dword ptr    ;-》eax
004EA531   .E8 62FEF1FF             call    b.0040A398                ;//将该数字送到eax
004EA536   .8BF0                  mov   esi, eax                  ;esi := eax;
004EA538   .8D45 E8               lea   eax, dword ptr
004EA53B   .50                      push    eax
004EA53C   .B9 01000000             mov   ecx, 1                  ;ecx := 1;
004EA541   .BA 0E000000             mov   edx, 0E                   ;edx := 14;
004EA546   .8B45 FC               mov   eax, dword ptr     ;eax := 注册码;
004EA549   .E8 06B2F1FF             call    b.00405754                ;//取注册码第14个字符
004EA54E   .8B45 E8               mov   eax, dword ptr    ;-》eax
004EA551   .E8 42FEF1FF             call    b.0040A398                ;//将该数字送到eax
004EA556   .8BF8                  mov   edi, eax                  ;edi := eax;
004EA558   .8D45 E4               lea   eax, dword ptr
004EA55B   .50                      push    eax
004EA55C   .B9 01000000             mov   ecx, 1                  ;ecx := 1;
004EA561   .BA 16000000             mov   edx, 16                   ;edx := 22;
004EA566   .8B45 FC               mov   eax, dword ptr     ;eax := 注册码;
004EA569   .E8 E6B1F1FF             call    b.00405754                ;//取注册码第22个字符
004EA56E   .8B45 E4               mov   eax, dword ptr    ;-》eax
004EA571   .E8 22FEF1FF             call    b.0040A398                ;//将该数字送到eax
004EA576   .03FE                  add   edi, esi                  ;edi := edi + esi;
004EA578   .3BC7                  cmp   eax, edi                  ;edi 与 eax 比较
004EA57A   .74 02                   je      short b.004EA57E          ;相等,跳
004EA57C   .33DB                  xor   ebx, ebx
004EA57E   >33C0                  xor   eax, eax                  ;来到这里,便飞向了~~
004EA580   .5A                      pop   edx
004EA581   .59                      pop   ecx
004EA582   .59                      pop   ecx
004EA583   .64:8910               mov   dword ptr fs:, edx
004EA586   .EB 0C                   jmp   short b.004EA594
(省略...)
》》》》》》



另:
附上call    b.00405754中的代码,看看:

》》》》》》
00405754/$53                      push    ebx
00405755|.85C0                  test    eax, eax                  ;注册码是否为空
00405757|.74 2D                   je      short b.00405786          ;为空,跳走
00405759|.8B58 FC               mov   ebx, dword ptr     ;ebx := 注册码长度;
0040575C|.85DB                  test    ebx, ebx                  ;注册码长度是否为0
0040575E|.74 26                   je      short b.00405786          ;为0,跳走
00405760|.4A                      dec   edx                     ;//edx := edx - 1; //初始值前面已经确定
00405761|.7C 1B                   jl      short b.0040577E          ;为0,跳走
00405763|.39DA                  cmp   edx, ebx
00405765|.7D 1F                   jge   short b.00405786
00405767|>29D3                  sub   ebx, edx                  ;//ebx := ebx - edx;
00405769|.85C9                  test    ecx, ecx                  ;ecx := 1;
0040576B|.7C 19                   jl      short b.00405786          ;为0,跳走
0040576D|.39D9                  cmp   ecx, ebx                  ;ebx 与 1 比较
0040576F|.7F 11                   jg      short b.00405782          ;小于,跳走
00405771|>01C2                  add   edx, eax                  ;//edx := edx + eax;
00405773|.8B4424 08               mov   eax, dword ptr
00405777|.E8 98FBFFFF             call    b.00405314
0040577C|.EB 11                   jmp   short b.0040578F
0040577E|>31D2                  xor   edx, edx
00405780|.^ EB E5                   jmp   short b.00405767
00405782|>89D9                  mov   ecx, ebx
00405784|.^ EB EB                   jmp   short b.00405771
00405786|>8B4424 08               mov   eax, dword ptr
0040578A|.E8 95FAFFFF             call    b.00405224
0040578F|>5B                      pop   ebx
00405790\.C2 0400               retn    4
》》》》》》



兼:
附上call    b.0040A398中的代码,看看:

》》》》》》
0040A398/$53                      push    ebx
0040A399|.56                      push    esi
0040A39A|.83C4 F4               add   esp, -0C
0040A39D|.8BD8                  mov   ebx, eax
0040A39F|.8BD4                  mov   edx, esp
0040A3A1|.8BC3                  mov   eax, ebx
0040A3A3|.E8 6899FFFF             call    b.00403D10                ;F7进入
0040A3A8|.8BF0                  mov   esi, eax
0040A3AA|.833C24 00               cmp   dword ptr , 0
0040A3AE|.74 19                   je      short b.0040A3C9          ;相等,便跳走
0040A3B0|.895C24 04               mov   dword ptr , ebx
0040A3B4|.C64424 08 0B            mov   byte ptr , 0B
0040A3B9|.8D5424 04               lea   edx, dword ptr
0040A3BD|.A1 F09E6400             mov   eax, dword ptr
0040A3C2|.33C9                  xor   ecx, ecx
0040A3C4|.E8 3FF7FFFF             call    b.00409B08                ;抛出异常
0040A3C9|>8BC6                  mov   eax, esi
0040A3CB|.83C4 0C               add   esp, 0C
0040A3CE|.5E                      pop   esi
0040A3CF|.5B                      pop   ebx
0040A3D0\.C3                      retn
》》》》》》



再:
附上call    b.00403D10中的代码,看看:

》》》》》》
00403D10/$53                      push    ebx
00403D11|.56                      push    esi
00403D12|.57                      push    edi
00403D13|.89C6                  mov   esi, eax
00403D15|.50                      push    eax
00403D16|.85C0                  test    eax, eax
00403D18|.74 6C                   je      short b.00403D86
00403D1A|.31C0                  xor   eax, eax                  ;eax := 0;
00403D1C|.31DB                  xor   ebx, ebx                  ;ebx := 0;
00403D1E|.BF CCCCCC0C             mov   edi, 0CCCCCCC             ;edi := $0CCCCCCC;
00403D23|>8A1E                  /mov   bl, byte ptr        ;bl := 注册码第11、14、22位的字符码;
00403D25|.46                      |inc   esi                      ;加1
00403D26|.80FB 20               |cmp   bl, 20                   ;与空格符号比较
00403D29|.^ 74 F8                   \je      short b.00403D23         ;相等,循环
00403D2B|.B5 00                   mov   ch, 0                     ;//ch := 0;
00403D2D|.80FB 2D               cmp   bl, 2D                  ;与'-'符号比较
00403D30|.74 62                   je      short b.00403D94          ;相等,跳走
00403D32|.80FB 2B               cmp   bl, 2B                  ;与'+'符号比较
00403D35|.74 5F                   je      short b.00403D96          ;相等,跳走
00403D37|>80FB 24               cmp   bl, 24                  ;与'$'符号比较; Switch (cases 0..78)
00403D3A|.74 5F                   je      short b.00403D9B          ;相等,跳走
00403D3C|.80FB 78               cmp   bl, 78                  ;与'x'字符比较
00403D3F|.74 5A                   je      short b.00403D9B          ;相等,跳走
00403D41|.80FB 58               cmp   bl, 58                  ;与'X'字符比较
00403D44|.74 55                   je      short b.00403D9B          ;相等,跳走
00403D46|.80FB 30               cmp   bl, 30                  ;与'0'字符比较
00403D49|.75 13                   jnz   short b.00403D5E          ;不相等,跳走
00403D4B|.8A1E                  mov   bl, byte ptr       ;Case 30 ('0') of switch 00403D37
00403D4D|.46                      inc   esi
00403D4E|.80FB 78               cmp   bl, 78                  ;与'x'字符比较
00403D51|.74 48                   je      short b.00403D9B          ;相等,跳走
00403D53|.80FB 58               cmp   bl, 58                  ;与'X'字符比较
00403D56|.74 43                   je      short b.00403D9B          ;相等,跳走
00403D58|.84DB                  test    bl, bl                  ;是否为空
00403D5A|.74 20                   je      short b.00403D7C          ;为空,跳走
00403D5C|.EB 04                   jmp   short b.00403D62
00403D5E|>84DB                  test    bl, bl                  ;是否为空
00403D60|.74 2D                   je      short b.00403D8F          ;为空,跳走
00403D62|>80EB 30               /sub   bl, 30                   ;Default case of switch 00403D37
00403D65|.80FB 09               |cmp   bl, 9
00403D68|.77 25                   |ja      short b.00403D8F         ;大于,跳走
00403D6A|.39F8                  |cmp   eax, edi
00403D6C|.77 21                   |ja      short b.00403D8F         ;大于,跳走
00403D6E|.8D0480                  |lea   eax, dword ptr [eax+eax*>
00403D71|.01C0                  |add   eax, eax
00403D73|.01D8                  |add   eax, ebx
00403D75|.8A1E                  |mov   bl, byte ptr
00403D77|.46                      |inc   esi
00403D78|.84DB                  |test    bl, bl
00403D7A|.^ 75 E6                   \jnz   short b.00403D62         ;不相等,循环
00403D7C|>FECD                  dec   ch                        ;减1
00403D7E|.74 09                   je      short b.00403D89          ;为0,跳走
00403D80|.85C0                  test    eax, eax
00403D82|.7D 54                   jge   short b.00403DD8          ;为0,跳走
00403D84|.EB 09                   jmp   short b.00403D8F
00403D86|>46                      inc   esi
00403D87|.EB 06                   jmp   short b.00403D8F
00403D89|>F7D8                  neg   eax
00403D8B|.7E 4B                   jle   short b.00403DD8
00403D8D|.78 49                   js      short b.00403DD8
00403D8F|>5B                      pop   ebx                     ;Default case of switch 00403DAF
00403D90|.29DE                  sub   esi, ebx
00403D92|.EB 47                   jmp   short b.00403DDB
00403D94|>FEC5                  inc   ch
00403D96|>8A1E                  mov   bl, byte ptr
00403D98|.46                      inc   esi
00403D99|.^ EB 9C                   jmp   short b.00403D37
00403D9B|>BF FFFFFF0F             mov   edi, 0FFFFFFF             ;Cases 24 ('$'),58 ('X'),78 ('x') of switch 00403D37
00403DA0|.8A1E                  mov   bl, byte ptr
00403DA2|.46                      inc   esi
00403DA3|.84DB                  test    bl, bl
00403DA5|.^ 74 DF                   je      short b.00403D86
00403DA7|>80FB 61               /cmp   bl, 61
00403DAA|.72 03                   |jb      short b.00403DAF
00403DAC|.80EB 20               |sub   bl, 20
00403DAF|>80EB 30               |sub   bl, 30                   ;Switch (cases 30..46)
00403DB2|.80FB 09               |cmp   bl, 9
00403DB5|.76 0B                   |jbe   short b.00403DC2
00403DB7|.80EB 11               |sub   bl, 11
00403DBA|.80FB 05               |cmp   bl, 5
00403DBD|.^ 77 D0                   |ja      short b.00403D8F
00403DBF|.80C3 0A               |add   bl, 0A                   ;Cases 41 ('A'),42 ('B'),43 ('C'),44 ('D'),45 ('E'),46 ('F') of switch 00403DAF
00403DC2|>39F8                  |cmp   eax, edi               ;Cases 30 ('0'),31 ('1'),32 ('2'),33 ('3'),34 ('4'),35 ('5'),36 ('6'),37 ('7'),38 ('8'),39 ('9') of switch 00403DAF
00403DC4|.^ 77 C9                   |ja      short b.00403D8F
00403DC6|.C1E0 04               |shl   eax, 4
00403DC9|.01D8                  |add   eax, ebx
00403DCB|.8A1E                  |mov   bl, byte ptr
00403DCD|.46                      |inc   esi
00403DCE|.84DB                  |test    bl, bl
00403DD0|.^ 75 D5                   \jnz   short b.00403DA7
00403DD2|.FECD                  dec   ch
00403DD4|.75 02                   jnz   short b.00403DD8
00403DD6|.F7D8                  neg   eax
00403DD8|>59                      pop   ecx
00403DD9|.31F6                  xor   esi, esi
00403DDB|>8932                  mov   dword ptr , esi
00403DDD|.5F                      pop   edi
00403DDE|.5E                      pop   esi
00403DDF|.5B                      pop   ebx
00403DE0\.C3                      retn
》》》》》》



通过上面的分析,我们知道了其注册算法的方式为:

注册码的长度是由30个字符组成的;
第 4个字符必须为:1 ;
第12个字符必须为:L ;
第20个字符必须为:R ;
注册码的第11位、第14位、第22位的字符必须是数字,并且要满足如下的公式:
注册码的第11位数字 + 注册码的第14位数字 = 注册码的第22位数字 ;
当上面的要求全部满足时,便注册成功了!

注册成功后,注册信息保存在了:
中!

放上一组可用的Key:
注册名:aCaFeeL
注册码:aCa1badboy4L-4shortR-8-aCaFeeL

好的,就到这里结束吧!分析难免有不当之处,还望大家给我指出来!

rb191195 发表于 2007-11-12 03:01:49

太强了。学习以下 ^^

fing 发表于 2007-11-14 15:25:58

呵呵,不错呀顶/:001 /:001

fwtfd 发表于 2007-11-14 15:57:30

学习以下,~~:loveliness:

yunfeng 发表于 2007-11-14 18:36:50

文章写得通俗易懂,下来学习研究一下

wan 发表于 2007-11-14 20:04:02

楼主一下子发了好多文章啊,学习中~~~

clh1979cmh 发表于 2007-11-22 11:00:53

一个字强!!!!我要加油了哟

run108 发表于 2007-11-24 10:43:32

好东西多谢了/:001

wjq19002009 发表于 2007-12-18 21:47:17

高手,太厉害了。我什么时候才能到这样的境界啊?
页: [1]
查看完整版本: 翱文中华灯谜大全1.1注册算法分析