Sometimes you have to hide stuff that your code does from a reverse engineer’s eye or static analysis tools. To achieve that, I came up with a few helper macros and functions to search for functions at runtime and call them without leaving a trace in the executable’s import table.

TL;DR

Hiding function imports

Let’s take this simple program as an example:

1
2
3
4
5
6
7
#include <Windows.h>

int main()
{
    auto memory = VirtualAlloc(0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    std::cout << "Allocated memory at: 0x" << std::hex << memory << std::endl;
}

If you compile it and dump the imports using dumpbin.exe you will see that the VirtualAlloc function from kernel32.dll is imported by our program:

dumpbin.exe /IMPORTS .\RTFNTemplate.exe

dumpbin output

1
2
3
4
5
6
7
#include <Windows.h>

int main()
{
    auto memory = RTFN_GET_ADDR(L"kernel32.dll", VirtualAlloc)(0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    std::cout << "Allocated memory at: 0x" << std::hex << memory << std::endl;
}

Run dumpbin.exe again and voila, the import is gone:

dumpbin output

Hiding *.dll imports

This is a simple program that downloads a file using the URLDownloadToFileA which is located in the urlmon.dll.

1
2
3
4
5
6
7
#include <urlmon.h>
#pragma comment(lib, "urlmon.lib")

int main()
{
    URLDownloadToFileA(nullptr, "http://example.org/image.avif", "./image.avif", 0, nullptr);
}

dumpbin output

You have to load the DLL file if it’s not already loaded like “kernel32.dll” (maybe use manual DLL mapping to load it to hide LoadLibrary calls).

1
2
3
4
5
6
7
#include <urlmon.h>

int main()
{
    RTFN::RtFnLoadLibraryA("urlmon.dll");
    RTFN_GET_ADDR(L"urlmon.dll", URLDownloadToFileA)(nullptr, "http://example.org/image.avif", "./image.avif", 0, nullptr);
}

The import should be gone now. But keep in mind that the string urlmon.dll is going to be in you binary. To hide this, use some kind of compile-time string encryption like this: https://github.com/JustasMasiulis/xorstr

strings64.exe .\RTFNTemplate.exe

strings output

How it works