我寫的一個記憶體補丁,很基本。。高手莫入。。 (5千字)

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

某個軟體因為有殼,在將殼部分模擬完成後,發現還需要對某個地址SMC,故在解壓縮完成後,
將要跳到真正入口處時,先跳到SMC處執行補丁,然後再跳到真正入口處。採用了增加一個節
的方法擴充SMC程式碼(怎樣增加一個節,因為很簡單,不再做說明)
  為什麼不直接脫殼呢?因為這是個DLL,脫殼很麻煩的,要處理引入表、衝定位項,乾脆模擬
透過算了,這樣的問題是要修改某個記憶體地址的時候,需要用SMC,不能直接修改了。。

--------------------------------------------------------------------------------
//要修改的地址Address=1067206h-00029302h=103DF04h開始的5位元組
//要修改的地址將以1067206h作為基準,因為這個基準地址我們可以很容易得到且不受任何
//因素影響,上面為什麼使用“-”,因為我將節加到最後,地址肯定大於原程式中的任何地
//址。
--------------------------------------------------------------------------------
//補丁程式
//1.因為原來程式引入表中沒有"VirtualQuery"函式,所以要先取得
//2.以下用到的其它函式,原來程式引入表中都有,所以直接使用
--------------------------------------------------------------------------------
EAX=00000000  EBX=01067012  ECX=00000000  EDX=01030000  ESI=00000004       
EDI=FFFFFFFC  EBP=01067206  ESP=016FFBC0  EIP=0106720F  o d I s z a P c   
CS=0167  DS=016F  SS=016F  ES=016F  FS=3C8F  GS=0000                     
--------------------------------------------------------------------------------
016F:01066FE2 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
016F:01066FF2 00 00 00 00 00 00 00 00-00 00 00 00 00 00 E9 FB  ................
016F:01067002 01 00 00 56 69 72 74 75-61 6C 51 75 65 72 79 00  ...VirtualQuery.
016F:01067012 4B 65 72 6E 65 6C 33 32-2E 44 4C 4C 00 00 00 00  Kernel32.DLL....
016F:01067022 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
016F:01067032 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
--------------------------------------------------------------------------------
0167:01067200  PUSHAD
0167:01067201  CALL      01067206
0167:01067206  POP      EBP          ;此時,ebp = 1067206h
0167:01067207  MOV      EBX,EBP
0167:01067209  SUB      EBX,000001F4  ;EBX-1F4h = "Kernel32.DLL"
0167:0106720F  PUSH      EBX
0167:01067210  CALL      [KERNEL32!GetModuleHandleA]
0167:01067216  TEST      EAX,EAX
0167:01067218  JZ        010672AC
0167:0106721E  MOV      EDX,EAX
0167:01067220  MOV      EBX,EBP
0167:01067222  SUB      EBX,00000201  ;EBX-201h 指向"VirtualQuery"
0167:01067228  PUSH      EBX
0167:01067229  PUSH      EDX
0167:0106722A  NOP
0167:0106722B  NOP
0167:0106722C  NOP
0167:0106722D  NOP
0167:0106722E  NOP
0167:0106722F  NOP
//
0167:01067230  CALL      [KERNEL32!GetProcAddress] ;取得VirtualQuery函式地址
0167:01067236  TEST      EAX,EAX
0167:01067238  JZ        010672AC
0167:0106723A  MOV      EBX,EBP
0167:0106723C  SUB      EBX,00000106 ;EBX-106h 指向 VirtualQuery函式引數區(引數設定參考SDK)
0167:01067242  PUSH      1C          ;VirtualQuery函式引數區長度
0167:01067244  PUSH      EBX          ;PMEMORY_BASIC_INFORMATION
0167:01067245  MOV      EBX,EBP
0167:01067247  SUB      EBX,00029302 ;要修改的地址Address=EBX-00029302h=103DF04h
0167:0106724D  PUSH      EBX          ;address of region
0167:0106724E  CALL      EAX          ;呼叫VirtualQuery取得Address所屬頁的頁基址
//
0167:01067250  MOV      EBX,EBP
0167:01067252  SUB      EBX,000001E6 ;EBX-1e6h = VirtualProtect引數,返回的原來的頁屬性
0167:01067258  PUSH      EBX
0167:01067259  PUSH      00000040    ;新的頁屬性(PAGE_EXECUTE_READWRITE)
0167:0106725E  MOV      EBX,EBP
0167:01067260  SUB      EBX,00000106         ;EBX-106h = VirtualProtect引數區,資料來自VirtualQuery
0167:01067266  PUSH      DWORD PTR [EBX+0C] ;VirtualProtect引數,size of the region
0167:01067269  PUSH      DWORD PTR [EBX]    ;VirtualProtect引數,address of region of committed
                                            ;pages
0167:0106726B  NOP
0167:0106726C  NOP
0167:0106726D  NOP
0167:0106726E  CALL      [KERNEL32!VirtualProtect] ;呼叫VirtualProtect改變頁屬性
0167:01067274  MOV      EBX,EBP
0167:01067276  SUB      EBX,00029302  ;要修改的地址Address=EBX-00029302h=103DF04h
0167:0106727C  MOV      DWORD PTR [EBX],b3b2b1b0  ;將原來4位元組改為b3b2b1b0
0167:01067282  MOV      BYTE PTR [EBX+04],XX      ;將原來1位元組改為XXh

//下面恢復修改的頁屬性
0167:01067286  MOV      EBX,EBP
0167:01067288  SUB      EBX,000001E4  ;VirtualProtect引數,原來的頁屬性,此時這個引數對
                                      ;我們沒用,但必須有
0167:0106728E  PUSH      EBX
0167:0106728F  MOV      EBX,EBP
0167:01067291  SUB      EBX,000001E6  ;儲存的原來的頁屬性
0167:01067297  PUSH      DWORD PTR [EBX]
0167:01067299  MOV      EBX,EBP
0167:0106729B  SUB      EBX,00000106          ;EBX-106h = VirtualProtect引數區,資料來自VirtualQuery
0167:010672A1  PUSH      DWORD PTR [EBX+0C] ;VirtualProtect引數,size of the region
0167:010672A4  PUSH      DWORD PTR [EBX]    ;VirtualProtect引數,address of region of committed
                                            ;pages
0167:010672A6  CALL      [KERNEL32!VirtualProtect]  ;呼叫VirtualProtect恢復頁屬性
0167:010672AC  POPAD
0167:010672AD  JMP      XXXXXXXX        ;跳轉到原來程式處繼續執行


  因為涉及某個國產軟體,恕不說明具體程式。。。
                                Spring.W
                                2002/10/20

相關文章