//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”的。我希望这是有道理的,如果需要我可以发送更多信息!
在头文件中:
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";
}
}