我的破解心得(6) (3千字)

看雪資料發表於2001-03-13

破解程式:
    明倫五筆高手1.2A
破解工具:
    SoftICE 3.0 For Windows 95 (Util16 Dldr)    
    W32Dasm 8.5
    UltraEdit 5.0
破解者:
    chcw

  明倫五筆高手是Dos下的一個應用程式,該程式在初啟時和選擇選單命令時,都會去訪問軟碟機,並顯示
‘請插入Key盤’的對話方塊,但在軟碟機中無盤或無鑰匙盤的情況下,並不會出錯。由於頻繁的訪問軟碟機對軟
驅損害較大,所以我們要把該程式訪問軟碟機的部分破解掉。

1. 用Dldr載入WT.EXE程式。
2. 在DOS下常用的磁碟IO中斷是INT 13H,我們就對該中斷設定斷點:
    BPINT 13
3. 鍵入X, 執行程式。立即就會被SoftICE攔截到:

    1DB3:13B3    XOR AX, AX        
    1DB3:13B5    INT 13        ; Reset Controler      <----亮帶所在點

4. 鍵入BC *,清除原有的斷點。然後從亮帶處向下,找到子程式的返回點處:
    1DB3:1458    RETF    
  將游標移到1458處,鍵入'HERE'。程式將執行至此處。
5. 按F10返回到呼叫的語句處:
    1DB3:01C3    CALL 13A8
    1DB3:01C6    POP CX
    1DB3:01C7    POP CX
  鍵入r ax,查得返回值ax=0。仔細分析堆疊,發現執行呼叫CALL 13A8後,SP指標增加了2。因此我們可以
  用語句:
            XOR AX, AX    ; 將ax置為0
            POP CX        ; 將SP指標增加2
  代替CALL 13A8語句來獲得相同的效果。    
6. 用W32Dasm反彙編WT.EXE程式,並將反彙編程式碼存為檔案WT.ALF, 在檔案WT.ALF中查詢字串'int 13',找
  到以下地址:
    :0002.2B95 CD13                  int 13
7. 從該地址向上找,可以找到該語句所在子程式的入口點,並得到呼叫該程式的語句地址:
    * Referenced by a CALL at Addresses:
    |:0002.19A3, :0002.2C42
    |
    :0002.2B88 55                    push bp        <---子程式入口點
8. 下面我們將把WT.EXE程式中所有呼叫子函式0002.2B88的語句改為語句xor ax,ax/pop cx。找到地址
  0002.19A3處:
    :0002.19A3 E8E211                call 2B88
  該函式呼叫語句的機器碼為'E8E211',用UltraEdit開啟WT.EXE程式,查詢字串'E8E211'並將其替換為
  '33C059'('33C0'是xor ax, ax的機器碼, '59'是pop cx的機器碼)。同理可以將0002.2C42地址處的機
  器碼進行修改。
9. 執行WT.EXE程式,程式不會再對軟碟機進行訪問了,但仍會顯示‘請插入Key盤’的對話方塊。

注:程式在呼叫2B88之後,若返回值ax==0,會顯示‘請插入Key盤’的對話方塊。因此如果在第8步中將替換
  的字串該為'B00159'('B001'是mov al, 1的機器碼,'59'是pop cx的機器碼),那麼連對話方塊也不會
  顯示了。

附: WT.EXE的Patch程式Patcher.c

----------------------------Patcher.c---------------------------------
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>

void main()
{
    const long filesize=101334;    //101,334 bytes
    const unsigned char oldcode[][4]={{0xE8, 0xE2, 0x11, 0x00}, {0xE8, 0x43, 0xFF, 0x00}};

    unsigned char patchcode[4]={0xB0, 0x01, 0x59, 0x00};
    unsigned char buffer[4];
    long offset[]={0x000135A3, 0x00014842};
    FILE *fp;
    int i;

    printf("Crack for WT\n");
    printf("Written by Mr. Chcw\n");

    if ((fp=fopen("wt.exe", "r+"))==NULL) {
        printf("Error: Cannot open file wt.exe\n");
        exit(1);
    }
    else if (filelength(fileno(fp))!=filesize) {
        printf("Error: Incorrect WT version, cannot patch it\n");
        exit(2);
    }    

    for (i=0; i<2; i++) {
        fseek(fp,offset[i],SEEK_SET);
        fread(buffer, 3, 1, fp);
        buffer[3]='\0';

        if (strcmp(buffer, oldcode[i]) != 0) {
            printf("Error: The file wt.exe is corrupted\n");            
            exit(3);
        }        
    }
    
    for (i=0; i<2; i++) {
        fseek(fp,offset[i],SEEK_SET);
        fwrite(patchcode, 3, 1, fp);
    }

    fclose(fp);

    printf("Patch successful\n");
}
---------------------- End of File Patcher.c --------------------------

相關文章