程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言基礎知識 >> 還未結束就能把自身刪除的程序

還未結束就能把自身刪除的程序

編輯:C語言基礎知識

  下面的代碼由Gary Nebbett寫就.Gary Nebbett乃是WINDOWS NT/2000 NATIVE API REFERENCE的作者.乃NT系統一等一的高手.下面就分析一些他的這段代碼.
   這段代碼在PROCESS沒有結束前就將啟動PROCESS的EXE文件刪除了.
   int main(int argc, char *argv[])
   {
   HMODULE module = GetModuleHandle(0);
   CHAR buf[MAX_PATH];
   GetModuleFileName(module, buf, sizeof buf);
   CloseHandle(HANDLE(4));
   __asm {
   lea eax, buf
   push 0
   push 0
   push eax
   push ExitProcess
   push module
   push DeleteFile
   push UnmapViewOfFile
   ret
   }
   return 0;
   }
   現在,我們先看一下堆棧中的東西
  
   偏移 內容
   24 0
   20 0
   16 offset buf
   12 address of ExitProcess
   8 module
   4 address of DeleteFile
   0 address of UnmapViewOfFile
  
   調用RET返回到了UnmapViewOfFile,也就是棧裡的偏移0所指的地方.當進入UnmapViewOfFile的流程時,棧裡見到的是返回地址DeleteFile和HMODUL module.也就是說調用完畢後返回到了DeleteFile的入口地址.當返回到DeleteFile時,看到了ExitProcess的地址,也就是返回地址.和參數EAX,而EAX則是buffer.buffer存的是EXE的文件名.由GetModuleFileName(module, buf, sizeof buf)返回得到.執行了DeleteFile後,就返回到了ExitProcess的函數入口.並且參數為0而返回地址也是0.0是個非法地址.假如返回到地址0則會出錯.而調用ExitProcess則應該不會返回.
   這段代碼的精妙之處在於:
   1.假如有文件的HANDLE打開,文件刪除就會失敗,所以,CloseHandle(HANDLE(4));是十分巧妙的一手.HANDLE4是OS的硬編碼,對應於EXE的IMAGE.在缺省情況下,OS假定沒有任何調用會關閉IMAGE SECTION的HANDLE,而現在,該HANDLE被關閉了.刪除文件就解除了文件對應的一個句柄.
   2.由於UnmapViewOfFile解除了另外一個對應IMAGE的HANDLE,而且解除了IMAGE在內存的映射.所以,後面的任何代碼都不可以引用IMAGE映射地址內的任何代碼.否則就OS會報錯.而現在的代碼在UnmapViewOfFile後則剛好沒有引用到任何IMAGE內的代碼.
   3.在ExitProcess之前,EXE文件就被刪除了.也就是說,進程尚在,而主線程所在的EXE文件已經沒了.(WINNT/9X都保護這些被映射到內存的WIN32 IMAGE不被刪除.)
  
   Gary Nebbett果然是WIN系列平台的頂尖高手之一.能寫出如此代碼.獨辟蹊徑啊:) 
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved