• 标 题:Mapbuilder(城市鸟瞰图编辑器)1.01注册算法分析(在这的第一篇文章,请多指教) (7千字)
  • 作 者:Stoby
  • 时 间:2002-8-26 16:49:56
  • 链 接:http://bbs.pediy.com

软件名称:Mapbuilder(城市鸟瞰图编辑器)1.01
工具:TRW2000,winasm
下载地址:http://getdns.net/xh/download.asp?downid=1&id=461

第一篇在这发表的破文,有不足之处请指教。
去赢征论坛时,看到了这个软件的注册版下载,软件实用性没什么,反正有空,那它来练练手,就算当成Crackme玩吧。
废话少说,FI一查,没加壳,正和我意。Winasm,查找字符串"Wrong registration code!"。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411151(C)
|

* Possible Reference to String Resource ID=03004: "Wrong registration code!"
                                  |
:00411200 68BC0B0000              push 00000BBC
:00411205 E86639FFFF              call 00404B70
:0041120A 83C404                  add esp, 00000004
:0041120D 6A00                    push 00000000
:0041120F 53                      push ebx
知道是00411151跳来的:
* Reference To: USER32.GetWindowTextA, Ord:015Eh
                                  |
:00411121 8B3D54524100            mov edi, dword ptr [00415254]
:00411127 50                      push eax
:00411128 FFD7                    call edi
:0041112A 8D542470                lea edx, dword ptr [esp+70]
:0041112E 6A64                    push 00000064
:00411130 52                      push edx
:00411131 685E9C0000              push 00009C5E
:00411136 53                      push ebx
:00411137 FFD6                    call esi
:00411139 50                      push eax
:0041113A FFD7                    call edi
:0041113C 8D442470                lea eax, dword ptr [esp+70]
:00411140 8D4C240C                lea ecx, dword ptr [esp+0C]
:00411144 50                      push eax
:00411145 51                      push ecx
:00411146 E885010000              call 004112D0                〈==好家伙,看看里面什么古怪
:0041114B 83C408                  add esp, 00000008
:0041114E 83F801                  cmp eax, 00000001
:00411151 0F85A9000000            jne 00411200          〈==这里跳就玩完

进入004112D0后,过了一些代码后来到关键部分:
* Possible StringData Ref from Data Obj ->"wengmanibeimeihong"              〈==后面有用
                                  |
:00411303 BBEC744100              mov ebx, 004174EC
:00411308 8D442410                lea eax, dword ptr [esp+10]
:0041130C 2BDD                    sub ebx, ebp
:0041130E 2BC5                    sub eax, ebp
:00411310 8BFD                    mov edi, ebp
:00411312 89442478                mov dword ptr [esp+78], eax
:00411316 EB04                    jmp 0041131C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411334(C)
|
:00411318 8B442478                mov eax, dword ptr [esp+78]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411316(U)
|
:0041131C 8A0C3B                  mov cl, byte ptr [ebx+edi]      〈==ebx+edi中放的就是字符串"wengmanibeimeihong",听起来好象是和尚念的经,作者佛教信徒????
:0041131F 8A17                    mov dl, byte ptr [edi]            〈==edi指向输入的用户名
:00411321 80C120                  add cl, 20          〈==cl中的字符+20
:00411324 55                      push ebp
:00411325 32CA                    xor cl, dl    〈==用户名的字符与cl异或
:00411327 46                      inc esi
:00411328 880C38                  mov byte ptr [eax+edi], cl    〈==结果存放到这里,记最终结果为S1
:0041132B 47                      inc edi

* Reference To: KERNEL32.lstrlenA, Ord:0308h
                                  |
:0041132C FF154C514100            Call dword ptr [0041514C]
:00411332 3BF0                    cmp esi, eax    〈==比较是否取完用户名的字符
:00411334 7CE2                    jl 00411318

再来这里:

* Possible StringData Ref from Data Obj ->"wengmanibeimeihong"
                                  |
:0041135C BAEC744100              mov edx, 004174EC
:00411361 8D442410                lea eax, dword ptr [esp+10]
:00411365 2BD0                    sub edx, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411381(C)
|
:00411367 8D0432                  lea eax, dword ptr [edx+esi]
:0041136A 8A440410                mov al, byte ptr [esp+eax+10]      〈==esp+eax+10指向字符串"wengmanibeimeihong"中去除用户名长度的字符,如用户名长度为10,则指向"imeihong"
:0041136E 0420                    add al, 20    〈==al+20
:00411370 32440C10                xor al, byte ptr [esp+ecx+10]    〈==al分别与S1中字符异或
:00411374 83FE11                  cmp esi, 00000011
:00411377 88443410                mov byte ptr [esp+esi+10], al      〈==结果放到这里,记最终结果为S2.

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004113E0(C)
|*****************************************************现在令S=S1+S2*****************************************
:004113A6 807C341041              cmp byte ptr [esp+esi+10], 41    〈==判断字符串S中的字符是否大于“A”
:004113AB 7D11                    jge 004113BE    〈==不是就不跳

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004113BC(C)
|
:004113AD 8A4C3410                mov cl, byte ptr [esp+esi+10]      〈==分别取S中的字符到cl
:004113B1 80C10A                  add cl, 0A          〈==cl+0A
:004113B4 8AC1                    mov al, cl
:004113B6 884C3410                mov byte ptr [esp+esi+10], cl      〈==保存结果
:004113BA 3C41                    cmp al, 41            〈==运算后是不是还大于“A”,不是下面跳回继续运算。
:004113BC 7CEF                    jl 004113AD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004113AB(C)
|
:004113BE 807C34105A              cmp byte ptr [esp+esi+10], 5A
:004113C3 7E11                    jle 004113D6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004113D4(C)
|
:004113C5 8A4C3410                mov cl, byte ptr [esp+esi+10]                  〈==如果S中的字符大于"A",那么就来到这里了。分别把S中的字符放到cl.
:004113C9 80C1F6                  add cl, F6        〈==cl+0xF6
:004113CC 8AC1                    mov al, cl
:004113CE 884C3410                mov byte ptr [esp+esi+10], cl        〈==保存结果
:004113D2 3C5A                    cmp al, 5A        〈==运算后是不是还大于"Z"
:004113D4 7FEF                    jg 004113C5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004113C3(C)
|
:004113D6 8D442410                lea eax, dword ptr [esp+10]
:004113DA 46                      inc esi
:004113DB 50                      push eax
:004113DC FFD3                    call ebx
:004113DE 3BF0                    cmp esi, eax          〈==比较S中的字符是否全部算完
:004113E0 7CC4                    jl 004113A6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004113A4(C)
|
:004113E2 8B4C247C                mov ecx, dword ptr [esp+7C]    〈==到这里edx中就是正确的注册码了。
:004113E6 8D542410                lea edx, dword ptr [esp+10]
:004113EA 51                      push ecx
:004113EB 52                      push edx



算法总结:
先把字符串"wengmanibeimeihong"中的第n个字符的ASCII值加上十六进制20再与用户名中相对应的第n个字符的ASCII值异或,直到用户名取完,记最终结果为S1。然后从"wengmanibeimeihong"中的
第(用户名长度)个字符开始取,取出字符的ASCII值加上十六进制20再分别与S1中的字符的ASCII
值异或,直到取完字符串"wengmanibeimeihong",记最终结果为S2。将S2字符串连接到字符串S1后记为S。比较S中的字符是否位于A-Z之间,如果小于A,则将S中的字符ASCII每次加十六进制0A,直到大于A为止;如果S中字符大于Z,则将字符ASCII每次加十六进制F6,直到全部处理完。处理完的
S中即为注册码,长度为18。

剩下写注册机的任务就留给某某老大了,写得菜,罗嗦了点,请原谅。等会儿放到DFCG论坛去。