• 标 题:《chm帮助编辑器V2.61》注册码破解心得: (11千字)
  • 作 者:小 明
  • 时 间:2001-2-17 15:50:22
  • 链 接:http://bbs.pediy.com

软件名称:chm帮助编辑器V2.61
下载地址:http://kshii.51.net/
破解工具:TRW1.23注册版
破解目的:注册码及其产生机制
破解过程:在注册界面里,用bpx hmemcpy等方法都拦不住,说明作者在这方面下了很大功夫,但百密难免一疏,在使用31次后会跳出一个NAG,提示试用期已到,这是cracker最喜欢见到的:),此时按^N,并下命令PMODULE,又回到NAG画面,点确定后立刻被拦,往上找就会看到如下代码:
016F:0047A204  LEA      EAX,[EBP+FFFFFEF7]
016F:0047A20A  PUSH    EAX
016F:0047A20B  PUSH    DWORD 0047A4F8        |
016F:0047A210  PUSH    DWORD 0047A4FC        |读取win.ini的[AgeSet]中的
016F:0047A215  PUSH    DWORD 0047A504        |Pnum的值,即软件序号
016F:0047A21A  CALL    `KERNEL32!GetProfileStringA` |
016F:0047A21F  CMP      BYTE [EBP+FFFFFEF7],00
016F:0047A226  JNZ      NEAR 0047A2C7         如Pnum非空则跳过去
016F:0047A22C  CALL    00402A4C           |
016F:0047A231  LEA      EAX,[EBP-04]         |
016F:0047A234  CALL    00403BF4           |
016F:0047A239  MOV      EBX,0A            |
016F:0047A23E  MOV      EAX,49            |
016F:0047A243  CALL    00402BF4           |
016F:0047A248  MOV      ESI,EAX            |
016F:0047A24A  INC      ESI              |
016F:0047A24B  LEA      EAX,[EBP+FFFFFEF0]      |随机产生新的软件序号
016F:0047A251  PUSH    EAX              |(10个字符)
016F:0047A252  MOV      ECX,01            |
016F:0047A257  MOV      EDX,ESI            |
016F:0047A259  MOV      EAX,0047A514         |
016F:0047A25E  CALL    0040407C           |
016F:0047A263  MOV      EDX,[EBP+FFFFFEF0]      |
016F:0047A269  LEA      EAX,[EBP-04]         |
016F:0047A26C  CALL    00403E7C           |
016F:0047A271  DEC      EBX              |
016F:0047A272  JNZ      0047A23E           |
016F:0047A274  MOV      EAX,[0048B8E0]
016F:0047A279  MOV      EAX,[EAX+06C0]
016F:0047A27F  MOV      EDX,[EBP-04]
016F:0047A282  CALL    004306F0
016F:0047A287  MOV      EDX,0047A568
016F:0047A28C  MOV      EAX,[0048B8E0]
016F:0047A291  CALL    004306F0
016F:0047A296  MOV      EAX,[EBP-04]
016F:0047A299  CALL    00404038
016F:0047A29E  PUSH    EAX
016F:0047A29F  PUSH    DWORD 0047A4FC
016F:0047A2A4  PUSH    DWORD 0047A504
016F:0047A2A9  CALL    `KERNEL32!WriteProfileStringA` 将软件序号写入win.ini
016F:0047A2AE  PUSH    DWORD 0047A5C0
016F:0047A2B3  PUSH    DWORD 0047A5C8
016F:0047A2B8  PUSH    DWORD 0047A504
016F:0047A2BD  CALL    `KERNEL32!WriteProfileStringA` 写入Pwes,即试用次数
016F:0047A2C2  JMP      0047A4BD
016F:0047A2C7  LEA      EAX,[EBP+FFFFFEEC]
016F:0047A2CD  LEA      EDX,[EBP+FFFFFEF7]
016F:0047A2D3  MOV      ECX,0101
016F:0047A2D8  CALL    00403E24
016F:0047A2DD  MOV      EDX,[EBP+FFFFFEEC]
016F:0047A2E3  MOV      EAX,[0048B8E0]
016F:0047A2E8  MOV      EAX,[EAX+06C0]
016F:0047A2EE  CALL    004306F0
016F:0047A2F3  PUSH    DWORD 0100
016F:0047A2F8  LEA      EAX,[EBP+FFFFFEF7]
016F:0047A2FE  PUSH    EAX
016F:0047A2FF  PUSH    DWORD 0047A4F8
016F:0047A304  PUSH    DWORD 0047A5D0
016F:0047A309  PUSH    DWORD 0047A504
016F:0047A30E  CALL    `KERNEL32!GetProfileStringA` 读取Pset值
016F:0047A313  LEA      EAX,[EBP+FFFFFEE8]
016F:0047A319  LEA      EDX,[EBP+FFFFFEF7]
016F:0047A31F  MOV      ECX,0101
016F:0047A324  CALL    00403E24
016F:0047A329  MOV      EDX,[EBP+FFFFFEE8]
016F:0047A32F  MOV      EAX,[0048B8E0]
016F:0047A334  MOV      EAX,[EAX+06C8]
016F:0047A33A  CALL    004306F0
016F:0047A33F  XOR      EDX,EDX
016F:0047A341  MOV      EAX,[0048B8E0]
016F:0047A346  CALL    0047A108        这个CALL是关键,从这里追进去
016F:0047A34B  MOV      EAX,[0048B8E0]
016F:0047A350  MOV      EAX,[EAX+06CC]
016F:0047A356  CMP      DWORD [EAX+0C],01F4
016F:0047A35D  JZ      NEAR 0047A4BD
 .
 .
 .
---------------------------------
016F:0047A108  PUSH    EBX
016F:0047A109  MOV      EBX,EAX
016F:0047A10B  MOV      EAX,[EBX+06BC]
016F:0047A111  MOV      EAX,[EAX+70]
016F:0047A114  CALL    00479E54    这个CALL是关键的关键,判断注册码的真假,再追...
016F:0047A119  TEST    AL,AL
016F:0047A11B  JZ      0047A157
016F:0047A11D  MOV      EAX,[EBX+06BC]
016F:0047A123  MOV      EAX,[EAX+70]
016F:0047A126  CALL    00404038
016F:0047A12B  PUSH    EAX
016F:0047A12C  PUSH    DWORD 0047A15C
016F:0047A131  PUSH    DWORD 0047A164
016F:0047A136  CALL    `KERNEL32!WriteProfileStringA`
016F:0047A13B  MOV      EAX,[EBX+06CC]
016F:0047A141  MOV      DWORD [EAX+0C],01F4
016F:0047A148  MOV      EDX,0047A174
016F:0047A14D  MOV      EAX,[0048B8E0]
016F:0047A152  CALL    004306F0
016F:0047A157  POP      EBX
016F:0047A158  RET   
-----------------------------
016F:00479E54  PUSH    EBP
016F:00479E55  MOV      EBP,ESP
016F:00479E57  MOV      ECX,07
016F:00479E5C  PUSH    BYTE +00
016F:00479E5E  PUSH    BYTE +00
016F:00479E60  DEC      ECX
016F:00479E61  JNZ      00479E5C
016F:00479E63  PUSH    EBX
016F:00479E64  PUSH    ESI
016F:00479E65  MOV      [EBP-04],EAX
016F:00479E68  MOV      EAX,[EBP-04]
016F:00479E6B  CALL    00404028
016F:00479E70  XOR      EAX,EAX
016F:00479E72  PUSH    EBP
016F:00479E73  PUSH    DWORD 0047A066
016F:00479E78  PUSH    DWORD [FS:EAX]
016F:00479E7B  MOV      [FS:EAX],ESP
016F:00479E7E  MOV      BYTE [EBP-05],00 将注册的标志置为假
016F:00479E82  MOV      EAX,[EBP-04]
016F:00479E85  CALL    00403E74     计算注册码的长度
016F:00479E8A  CMP      EAX,BYTE +0D   等13吗?
016F:00479E8D  JNZ      NEAR 0047A043   不是,说明是假的,那就在此下中断,把win.ini
016F:00479E93  LEA      EAX,[EBP-1C]   里的Pset值改为123456789abcd,再来吧
016F:00479E96  PUSH    EAX
016F:00479E97  MOV      ECX,02
016F:00479E9C  MOV      EDX,01
016F:00479EA1  MOV      EAX,[EBP-04]
016F:00479EA4  CALL    0040407C     取注册码的前2位
016F:00479EA9  MOV      EAX,[EBP-1C]
016F:00479EAC  MOV      EDX,0047A080
016F:00479EB1  CALL    00403F84
016F:00479EB6  JNZ      NEAR 0047A043  是“El”吗?不是则假
016F:00479EBC  LEA      EAX,[EBP-20]
016F:00479EBF  PUSH    EAX
016F:00479EC0  MOV      ECX,01
016F:00479EC5  MOV      EDX,03
016F:00479ECA  MOV      EAX,[EBP-04]
016F:00479ECD  CALL    0040407C    取注册码的第3位
016F:00479ED2  MOV      EAX,[EBP-20]
016F:00479ED5  MOV      EDX,0047A08C
016F:00479EDA  CALL    00403F84
016F:00479EDF  JNZ      NEAR 0047A043  是“@”吗?不是则假
016F:00479EE5  LEA      EAX,[EBP-24]
016F:00479EE8  PUSH    EAX
016F:00479EE9  MOV      ECX,01
016F:00479EEE  MOV      EDX,0A
016F:00479EF3  MOV      EAX,[EBP-04]
016F:00479EF6  CALL    0040407C    取注册码的第10位
016F:00479EFB  MOV      EAX,[EBP-24]
016F:00479EFE  MOV      EDX,0047A098
016F:00479F03  CALL    00403F84
016F:00479F08  JNZ      NEAR 0047A043  是“%”吗?不是则假
016F:00479F0E  LEA      EAX,[EBP-28]
016F:00479F11  PUSH    EAX
016F:00479F12  MOV      ECX,01
016F:00479F17  MOV      EDX,0B
016F:00479F1C  MOV      EAX,[EBP-04]
016F:00479F1F  CALL    0040407C    取注册码的第11位
016F:00479F24  MOV      EAX,[EBP-28]
016F:00479F27  MOV      EDX,0047A0A4
016F:00479F2C  CALL    00403F84
016F:00479F31  JNZ      NEAR 0047A043  是“s”吗?不是则假
016F:00479F37  LEA      EAX,[EBP-2C]
016F:00479F3A  PUSH    EAX
016F:00479F3B  MOV      ECX,01
016F:00479F40  MOV      EDX,0D
016F:00479F45  MOV      EAX,[EBP-04]
016F:00479F48  CALL    0040407C    取注册码的第13位
016F:00479F4D  MOV      EAX,[EBP-2C]
016F:00479F50  MOV      EDX,0047A0B0
016F:00479F55  CALL    00403F84
016F:00479F5A  JNZ      NEAR 0047A043 是“e”吗?不是则假
016F:00479F60  LEA      EAX,[EBP-0C]
016F:00479F63  PUSH    EAX
016F:00479F64  MOV      ECX,06
016F:00479F69  MOV      EDX,04
016F:00479F6E  MOV      EAX,[EBP-04]
016F:00479F71  CALL    0040407C   取软件序号的第4至9位
016F:00479F76  LEA      EAX,[EBP-30] 以下将序号的第4至9位做简单的变换:
016F:00479F79  PUSH    EAX      如将“456789”变成“896745”
016F:00479F7A  MOV      ECX,02
016F:00479F7F  MOV      EDX,05
016F:00479F84  MOV      EAX,[EBP-0C]
016F:00479F87  CALL    0040407C
016F:00479F8C  PUSH    DWORD [EBP-30]
016F:00479F8F  LEA      EAX,[EBP-34]
016F:00479F92  PUSH    EAX
016F:00479F93  MOV      ECX,02
016F:00479F98  MOV      EDX,03
016F:00479F9D  MOV      EAX,[EBP-0C]
016F:00479FA0  CALL    0040407C
016F:00479FA5  PUSH    DWORD [EBP-34]
016F:00479FA8  LEA      EAX,[EBP-38]
016F:00479FAB  PUSH    EAX
016F:00479FAC  MOV      ECX,02
016F:00479FB1  MOV      EDX,01
016F:00479FB6  MOV      EAX,[EBP-0C]
016F:00479FB9  CALL    0040407C
016F:00479FBE  PUSH    DWORD [EBP-38]
016F:00479FC1  LEA      EAX,[EBP-0C]
016F:00479FC4  MOV      EDX,03
016F:00479FC9  CALL    00403F34
016F:00479FCE  LEA      EDX,[EBP-10]
016F:00479FD1  MOV      EAX,[0048B8E0]
016F:00479FD6  MOV      EAX,[EAX+06C0]
016F:00479FDC  CALL    004306C0     --变换到此结束--
016F:00479FE1  MOV      EBX,01
016F:00479FE6  LEA      EAX,[EBP-14]  从这里到016F:0047A03D是一个循环,EBX是循环变量
016F:00479FE9  PUSH    EAX
016F:00479FEA  MOV      ECX,01
016F:00479FEF  MOV      EDX,EBX
016F:00479FF1  MOV      EAX,[EBP-10]
016F:00479FF4  CALL    0040407C    取软件序号的第EBX位
016F:00479FF9  LEA      EAX,[EBP-18]
016F:00479FFC  PUSH    EAX
016F:00479FFD  MOV      EDX,07
016F:0047A002  SUB      EDX,EBX
016F:0047A004  MOV      ECX,01
016F:0047A009  MOV      EAX,[EBP-0C]
016F:0047A00C  CALL    0040407C    取注册码的第7-EBX
016F:0047A011  MOV      EDX,0047A0BC  在0047A0BC处有一张表:“123456789!@#$%^-*()PLWAQokmIJNuhbYGVtfcRDXeszESZrdxFTCygvUHBijnOKMplqwa”
016F:0047A016  MOV      EAX,[EBP-14]
016F:0047A019  CALL    00404160    算出注册码的第7-EBX位在上表中的位置
016F:0047A01E  MOV      ESI,EAX     存入ESI
016F:0047A020  MOV      EDX,0047A0BC
016F:0047A025  MOV      EAX,[EBP-18]
016F:0047A028  CALL    00404160    算出软件序号的第EBX位在上表中的位置
016F:0047A02D  MOV      EDX,EAX     存入EDX及EAX
016F:0047A02F  DEC      EDX
016F:0047A030  CMP      ESI,EDX    ESI=EDX-1?
016F:0047A032  JZ      0047A039   是则真
016F:0047A034  INC      EAX
016F:0047A035  CMP      ESI,EAX    ESI=EAX+1?
016F:0047A037  JNZ      0047A043    不是则假
016F:0047A039  INC      EBX
016F:0047A03A  CMP      EBX,BYTE +07   共循环6次
016F:0047A03D  JNZ      00479FE6     --循环结束--
016F:0047A03F  MOV      BYTE [EBP-05],01 真注册码的标志
016F:0047A043  XOR      EAX,EAX
016F:0047A045  POP      EDX
016F:0047A046  POP      ECX
016F:0047A047  POP      ECX
016F:0047A048  MOV      [FS:EAX],EDX
016F:0047A04B  PUSH    DWORD 0047A06D
016F:0047A050  LEA      EAX,[EBP-38]
016F:0047A053  MOV      EDX,0C
016F:0047A058  CALL    00403C18
016F:0047A05D  LEA      EAX,[EBP-04]
016F:0047A060  CALL    00403BF4
016F:0047A065  RET   
---------------------------------
  总结一下注册码的产生机制:注册码为13位,其中第12位为任意字符,注册码的形式为:El@??????%s?e,第4-9位是根据软件序号的前6位产生的,而且不是唯一的(一个软件序号大概对应2^6=64个注册码)。分析上述算法不难做出注册机,不过作者的处境好象很困难,所以最好不要将注册机传播。
  这里给出几个成功的注册码:
  软件序号   注册码
 1234567890 El@325476%s?e
 61WM!dgQ^N El@27pAx@%s?e
  另外,从2.21版的分析中发现一个数字:“740926”,估计是作者的生日,到时别忘了给他寄份贺卡喔。