入口地址

时间:2012-03-08 06:44:15

标签: exe portable-executable entry-point

我使用下面的代码找出一个名为linked 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);
}

2 个答案:

答案 0 :(得分:1)

AddressOfEntryPoint是入口点的相对虚拟地址,而不是文件中的原始偏移量。它保存程序启动时将执行的第一条指令的地址。

通常这与代码部分的开头不同。如果您想获得代码部分的开头,您应该看到BaseOfCode字段。

答案 1 :(得分:1)

文件在内存中打开,这就是入口点编号的地址非常大的原因。系统为文件提供可用内存,因此,在内存中打开文件时,基址始终会更改。

如果您想访问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;
    }