Hooking the CRT using the Import Address Table

Continuing the memory pool implementation I needed to replace memory allocation functions such as malloc, free, new, delete etc. But first we need to understand how it works internally.

CRT as a DLL

I am using the CRT as a dynamic library, using the static library would have made things a bit easier (see Google Chrome’s way of doing this) but we are stuck with dynamic so we still need a solution.

Let’s take a look at what happens at the assembly level when we call new :

call operator new (013F2B5C0Ch)
13F2B5C0C jmp qword ptr [__imp_operator new (013F729508h)]

Now at 013F2B5C0Ch we see this :

jmp qword ptr [013F729508h]

So as we can see, we go call at a fixed address and this fixed address is just a jmp to somewhere else, but why ?
It turns out we are using the CRT as a DLL so when the program is linked we don’t know where the function will be in memory, that’s why the compiler generates this jumper function. On load the program will load the DLLs in memory, lookup the functions it needs and finally write the correct jmp. Before we jump into the exploit a bit of terminology :
This mechanism is the Import Address Table, and the jumper we found is in the jump thunk table.


Now that we understand what happens and even found a jumper function it will be very simple for us to replace new with out own version of new !
All we got to do is replace the jmp with our own function and we should be good to go (also remember to save the old address as you might need it).

#define PtrFromRva( base, rva ) ( ( ( PBYTE ) base ) + rva )

PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)PtrFromRva(dosHeader, dosHeader->e_lfanew);

	PtrFromRva(dosHeader, ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

This will give us the import descriptor list which contains everything we import from DLLs.
We will then iterate over every entry in the descriptor list and grab the DLL’s name :

for (unsigned int index = 0; ImportDescriptor[index].Characteristics != 0; ++index)
	const char* dllName = (const char*)PtrFromRva( dosHeader, ImportDescriptor[index].Name);

Assuming we found the DLL that contains the symbol we want to hook we would look for our function :

PIMAGE_THUNK_DATA thunk = (PIMAGE_THUNK_DATA)PtrFromRva(dosHeader, ImportDescriptor[index].FirstThunk);
PIMAGE_THUNK_DATA origThunk = (PIMAGE_THUNK_DATA)PtrFromRva(dosHeader, ImportDescriptor[index].OriginalFirstThunk);

for (;origThunk->u1.Function != NULL; origThunk++, thunk++)
	if (origThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)	continue;
	PIMAGE_IMPORT_BY_NAME import = (PIMAGE_IMPORT_BY_NAME)PtrFromRva(dosHeader, origThunk->u1.AddressOfData);
	import->name; // this gives us the symbol name

So what’s with “thunk” and “origThunk” ? They are both needed, origThunk gives us the import information we need like the name of the symbol and thunk is where the actual jmp is stored. So we are using origThunk to find the symbol and once we found it thunk will contain our jmp.

Now let’s assume we found our symbol, you will need to make thunk writable using VirtualProtect and all you have to do is access


It will contain the address of the jump which you can save or not and finally replace with the address of your function.

That’s it ! Now you know how to hook imported symbols, all you need to do is find the DLL’s name and the symbol’s name, I trust you know how to use a dependency walker and will not have any trouble doing so.

Hooking the CRT using the Import Address Table

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s