软件名称:Small HTTP server 1.212  sethttp.exe  40.5KB
下载地点:http://www.computerinfo.com.cn
发 信 人: 井  风
时    间: 2001-02-23 
破解工具:Trw20001.22
解题难度:[专  业]      [学  士]      [硕  士]      [博  士]
                        ********
前    言:
             很小巧的WEB服务器,占用资源很小,支持CGI 1.1、 SSI、PHP。

             
过    程:
        1、注册窗口填入: 注册名称:abcdef  注册码:ABCD12345678;
        2、用“井风跟踪”法找到出错的CALL,此程序为:00403C31 CALL 004027BB。
           详细方法请阅读“井风”之WINZIP8.0破解教学篇;
        3、分析代码:   
代码段之一
0015F:00403C1C  PUSH     DWORD 83
015F:00403C21  PUSH     DWORD [0040FB3C]
015F:00403C27  CALL     004048E4
015F:00403C2C  PUSH     DWORD 0040FC50
015F:00403C31  CALL     004027BB        <---(过程2、)找出,执行此CALL则出错,追入此CALL
015F:00403C36  ADD      ESP,BYTE +04    < 到代码段之二,由后向前分析 
015F:00403C39  TEST     EAX,EAX         <    
015F:00403C3B  JZ       00403C57

代码段之二
015F:00402808  CMP      EDX,EDX
015F:0040280A  JZ       00402813
015F:0040280C  MOV      ESP,[004011AA]
015F:00402812  RET     
015F:00402813  MOV      [0040FB14],EDX
015F:00402819  CMP      BYTE [EBP+FFFFF800],00  <===检查有否输入NAME
015F:00402820  JZ       NEAR 00402978           <===NAME为空则出错
015F:00402826  PUSH     BYTE +10
015F:00402828  LEA      EBX,[EBP+FFFFF8F0]
015F:0040282E  PUSH     EBX
015F:0040282F  PUSH     BYTE +79
015F:00402831  PUSH     DWORD [0040FB3C]
015F:00402837  CALL     004048E4
015F:0040283C  PUSH     EBX
015F:0040283D  CALL     00401E0C
015F:00402842  MOV      [EBP+FFFFF7FC],EAX
015F:00402848  ADD      ESP,BYTE +04
015F:0040284B  MOV      EDI,[EBP+FFFFF7F8]
015F:00402851  MOV      ESI,0040261D
015F:00402856  CLD     
015F:00402857  LODSB   
015F:00402858  SCASB   
015F:00402859  JNZ      0040285F
015F:0040285B  OR       AL,AL
015F:0040285D  JNZ      00402857
015F:0040285F  MOV      AL,[EDI-01]
015F:00402862  SUB      AL,[ESI-01]
015F:00402865  MOVSX    EAX,AL
015F:00402868  MOV      EDX,EAX
015F:0040286A  TEST     EDX,EDX
015F:0040286C  JNZ      00402899
015F:0040286E  CMP      DWORD [EBP+FFFFF7FC],BYTE +16
015F:00402875  JA       0040287E
015F:00402877  PUSH     DWORD 00402633
015F:0040287C  JMP      SHORT 0040288C
015F:0040287E  CMP      DWORD [EBP+FFFFF7FC],BYTE +1C
015F:00402885  JNA      004028E2
015F:00402887  PUSH     DWORD 0040264D
015F:0040288C  PUSH     BYTE +79
015F:0040288E  PUSH     DWORD [0040FB3C]
015F:00402894  CALL     00404918
015F:00402899  ADD      BYTE [EBP+FFFFF8F1],CF      <===将注册码的第二位加上CF
015F:004028A0  ADD      BYTE [EBP+FFFFF8F3],CA      <===将注册码的第四位加上CA
015F:004028A7  LEA      EBX,[EBP+FFFFF800]
015F:004028AD  LEA      EAX,[EBP+FFFFF8F0]
015F:004028B3  PUSH     EAX
015F:004028B4  CALL     00401E0C        <===将变化过的注册码计算产生EAX值,记为[**]
015F:004028B9  MOV      [EBP+FFFFF7FC],EAX          <===形成[EBP+FFFFF7FC]的值
015F:004028BF  ADD      BYTE [EBP+FFFFF8F1],31      <===还原注册码第二位值
015F:004028C6  ADD      BYTE [EBP+FFFFF8F3],36      <===还原注册码第四位值
015F:004028CD  PUSH     EBX
015F:004028CE  CALL     00402DB1
015F:004028D3  ADD      ESP,BYTE +08
015F:004028D6  CMP      [EBP+FFFFF7FC],EAX  <===比较两次计算的结果,[EBP+FFFFF7FC]为根据变化后
          上面这行记为:[^-^]                   的注册码计算结果,EAX根据注册名称计算结果。
                                                下命令:D EAX 见E475CA=(14972362)十进制                                                      
015F:004028DC  JNZ      NEAR 00402978       <===不相等则跳转执行***,出错
015F:004028E2  MOV      EAX,0040EE28
015F:004028E7  MOV      EBX,EAX
015F:004028E9  SUB      EBX,004092A8
015F:004028EF  PUSH     EBX
015F:004028F0  PUSH     DWORD 53494745
015F:004028F5  PUSH     DWORD 524E5528
015F:004028FA  PUSH     DWORD 004092A8
015F:004028FF  CALL     00401E30
015F:00402904  MOV      [EBP+FFFFF7E8],EAX
015F:0040290A  ADD      ESP,BYTE +10
015F:0040290D  TEST     EAX,EAX
015F:0040290F  JZ       00402915
015F:00402911  MOV      BYTE [EAX-01],00
015F:00402915  PUSH     EBX
015F:00402916  PUSH     DWORD 53494745
015F:0040291B  PUSH     DWORD 524E550A
015F:00402920  PUSH     DWORD 004092A8
015F:00402925  CALL     00401E30
015F:0040292A  MOV      [EBP+FFFFF7E8],EAX
015F:00402930  ADD      ESP,BYTE +10
015F:00402933  TEST     EAX,EAX
015F:00402935  JZ       00402962
015F:00402937  MOV      ECX,EAX
015F:00402939  INC      ECX
015F:0040293A  MOV      EDI,ECX
015F:0040293C  MOV      ESI,0040267D
015F:00402941  CLD     
015F:00402942  LODSB   
015F:00402943  STOSB   
015F:00402944  OR       AL,AL
015F:00402946  JNZ      00402942
015F:00402948  MOV      ECX,[EBP+FFFFF7E8]
015F:0040294E  ADD      ECX,BYTE +0F
015F:00402951  LEA      EDX,[EBP+FFFFF800]
015F:00402957  MOV      EDI,ECX
015F:00402959  MOV      ESI,EDX
015F:0040295B  CLD     
015F:0040295C  LODSB   
015F:0040295D  STOSB   
015F:0040295E  OR       AL,AL
015F:00402960  JNZ      0040295C
015F:00402962  MOV      EAX,[0040FC40]
015F:00402967  MOV      [0040EE28],EAX
015F:0040296C  MOV      DWORD [0040EE2C],0FFFFFFF
015F:00402976  JMP      SHORT 004029DB
015F:00402978  MOV      DWORD [EBP+FFFFF7FC],00100000
015F:00402982  PUSH     BYTE +14
015F:00402984  PUSH     DWORD 0040268C
015F:00402989  PUSH     DWORD 0040269E
015F:0040298E  PUSH     BYTE +00
015F:00402990  CALL     00404930           <===执行此行出错,记为[***],向上分析
015F:00402995  CMP      EAX,BYTE +07
015F:00402998  JNZ      004029DB
015F:0040299A  CMP      DWORD [EBP+FFFFF7FC],BYTE +00
015F:004029A1  JZ       NEAR 00402C6D
015F:004029A7  MOV      ESI,004027BB

代码段之三
015F:00401E0C  PUSH     EBP                  <===追入**CALL,来到此行
015F:00401E0D  MOV      EBP,ESP
015F:00401E0F  PUSH     EBX
015F:00401E10  MOV      EBX,[EBP+08]
015F:00401E13  XOR      ECX,ECX              <===将ECX清零
015F:00401E15  JMP      SHORT 00401E1E
015F:00401E17  LEA      EAX,[ECX+ECX*4]      <   这段程序实际上是将十进制数转成十六进制数,
015F:00401E1A  LEA      ECX,[EDX+EAX*2]      <很经典的算法!
015F:00401E1D  INC      EBX                  <
015F:00401E1E  MOVSX    EAX,BYTE [EBX]       <   
015F:00401E21  LEA      EDX,[EAX-30]         <---这句和B句的作用为检查最后一位,如不为数字则结束
015F:00401E24  CMP      EDX,BYTE +09         <---记为[B]                              
015F:00401E27  JNA      00401E17             <
015F:00401E29  MOV      EAX,ECX          <===将得出结果传给EAX,以产生后面[EBP+FFFFF7FC]值
015F:00401E2B  MOV      EBX,[EBP-04]
015F:00401E2E  LEAVE   
015F:00401E2F  RET     
   
   
   
小   结:
           弄清楚了代码段之三的功能后,我们就知道如何得出注册码了。

           因为经变化过的注册码的计算过程实际上是将一个十进制数转化为十六进制数。所以得出:变化过
       的注册码的十六进制形式与[^-^]处根据注册名产生的EAX值相同,即E475CA=(14972362)。

           现在已经知道了变化过的注册码应为14972362,由[**]前面几行代码可知道:变化过程只是将你输
       入的注册码的第二、四位分别加上了CF、CA。所以只要将14972362中的4和7的ASCII值分别减去CF、CA
       (34-CF=65为e、37-CA=6D为m)即为正确注册码:1e9m2362
       
       NAME:abcdef  CODE:1e9m2362
后   记:
        有疑问请与我联系:hz.cy@163.net