2012-03-08 7 views
2

私は、リンクされたlist.exeと呼ばれるファイルのエントリポイントのアドレスを見つけるために次のコードを使用していますが、ファイルのサイズ自体は699907 29Kbなので、この番号は何を意味し、どのようにしてエントリポイントのアドレスを見つけることができますか?エントリポイントのアドレス

#include<iostream> 
#include<fstream> 
#include<iomanip> 
#include<strstream> 
#include<Windows.h> 
#include<stdio.h> 
#include<WinNT.h> 

int main() 
{ 
FILE *fp; 
if((fp = fopen("linked list.exe","rb"))==NULL) 
    std::cout<<"unable to open"; 
int i ; 
char s[2]; 
IMAGE_DOS_HEADER imdh; 
fread(&imdh,sizeof(imdh),1,fp); 
fseek(fp,imdh.e_lfanew,0); 

IMAGE_NT_HEADERS imnth; 
fread(&imnth,sizeof(imnth),1,fp); 

printf("%d",imnth.OptionalHeader.AddressOfEntryPoint); 
} 

答えて

1

AddressOfEntryPointは、エントリポイントの相対仮想アドレスであり、ファイル内の生のオフセットではありません。プログラムの開始時に実行される最初の命令のアドレスを保持します。

通常、これはコードセクションの最初と同じではありません。コードセクションの先頭を取得する場合は、BaseOfCodeフィールドが表示されます。

0

ファイルがメモリに開かれているため、エントリポイント番号のアドレスが非常に大きいです。システムはファイルに利用可能なメモリを提供します。したがって、ファイルがメモリ内で開かれると、ベースアドレスは常に変更されます。

AEPの実際のディスクオフセット、つまりエントリポイントのアドレスにアクセスする場合は、下記のスニペットコードをご覧ください。

LPCSTR fileName="exe_file_to_parse"; 
    HANDLE hFile; 
    HANDLE hFileMapping; 
    LPVOID lpFileBase; 
    PIMAGE_DOS_HEADER dosHeader; 
    PIMAGE_NT_HEADERS peHeader; 
    PIMAGE_SECTION_HEADER sectionHeader; 

    hFile = CreateFileA(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); 

    if(hFile==INVALID_HANDLE_VALUE) 
    { 
     printf("\n CreateFile failed in read mode \n"); 
     return 1; 
    } 

    hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL); 

    if(hFileMapping==0) 
    { 
     printf("\n CreateFileMapping failed \n"); 
     CloseHandle(hFile); 
     return 1; 
    } 

    lpFileBase = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0); 

    if(lpFileBase==0) 
    { 
     printf("\n MapViewOfFile failed \n"); 
     CloseHandle(hFileMapping); 
     CloseHandle(hFile); 
     return 1; 
    } 

    dosHeader = (PIMAGE_DOS_HEADER) lpFileBase; //pointer to dos headers 

    if(dosHeader->e_magic==IMAGE_DOS_SIGNATURE) 
    { 
     //if it is executable file print different fileds of structure 
     //dosHeader->e_lfanew : RVA for PE Header 
     printf("\n DOS Signature (MZ) Matched"); 

     //pointer to PE/NT header 
     peHeader = (PIMAGE_NT_HEADERS) ((u_char*)dosHeader+dosHeader->e_lfanew); 

     if(peHeader->Signature==IMAGE_NT_SIGNATURE) 
     { 
      printf("\n PE Signature (PE) Matched \n"); 
      // valid executable 
      //address of entry point 
      DWORD ptr = peHeader->OptionalHeader.AddressOfEntryPoint; 
      printf("\n RVA : %x \n",ptr); // this is in memory address 
      //suppose any one wants to know actual disk offset of "address of entry point" (AEP) 

      sectionHeader = IMAGE_FIRST_SECTION(peHeader); 
      UINT nSectionCount = peHeader->FileHeader.NumberOfSections; 
      UINT i=0; 
      for(i=0; i<=nSectionCount; ++i, ++sectionHeader) 
      { 
       if((sectionHeader->VirtualAddress) > ptr) 
       { 
        sectionHeader--; 
        break; 
       } 
      } 

      if(i>nSectionCount) 
      { 
       sectionHeader = IMAGE_FIRST_SECTION(peHeader); 
       UINT nSectionCount = peHeader->FileHeader.NumberOfSections; 
       for(i=0; i<nSectionCount-1; ++i,++sectionHeader); 
      } 

      DWORD retAddr = ptr - (sectionHeader->VirtualAddress) + 
        (sectionHeader->PointerToRawData); 
      printf("\n Disk Offset : %x \n",retAddr+(PBYTE)lpFileBase); 
      // retAddr+(PBYTE)lpFileBase contains the actual disk offset of address of entry point 

     } 
     UnmapViewOfFile(lpFileBase); 
     CloseHandle(hFileMapping); 
     CloseHandle(hFile); 
     //getchar(); 
     return 0; 
    } 
    else 
    { 
     printf("\n DOS Signature (MZ) Not Matched \n"); 
     UnmapViewOfFile(lpFileBase); 
     CloseHandle(hFileMapping); 
     CloseHandle(hFile); 
     return 1; 
    } 
関連する問題