Jump to content
View in the app

A better way to browse. Learn more.

Tuts 4 You

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[C++] Simple Import Table Parser

Featured Replies

Posted

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

  • Author

My apologies, I posted in the wrong section! Would a moderator be so kind to move it?

  • Author

@Teddy Rogers No, it was just a small code snippet. Thanks for moving!

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?

  • Author

@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. 

Interesting, I didn't know that we can do that

Create an account or sign in to comment

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.