1

假设我有一些代码

_declspec(noinline) void foo() {
    printf("...");
}

而且我已经像这样将可执行文件映射到内存中

#include <Windows.h>
#include <stdio.h>

_declspec(noinline) void foo() {
    printf("...");
}

int main(int argc, char* argv[]) {
    IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)GetModuleHandle(NULL);
    IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)((UCHAR*)dos + dos->e_lfanew);
    return 0;
}

如何将 &foo 转换为可执行文件中的偏移量?这甚至可能吗?

编辑:我尝试了@moonshadow 的解决方案,但函数的地址总是在 .text 部分之外,如下所示

#include <Windows.h>
#include <stdio.h>

IMAGE_SECTION_HEADER* getSection(const IMAGE_NT_HEADERS* nt_headers, unsigned section) {
    return reinterpret_cast<IMAGE_SECTION_HEADER*>(
        (UCHAR*)nt_headers->OptionalHeader.DataDirectory +
        nt_headers->OptionalHeader.NumberOfRvaAndSizes*sizeof(IMAGE_DATA_DIRECTORY) +
        section*sizeof(IMAGE_SECTION_HEADER)
    );
}

_declspec(noinline) void foo() {
    printf("...");
}

int main(int argc, char* argv[]) {
    HANDLE hFile = CreateFileA(argv[0], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    HANDLE hFileMapObj = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    UCHAR* content = static_cast<UCHAR*>(MapViewOfFile(hFileMapObj, FILE_MAP_READ, 0, 0, 0));

    IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)content;
    IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)((UCHAR*)dos + dos->e_lfanew);

    for(int i = 0; i < nt->FileHeader.NumberOfSections; i++) {
        auto sec = getSection(nt, i);
        printf("%s\n", sec->Name);
        DWORD va = sec->VirtualAddress + nt->OptionalHeader.ImageBase;
        printf("0x%x - 0x%x\n\n", va, va + sec->SizeOfRawData);
    }

    auto text = getSection(nt, 0);
    printf("%s\n0x%x\n", text->Name, (DWORD)foo);

    foo();

    return 0;
}

知道这里出了什么问题吗?

4

0 回答 0