• 标 题:quickchm v2.49
  • 作 者:ben007
  • 时 间:2003/02/16 01:00pm
  • 链 接:http://bbs.pediy.com

软件:quickchm v2.49
简介:一个编译与反编译chm文件的软件

原来我是想找能将windows help格式的文件转换成chm文件的工具,于是找到了这个软件。但后来发觉还是不行。
--------------------------------------------------------
这个软件的主程序加了壳,用fi查看,是Aspack v2.1。用unaspack脱壳,启动程序,程序一闪而过,证明程序有自较检。
反汇编程序,查找函数postquitmessage。
* Referenced by a CALL at Addresses:
|:004644A0   , :0049C69B  
|
* Reference To: user32.PostQuitMessage, Ord:0000h
                                 |
:004079C0 FF2598965000            Jmp dword ptr [00509698]
:004079C6 8BC0                    mov eax, eax
有两个调用处,004644a0与0049c69b。用trw2000载入主程序,先在第一处下断点,
---------------------------------------
:0046448D E81E35FAFF              Call 004079B0
:00464492 85C0                    test eax, eax
:00464494 7411                    je 004644A7
:00464496 837DD812                cmp dword ptr [ebp-28], 00000012
:0046449A 750B                    jne 004644A7        -------尝试改为jmp,虽然跳过自较检,但程序不能退出。
:0046449C 8B45DC                  mov eax, dword ptr [ebp-24]
:0046449F 50                      push eax

* Reference To: user32.PostQuitMessage, Ord:0000h
                                 |
:004644A0 E81B35FAFF              Call 004079C0
---------------------------------------
在第二处下断点,
---------------------------------------
:004FC2BC 83FA00                  cmp edx, 00000000
:004FC2BF 7509                    jne 004FC2CA
:004FC2C1 3D20A10700              cmp eax, 0007A120
:004FC2C6 7610                    jbe 004FC2D8           ----------|--这里有两个地方跳过自较检退出,可先载入未脱
:004FC2C8 EB02                    jmp 004FC2CC                               |  壳的程序,观察原程序在哪个地方跳过。结果
                                                                            |  发现原程序在004fc2c6处跳过。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:          |  改为jmp 004fc2c6
|:004FC2BF(C)                                                                |
|                                                                            |
:004FC2CA 7E0C                    jle 004FC2D8           ----------|

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004FC2C8(U)
|
:004FC2CC A1405E5000              mov eax, dword ptr [00505E40]
:004FC2D1 8B00                    mov eax, dword ptr [eax]
:004FC2D3 E8B803FAFF              call 0049C690
----------------------------------------
用hex workshop编辑程序,将3d20a107007610eb02
                     改为          eb        即可跳过自较检退出。
----------------------------------------

这个程序在启动时会要求注册,但反汇编看到这里好像并不较检注册码,只是将注册码保存起来。
以下是破解注册码部分。
----------------------------------------------------------
:0050175B 55                      push ebp
:0050175C 6890195000              push 00501990
:00501761 64FF30                  push dword ptr fs:[eax]
:00501764 648920                  mov dword ptr fs:[eax], esp
:00501767 8D55F8                  lea edx, dword ptr [ebp-08]
:0050176A A1A45B5000              mov eax, dword ptr [00505BA4]
:0050176F 8B00                    mov eax, dword ptr [eax]
:00501771 8B80F8020000            mov eax, dword ptr [eax+000002F8]
:00501777 E8B0A1F7FF              call 0047B92C
:0050177C 8D45E4                  lea eax, dword ptr [ebp-1C]

* Possible StringData Ref from Code Obj ->"F0E1"        -------- 这个字符串“F0E1”与注册码的计算有关
                                 |
:0050177F BAA8195000              mov edx, 005019A8                
:00501784 E84F33F0FF              call 00404AD8
:00501789 8D55F4                  lea edx, dword ptr [ebp-0C]
:0050178C A1A45B5000              mov eax, dword ptr [00505BA4]
:00501791 8B00                    mov eax, dword ptr [eax]
:00501793 8B8004030000            mov eax, dword ptr [eax+00000304]
:00501799 E88EA1F7FF              call 0047B92C
:0050179E 8B45E4                  mov eax, dword ptr [ebp-1C]----(ebp-1c)存放字符串“F0E1”
:005017A1 E85A35F0FF              call 00404D00  ---0040d00的这个call的作用是将eax中的字符串的长度存入eax中,后面常用到。
:005017A6 8945F0                  mov dword ptr [ebp-10], eax---(ebp-10)存放字符串“F0E1”的长度。
:005017A9 33FF                    xor edi, edi   ---------edi存放的是字符串“F0E1”的指针。
:005017AB C745E801000000          mov [ebp-18], 00000001----(ebp-18)中存放的是假注册码的指针,以后每次+2
:005017B2 BB80000000              mov ebx, 00000080  ------令ebx=80,这与计算注册码的第一二个字符有关
:005017B7 C645E300                mov [ebp-1D], 00   ------初始化标志,(ebp-1d)存放的是注册是否成功的标志。
:005017BB 8B45F8                  mov eax, dword ptr [ebp-08]---将名字存入eax中
:005017BE E83D35F0FF              call 00404D00   ------名字长度存入eax,又一次用到这个函数了。
:005017C3 8BF0                    mov esi, eax
:005017C5 83FE01                  cmp esi, 00000001
:005017C8 0F8CA7000000            jl 00501875     ------如果名字长度小于1,则game over。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050186F(C)
|
:005017CE 8B45F8                  mov eax, dword ptr [ebp-08]----名字存入eax,esi存放的是名字的长度。
:005017D1 0FB64430FF              movzx eax, byte ptr [eax+esi-01]---将名字的第n位(从最后一位开始取)放入eax中。
:005017D6 03C3                    add eax, ebx     --------eax+ebx,(即字符的ascii码+ebx),存放于eax中。
:005017D8 B9FF000000              mov ecx, 000000FF--------令ecx=ffh,(十进制的255)
:005017DD 99                      cdq
:005017DE F7F9                    idiv ecx         --------eax÷ecx
:005017E0 8BDA                    mov ebx, edx     --------将余数存入ebx中
:005017E2 3B7DF0                  cmp edi, dword ptr [ebp-10]
:005017E5 7D03                    jge 005017EA     --------  ]
:005017E7 47                      inc edi          --------  ]
:005017E8 EB05                    jmp 005017EF                       ]
                                                                    ]->字符串“F0E1”的指针+1,如果到尾了,就重新指向头部。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:  ]
|:005017E5(C)                                                        ]
|                                                                    ]
:005017EA BF01000000              mov edi, 00000001---------]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005017E8(U)
|
:005017EF 8B45E4                  mov eax, dword ptr [ebp-1C]-----字符串“F0E1”放入eax
:005017F2 0FB64438FF              movzx eax, byte ptr [eax+edi-01]--将字符串“F0E1”的第n位(从头开始取)放入eax中。
:005017F7 33D8                    xor ebx, eax               ---异或,结果存入ebx中。
:005017F9 8D45EC                  lea eax, dword ptr [ebp-14]
:005017FC 50                      push eax
:005017FD 895DD8                  mov dword ptr [ebp-28], ebx
:00501800 C645DC00                mov [ebp-24], 00
:00501804 8D55D8                  lea edx, dword ptr [ebp-28]
:00501807 33C9                    xor ecx, ecx

* Possible StringData Ref from Code Obj ->"%1.2x"           ----以下这一大段是比较代码,作用大概是:用计算出来的结果
                                 |                                 (存入ebx中)转为ascii码,与假注册码的指针(指针存于ebp-
:00501809 B8B8195000              mov eax, 005019B8                 18中)所指向的字符相比较(每次比较两位)。比较的结果影响
:0050180E E8C98BF0FF              call 0040A3DC                     标志ebp-1d,相等则置1,不相等则置0,相等则令指针+2,不
:00501813 8D45D4                  lea eax, dword ptr [ebp-2C]       相等则令指针不动。
:00501816 50                      push eax                          我个人认为这段代码写的有的笨,其实只要一发现比较不相等,
:00501817 8B45EC                  mov eax, dword ptr [ebp-14]       就跳去game over就行了,不用将整个假的注册码比较完。
:0050181A E8E134F0FF              call 00404D00
:0050181F 8BC8                    mov ecx, eax
:00501821 8B55E8                  mov edx, dword ptr [ebp-18]
:00501824 8B45F4                  mov eax, dword ptr [ebp-0C]
:00501827 E83437F0FF              call 00404F60
:0050182C 8B45D4                  mov eax, dword ptr [ebp-2C]
:0050182F 8B55EC                  mov edx, dword ptr [ebp-14]
:00501832 E81536F0FF              call 00404E4C
:00501837 0F9445E3                sete byte ptr [ebp-1D]
:0050183B 8D45D0                  lea eax, dword ptr [ebp-30]
:0050183E 50                      push eax
:0050183F 8B45EC                  mov eax, dword ptr [ebp-14]
:00501842 E8B934F0FF              call 00404D00
:00501847 8BC8                    mov ecx, eax
:00501849 8B55E8                  mov edx, dword ptr [ebp-18]
:0050184C 8B45F4                  mov eax, dword ptr [ebp-0C]
:0050184F E80C37F0FF              call 00404F60
:00501854 8B55D0                  mov edx, dword ptr [ebp-30]
:00501857 8B45EC                  mov eax, dword ptr [ebp-14]
:0050185A E8ED35F0FF              call 00404E4C
:0050185F 750B                    jne 0050186C
:00501861 8B45EC                  mov eax, dword ptr [ebp-14]
:00501864 E89734F0FF              call 00404D00
:00501869 0145E8                  add dword ptr [ebp-18], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050185F(C)
|
:0050186C 4E                      dec esi
:0050186D 85F6                    test esi, esi
:0050186F 0F8559FFFFFF            jne 005017CE                     -------循环

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005017C8(C)
|
:00501875 807DE300                cmp byte ptr [ebp-1D], 00
:00501879 0F84D9000000            je 00501958                     -------比较标志,如果为0,则game over。
:0050187F B201                    mov dl, 01                      -------以下是注册成功的代码,将名字和注册码存放到
:00501881 A1D0444400              mov eax, dword ptr [004444D0]                 注册表中,以便启动软件时检查是否注册了。
:00501886 E8452DF4FF              call 004445D0
:0050188B 8BD8                    mov ebx, eax
:0050188D BA02000080              mov edx, 80000002
:00501892 8BC3                    mov eax, ebx
:00501894 E8D72DF4FF              call 00444670
:00501899 B101                    mov cl, 01

* Possible StringData Ref from Code Obj ->"Software\Microsoft\DirectX"----竟然将名字和注册码存放在这里???奇怪!!!
                                 |
:0050189B BAC8195000              mov edx, 005019C8
:005018A0 8BC3                    mov eax, ebx
:005018A2 E8312EF4FF              call 004446D8
:005018A7 84C0                    test al, al
:005018A9 741E                    je 005018C9
:005018AB 8B4DF8                  mov ecx, dword ptr [ebp-08]

* Possible StringData Ref from Code Obj ->"Label_N"                  -----这里放名字
                                 |
:005018AE BAEC195000              mov edx, 005019EC
:005018B3 8BC3                    mov eax, ebx
:005018B5 E83A34F4FF              call 00444CF4
:005018BA 8B4DF4                  mov ecx, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"Label_K"                  -----这里放注册码
                                 |
:005018BD BAFC195000              mov edx, 005019FC
:005018C2 8BC3                    mov eax, ebx
:005018C4 E82B34F4FF              call 00444CF4
---------------------------------------------------------
username:ben007
regcode:F1120744EF62

以下是我个人写的注册机,本人乃菜鸟一只,编程水平不高,程序若有不妥之处,请指正。
------------------------------------------------------------------------------------------------------------------
data segment
msg1 db 'The keygen for the Quickchm v2.49,created by ben007.',0ah,0dh,'$'
input_msg db 'Please input the name:$'
inputname db 15,?,10 dup(?),0ah,0dh,'$'
regcode db 25 dup(?)
output_msg db 0dh,0ah,'The regcode is:$'
regcode_ptr dw 0
dat db 'F0E1'
lastnum dw 80h
data ends
stack segment para  stack 'stack'
db 10 dup(?)
stack ends
code segment
assume cs:code,ds:data,ss:stack
start:mov ax,data
     mov ds,ax
     mov ah,09h
     lea dx,msg1
     int 21h
     lea dx,input_msg
     int 21h
     mov ah,0ah
     lea dx,inputname
     int 21h
     xor ax,ax
     xor dx,dx
     xor di,di
     mov ch,0
     mov cl,inputname+1
     lea bx,inputname+2
     mov si,cx
     dec si
next: mov al,byte ptr[bx+si]
     cbw
     add ax,lastnum
     mov dl,0ffh
     div dl
     mov dl,ah
     push bx
     lea bx,dat
     mov al,byte ptr[bx+di]
     cbw
     xor ax,dx
     mov lastnum,ax
     call changetoascii
     inc di
     cmp di,3
     ja pointtohead
     jmp lp
pointtohead:mov di,0
lp:   pop bx
     dec si
     loop next
     mov ah,09h
     lea dx,output_msg
     int 21h
     lea bx,regcode
     mov di,regcode_ptr
     mov byte ptr[bx+di],'$'
     mov dx,bx
     int 21h
     mov ah,4ch
     int 21h
changetoascii proc
     push bx
     push di
     mov bh,0
     mov bl,10h
     div bl
     lea bx,regcode
     cmp al,0ah
     jae alplus37h
     add al,30h
     jmp next1
alplus37h:add al,37h
next1:cmp ah,0ah
     jae ahplus37h
     add ah,30h
     jmp next2
ahplus37h:add ah,37h
next2:mov di,regcode_ptr
     mov byte ptr[bx+di],al
     inc di
     mov byte ptr[bx+di],ah
     inc di
     mov regcode_ptr,di
     pop di
     pop bx
     ret
changetoascii endp
code ends
end start
                                                                     ben007
                                                                  2003.2.15