如何在不使用硬编码值的情况下使用基础地址计算函数地址
因此,我正在尝试使用C代码计算ntoskrnl.exe中的函数的64位虚拟地址。我使用C代码确定了此可执行文件的基础地址。该地址与WINDBG报告的内容相吻合。
目前,我有代码确定指向 image_optional_header64 结构的指针。现在,我想知道的是,可以使用与此结构相关联的成员(例如以下成员)确定确切的64位地址的指针(请参见下文)?如果是,请提供一个将计算此地址的公式。目标操作系统是Windows 8.1 64位。
请纠正我的理解,如果无法实现。
extern IMAGE_DOS_HEADER* NtBase; // calculated in another file
dosHeader = (PIMAGE_DOS_HEADER)NtBase;
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
PIMAGE_NT_HEADERS NtHeader = (PIMAGE_NT_HEADERS)((UCHAR*)dosHeader + dosHeader->e_lfanew);
if (NtHeader->Signature == IMAGE_NT_SIGNATURE)
{
//int NumSections = NtHeader->FileHeader.NumberOfSections;
sectionHeader = IMAGE_FIRST_SECTION(NtHeader);
nSectionCount = NtHeader->FileHeader.NumberOfSections;
PIMAGE_OPTIONAL_HEADER64 pOptionalHeader64 = (PIMAGE_OPTIONAL_HEADER64) & (NtHeader->OptionalHeader);
// how to calculate 64 bit address of a function using these members
//pOptionalHeader64->BaseOfCode
//pOptionalHeader64->AddressOfEntryPoint
//pOptionalHeader64->ImageBase;
}
}
So I'm trying to calculate, using C code the 64 bit virtual address of a function located in ntoskrnl.exe. I have, using C code, determined the base address of this executable. This address coincides with what Windbg reports.
At the present I have code that determines the pointer to an IMAGE_OPTIONAL_HEADER64 structure. Now what I would like to know is that given a pointer to this structure is it possible to determine the exact 64 bit address using the members associated with this structure such as the following members (see below)? If yes then please provide a formula that will calculate this address. The target OS is Windows 8.1 64 bit.
Please correct my understanding should this be not possible to achieve.
extern IMAGE_DOS_HEADER* NtBase; // calculated in another file
dosHeader = (PIMAGE_DOS_HEADER)NtBase;
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
PIMAGE_NT_HEADERS NtHeader = (PIMAGE_NT_HEADERS)((UCHAR*)dosHeader + dosHeader->e_lfanew);
if (NtHeader->Signature == IMAGE_NT_SIGNATURE)
{
//int NumSections = NtHeader->FileHeader.NumberOfSections;
sectionHeader = IMAGE_FIRST_SECTION(NtHeader);
nSectionCount = NtHeader->FileHeader.NumberOfSections;
PIMAGE_OPTIONAL_HEADER64 pOptionalHeader64 = (PIMAGE_OPTIONAL_HEADER64) & (NtHeader->OptionalHeader);
// how to calculate 64 bit address of a function using these members
//pOptionalHeader64->BaseOfCode
//pOptionalHeader64->AddressOfEntryPoint
//pOptionalHeader64->ImageBase;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

对我有用的解决方案首先找到了ntoskrnl.exe的基础地址,然后使用windbg找到了感兴趣函数的第一个4-10字节。您可以在windbg命令提示
> uf nt!kisettimerex
上发布以下命令。然后编写从基本地址开始一次读取一个字节的代码,直到到达代码部分的末尾。在到达代码部分的末尾之前,您可能会找到感兴趣的功能。通过一次读取一个字节,将每个字节与第一个字节(然后是第二个字节进行第一个匹配项等)的字节阵列在WINDBG命令提示符处找到的字节数组。这里可能会有一种更有效的算法。The solution that worked for me was first finding the base address of Ntoskrnl.exe then using Windbg locate the first 4-10 bytes of the function of interest. You can issue the following command at the Windbg command prompt
>uf nt!KiSetTimerEx
. Then write code that reads one byte at a time starting from the base address until you have reached the end of the code section. Chances are you're going to find the function of interest before reaching the end of the code section. By reading one byte at a time compare each byte with the first byte (then with the second byte once the first matches and so on) of the byte array found using the above command at the Windbg command prompt. There is likely a more efficient algorithm that can be used here.