程序的自我修改

本文目的在于向读者说明程序进行自我修改的基本方法,并希望可以起到抛砖引玉的作用。
如果读者有更好的方法或见解,欢迎来信交流E-mail: default_and_default_AT_yahoo.cn

C++代码
  1. /*//////////////////////////////////////////////////////////////////////////////
  2. This program will modify itself at the running time,
  3. These  methods will be very useful in some situations,
  4. Gook Luck!
  5. //////////////////////////////////////////////////////////////////////////////*/
  6. #include<stdio.h>
  7. #include<windows.h>
  8. void main()
  9. {
  10. TCHAR Info001[MAX_PATH]=“Welcome to Big Apple!”;
  11. TCHAR Info002[MAX_PATH]=“Welcome to Washington!”;
  12. char temp=(char)0×90;
  13. WORD temp001=0×9090;
  14. DWORD temp002=0×90909090;
  15. PVOID BaseAddressOne=NULL;
  16. PVOID BaseAddressTwo=NULL;
  17. _asm
  18. {
  19. mov BaseAddressOne,offset LabelOne
  20. mov BaseAddressTwo,offset LabelTwo
  21. }
  22. MessageBox(NULL,Info001,“Information”,MB_OK|MB_ICONINFORMATION);
  23. //a kind of method to modify itself
  24. WriteProcessMemory(GetCurrentProcess(),BaseAddressTwo,&temp001,2,NULL);
  25. WriteProcessMemory(GetCurrentProcess(),BaseAddressOne,&temp001,2,NULL);
  26. /*
  27. //Another method to modify itself,this method needs to modify the code section’s
  28. //characteristics in PE file.
  29. _asm
  30. {
  31. mov ebx,BaseAddressOne
  32. mov ecx,BaseAddressTwo
  33. mov dx,temp001
  34. mov [ebx],dx
  35. mov [ecx],dx
  36. }
  37. */
  38. LabelTwo:
  39. _asm
  40. {
  41. jmp LabelOne
  42. }
  43. _asm
  44. {
  45. nop
  46. nop
  47. nop
  48. }
  49. MessageBox(NULL,Info002,“Information”,MB_OK|MB_ICONINFORMATION);
  50. LabelOne:
  51. _asm
  52. {
  53. jmp Over
  54. }
  55. MessageBox(NULL,Info002,“Information”,MB_OK|MB_ICONINFORMATION);
  56. Over:
  57. return;
  58. }

编译这个程序,我们发现WriteProcessMemory() 成功修改了程序自身代码,程序运行正常。
然后我们屏蔽程序中的WriteProcessMemory()调用,用/*  */之中的代码完成自我修改,
运行后会发现系统抛出异常 Access Violation.这是因为PE 中 代码节的属性默认为 0×60000020,
20 表示代码 20000000表示可执行,40000000表示可读,如果我们在此基础上加上 0×80000000(可写)
操作系统的loader在装载可执行文件时,便会将存放代码节数据的内存标记为可读,可写,可执行。
这样就不会有异常了。
读者可使用下面的程序来修改节属性:

C++代码
  1. /**************************************************************************************/
  2. //The following code is used to modify characteristics of sections
  3. #include<windows.h>
  4. #include<stdio.h>
  5. BOOL ModifyCharacteristicsOfSections (LPCTSTR FileName)
  6. {
  7. DWORD i=0;
  8. HANDLE hDestinationFile=NULL;
  9. TCHAR DestinationPEFile[MAX_PATH];
  10. DWORD NumberOfBytesRead=0; //Number of bytes read
  11. DWORD NumberOfBytesWritten=0; //Number of bytes written
  12. DWORD ImageNtSignature=0; //PE signature
  13. DWORD OffsetOfNewHeader=0;
  14. DWORD NumberOfSections=0;
  15. DWORD SizeOfSectionTable=0; //size of section table
  16. HANDLE hGlobalAllocatedMemory=NULL; //use GlobalAlloc();
  17. PIMAGE_SECTION_HEADER pImageSectionHeader=NULL; //a pointer to IMAGE_SECTION_TABLE
  18. IMAGE_DOS_HEADER ImageDosHeader;
  19. IMAGE_NT_HEADERS ImageNTHeaders;
  20. IMAGE_FILE_HEADER ImageFileHeader;
  21. IMAGE_OPTIONAL_HEADER ImageOptionalHeader;
  22. IMAGE_SECTION_HEADER ImageSectionHeader;
  23. DWORD dwFileSize=0;
  24. RtlZeroMemory(&ImageDosHeader,sizeof(IMAGE_DOS_HEADER));
  25. RtlZeroMemory(&ImageNTHeaders,sizeof(IMAGE_NT_HEADERS));
  26. RtlZeroMemory(&ImageFileHeader,sizeof(IMAGE_FILE_HEADER));
  27. RtlZeroMemory(&ImageOptionalHeader,sizeof(IMAGE_OPTIONAL_HEADER));
  28. RtlZeroMemory(&ImageSectionHeader,sizeof(IMAGE_SECTION_HEADER));
  29. strcpy(DestinationPEFile,FileName);
  30. hDestinationFile=CreateFile(DestinationPEFile,
  31. FILE_WRITE_DATA|FILE_READ_DATA,
  32. FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL);
  33. if(hDestinationFile==INVALID_HANDLE_VALUE)
  34. {
  35. //    printf(“\nCreateFile() fails!Can’t open file. Please try again!\n”);
  36. //    CloseHandle(hDestinationFile);
  37. return TRUE;
  38. }
  39. else
  40. {
  41. dwFileSize=GetFileSize(hDestinationFile,NULL);
  42. }
  43. SetFilePointer(hDestinationFile,0,NULL,FILE_BEGIN); //Revert the file pointer,this is very important.
  44. ReadFile(hDestinationFile,&ImageDosHeader,
  45. sizeof(IMAGE_DOS_HEADER),&NumberOfBytesRead,NULL);
  46. if(NumberOfBytesRead!=sizeof(IMAGE_DOS_HEADER))
  47. {
  48. //    printf(“\nReadFile() fails! Can’t get IMAGE_DOS_HEADER.\n”);
  49. CloseHandle(hDestinationFile);
  50. return FALSE;
  51. }
  52. OffsetOfNewHeader=ImageDosHeader.e_lfanew; //File address of new exe header
  53. SetFilePointer(hDestinationFile,(LONG)OffsetOfNewHeader,NULL,FILE_BEGIN);
  54. ReadFile(hDestinationFile,&ImageNTHeaders,
  55. sizeof(IMAGE_NT_HEADERS),&NumberOfBytesRead,NULL); //Retrieve IMAGE_NT_HEADERS
  56. if(NumberOfBytesRead!=sizeof(IMAGE_NT_HEADERS))
  57. {
  58. CloseHandle(hDestinationFile);
  59. return FALSE;
  60. }
  61. if(ImageNTHeaders.Signature!=0×00004550)
  62. {
  63. //    printf(“Error.\nPE signature is invalid!\n”);
  64. CloseHandle(hDestinationFile);
  65. return FALSE;
  66. }
  67. SetFilePointer(hDestinationFile,OffsetOfNewHeader+4,NULL,FILE_BEGIN);  //Set the file pointer to point to IMAGE_FILE_HEADER
  68. ReadFile(hDestinationFile,&ImageFileHeader,
  69. sizeof(IMAGE_FILE_HEADER),&NumberOfBytesRead,NULL); //Retrieve IMAGE_FILE_HEADER
  70. if(NumberOfBytesRead!=sizeof(IMAGE_FILE_HEADER))
  71. {
  72. //    printf(“\nReadFile() fails! Can’t get IMAGE_FILE_HEADER.\n”);
  73. CloseHandle(hDestinationFile);
  74. return FALSE;
  75. }
  76. if(ImageFileHeader.NumberOfSections<1)
  77. {
  78. CloseHandle(hDestinationFile);
  79. return FALSE;
  80. }
  81. if(dwFileSize<(sizeof(IMAGE_DOS_HEADER)+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*ImageFileHeader.NumberOfSections))
  82. {
  83. CloseHandle(hDestinationFile);
  84. return FALSE;
  85. }
  86. ReadFile(hDestinationFile,&ImageOptionalHeader,
  87. sizeof(IMAGE_OPTIONAL_HEADER),&NumberOfBytesRead,NULL); //Retrieve IMAGE_OPTIONAL_HEADER
  88. if(NumberOfBytesRead!=sizeof(IMAGE_OPTIONAL_HEADER))
  89. {
  90. //    printf(“\nReadFile() fails! Can’t get IMAGE_OPTIONAL_HEADER.\n”);
  91. CloseHandle(hDestinationFile);
  92. return FALSE;
  93. }
  94. if(ImageOptionalHeader.SectionAlignment<ImageOptionalHeader.FileAlignment)
  95. {
  96. CloseHandle(hDestinationFile);
  97. return FALSE;
  98. }
  99. NumberOfSections=ImageFileHeader.NumberOfSections; //Number of sections
  100. SizeOfSectionTable=sizeof(IMAGE_SECTION_HEADER)*NumberOfSections; //Get the size of Section Table
  101. hGlobalAllocatedMemory=GlobalAlloc(GPTR,SizeOfSectionTable);      //Allocate memory and initialize with zero
  102. if(hGlobalAllocatedMemory==NULL)
  103. {
  104. //    printf(“\nGlobalAlloc() failed! Please try again.\n”); //if failed,return
  105. CloseHandle(hDestinationFile);
  106. return FALSE;
  107. }
  108. pImageSectionHeader=(PIMAGE_SECTION_HEADER)hGlobalAllocatedMemory; //Convert a handle to a pointer to IMAGE_SECTION_HEADER
  109. for(i=0;i<NumberOfSections;i++) //Retrieve the Section Table
  110. {
  111. ReadFile(hDestinationFile,pImageSectionHeader+i,
  112. sizeof(IMAGE_SECTION_HEADER),&NumberOfBytesRead,NULL);
  113. if(NumberOfBytesRead!=sizeof(IMAGE_SECTION_HEADER))
  114. {
  115. //      printf(“Error.Can’t get IMAGE_SECTION_HEADER.\n”);
  116. CloseHandle(hDestinationFile);
  117. return FALSE;
  118. }
  119. }
  120. for(i=0;i<NumberOfSections;i++)
  121. {
  122. DWORD dwTempCharacteristics=0;
  123. if((*(pImageSectionHeader+i)).PointerToRawData+(*(pImageSectionHeader+i)).SizeOfRawData>dwFileSize)
  124. {
  125. CloseHandle(hDestinationFile);
  126. return FALSE;
  127. }
  128. if((*(pImageSectionHeader+i)).PointerToRawData % ImageOptionalHeader.FileAlignment!=0)
  129. {
  130. CloseHandle(hDestinationFile);
  131. return FALSE;
  132. }
  133. printf(“\nThe name of the section%d: ”,i);
  134. printf(“%s\n”,(*(pImageSectionHeader+i)).Name);
  135. printf(“Characteristics: %#x\n”,(*(pImageSectionHeader+i)).Characteristics);
  136. printf(“\nPlease input the new characteristics of the section.\n”);
  137. printf(“If you enter 0,the characteristics of the section will not be modified.\n”);
  138. scanf(“%x”,&dwTempCharacteristics);
  139. if(dwTempCharacteristics!=0)
  140. (*(pImageSectionHeader+i)).Characteristics=dwTempCharacteristics;
  141. printf(“——————————————————”);
  142. }
  143. SetFilePointer(hDestinationFile,-((long)SizeOfSectionTable),NULL,FILE_CURRENT); //Set the file poiner
  144. WriteFile(hDestinationFile,pImageSectionHeader,SizeOfSectionTable,&NumberOfBytesWritten,NULL);
  145. if(NumberOfBytesWritten==SizeOfSectionTable)
  146. {
  147. printf(“\nComplete successfully!\n”);
  148. }
  149. else
  150. {
  151. printf(“\nWriteFile() failed!\n”);
  152. }
  153. GlobalFree(hGlobalAllocatedMemory); //Free memory
  154. CloseHandle(hDestinationFile);
  155. return TRUE;
  156. }
  157. void main(int argc,char *argv[])
  158. {
  159. if(argc!=2)
  160. {
  161. printf(“Error\nUsage:ModifyCharacteristicsOfSections CompleteDestinationFileName\n”);
  162. return;
  163. }
  164. if(!ModifyCharacteristicsOfSections(argv[1]))
  165. {
  166. printf(“\nError.This usually means that this file is not a valid PE file or\n”);
  167. printf(“that this PE file has been modified by another program,for example,shell programm.\n”);
  168. }
  169. }

/**********************************************************************************************/
以下是上面程序的输出信息:

The name of the section0: .text
Characteristics: 0×60000020

Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
e0000020
——————————————————
The name of the section1: .rdata
Characteristics: 0×40000040

Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
——————————————————
The name of the section2: .data
Characteristics: 0xc0000040

Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
——————————————————
The name of the section3: .idata
Characteristics: 0xc0000040

Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
——————————————————
The name of the section4: .reloc
Characteristics: 0×42000040

Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
——————————————————
Complete successfully!

////////////////////////////////////////////////////////////////////////////

The name of the section0: .text
Characteristics: 0xe0000020

Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
——————————————————
The name of the section1: .rdata
Characteristics: 0×40000040

Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
——————————————————
The name of the section2: .data
Characteristics: 0xc0000040

Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
——————————————————
The name of the section3: .idata
Characteristics: 0xc0000040

Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
——————————————————
The name of the section4: .reloc
Characteristics: 0×42000040

Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
——————————————————
Complete successfully!

原文:http://bbs.pediy.com/showthread.php?t=64033

发表评论





XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>