2009年12月30日 星期三

程序的自我修改

程序的自我修改
April 30th, 2008 | lonkil | Visual C++ | 發表評論 | trackback
本文目的在於向讀者說明程序進行自我修改的基本方法,並希望可以起到拋磚引玉的作用。
如果讀者有更好的方法或見解,歡迎來信交流E-mail: default_and_default_AT_yahoo.cn

C++代碼
/*//////////////////////////////////////////////////////////////////////////////
This program will modify itself at the running time,
These methods will be very useful in some situations,
Gook Luck!
//////////////////////////////////////////////////////////////////////////////*/
#include
#include
void main()
{
TCHAR Info001[MAX_PATH]=「Welcome to Big Apple!」;
TCHAR Info002[MAX_PATH]=「Welcome to Washington!」;
char temp=(char)0×90;
WORD temp001=0×9090;
DWORD temp002=0×90909090;
PVOID BaseAddressOne=NULL;
PVOID BaseAddressTwo=NULL;
_asm
{
mov BaseAddressOne,offset LabelOne
mov BaseAddressTwo,offset LabelTwo
}
MessageBox(NULL,Info001,「Information」,MB_OK|MB_ICONINFORMATION);
//a kind of method to modify itself
WriteProcessMemory(GetCurrentProcess(),BaseAddressTwo,&temp001,2,NULL);
WriteProcessMemory(GetCurrentProcess(),BaseAddressOne,&temp001,2,NULL);
/*
//Another method to modify itself,this method needs to modify the code section’s
//characteristics in PE file.
_asm
{
mov ebx,BaseAddressOne
mov ecx,BaseAddressTwo
mov dx,temp001
mov [ebx],dx
mov [ecx],dx
}
*/
LabelTwo:
_asm
{
jmp LabelOne
}
_asm
{
nop
nop
nop
}
MessageBox(NULL,Info002,「Information」,MB_OK|MB_ICONINFORMATION);
LabelOne:
_asm
{
jmp Over
}
MessageBox(NULL,Info002,「Information」,MB_OK|MB_ICONINFORMATION);
Over:
return;
}
編譯這個程序,我們發現WriteProcessMemory() 成功修改了程序自身代碼,程序運行正常。
然後我們屏蔽程序中的WriteProcessMemory()調用,用/* */之中的代碼完成自我修改,
運行後會發現系統拋出異常 Access Violation.這是因為PE 中 代碼節的屬性默認為 0×60000020,
20 表示代碼 20000000表示可執行,40000000表示可讀,如果我們在此基礎上加上 0×80000000(可寫)
操作系統的loader在裝載可執行文件時,便會將存放代碼節數據的內存標記為可讀,可寫,可執行。
這樣就不會有異常了。
讀者可使用下面的程序來修改節屬性:

C++代碼
/**************************************************************************************/
//The following code is used to modify characteristics of sections
#include
#include
BOOL ModifyCharacteristicsOfSections (LPCTSTR FileName)
{
DWORD i=0;
HANDLE hDestinationFile=NULL;
TCHAR DestinationPEFile[MAX_PATH];
DWORD NumberOfBytesRead=0; //Number of bytes read
DWORD NumberOfBytesWritten=0; //Number of bytes written
DWORD ImageNtSignature=0; //PE signature
DWORD OffsetOfNewHeader=0;
DWORD NumberOfSections=0;
DWORD SizeOfSectionTable=0; //size of section table
HANDLE hGlobalAllocatedMemory=NULL; //use GlobalAlloc();
PIMAGE_SECTION_HEADER pImageSectionHeader=NULL; //a pointer to IMAGE_SECTION_TABLE
IMAGE_DOS_HEADER ImageDosHeader;
IMAGE_NT_HEADERS ImageNTHeaders;
IMAGE_FILE_HEADER ImageFileHeader;
IMAGE_OPTIONAL_HEADER ImageOptionalHeader;
IMAGE_SECTION_HEADER ImageSectionHeader;
DWORD dwFileSize=0;
RtlZeroMemory(&ImageDosHeader,sizeof(IMAGE_DOS_HEADER));
RtlZeroMemory(&ImageNTHeaders,sizeof(IMAGE_NT_HEADERS));
RtlZeroMemory(&ImageFileHeader,sizeof(IMAGE_FILE_HEADER));
RtlZeroMemory(&ImageOptionalHeader,sizeof(IMAGE_OPTIONAL_HEADER));
RtlZeroMemory(&ImageSectionHeader,sizeof(IMAGE_SECTION_HEADER));
strcpy(DestinationPEFile,FileName);
hDestinationFile=CreateFile(DestinationPEFile,
FILE_WRITE_DATA|FILE_READ_DATA,
FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL);
if(hDestinationFile==INVALID_HANDLE_VALUE)
{
// printf(」\nCreateFile() fails!Can’t open file. Please try again!\n」);
// CloseHandle

參考來源:

"上一篇: Windows XP SP3 簡體中文官方http下載地址下一篇: 算法的時間複雜度"
- 程序的自我修改 « Vc爱好者 v3.0 (在「Google 網頁註解」中檢視)

沒有留言:

張貼留言