R!SC'sPatcher 工具使用

看雪資料發表於2015-11-15
         

 RPP.EXE  是記憶體動態補丁製作軟體。它透過指令碼命令建立 win32 檔案,以此檔案裝載程式,裝載過程中等待軟體解壓或解除其自身保護後,然後按指令碼要求修補記憶體中的指令,以使軟體能夠按我們要求執行。

  如 ACDSEE3.0 是用 ASPACK 壓縮軟體,你 crack 時發現在記憶體地址 433FEA 處把 6A00 改成 EB17 就可成功,但你不可能直接修改壓縮過的 ACDSEE.EXE 檔案;這裡就可用  RPP.EXE  按我們要求生成一 LOAD.EXE 檔案,首先執行 LOAD.EXE ,它自動裝載 ACDSEE.EXE, 等其自解壓完成後,然後修改記憶體 433FEA 地址為 EB17, 這樣 ACDSEE.EXE 就可按我們要求執行了,不過我不贊成用此法對付 ACDSEE.EXE ,因為 ACDSEE.EXE 執行有兩種介面,其中 VIEW 介面用此法不太靈。

RPP.EXE  還可很方便對付 NAG (一些提示、警告視窗的軟體),如用  NEOLITE 2.0 Y 壓縮過的軟體執行之前彈出來的那種視窗,當然也有專門除掉 NAG 的工具。

用法

在資源管理器中雙擊 rpp.exe 檔案,它彈出一選單,你選擇事先編好的指令碼檔案,然後按 OK 

或在 WINDOWS 下的 DOS 視窗下用命令方式“ rpp.exe <script.rpp> ”,其中 script.rpp 為指令碼命令檔案。

如你的輸出檔案己存在,它將覆蓋。在命令方式下,指令碼檔案可是任何檔名和副檔名;但在對話視窗操作方式下,檔名必須為  *.rpp

 

     

 -------------------  

';'   註釋符號 跟著的只是些說明 不會執行的 直到下一行 .

 'T='  表示對記憶體的檢測次數, T=1000: 意味著對記憶體檢測 1000 次,在放棄之前,告訴你的應用程式是

        不正確的版本。

注意:在指令碼檔案裡,預設值 T=8000

 'F='  需要補丁的檔名

 'O='  生成的補丁檔名 , 如你沒指定檔名,預設為 LOAD.EXE

 'P='  如何在記憶體補丁 格式:記憶體地址 / 原碼 / 補碼

       具體看看指令碼的例子

 'R:'  把前面需要補的全部補好後 再繼續 可以看看 azpr243.rpp 這個例子

 ':'  每一行都要以冒號結尾 相當於回車

 '$'  指令碼結束標誌

  所有數字採用 16 進位制

  記憶體地址和原碼都符合才會進行補丁 位元組間請用逗號分開。指令碼檔案不能大於 40K, 被補的位元組有限為 1f0h 位元組,被處理的原檔案不小於 30h 位元組。

指令碼例子

;script.rpp

T=1000:     ; 對記憶體嘗試 1000 次補丁 不行則放棄 如果不設預設為 8000

F=test.exe: ; 要補丁的程式

P=40101D/74,60/74,00:   ; 將命令 jz xx  改為 jz next instruction

P=4024A6/46,52,45,45,20/52,21,53,43,00: ; 將字元  'FREE '  替換成  'R!SC'

$ ; 結束

具體的指令碼範例大家可參考其自帶的 Scripts.zip

 

一些問題

  下面是一有趣的試驗,寫一指令碼檔案,輸入輸出名一樣,產生一執行檔案,該檔案將不斷裝載其自身

最後導致 windows 崩潰,你只好重新啟動了。

 'P=401000/68/B8:'

 'F=fun.exe:'

 'O=fun.exe:',  然後執行  fun.exe  不一會你只好重新啟動微機了  :)

――――――――――――――――――――――――――――――――――


2.2 如何寫Loader
       

作者:夜月
E-mail:luoyi.ly@yeah.net
寫作日期:31th, August 2001

使用的工具

Trw2000 V1.23--Win9X Debugger
Masm32  V5.00--Loader Compiler

難易程度

Easy( )  Medium(X)  Hard( )  Pro( )

                  ----------=======Declare========----------

    未經作者同意,不得修改、引用原文,一切權利保留。
    本教程只供教學用,其他一切用途皆被禁止。
              ------------------=====Begin=====------------------ 
    以Director 7.0為例,和大家談談如何寫 Loader。當然,破解Director 7.0並不一定需要Loader,
它既沒加殼,也沒有CRC校驗,完全可以用Patch的方法。但我這篇文章的目的不是教你如何破解Director,
而是教你如何寫Loader。Clearly?
    Ready?
    Go!
    Director 7.0也是一個狗保護的軟體,和Authorware差不多。跟蹤過程並不複雜,在此略去。
    程式判斷的關鍵點:

* Referenced by a CALL at Address:
|:00445A24 
|
:0058CC24 53                      push ebx
:0058CC25 32DB                    xor bl, bl
:0058CC27 E835000000              call 0058CC61
:0058CC2C 83F852                  cmp eax, 00000052
:0058CC2F 741D                    je 0058CC4E
:0058CC31 83F856                  cmp eax, 00000056
:0058CC34 7418                    je 0058CC4E
:0058CC36 3D76030000              cmp eax, 00000376
:0058CC3B 7411                    je 0058CC4E
:0058CC3D 3D54030000              cmp eax, 00000354
:0058CC42 740A                    je 0058CC4E
:0058CC44 83F841                  cmp eax, 00000041
:0058CC47 7405                    je 0058CC4E
:0058CC49 83F851                  cmp eax, 00000051
:0058CC4C 7502                    jne 0058CC50

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0058CC2F(C), :0058CC34(C), :0058CC3B(C), :0058CC42(C), :0058CC47(C)
|
:0058CC4E B301                    mov bl, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0058CC4C(C)
|
:0058CC50 E83E000000              call 0058CC93
:0058CC55 84C0                    test al, al
:0058CC57 7402                    je 0058CC5B
:0058CC59 B301                    mov bl, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0058CC57(C)
|
:0058CC5B 8AC3                    mov al, bl    <-----------改為 mov    al,1
:0058CC5D 5B                      pop ebx
:0058CC5E C20400                  ret 0004
 
    Loader的寫作思路很簡單,主要是你要知道有這些個API存在。我買了一本32位彙編的書,上面
竟然說在Window98裡面,不能對別的程式進行讀寫。幸虧有《論壇精華2》中,DDXia翻譯的一篇文章上
面有介紹如何讀寫別的程式,不然,我到現在還被矇在鼓裡。哎!現在的書呀,真有誤人子弟的嫌疑了。
    寫Loader要用到的幾個API函式:
(1)    BOOL GetOpenFileName(
    LPOPENFILENAME lpofn  // 指向一個OPENFILENAME的結構
                            );

    該函式的作用是得到要被Load的程式的路徑以及檔名            

(2)  (摘自羅雲彬的Win32Asm教程)
    BOOL CreateProcess(
LPCTSTR lpApplicationName, // 執行程式檔名
LPTSTR lpCommandLine, // 引數行
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 程式安全引數
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 執行緒安全引數
BOOL bInheritHandles, // 繼承標記
DWORD dwCreationFlags, // 建立標記
LPVOID lpEnvironment, // 環境變數
LPCTSTR lpCurrentDirectory, // 執行該子程式的初始目錄
LPSTARTUPINFO lpStartupInfo, // 建立該子程式的相關引數
LPPROCESS_INFORMATION lpProcessInformation // 建立後用於被建立子程式的資訊
);

        改函式的作用是建立程式,使被Load的程式執行起來

(3)    BOOL ReadProcessMemory(
    HANDLE hProcess,  // 被讀的程式的控制程式碼
    LPCVOID lpBaseAddress, // 開始讀的地址
    LPVOID lpBuffer,  //  讀完後,資料存放的地址
    DWORD nSize,      // 要讀的數量,以位元組為單位
    LPDWORD lpNumberOfBytesRead  // 實際上讀的數量,以位元組為單位
                );
    改函式的作用是讀去一片範圍的記憶體,可以作校驗用――看看執行的程式是不是我們要Load的那個。

(4)    BOOL WriteProcessMemory(
    HANDLE hProcess,  // 被寫的程式的控制程式碼
    LPVOID lpBaseAddress, // 開始寫的地址
    LPVOID lpBuffer,  // 要寫入的資料存放地址
    DWORD nSize,      // 要寫的數量,以位元組為單位
    LPDWORD lpNumberOfBytesWritten // 實際上寫的數量,以位元組為單位
                            );
    
    寫一個Loader要用的主要就是這4個函式。
    還有一個問題:如果程式被加殼了,我們如何知道它已經在記憶體裡面節壓縮完畢?
    R!sc用的是WaitForInputIdle的方法。這個方法很不錯,對付大多數的殼都可以行得通。
    但是,對於這個程式而言,就沒有WaitForInputIdle的必要了。因為它並沒有加殼。
    好了,下面看看我寫的這個Loader的原始碼:
Loader原始碼(load.exe):
---------------------------------------Cut From Here------------------------------------------
;
;**********************************************************
;          主程式                                *
;**********************************************************
    .386p
    .model flat,stdcall
    option casemap :none
include        windows.inc
include        kernel32.inc
include          user32.inc
include          comdlg32.inc
include          comctl32.inc

includelib    kernel32.lib
includelib  user32.lib
includelib  comdlg32.lib
includelib  comctl32.lib
;**********************************************************
;        Normal Data                              *
;**********************************************************
       
    .data
CSiR_Tag    db    'PE LOADER & CRACKER-----ROBOTOW 2001',0
CSiR_Error    db    'Error!',0
CSiR_Error1    db    'Something fucked up...',0
OpenERR_txt    db    'CreateProcess Error :( ',0
ReadERR_txt    db    'ReadProcess Error :(',0
WriteERR_txt    db    'WriteProcess Error :P',0
VersionERR_txt    db    'Incorrect Version of application :(',0
CSiR_ProcessInfo    dd    4 dup(0)
CSiR_StartupInfo    db    48h dup(0)
CSiR_RPBuffer    db    10h dup(0)
szFilter          db    'Director.exe',0,'Director.exe',0
                  db    'Execute Files',0,'*.exe,;*.com',0
                  db 0
szTitleOpen    db    'Find Director.exe,0
szExt        db    '*.exe',0

;**********************************************************
;        Patch Data                                *
;**********************************************************
CSiR_AppName    OPENFILENAME <?>
CSiR_AppName_Buffer db 512 dup(?)
fuck        dd    58cc5bh
mysizeof        dd    6h
checkbytes    db    08Ah,0C3h,05Bh,0C2h,04h,00h
patch_data_1    db    0B0h,0
patch_size_1    dd    2
patch_addr_1    dd    58cc5bh

    .code
Start:

      invoke    InitCommonControls
      invoke    GetModuleHandle,NULL
            mov    CSiR_AppName.Flags,OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST
        mov    CSiR_AppName.lStructSize,SIZEOF CSiR_AppName
        mov    CSiR_AppName.hwndOwner,eax
        mov    CSiR_AppName.lpstrFilter,offset szFilter    
        mov    CSiR_AppName.lpstrFile,offset CSiR_AppName_Buffer    
        mov    CSiR_AppName.nMaxFile,512            
        mov    CSiR_AppName.lpstrInitialDir,0
        mov    CSiR_AppName.lpstrTitle,offset szTitleOpen
        mov    CSiR_AppName.lpstrDefExt,offset szExt
 
        invoke GetOpenFileName,offset CSiR_AppName
    mov    dword ptr [CSiR_StartupInfo],44h
    invoke CreateProcessA,offset CSiR_AppName_Buffer,0,0,0,0,20h,0,0,\
        offset CSiR_StartupInfo,offset CSiR_ProcessInfo
    test    eax,eax
    jz    OpenERR

    invoke    ReadProcessMemory,[CSiR_ProcessInfo],[fuck],offset CSiR_RPBuffer,\
                  [mysizeof],0
    test    eax,eax
    jz    ReadERR
    cld
    lea    esi,CSiR_RPBuffer
    lea    edi,checkbytes
    mov    ecx,6
    repe    cmpsb
    jnz    VersionERR
Patch:    
    invoke    WriteProcessMemory,[CSiR_ProcessInfo],[patch_addr_1],offset patch_data_1,\
                  [patch_size_1],0
    test    eax,eax
    jz    WriteERR

close_this_app:
    invoke    CloseHandle,[CSiR_ProcessInfo]
    invoke    CloseHandle,[CSiR_ProcessInfo+4]

    invoke    ExitProcess,NULL


VersionERR:
    lea    eax,VersionERR_txt
    jmp    abort
ReadERR:
    lea    eax,ReadERR_txt
    jmp    abort
WriteERR:
    lea    eax,WriteERR_txt
    jmp    abort
OpenERR:
    lea    eax,OpenERR_txt

abort:
    invoke    MessageBox,0,eax,offset CSiR_Error,0
    jmp    close_this_app
End    Start
------------------------------------------Cut End---------------------------------------------

                  ------------------=====Last Words=====------------------
    看過TKC教程的人都會發現,我寫的這個Loader,和R!sc的相差無幾。的確,R!sc的這個程式的框架
很不錯,可以很方便地透過改變很小的程式碼而實現我們想要的不同功能。 :)

                  ------------------=====Ending=====------------------
    aNY qUESTIONS,pLEASE eMAIL tO: luoyi.ly@yeah.net

    Thanks To All!Good Luck!

相關文章