Адрес точки входа - PullRequest
       28

Адрес точки входа

2 голосов
/ 08 марта 2012

Я использую следующий код, чтобы узнать адрес точки входа для файла с именем connected list.exe, но он выводит большое число типа 699907, тогда как размер самого файла составляет всего 29 КБ, такозначает это число и как я могу найти адрес точки входа?

#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 ]

1 голос
/ 15 января 2018

Файл открывается в памяти, поэтому адрес номера точки входа очень большой. Система предоставляет доступную память для файла, следовательно, базовый адрес всегда изменяется при открытии файла в памяти.

Если вы хотите получить доступ к фактическому смещению диска 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;
    }
1 голос
/ 08 марта 2012

AddressOfEntryPoint - это относительный виртуальный адрес точки входа, а не необработанное смещение в файле. Он содержит адрес первой инструкции, которая будет выполнена при запуске программы.

Обычно это не то же самое, что начало раздела кода. Если вы хотите получить начало раздела кода, вы должны увидеть поле BaseOfCode.

...