160 个 CrackMe 之 021 - Cabeca 注册分析和注册机实现
本帖最后由 solly 于 2019-7-21 15:06 编辑160 个 CrackMe 之 021 - Cabeca 是的一个用户名和双序列号验证的 CrackMe,其文件信息如下:
是由 Delphi 编译的 CrackMe 程序,我们用 DeDeDark 打开来查看其事件处理过程,快速定位事件处理函数入口。
可以看到,有两个事件,一个是 Edit1KeyPress,一个是 Button1Click,双击 Edit1KeyPress,打开代码查看器:
只显示了一部分代码不完整,不用管它,我们只要函数入口地址即可。
Edit1KeyPress 的入口地址是 0x0042CE30,另一个 Button1Click 的入口是 0x0042D3C4。
我们直接运行一下这个 CrackMe,显示如下:
需要输入 name, serial 1, serial 2,共3条信息,我们随便输入一些数据,按 “Try“按钮,显示如下:
表示输入的注册信息不正确。关闭对话框并退出 CrackMe。
现在我们用 OD 载入 CrackMe,然后利用在 DeDeDark 中找到的入口来定位函数并下断点。如下图:
跟随表达式,来到 Edit1KeyPress 函数入口处,下一个断点(0x0042CE30 处),如下图所示位置:
另一个 Button1Click 函数入口也按上面操作去下一个断点(下在 0x0042D3C7 处),如下图所示:
下好断点后,就可以开始动态跟踪了。
按 F9 直接启动 CrackMe 去输入数据,当在 Name 文本框,一输入字符,就被 OD 断下来了,断在了 Edit1KeyPress 入口处。
下面是对该函数的跟踪説明,代码行后面有注释:
0042CE30 .33D2 xor edx, edx
0042CE32 .8A11 mov dl, byte ptr ;键入的字符:'s','o','l','l','y'
0042CE34 .83C2 F8 add edx, -8
0042CE37 .83FA 72 cmp edx, 72
0042CE3A .0F87 80050000 ja 0042D3C0
0042CE40 .8A92 4DCE4200 mov dl, byte ptr
0042CE46 .FF2495 C0CE4200 jmp dword ptr
0042CE4D .35 db 35 ;CHAR '5', 对应 backspace ,回退删除键 keyValue == 0x08
0042CE4E .00 db 00
0042CE4F .00 db 00
0042CE50 .00 db 00
0042CE51 .00 db 00
0042CE52 .00 db 00
0042CE53 .00 db 00
0042CE54 .00 db 00
0042CE55 .00 db 00
0042CE56 .00 db 00
0042CE57 .00 db 00
0042CE58 .00 db 00
0042CE59 .00 db 00
0042CE5A .00 db 00
0042CE5B .00 db 00
0042CE5C .00 db 00
0042CE5D .00 db 00
0042CE5E .00 db 00
0042CE5F .00 db 00
0042CE60 .00 db 00
0042CE61 .00 db 00
0042CE62 .00 db 00
0042CE63 .00 db 00
0042CE64 .00 db 00
0042CE65 .00 db 00
0042CE66 .00 db 00
0042CE67 .00 db 00
0042CE68 .00 db 00
0042CE69 .00 db 00
0042CE6A .00 db 00
0042CE6B .00 db 00
0042CE6C .00 db 00
0042CE6D .00 db 00
0042CE6E .00 db 00
0042CE6F .00 db 00
0042CE70 .00 db 00
0042CE71 .00 db 00
0042CE72 .00 db 00
0042CE73 .00 db 00
0042CE74 .00 db 00
0042CE75 .00 db 00
0042CE76 .00 db 00
0042CE77 .00 db 00
0042CE78 .00 db 00
0042CE79 .00 db 00
0042CE7A .00 db 00
0042CE7B .00 db 00
0042CE7C .00 db 00
0042CE7D .00 db 00
0042CE7E .00 db 00
0042CE7F .00 db 00
0042CE80 .00 db 00
0042CE81 .00 db 00
0042CE82 .00 db 00
0042CE83 .00 db 00
0042CE84 .00 db 00
0042CE85 .00 db 00
0042CE86 .1B db 1B ;对应大写字母 'A'
0042CE87 .1C db 1C
0042CE88 .1D db 1D
0042CE89 .1E db 1E
0042CE8A .1F db 1F
0042CE8B .20 db 20 ;CHAR ' '
0042CE8C .21 db 21 ;CHAR '!'
0042CE8D .22 db 22 ;CHAR '"'
0042CE8E .23 db 23 ;CHAR '#'
0042CE8F .24 db 24 ;CHAR '$'
0042CE90 .25 db 25 ;CHAR '%'
0042CE91 .26 db 26 ;CHAR '&'
0042CE92 .27 db 27 ;CHAR '''
0042CE93 .28 db 28 ;CHAR '('
0042CE94 .29 db 29 ;CHAR ')'
0042CE95 .2A db 2A ;CHAR '*'
0042CE96 .2B db 2B ;CHAR '+'
0042CE97 .2C db 2C ;CHAR ','
0042CE98 .2D db 2D ;CHAR '-'
0042CE99 .2E db 2E ;CHAR '.'
0042CE9A .2F db 2F ;CHAR '/'
0042CE9B .30 db 30 ;CHAR '0'
0042CE9C .32 db 32 ;CHAR '2'
0042CE9D .31 db 31 ;CHAR '1'
0042CE9E .33 db 33 ;CHAR '3'
0042CE9F .34 db 34 ;CHAR '4' 对应大写字母 'Z'
0042CEA0 .00 db 00
0042CEA1 .00 db 00
0042CEA2 .00 db 00
0042CEA3 .00 db 00
0042CEA4 .00 db 00
0042CEA5 .00 db 00
0042CEA6 .01 db 01 ;对应小写字母 'a'
0042CEA7 .02 db 02
0042CEA8 .03 db 03
0042CEA9 .04 db 04
0042CEAA .05 db 05
0042CEAB .06 db 06
0042CEAC .07 db 07
0042CEAD .08 db 08
0042CEAE .09 db 09
0042CEAF .0A db 0A
0042CEB0 .0B db 0B
0042CEB1 .0C db 0C ;对应字符 'l'
0042CEB2 .0D db 0D
0042CEB3 .0E db 0E
0042CEB4 .0F db 0F ;对应字符 'o'
0042CEB5 .10 db 10
0042CEB6 .11 db 11
0042CEB7 .12 db 12
0042CEB8 .13 db 13 ;对应字符 's'
0042CEB9 .14 db 14
0042CEBA .15 db 15
0042CEBB .16 db 16
0042CEBC .18 db 18
0042CEBD .17 db 17
0042CEBE .19 db 19 ;对应字符 'y'
0042CEBF .1A db 1A ;对应小写字母 'z'
0042CEC0 .C0D34200 dd Cabeca.0042D3C0 ;分支表 被用于 0042CE46
0042CEC4 .98CF4200 dd Cabeca.0042CF98
0042CEC8 .AACF4200 dd Cabeca.0042CFAA
0042CECC .BCCF4200 dd Cabeca.0042CFBC
0042CED0 .D1CF4200 dd Cabeca.0042CFD1
0042CED4 .E6CF4200 dd Cabeca.0042CFE6
0042CED8 .F8CF4200 dd Cabeca.0042CFF8
0042CEDC .0AD04200 dd Cabeca.0042D00A
0042CEE0 .1CD04200 dd Cabeca.0042D01C
0042CEE4 .2ED04200 dd Cabeca.0042D02E
0042CEE8 .40D04200 dd Cabeca.0042D040
0042CEEC .55D04200 dd Cabeca.0042D055
0042CEF0 .67D04200 dd Cabeca.0042D067
0042CEF4 .7CD04200 dd Cabeca.0042D07C
0042CEF8 .8ED04200 dd Cabeca.0042D08E
0042CEFC .A0D04200 dd Cabeca.0042D0A0
0042CF00 .B5D04200 dd Cabeca.0042D0B5
0042CF04 .CAD04200 dd Cabeca.0042D0CA
0042CF08 .DFD04200 dd Cabeca.0042D0DF
0042CF0C .F4D04200 dd Cabeca.0042D0F4
0042CF10 .05D14200 dd Cabeca.0042D105
0042CF14 .17D14200 dd Cabeca.0042D117
0042CF18 .29D14200 dd Cabeca.0042D129
0042CF1C .3BD14200 dd Cabeca.0042D13B
0042CF20 .4DD14200 dd Cabeca.0042D14D
0042CF24 .5FD14200 dd Cabeca.0042D15F
0042CF28 .71D14200 dd Cabeca.0042D171
0042CF2C .86D14200 dd Cabeca.0042D186
0042CF30 .9BD14200 dd Cabeca.0042D19B
0042CF34 .ADD14200 dd Cabeca.0042D1AD
0042CF38 .C2D14200 dd Cabeca.0042D1C2
0042CF3C .D7D14200 dd Cabeca.0042D1D7
0042CF40 .ECD14200 dd Cabeca.0042D1EC
0042CF44 .01D24200 dd Cabeca.0042D201
0042CF48 .16D24200 dd Cabeca.0042D216
0042CF4C .2BD24200 dd Cabeca.0042D22B
0042CF50 .40D24200 dd Cabeca.0042D240
0042CF54 .55D24200 dd Cabeca.0042D255
0042CF58 .6AD24200 dd Cabeca.0042D26A
0042CF5C .7FD24200 dd Cabeca.0042D27F
0042CF60 .94D24200 dd Cabeca.0042D294
0042CF64 .A9D24200 dd Cabeca.0042D2A9
0042CF68 .BED24200 dd Cabeca.0042D2BE
0042CF6C .D3D24200 dd Cabeca.0042D2D3
0042CF70 .E8D24200 dd Cabeca.0042D2E8
0042CF74 .FDD24200 dd Cabeca.0042D2FD
0042CF78 .12D34200 dd Cabeca.0042D312
0042CF7C .27D34200 dd Cabeca.0042D327
0042CF80 .3CD34200 dd Cabeca.0042D33C
0042CF84 .51D34200 dd Cabeca.0042D351
0042CF88 .66D34200 dd Cabeca.0042D366
0042CF8C .7BD34200 dd Cabeca.0042D37B
0042CF90 .90D34200 dd Cabeca.0042D390
0042CF94 .A5D34200 dd Cabeca.0042D3A5
0042CF98 >8105 14F74200 27040000 add dword ptr , 427 ;对应小写字母 'a'
0042CFA2 .8305 18F74200 79 add dword ptr , 79
0042CFA9 .C3 retn
0042CFAA >8105 14F74200 BC060000 add dword ptr , 6BC
0042CFB4 .8305 18F74200 6F add dword ptr , 6F
0042CFBB .C3 retn
0042CFBC >8105 14F74200 91040000 add dword ptr , 491
0042CFC6 .8105 18F74200 E2020000 add dword ptr , 2E2
0042CFD0 .C3 retn
0042CFD1 >8105 14F74200 4D470000 add dword ptr , 474D
0042CFDB .8105 18F74200 FA020000 add dword ptr , 2FA
0042CFE5 .C3 retn
0042CFE6 >8105 14F74200 00040000 add dword ptr , 400
0042CFF0 .8305 18F74200 0E add dword ptr , 0E
0042CFF7 .C3 retn
0042CFF8 >8105 14F74200 D0060000 add dword ptr , 6D0
0042D002 .8305 18F74200 0D add dword ptr , 0D
0042D009 .C3 retn
0042D00A >8105 14F74200 7D060000 add dword ptr , 67D
0042D014 .8305 18F74200 0C add dword ptr , 0C
0042D01B .C3 retn
0042D01C >8105 14F74200 50070000 add dword ptr , 750
0042D026 .8305 18F74200 0B add dword ptr , 0B
0042D02D .C3 retn
0042D02E >8105 14F74200 3C040000 add dword ptr , 43C
0042D038 .8305 18F74200 63 add dword ptr , 63
0042D03F .C3 retn
0042D040 >8105 14F74200 64070000 add dword ptr , 764
0042D04A .8105 18F74200 78030000 add dword ptr , 378
0042D054 .C3 retn
0042D055 >8105 14F74200 C0000000 add dword ptr , 0C0
0042D05F .8305 18F74200 4D add dword ptr , 4D
0042D066 .C3 retn
0042D067 >8105 14F74200 7D270000 add dword ptr , 277D ;对应字符 'l'
0042D071 .8105 18F74200 2B020000 add dword ptr , 22B
0042D07B .C3 retn
0042D07C >8105 14F74200 1E080000 add dword ptr , 81E
0042D086 .8305 18F74200 5A add dword ptr , 5A
0042D08D .C3 retn
0042D08E >8105 14F74200 070E0000 add dword ptr , 0E07
0042D098 .8305 18F74200 62 add dword ptr , 62
0042D09F .C3 retn
0042D0A0 >8105 14F74200 8E000000 add dword ptr , 8E ;对应字符 'o'
0042D0AA .8105 18F74200 2C1D0000 add dword ptr , 1D2C
0042D0B4 .C3 retn
0042D0B5 >8105 14F74200 70A60900 add dword ptr , 9A670
0042D0BF .8105 18F74200 F3C70800 add dword ptr , 8C7F3
0042D0C9 .C3 retn
0042D0CA >8105 14F74200 570D0000 add dword ptr , 0D57
0042D0D4 .8105 18F74200 88020000 add dword ptr , 288
0042D0DE .C3 retn
0042D0DF >8105 14F74200 EB5F0000 add dword ptr , 5FEB
0042D0E9 .8105 18F74200 1A020000 add dword ptr , 21A
0042D0F3 .C3 retn
0042D0F4 >8105 14F74200 B0080000 add dword ptr , 8B0 ;对应字符 's'
0042D0FE .FF05 18F74200 inc dword ptr
0042D104 .C3 retn
0042D105 >8105 14F74200 BB040000 add dword ptr , 4BB
0042D10F .8305 18F74200 40 add dword ptr , 40
0042D116 .C3 retn
0042D117 >8105 14F74200 C2080000 add dword ptr , 8C2
0042D121 .8305 18F74200 4B add dword ptr , 4B
0042D128 .C3 retn
0042D129 >8105 14F74200 A61C0000 add dword ptr , 1CA6
0042D133 .8305 18F74200 4E add dword ptr , 4E
0042D13A .C3 retn
0042D13B >8105 14F74200 95030000 add dword ptr , 395
0042D145 .8305 18F74200 26 add dword ptr , 26
0042D14C .C3 retn
0042D14D >8105 14F74200 1E250000 add dword ptr , 251E
0042D157 .8305 18F74200 05 add dword ptr , 5
0042D15E .C3 retn
0042D15F >8105 14F74200 132D0000 add dword ptr , 2D13 ;对应字符 'y'
0042D169 .8305 18F74200 08 add dword ptr , 8
0042D170 .C3 retn
0042D171 >8105 14F74200 00190000 add dword ptr , 1900 ;对应小写字母 'z'
0042D17B .8105 18F74200 C8010000 add dword ptr , 1C8
0042D185 .C3 retn
0042D186 >8105 14F74200 28040000 add dword ptr , 428 ;对应大写字母 'A'
0042D190 .8105 18F74200 10160000 add dword ptr , 1610
0042D19A .C3 retn
0042D19B >8105 14F74200 30160B00 add dword ptr , 0B1630
0042D1A5 .8305 18F74200 02 add dword ptr , 2
0042D1AC .C3 retn
0042D1AD >8105 14F74200 860D0000 add dword ptr , 0D86
0042D1B7 .8105 18F74200 0F270000 add dword ptr , 270F
0042D1C1 .C3 retn
0042D1C2 >8105 14F74200 A4110000 add dword ptr , 11A4
0042D1CC .8105 18F74200 3CF36F04 add dword ptr , 46FF33C
0042D1D6 .C3 retn
0042D1D7 >8105 14F74200 0A1F0100 add dword ptr , 11F0A
0042D1E1 .8105 18F74200 3C8B0000 add dword ptr , 8B3C
0042D1EB .C3 retn
0042D1EC >8105 14F74200 C23C0000 add dword ptr , 3CC2
0042D1F6 .8105 18F74200 18860000 add dword ptr , 8618
0042D200 .C3 retn
0042D201 >8105 14F74200 A8E10300 add dword ptr , 3E1A8
0042D20B .8105 18F74200 1CC80600 add dword ptr , 6C81C
0042D215 .C3 retn
0042D216 >8105 14F74200 E4910000 add dword ptr , 91E4
0042D220 .8105 18F74200 45E92700 add dword ptr , 27E945
0042D22A .C3 retn
0042D22B >8105 14F74200 426B0000 add dword ptr , 6B42
0042D235 .8105 18F74200 C3C72F00 add dword ptr , 2FC7C3
0042D23F .C3 retn
0042D240 >8105 14F74200 A4160500 add dword ptr , 516A4
0042D24A .8105 18F74200 7CF4B800 add dword ptr , 0B8F47C
0042D254 .C3 retn
0042D255 >8105 14F74200 5A340400 add dword ptr , 4345A
0042D25F .8105 18F74200 C7150100 add dword ptr , 115C7
0042D269 .C3 retn
0042D26A >8105 14F74200 D9FD1B00 add dword ptr , 1BFDD9
0042D274 .8105 18F74200 542B0100 add dword ptr , 12B54
0042D27E .C3 retn
0042D27F >8105 14F74200 6D280000 add dword ptr , 286D
0042D289 .8105 18F74200 8C340B00 add dword ptr , 0B348C
0042D293 .C3 retn
0042D294 >8105 14F74200 01040000 add dword ptr , 401
0042D29E .8105 18F74200 74E17C35 add dword ptr , 357CE174
0042D2A8 .C3 retn
0042D2A9 >8105 14F74200 74060000 add dword ptr , 674
0042D2B3 .8105 18F74200 D77C3100 add dword ptr , 317CD7
0042D2BD .C3 retn
0042D2BE >8105 14F74200 9C000000 add dword ptr , 9C
0042D2C8 .8105 18F74200 34D87D00 add dword ptr , 7DD834
0042D2D2 .C3 retn
0042D2D3 >8105 14F74200 56010000 add dword ptr , 156
0042D2DD .8105 18F74200 D09C0300 add dword ptr , 39CD0
0042D2E7 .C3 retn
0042D2E8 >8105 14F74200 27860000 add dword ptr , 8627
0042D2F2 .8105 18F74200 4AF40B00 add dword ptr , 0BF44A
0042D2FC .C3 retn
0042D2FD >8105 14F74200 90817400 add dword ptr , 748190
0042D307 .8105 18F74200 86468500 add dword ptr , 854686
0042D311 .C3 retn
0042D312 >8105 14F74200 68A50000 add dword ptr , 0A568
0042D31C .8105 18F74200 20320100 add dword ptr , 13220
0042D326 .C3 retn
0042D327 >8105 14F74200 92550100 add dword ptr , 15592
0042D331 .8105 18F74200 2E300000 add dword ptr , 302E
0042D33B .C3 retn
0042D33C >8105 14F74200 D91D0000 add dword ptr , 1DD9
0042D346 .8105 18F74200 431C0000 add dword ptr , 1C43
0042D350 .C3 retn
0042D351 >8105 14F74200 6A260000 add dword ptr , 266A
0042D35B .8105 18F74200 086CA92B add dword ptr , 2BA96C08
0042D365 .C3 retn
0042D366 >8105 14F74200 C03C0000 add dword ptr , 3CC0
0042D370 .8105 18F74200 C8EF0400 add dword ptr , 4EFC8
0042D37A .C3 retn
0042D37B >8105 14F74200 11830000 add dword ptr , 8311
0042D385 .8105 18F74200 461C0000 add dword ptr , 1C46
0042D38F .C3 retn
0042D390 >8105 14F74200 1BCE0000 add dword ptr , 0CE1B ;对应大写字母 'Z'
0042D39A .8105 18F74200 64160B00 add dword ptr , 0B1664
0042D3A4 .C3 retn
0042D3A5 >33D2 xor edx, edx ;对应回退键 backspace, 本来是往前删除一个字符,但 CrackMe 会清空 Edit 控件
0042D3A7 .8B80 E0010000 mov eax, dword ptr
0042D3AD .E8 5ECAFEFF call 00419E10 ;TEdit.SetText(""), 清空文本框内容,重新输入
0042D3B2 .33C0 xor eax, eax
0042D3B4 .A3 14F74200 mov dword ptr , eax ;清空累加值1
0042D3B9 .33C0 xor eax, eax
0042D3BB .A3 18F74200 mov dword ptr , eax ;清空累加值2
0042D3C0 >C3 retn
代码看起来很长,但完成的功能很简单,就是根据我们输入的用户名的字符,先查询一个索引值,再根据索引值查到一个跳转地址,再跳转去对两个全局变量进行累加和计算,每输入一个字符,就累加一次,累加的值就是根据我们输入字符的 ascii 码来查询索引表,再根据索引表查地址表,查得地址后,就跳转去执行累加操作。
流程如下:
输入 ==> 字符ASCII值 ===>索引表 ====> 地址表 ======> 跳转 ======>累加计算
索引表如下:
;-------------------------------- 索引表 115 个索引 -------------------------------------------------------------
; 1、索引第1个索引值 0x35 表示按了 backspace 键,CrackMe 会将文本框清空,两个全局变量也清空,也就是重新来一遍的意思
; 2、中间很多索引值为 0 的索引,表示输入的所有非大小字母的其它符号,包括标点、数字、控制符和特殊符号等。
; 3、其它有数值的索引共52个,表示输入的是大写、小写字母,大小写一起共52个字母。
;
0042CE4D35 00 00 00 00 00 00 00 00 00 00 00 00 00 00 005...............
0042CE5D00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00................
0042CE6D00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00................
0042CE7D00 00 00 00 00 00 00 00 00 1B 1C 1D 1E 1F 20 21......... !
0042CE8D22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 32"#$%&'()*+,-./02
0042CE9D31 33 34 00 00 00 00 00 00 01 02 03 04 05 06 07134......
0042CEAD08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 18....
0042CEBD17 19 1A
地址表如下:
;-------------------------------- 跳转分支地址表 54 个 -------------------------------------------------------
; 1、最后一个分支,表示输入的是 backspace,CrackMe将清空所有字符重新再来一遍。
; 2、第一个分支,表示输入的是非大小写字母的其它符号,包括数字、标点等等
; 3、中间的52个对应52个大小字母,分别对两个全局变量进行累加值计算。
;
0042CEC0C0 D3 42 00 98 CF 42 00 AA CF 42 00 BC CF 42 00烙B.樝B.B.枷B.
0042CED0D1 CF 42 00 E6 CF 42 00 F8 CF 42 00 0A D0 42 00严B.嫦B.B..蠦.
0042CEE01C D0 42 00 2E D0 42 00 40 D0 42 00 55 D0 42 00蠦..蠦.@蠦.U蠦.
0042CEF067 D0 42 00 7C D0 42 00 8E D0 42 00 A0 D0 42 00g蠦.|蠦.幮B.犘B.
0042CF00B5 D0 42 00 CA D0 42 00 DF D0 42 00 F4 D0 42 00敌B.市B.咝B.粜B.
0042CF1005 D1 42 00 17 D1 42 00 29 D1 42 00 3B D1 42 00袯.袯.)袯.;袯.
0042CF204D D1 42 00 5F D1 42 00 71 D1 42 00 86 D1 42 00M袯._袯.q袯.喲B.
0042CF309B D1 42 00 AD D1 42 00 C2 D1 42 00 D7 D1 42 00浹B.B.卵B.籽B.
0042CF40EC D1 42 00 01 D2 42 00 16 D2 42 00 2B D2 42 00煅B.褺.褺.+褺.
0042CF5040 D2 42 00 55 D2 42 00 6A D2 42 00 7F D2 42 00@褺.U褺.j褺.褺.
0042CF6094 D2 42 00 A9 D2 42 00 BE D2 42 00 D3 D2 42 00斠B.┮B.疽B.右B.
0042CF70E8 D2 42 00 FD D2 42 00 12 D3 42 00 27 D3 42 00枰B.B.覤.'覤.
0042CF803C D3 42 00 51 D3 42 00 66 D3 42 00 7B D3 42 00<覤.Q覤.f覤.{覤.
0042CF9090 D3 42 00 A5 D3 42 00 愑B.ビB.?
由上面分析可见,只有输入大写、小写字母时,才会进行累加操作,如果输入全数字用户名,是通不过 CrackMe 注册验证的。
不过,针对 Delphi 对 KeyPress 的处理,Delete 键不会产生这个事件,但字符还是会删除。还有另外一个问题,字符选中替换或粘贴字符都会导致不正确的累加结果。
所以输入字符不对时,需要按 backspace 键重新输入。而且也不能粘贴用户名来进行快速输入。
当用户名所有字符全部输入完成后,就会形成两个全局累加和,保存在 42F714] 和 42F718] 中。
然后,我们按在 serial 1 和 serial 2 中输入一些数据,再按 "Try" 按钮进行校验,OD 又会中断下,校验代码分析如下:
;========================= Button.Click 事件 =============================================================
0042D3C4/.55 push ebp
0042D3C5|.8BEC mov ebp, esp
0042D3C7|.33C9 xor ecx, ecx
0042D3C9|.51 push ecx
0042D3CA|.51 push ecx
0042D3CB|.51 push ecx
0042D3CC|.51 push ecx
0042D3CD|.53 push ebx
0042D3CE|.8BD8 mov ebx, eax ;Sender 对象
0042D3D0|.33C0 xor eax, eax
0042D3D2|.55 push ebp
0042D3D3|.68 ADD54200 push 0042D5AD ;new SEH
0042D3D8|.64:FF30 push dword ptr fs: ;old SEH
0042D3DB|.64:8920 mov dword ptr fs:, esp ;安装 SEH
0042D3DE|.833D 14F74200 00 cmp dword ptr , 0 ;累加值1
0042D3E5|.74 45 je short 0042D42C
0042D3E7|.833D 18F74200 00 cmp dword ptr , 0 ;累加值2
0042D3EE|.74 3C je short 0042D42C
0042D3F0|.8D55 FC lea edx, dword ptr ;返回结果缓冲区
0042D3F3|.8B83 E0010000 mov eax, dword ptr
0042D3F9|.E8 E2C9FEFF call 00419DE0 ;取用户名,eax == 长度, TEdit.GetText()
0042D3FE|.837D FC 00 cmp dword ptr , 0 ;堆栈 ss:=022A6E7C, (ASCII "solly8AZAZaz")
0042D402|.74 28 je short 0042D42C
0042D404|.8D55 F8 lea edx, dword ptr ;返回结果缓冲区
0042D407|.8B83 E4010000 mov eax, dword ptr
0042D40D|.E8 CEC9FEFF call 00419DE0 ;取序列号1,eax == 长度, TEdit.GetText()
0042D412|.837D F8 00 cmp dword ptr , 0 ;堆栈 ss:=022A0FC0, (ASCII "12345")
0042D416|.74 14 je short 0042D42C
0042D418|.8D55 F4 lea edx, dword ptr ;返回结果缓冲区
0042D41B|.8B83 EC010000 mov eax, dword ptr
0042D421|.E8 BAC9FEFF call 00419DE0 ;取序列号2,eax == 长度, TEdit.GetText()
0042D426|.837D F4 00 cmp dword ptr , 0 ;堆栈 ss:=022A6E98, (ASCII "67890")
0042D42A|.75 44 jnz short 0042D470
0042D42C|>B8 C4D54200 mov eax, 0042D5C4 ;ASCII "Fill all boxes first dumb!"
0042D431|.E8 56F6FFFF call 0042CA8C ;提示要完整输入注册信息
0042D436|.33C0 xor eax, eax
0042D438|.A3 14F74200 mov dword ptr , eax ;清空累加值1
0042D43D|.33C0 xor eax, eax
0042D43F|.A3 18F74200 mov dword ptr , eax ;清空累加值2
0042D444|.33D2 xor edx, edx
0042D446|.8B83 E0010000 mov eax, dword ptr
0042D44C|.E8 BFC9FEFF call 00419E10 ;TEdit.SetText(""), 清空文本框内容
0042D451|.33D2 xor edx, edx
0042D453|.8B83 E4010000 mov eax, dword ptr
0042D459|.E8 B2C9FEFF call 00419E10 ;TEdit.SetText(""), 清空文本框内容
0042D45E|.33D2 xor edx, edx
0042D460|.8B83 EC010000 mov eax, dword ptr
0042D466|.E8 A5C9FEFF call 00419E10 ;TEdit.SetText(""), 清空文本框内容
0042D46B|.E9 1A010000 jmp 0042D58A ;跳转退出本函数
0042D470|>833D 14F74200 00 cmp dword ptr , 0 ;所有输入不为空,跳转到这里
0042D477|.74 6C je short 0042D4E5
0042D479|.833D 18F74200 00 cmp dword ptr , 0
0042D480|.74 63 je short 0042D4E5
0042D482|.8D55 F0 lea edx, dword ptr
0042D485|.A1 14F74200 mov eax, dword ptr ;eax == 累加值1
0042D48A|.E8 C190FDFF call 00406550 ;IntToStr()
0042D48F|.8B45 F0 mov eax, dword ptr ;eax ===> IntToStr(累加值1)
0042D492|.50 push eax
0042D493|.8D55 FC lea edx, dword ptr
0042D496|.8B83 E4010000 mov eax, dword ptr
0042D49C|.E8 3FC9FEFF call 00419DE0 ;取序列号1,eax == 长度, TEdit.GetText()
0042D4A1|.8B55 FC mov edx, dword ptr ;参数str2, edx ===> 序列号1
0042D4A4|.58 pop eax ;参数str1, eax ===> IntToStr(累加值1)
0042D4A5|.E8 2664FDFF call 004038D0 ;AnsiStrComp(str1, str2),返加 0-相等,1-大于,2-小于
0042D4AA|.75 39 jnz short 0042D4E5
0042D4AC|.8D55 F0 lea edx, dword ptr
0042D4AF|.A1 18F74200 mov eax, dword ptr ;eax == 累加值2
0042D4B4|.E8 9790FDFF call 00406550 ;IntToStr()
0042D4B9|.8B45 F0 mov eax, dword ptr ;eax ===> IntToStr(累加值2)
0042D4BC|.50 push eax
0042D4BD|.8D55 FC lea edx, dword ptr
0042D4C0|.8B83 EC010000 mov eax, dword ptr
0042D4C6|.E8 15C9FEFF call 00419DE0 ;取序列号2,eax == 长度, TEdit.GetText()
0042D4CB|.8B55 FC mov edx, dword ptr ;参数str2,edx ===> 序列号2
0042D4CE|.58 pop eax ;参数str1, eax ===> IntToStr(累加值2)
0042D4CF|.E8 FC63FDFF call 004038D0 ;AnsiStrComp(str1, str2),返加 0-相等,1-大于,2-小于
0042D4D4|.75 0F jnz short 0042D4E5
0042D4D6|.B8 E8D54200 mov eax, 0042D5E8 ;ASCII "Hmmm.... Cracked... Congratulations idiot! :-)"
0042D4DB|.E8 ACF5FFFF call 0042CA8C ;提示注册成功!!!
0042D4E0|.E9 A5000000 jmp 0042D58A ;退出函数
0042D4E5|>833D 14F74200 00 cmp dword ptr , 0 ;当前及以下的对比处理,都是无效的,不影响失败的结果。
0042D4EC|.74 33 je short 0042D521
0042D4EE|.833D 18F74200 00 cmp dword ptr , 0
0042D4F5|.74 2A je short 0042D521
0042D4F7|.8D55 F0 lea edx, dword ptr
0042D4FA|.A1 14F74200 mov eax, dword ptr ;累加值1
0042D4FF|.E8 4C90FDFF call 00406550 ;IntToStr()
0042D504|.8B45 F0 mov eax, dword ptr
0042D507|.50 push eax
0042D508|.8D55 FC lea edx, dword ptr
0042D50B|.8B83 E4010000 mov eax, dword ptr
0042D511|.E8 CAC8FEFF call 00419DE0 ;取序列号1,eax == 长度, TEdit.GetText()
0042D516|.8B55 FC mov edx, dword ptr
0042D519|.58 pop eax
0042D51A|.E8 B163FDFF call 004038D0 ;AnsiStrComp(str1, str2),返加 0-相等,1-大于,2-小于
0042D51F|.75 2A jnz short 0042D54B
0042D521|>8D55 F0 lea edx, dword ptr
0042D524|.A1 18F74200 mov eax, dword ptr ;累加值2
0042D529|.E8 2290FDFF call 00406550 ;IntToStr()
0042D52E|.8B45 F0 mov eax, dword ptr
0042D531|.50 push eax
0042D532|.8D55 FC lea edx, dword ptr
0042D535|.8B83 EC010000 mov eax, dword ptr
0042D53B|.E8 A0C8FEFF call 00419DE0 ;取序列号2,eax == 长度, TEdit.GetText()
0042D540|.8B55 FC mov edx, dword ptr
0042D543|.58 pop eax
0042D544|.E8 8763FDFF call 004038D0 ;AnsiStrComp(str1, str2),返加 0-相等,1-大于,2-小于
0042D549|.74 3F je short 0042D58A
0042D54B|>B8 20D64200 mov eax, 0042D620 ;ASCII "Nice try... but is incorrect... Dumb.."
0042D550|.E8 37F5FFFF call 0042CA8C ;提示注册失败!!!
0042D555|.33C0 xor eax, eax
0042D557|.A3 14F74200 mov dword ptr , eax ;清空累加值1
0042D55C|.33C0 xor eax, eax
0042D55E|.A3 18F74200 mov dword ptr , eax ;清空累加值2
0042D563|.33D2 xor edx, edx
0042D565|.8B83 E0010000 mov eax, dword ptr
0042D56B|.E8 A0C8FEFF call 00419E10 ;TEdit.SetText(""), 清空文本框内容
0042D570|.33D2 xor edx, edx
0042D572|.8B83 E4010000 mov eax, dword ptr
0042D578|.E8 93C8FEFF call 00419E10 ;TEdit.SetText(""), 清空文本框内容
0042D57D|.33D2 xor edx, edx
0042D57F|.8B83 EC010000 mov eax, dword ptr
0042D585|.E8 86C8FEFF call 00419E10 ;TEdit.SetText(""), 清空文本框内容
0042D58A|>33C0 xor eax, eax
0042D58C|.5A pop edx
0042D58D|.59 pop ecx
0042D58E|.59 pop ecx
0042D58F|.64:8910 mov dword ptr fs:, edx ;恢复 SEH
0042D592|.68 B4D54200 push 0042D5B4
0042D597|>8D45 F0 lea eax, dword ptr
0042D59A|.E8 A55FFDFF call 00403544 ;释放1个局部变量资源
0042D59F|.8D45 F4 lea eax, dword ptr
0042D5A2|.BA 03000000 mov edx, 3 ;表示 3个 资源
0042D5A7|.E8 BC5FFDFF call 00403568 ;释放3个局部变量资源
0042D5AC\.C3 retn
0042D5AD .^ E9 365AFDFF jmp 00402FE8
0042D5B2 .^ EB E3 jmp short 0042D597
0042D5B4 .5B pop ebx
0042D5B5 .8BE5 mov esp, ebp
0042D5B7 .5D pop ebp
0042D5B8 .C3 retn
这个 Click 事件更简单,就是把前面 KeyPress 事件中的两个全局累加值转换成10进制字符串(IntToStr())与界面输入的 Serial 1、Serial 2 分别比较,如果都相等,就表示验证通过。
算法分析完毕,下面是注册机源码,使用 Dev-C++ 调试通过:
#include <iostream>
#include <stdlib.h>
#include <string.h>
int getCase(char ch);
int getUppValue(char ch, int i);
int getLowValue(char ch, int i);
int getSN(char * name);
int UPP = {{0x428, 0x1610}, {0x0B1630, 0x2}, {0x0D86, 0x270F}, {0x11A4, 0x46FF33C},
{0x11F0A, 0x8B3C}, {0x3CC2, 0x8618}, {0x3E1A8, 0x6C81C}, {0x91E4, 0x27E945},
{0x6B42, 0x2FC7C3}, {0x516A4, 0x0B8F47C}, {0x4345A, 0x115C7}, {0x1BFDD9, 0x12B54},
{0x286D, 0x0B348C}, {0x401, 0x357CE174}, {0x674, 0x317CD7}, {0x9C, 0x7DD834},
{0x156, 0x39CD0}, {0x8627, 0x0BF44A}, {0x748190, 0x854686}, {0x0A568, 0x13220},
{0x15592, 0x302E}, {0x1DD9, 0x1C43}, {0x266A, 0x2BA96C08}, {0x3CC0, 0x4EFC8},
{0x8311, 0x1C46}, {0x0CE1B, 0x0B1664}};
int LOW = {{0x427, 0x79},{0x6BC, 0x6F},{0x491, 0x2E2},{0x474D, 0x2FA},
{0x400, 0x0E},{0x6D0, 0x0D},{0x67D, 0x0C},{0x750, 0x0B},
{0x43C, 0x63},{0x764, 0x378},{0x0C0, 0x4D},{0x277D, 0x22B},
{0x81E, 0x5A},{0x0E07, 0x62},{0x8E, 0x1D2C},{0x9A670, 0x8C7F3},
{0x0D57, 0x288},{0x5FEB, 0x21A},{0x8B0, 0x01},{0x4BB, 0x40},
{0x8C2, 0x4B},{0x1CA6, 0x4E},{0x395, 0x26},{0x251E, 0x5},
{0x2D13, 0x8},{0x1900, 0x1C8}};
int main(int argc, char** argv) {
char name[] = "solly8899AAzz!"; /// 名字自己改
getSN(name);
return 0;
}
int getSN(char * name) {
long v1 = 0;
long v2 = 0;
int n = strlen(name);
for(int i=0; i<n; i++) {
switch (getCase(name)) {
case 1: /// 大写字母
v1 += getUppValue(name, 0);
v2 += getUppValue(name, 1);
break;
case 2: /// 小写字母
v1 += getLowValue(name, 0);
v2 += getLowValue(name, 1);
break;
default: /// 其它
break;
}
}
printf("name: %s\nserial1: %d\nserial2: %d\n", name, v1, v2);
}
int getUppValue(char ch, int i) {
return UPP;
}
int getLowValue(char ch, int i) {
return LOW;
}
int getCase(char ch) {
if((ch>='A') && (ch<='Z')) { //// 大写
return 1;
}
if((ch>='a') && (ch<='z')) { //// 小写
return 2;
}
return 0;/// 其它非字母符号
}
编译运行,得到两个序列号并输入(用户名必须手动输入,不得复制/粘贴),得到成功提示如下:
完毕!!!
感谢,感谢!!!!!!!!!!66666 真好用,谢谢 学习了 谢谢 感谢分享 感谢分享,继续学习, 感谢,感谢!!!!!!!!!!66666 好厉害,多谢分享
页:
[1]