如何解析PE文件格式的TLS目录?更具体地说是回调?

问题描述 投票:0回答:0

//offset 我用来在 tls 目录中查找回调

unsigned int offset = (tls_directory64.AddressOfCallBacks - nt_headers64.optional_header64.ImageBase) - tls_virtual_address + tls_offset;

我正在使用“AddressOfCallBacks”的 RVA 并将其从 Image Base 中减去。 tls_virtual_address 是 tls 目录所在的节的虚拟地址,tls_offset 是节的原始数据。这行得通,我到达了我的一个 .exe 文件(只有 1 个条目)的回调地址,但另一个 .exe 文件有 2 个回调,数学在这里不起作用......下面我有两张图片,但请注意具有 1 个条目的图像基本上与偏移量匹配,我们只需要减去图像基数。我只是很困惑我们是如何从“140009038”变成“3438”的。我希望这是有道理的,如果需要我可以发送更多信息!

1 entry 2 entries

在头文件中:

struct TLS_CALLBACK64 {
    QWORD Callback;
};
struct TLS_DIRECTORY64 {
    QWORD   StartAddressOfRawData;
    QWORD   EndAddressOfRawData;
    QWORD   AddressOfIndex;
    QWORD   AddressOfCallBacks;
    DWORD   SizeOfZeroFill;
    DWORD   Characteristics;
};

用于解析TLS内部文件。文件是一个 ifstream,我使用 bit_cast 将结构读入内存。

void PeFile::ParseTLS()
{
    DWORD directory_tls_va = nt_headers64.optional_header64.DataDirectory[DIRECTORY_ENTRY_TLS].VirtualAddress;
    unsigned int tls_directory_count = 0;

    unsigned int offset = tls_offset + (directory_tls_va - tls_virtual_address);
    file.seekg(offset, std::ios::beg);
    file.read(
                std::bit_cast<char*>(&tls_directory64),
                sizeof(tls_directory64)
    );

    std::cout << "***** TLS *****" << "\n";
    std::cout << "Start Address of Raw Data: " << tls_directory64.StartAddressOfRawData << "\n";
    std::cout << "End Address of Raw Data: " << tls_directory64.EndAddressOfRawData << "\n";
    std::cout << "Address of Index: " << tls_directory64.AddressOfIndex << "\n";
    std::cout << "Address of Call Backs: " << tls_directory64.AddressOfCallBacks << "\n";
    std::cout << "Size of Zero Fill: " << tls_directory64.SizeOfZeroFill << "\n";
    std::cout << "Characteristics: " << tls_directory64.Characteristics << "\n";

    while(true) {
        unsigned int offset = (tls_directory64.AddressOfCallBacks - nt_headers64.optional_header64.ImageBase) - tls_virtual_address + tls_offset;
        std::cout << offset << "\n";
        std::cout << tls_virtual_address << "\n";
        std::cout << tls_offset << "\n";
        file.seekg(offset, std::ios::beg);
        file.read(
                std::bit_cast<char*>(&tls_callback64),
                sizeof(tls_callback64)
        );

        if(tls_callback64.Callback == 0) {
            break;
        }

        std::cout << "Callback: " << tls_callback64.Callback << "\n";
    }


}
c++ portable-executable
© www.soinside.com 2019 - 2024. All rights reserved.