2012-03-08 90 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; 
    }