在記憶體中啟動EXE程式(過程詳解)

2021-09-18 05:57:36 字數 2938 閱讀 5026

這個檔案可加密,開啟檔案的同時解密成exe檔案即可。

char szfilename = "virus.exe";

handle hfile = createfile(szfilename, generic_read | generic_write,

file_share_read | file_share_write, null, open_existing,

file_attribute_archive, null);

獲取exe檔案大小,並放入堆空間中

dword dwfilesize = getfilesize(hfile, null);

byte *pdata = new byte[dwfilesize];

`readfile(hfile, pdata, dwfilesize, &dwret, null);

根據映象大小,在程序中開闢乙個可讀、可寫、可執行的記憶體塊

dword dwsizeofimage = getsizeofimage(lpdata);

virtualalloc(null, dwsizeofimage, mem_commit | mem_reserve, page_execute_readwrite);

rtlzeromemory(lpbaseaddress, dwsizeofimage);//初始化空間

將記憶體pe資料按sectionalignment大小對齊對映到程序記憶體中

// lpdata: 記憶體檔案資料的基址

// lpbaseaddress: sectionalignment大小對齊對映到程序記憶體中的記憶體基址

bool mmmapfile(lpvoid lpdata, lpvoid lpbaseaddress)

lpsrcmem = (lpvoid)((dword)lpdata + psectionheader->pointertorawdata);

lpdestmem = (lpvoid)((dword)lpbaseaddress + psectionheader->virtualaddress);

dwsizeofrawdata = psectionheader->sizeofrawdata;

::rtlcopymemory(lpdestmem, lpsrcmem, dwsizeofrawdata);

psectionheader++;

} return true;

}

修改pe檔案重定位表資訊

bool dorelocationtable(lpvoid lpbaseaddress)

while ((ploc->virtualaddress + ploc->sizeofblock) != 0) //開始掃瞄重定位表

}//轉移到下乙個節進行處理

ploc = (pimage_base_relocation)((pbyte)ploc + ploc->sizeofblock);

} return true;

}

填寫pe檔案匯入表資訊

bool doimporttable(lpvoid lpbaseaddress)

// 獲取匯入表中dll的名稱並載入dll

lpdllname = (char *)((dword)pdosheader + pimporttable->name);

hdll = ::getmodulehandle(lpdllname);

if (null == hdll)

}i = 0;

// 獲取originalfirstthunk以及對應的匯入函式名稱表首位址

lpimportnamearray = (pimage_thunk_data)((dword)pdosheader + pimporttable->originalfirstthunk);

// 獲取firstthunk以及對應的匯入函式位址表首位址

lpimportfuncaddrarray = (pimage_thunk_data)((dword)pdosheader + pimporttable->firstthunk);

while (true)

// 獲取image_import_by_name結構

lpimportbyname = (pimage_import_by_name)((dword)pdosheader + lpimportnamearray[i].u1.addressofdata);

// 判斷匯出函式是序號匯出還是函式名稱匯出

if (0x80000000 & lpimportnamearray[i].u1.ordinal)

else

// 注意此處的函式位址表的賦值,要對照pe格式進行裝載,不要理解錯了!!!

lpimportfuncaddrarray[i].u1.function = (dword)lpfuncaddress;

i++;

} pimporttable++;

} return true;

}

修改頁屬性

virtualprotect(lpbaseaddress, dwsizeofimage, page_execute_readwrite, &dwoldprotect)
修改pe檔案載入基址

image_nt_headers.optionalheader.imagebase

bool setimagebase(lpvoid lpbaseaddress)

跳轉到pe的入口點處執行

bool callexeentry(lpvoid lpbaseaddress)

return true;

}

程式在記憶體中開闢空間的過程

首先宣告兩條,這兩條很重要,下面的所有過程都將以這兩條為基礎 1 程式中每執行乙個方法都將在記憶體中建立乙個棧,執行完棧消失 2 程式中每執行乙個new都將在堆中建立乙個物件。執行main生成乙個棧,為敘述方便記為棧1 下同 test test new test 在堆中生成test物件,int da...

程式在記憶體中的分布

在現代的作業系統中,當我們說到記憶體,往往需要分兩部分來講 物理記憶體和虛擬記憶體。從硬體上講,虛擬空間是cpu內部的定址空間,位於mmu之前,物理空間是匯流排上的定址空間,是經過mmu轉換之後的空間。一般我們所說的程式在記憶體中的分布指的就是程式在虛擬記憶體中的儲存方式。從低位址到高位址,可分為下...

程式在記憶體中的分配

程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中的堆是兩回...