• 标 题:我的破解心得(8) (2千字)
  • 作 者:chcw
  • 时 间:2001-3-13 18:09:21
  • 链 接:http://bbs.pediy.com

破解程序:
    JPEG Optimizer Version 3.00 For Windows

破解工具:
    SoftICE 3.0 For Windows 95
    Ultra Edit 5.0

破解者:
    chcw

  JPEG Optimizer的注册只需要输入一个注册码即可,采用这种注册方式的程序一般都比较容易破解。

1. 用SoftICE将JPEGOPT.EXE程序载入。
2. 选择Help/Register打开注册对话框,并输入注册码9530109。
3. 按Ctrl-D,进入SoftICE窗口中,由于程序通常要用hmemcpy函数将输入注册对话框的注册码复制到
  程序自己的数据区中,因此我们就对hmemcpy设置断点:
    BPX hmemcpy
4. 按Ctrl-D,回到Jpeg Optimizer的注册窗口中,按"OK"键,触发SoftICE,执行光带停留在函数
  hmemcpy的启始处:
    KERNEL!HMEMCPY
    0117:9E30    PUSH BP    
  从此处开始连续按F10键,直到跳出系统模块,回到程序Jpeg Optimizer中:
    0137:00431D86    CALL    0044B2AC
    0137:00431D8B    MOV WORD PTR[EBP-28], 0008
    0137:00431D91    MOV WORD PTR[EBP-28], 0020
5. 键入BC *清除原先的断点。继续按F10,直到以下语句处:
    0137:00431DB2    LEA EAX, DWORD PTR [EBP-08]
  键入dd ds:eax,得到ds:eax指针所指的数据:
    013F:006EF5F4    00C1859C xxxxxxxx xxxxxxxx xxxxxxxx
  再键入db ds:00C1859C, 得到以下数据:
    013F:00C1859C    39 35 33 30 31 30 39 xx xx xx xx xx xx xx xx xx        9530109
  看来eax是指向注册码RegCode的双重指针,接下来的函数,很可能与注册码有关:
    0137:00431DB5    CALL 004521FE
    0137:00431DBA    CMP EAX, 00000006
  按F10,执行完0137:00431DB5    CALL 004521FE处的函数调用,发现EAX==7且呈高亮。回想我们输
  入的注册码的长度刚好为7,而在执行完上述调用之后,立即有一句比较语句CMP EAX, 00000006。
  看来函数004521FE的功能是取得注册码的长度,而程序要求的正确的注册码的长度应该为6。
6. 在0137:00431DBA处双击鼠标,设置断点。然后按Ctrl-D,回到Jpeg Optimizer的注册窗口,将注册
  码改为六位数字530109,再按按"OK"键,触发SoftICE,连续按F10,到0137:00431DC8处:
    0137:00431DBA    CMP EAX, 00000006        <-触发SoftICE后亮条所在处    
    0137:00431DBD    JNE 00431DD2
    0137:00431DBF    LEA EAX, DWORD PTR [EBP-04]    ;    eax是指向注册码RegCode的双重指针    
    0137:00431DC2    CALL 00405DA4            ;    取得RegCode的地址
    0137:00431DC7    PUSH EAX            ;    eax是指向注册码RegCode的指针
    0137:00431DC8    CALL 00432C4B            <-按F10直到此处
    0137:00431DCD    POP ECX
    0137:00431DCE    TEST AL, AL            ;    判断AL是否为0    
    0137:00431DD0    JNE 00431DD6            ;    若不为0,则跳转。
7. 注意到在执行0137:00431DC8处的调用CALL 00432C4B后,根据返回值的不同,程序将进行跳转,所以有必要
  分析一下子函数0137:00431DC8。按F8,进入此函数,然后连续按F10键:
    0137:00432C4B    PUSH EBP            ;    程序入口点
              ...
    0137:00432C8A    PUSH EAX            ;    将RegCode[0]地址压栈
    0137:00432C8B    CALL 004787B8            ;    将RegCode[0]转换为大写,并放在EAX中返回
    0137:00432C90    POP ECX
    0137:00432C91    CMP EAX, 0000005A          ;    RegCode[0]=='Z'?        
    0137:00432C94    JNE 00432CDA            ;    不是则跳转
              .            
              .
              .        
    0137:00432CC1    MOVSX ECX, BYTE PTR [EBP-03]    ;    将RegCode[5]地址压栈
    0137:00432CC5    CMP ECX, 00000031        ;    RegCode[5]=='1'?
    0137:00432CC8    JNE 00432CDA            ;    不是则跳转    
  很显然,从0137:00432C91到0137:00432CC8的一段比较/跳转语句就是程序在比较注册码,将每个比较语句
  中判断的16进制码收集起来是:
    5A 49 31 37 38 31
  用UltraEdit转换一下就得到注册码的ASCII值:
    RegCode="ZI1781"