Jump to content
Tuts 4 You

[C++] Simple Import Table Parser


mrexodia

Recommended Posts

Just some small code I created for a friend. Not stress-tested or anything, might be useful though :)

#include <windows.h>
#include <stdio.h>

int gtfo(const char* text = "")
{
    printf("gtfo! (%s)\n", text);
    return -1;
}

int main(int argc, char* argv[])
{
    //LEAKY AND UNSAFE!
    if (argc < 2)
        return gtfo("argc");

    //read the file
    auto hFile = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
    if (hFile == INVALID_HANDLE_VALUE)
        return gtfo("CreateFile");

    //map the file
    auto hMappedFile = CreateFileMappingA(hFile, nullptr, PAGE_READONLY | SEC_IMAGE, 0, 0, nullptr); //notice SEC_IMAGE
    if (!hMappedFile)
        return gtfo("CreateFileMappingA");

    //map the sections appropriately
    auto fileMap = MapViewOfFile(hMappedFile, FILE_MAP_READ, 0, 0, 0);
    if (!fileMap)
        return gtfo("MapViewOfFile");

    auto pidh = PIMAGE_DOS_HEADER(fileMap);
    if (pidh->e_magic != IMAGE_DOS_SIGNATURE)
        return gtfo("IMAGE_DOS_SIGNATURE");

    auto pnth = PIMAGE_NT_HEADERS(ULONG_PTR(fileMap) + pidh->e_lfanew);
    if (pnth->Signature != IMAGE_NT_SIGNATURE)
        return gtfo("IMAGE_NT_SIGNATURE");

    if (pnth->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
        return gtfo("IMAGE_FILE_MACHINE_I386");

    if (pnth->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
        return gtfo("IMAGE_NT_OPTIONAL_HDR_MAGIC");

    auto importDir = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
    puts("Import Directory");
    printf(" RVA: %08X\n", importDir.VirtualAddress);
    printf("Size: %08X\n\n", importDir.Size);

    if (!importDir.VirtualAddress || !importDir.Size)
        return gtfo("No Import directory!");

    auto importDescriptor = PIMAGE_IMPORT_DESCRIPTOR(ULONG_PTR(fileMap) + importDir.VirtualAddress);
    if (!IsBadReadPtr((char*)fileMap + importDir.VirtualAddress, 0x1000))
    {
        for (; importDescriptor->FirstThunk; importDescriptor++)
        {
            printf("OriginalFirstThunk: %08X\n", importDescriptor->OriginalFirstThunk);
            printf("     TimeDateStamp: %08X\n", importDescriptor->TimeDateStamp);
            printf("    ForwarderChain: %08X\n", importDescriptor->ForwarderChain);
            if (!IsBadReadPtr((char*)fileMap + importDescriptor->Name, 0x1000))
                printf("              Name: %08X \"%s\"\n", importDescriptor->Name, (char*)fileMap + importDescriptor->Name);
            else
                printf("              Name: %08X INVALID\n", importDescriptor->Name);
            printf("              Name: %08X\n", importDescriptor->Name);
            printf("        FirstThunk: %08X\n", importDescriptor->FirstThunk);

            auto thunkData = PIMAGE_THUNK_DATA(ULONG_PTR(fileMap) + importDescriptor->FirstThunk);
            for (; thunkData->u1.AddressOfData; thunkData++)
            {
                auto rva = ULONG_PTR(thunkData) - ULONG_PTR(fileMap);

                auto data = thunkData->u1.AddressOfData;
                if (data & IMAGE_ORDINAL_FLAG)
                    printf("              Ordinal: %08X\n", data & ~IMAGE_ORDINAL_FLAG);
                else
                {
                    auto importByName = PIMAGE_IMPORT_BY_NAME(ULONG_PTR(fileMap) + data);
                    if (!IsBadReadPtr(importByName, 0x1000))
                        printf("             Function: %08X \"%s\"\n", data, (char*)importByName->Name);
                    else
                        printf("             Function: %08X INVALID\n", data);
                }
            }

            puts("");
        }
    }
    else
        puts("INVALID IMPORT DESCRIPTOR");

    return 0;
}

Greetings

  • Like 9
Link to comment

Hi, interesting code and easy to read, but there's something that I don't understand : you are adding virtual addresses to raw address , is it possible with import table (I'm not used to it), or the file is supposed to be a dump?

Link to comment

@cob_258 What raw addresses? I map the file with SEC_IMAGE, which loads the executable like it would if the windows loader loaded it in memory. 

  • Like 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...