'How to calculate a address of a function using base address without using hard coded values

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;  
    }
}


Solution 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user121309