程序的自我修改收藏

来源:互联网 发布:js 逻辑或 编辑:程序博客网 时间:2024/05/20 09:10
本文目的在于向读者说明程序进行自我修改的基本方法,并希望可以起到抛砖引玉的作用。如果读者有更好的方法或见解,欢迎来信交流E-mail: default_and_default@yahoo.cn/*//////////////////////////////////////////////////////////////////////////////This program will modify itself at the running time,These  methods will be very useful in some situations,Gook Luck!//////////////////////////////////////////////////////////////////////////////*/#include<stdio.h>#include<windows.h>void main(){  TCHAR Info001[MAX_PATH]="Welcome to Big Apple!";  TCHAR Info002[MAX_PATH]="Welcome to Washington!";  char temp=(char)0x90;  WORD temp001=0x9090;  DWORD temp002=0x90909090;  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 中 代码节的属性默认为 0x60000020,20 表示代码 20000000表示可执行,40000000表示可读,如果我们在此基础上加上 0x80000000(可写)操作系统的loader在装载可执行文件时,便会将存放代码节数据的内存标记为可读,可写,可执行。这样就不会有异常了。读者可使用下面的程序来修改节属性:/**************************************************************************************///The following code is used to modify characteristics of sections#include<windows.h>#include<stdio.h>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(hDestinationFile);    return TRUE;  }  else  {    dwFileSize=GetFileSize(hDestinationFile,NULL);  }  SetFilePointer(hDestinationFile,0,NULL,FILE_BEGIN); //Revert the file pointer,this is very important.    ReadFile(hDestinationFile,&ImageDosHeader,    sizeof(IMAGE_DOS_HEADER),&NumberOfBytesRead,NULL);  if(NumberOfBytesRead!=sizeof(IMAGE_DOS_HEADER))  {//    printf("/nReadFile() fails! Can't get IMAGE_DOS_HEADER./n");    CloseHandle(hDestinationFile);    return FALSE;  }    OffsetOfNewHeader=ImageDosHeader.e_lfanew; //File address of new exe header    SetFilePointer(hDestinationFile,(LONG)OffsetOfNewHeader,NULL,FILE_BEGIN);    ReadFile(hDestinationFile,&ImageNTHeaders,    sizeof(IMAGE_NT_HEADERS),&NumberOfBytesRead,NULL); //Retrieve IMAGE_NT_HEADERS  if(NumberOfBytesRead!=sizeof(IMAGE_NT_HEADERS))  {    CloseHandle(hDestinationFile);    return FALSE;  }  if(ImageNTHeaders.Signature!=0x00004550)  {//    printf("Error./nPE signature is invalid!/n");    CloseHandle(hDestinationFile);    return FALSE;  }      SetFilePointer(hDestinationFile,OffsetOfNewHeader+4,NULL,FILE_BEGIN);  //Set the file pointer to point to IMAGE_FILE_HEADER  ReadFile(hDestinationFile,&ImageFileHeader,    sizeof(IMAGE_FILE_HEADER),&NumberOfBytesRead,NULL); //Retrieve IMAGE_FILE_HEADER  if(NumberOfBytesRead!=sizeof(IMAGE_FILE_HEADER))  {//    printf("/nReadFile() fails! Can't get IMAGE_FILE_HEADER./n");    CloseHandle(hDestinationFile);    return FALSE;  }  if(ImageFileHeader.NumberOfSections<1)  {    CloseHandle(hDestinationFile);    return FALSE;  }    if(dwFileSize<(sizeof(IMAGE_DOS_HEADER)+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*ImageFileHeader.NumberOfSections))  {    CloseHandle(hDestinationFile);    return FALSE;  }  ReadFile(hDestinationFile,&ImageOptionalHeader,    sizeof(IMAGE_OPTIONAL_HEADER),&NumberOfBytesRead,NULL); //Retrieve IMAGE_OPTIONAL_HEADER  if(NumberOfBytesRead!=sizeof(IMAGE_OPTIONAL_HEADER))  {//    printf("/nReadFile() fails! Can't get IMAGE_OPTIONAL_HEADER./n");    CloseHandle(hDestinationFile);    return FALSE;  }  if(ImageOptionalHeader.SectionAlignment<ImageOptionalHeader.FileAlignment)  {    CloseHandle(hDestinationFile);    return FALSE;  }  NumberOfSections=ImageFileHeader.NumberOfSections; //Number of sections  SizeOfSectionTable=sizeof(IMAGE_SECTION_HEADER)*NumberOfSections; //Get the size of Section Table    hGlobalAllocatedMemory=GlobalAlloc(GPTR,SizeOfSectionTable);      //Allocate memory and initialize with zero  if(hGlobalAllocatedMemory==NULL)  {//    printf("/nGlobalAlloc() failed! Please try again./n"); //if failed,return    CloseHandle(hDestinationFile);    return FALSE;  }        pImageSectionHeader=(PIMAGE_SECTION_HEADER)hGlobalAllocatedMemory; //Convert a handle to a pointer to IMAGE_SECTION_HEADER    for(i=0;i<NumberOfSections;i++)  //Retrieve the Section Table  {    ReadFile(hDestinationFile,pImageSectionHeader+i,      sizeof(IMAGE_SECTION_HEADER),&NumberOfBytesRead,NULL);    if(NumberOfBytesRead!=sizeof(IMAGE_SECTION_HEADER))    {//      printf("Error.Can't get IMAGE_SECTION_HEADER./n");      CloseHandle(hDestinationFile);      return FALSE;    }  }  for(i=0;i<NumberOfSections;i++)  {    DWORD dwTempCharacteristics=0;    if((*(pImageSectionHeader+i)).PointerToRawData+(*(pImageSectionHeader+i)).SizeOfRawData>dwFileSize)    {      CloseHandle(hDestinationFile);      return FALSE;    }    if((*(pImageSectionHeader+i)).PointerToRawData % ImageOptionalHeader.FileAlignment!=0)    {      CloseHandle(hDestinationFile);      return FALSE;    }    printf("/nThe name of the section%d: ",i);    printf("%s/n",(*(pImageSectionHeader+i)).Name);        printf("Characteristics: %#x/n",(*(pImageSectionHeader+i)).Characteristics);    printf("/nPlease input the new characteristics of the section./n");    printf("If you enter 0,the characteristics of the section will not be modified./n");    scanf("%x",&dwTempCharacteristics);    if(dwTempCharacteristics!=0)      (*(pImageSectionHeader+i)).Characteristics=dwTempCharacteristics;      printf("------------------------------------------------------");  }  SetFilePointer(hDestinationFile,-((long)SizeOfSectionTable),NULL,FILE_CURRENT); //Set the file poiner  WriteFile(hDestinationFile,pImageSectionHeader,SizeOfSectionTable,&NumberOfBytesWritten,NULL);  if(NumberOfBytesWritten==SizeOfSectionTable)  {    printf("/nComplete successfully!/n");  }  else  {       printf("/nWriteFile() failed!/n");  }  GlobalFree(hGlobalAllocatedMemory); //Free memory  CloseHandle(hDestinationFile);  return TRUE;    }void main(int argc,char *argv[]){  if(argc!=2)  {    printf("Error/nUsage:ModifyCharacteristicsOfSections CompleteDestinationFileName/n");    return;  }  if(!ModifyCharacteristicsOfSections(argv[1]))  {    printf("/nError.This usually means that this file is not a valid PE file or/n");    printf("that this PE file has been modified by another program,for example,shell programm./n");  }}/**********************************************************************************************/以下是上面程序的输出信息:The name of the section0: .textCharacteristics: 0x60000020Please 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: .rdataCharacteristics: 0x40000040Please 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: .dataCharacteristics: 0xc0000040Please 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: .idataCharacteristics: 0xc0000040Please 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: .relocCharacteristics: 0x42000040Please 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: .textCharacteristics: 0xe0000020Please 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: .rdataCharacteristics: 0x40000040Please 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: .dataCharacteristics: 0xc0000040Please 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: .idataCharacteristics: 0xc0000040Please 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: .relocCharacteristics: 0x42000040Please input the new characteristics of the section.If you enter 0,the characteristics of the section will not be modified.0------------------------------------------------------Complete successfully! 
原创粉丝点击