Tracing Free
For this example, we are going to go back to the original code we had- an example where the free function was imported and used.
Source Code
#include <iostream>
int main() {
char input[10];
std::cout << "Enter your name> ";
std::cin >> input;
char* copy = (char*)malloc(strlen(input) * sizeof(char));
strcpy(copy, input);
std::cout << "Echo -> " << copy << std::endl;
free(copy);
return 0;
}
Again, very basic buffer overflow.
Loading it into IDA
When we load the program in IDA, we are going to be looking at the import table for this one. This is because, if my assumptions are correct, the compiler had 0 reason to statically link this since the program was not in need of mass change or optimization. So we should see this symbol in the import table.
As shown below - this was accurate.

Since we are using this as practice, ignore the fact that this function exists. As sad as it may sound, we can not currently analyze the functions code as it is dynamically linked. Without intermediate dynamic analysis techniques, we will not be able to analyze this code- alas: this is why I chose to go static, its a more fun hunt!
Tracing Free Back To Its Origins
In order to trace this back to the origins, we must first pay attention to the way that this is imported. In this case, IDA tells us that the symbol table is reading that free comes from the api-ms-win-crt-heap-l1-1-0.dll library.
Cool, so lets check that out in windows. When typing that into the Windows search bar at the bottom of the screen, the DLL should show up as the following.

Awesome! We have located the DLL file! Now lets analyze it in IDA.
Analyzing 'api-ms-win-crt-heap'
We are going to be using the same methods here, but instead of checking the import table, we want to check the export table. This is because whatever the DLL is exporting is going to be what our program imports from the DLL during runtime.

When we analyze this DLL in IDA, there are many things that to the trained eye would not be confusing- but to an untrained eye, it might be confusing why this is happening? Lets first analyze WTF is happening here.
Function Table: Function table seems to be nonexistent. Nothing in there even the usual main entry point for a DLL is specified (DLLMain).
Import Table: Import table is empty which even for a DLL is even confusing to some.
No code: There is no actual .text code here, instead, just data definitions.
Calls like free: We did analyze that free was in fact in here, but then we see
_free_basewhich tells us that there might be an extension to the existing free function.
Most of this- however, is completely normal! The thing is, sometimes, developers will seperate definitions in one DLL to store the location of those functions and map them to other DLLs to avoid many different issues that can occure during the dynamic linking. So the empty import table, no code, etc is actually not a rare thing to come across.
So what now?
Well, lets go to one of the calls that represents free. For me, I will just be going directly to the exact definition. Below is the assembly brick that resembles the result of clicking on the export entry for free.
In here, we do see one interesting set of functions. We see the exported entry, see the public definition and see the functions prototype (pretty much a blueprint to the function) then see the actual database token which lies to be - ucrtbase.free. To someone who does not know Windows internals (which I highly suggest you learning if you will be a reverse engineer or exploit dev for Windows applications), this is pointing to the Dynamic Link Library for the Universal C Runtime Base Library.
Okay cool- so lets see if we can find that DLL.
When we pull up the search for the DLL file, we find it in C:\WINDOWS\system32\ucrtbase.dll. So now, lets analyze this file for the symbol we are looking for!
Analyzing 'ucrtbase.dll'
Before throwing this DLL into IDA, IDA may give you a 'permission denied' if you do not have IDA configured to store the dragged and dropped file into a specific location as you can by default not write to the system32 path in Windows without elevated privilege's.
Dragging and dropping this into IDA, then going to the export table is going to give us this output shown below.

Awesome! We now have a populated DLL! Now lets see if we can find that free function (CTRL+F in the exports area).

Even better! Our calls exist! Remember that both of these are calls that we want to analyze, for now, lets check out the definition to free and analyze the function routine.
When clicking on this function, we get the following.

Hm, even more interesting. It seems that the original function might have been modified a bit! Lets go back and analyze _free_base which was another COI (Call of Interest).
When we analyze this function- we actually see something quite interesting.

If you have been following along for some time now, and have been walking through the CTF, you would know that in the example during the Use After Free #1 exercise for REplay - Isolated Training you would notice this was the same exact function structure to the anonymous one I analyzed which you more specifically had come across in Analyzing Free.
Finalizing
With this finalized, we have learned how to verify specific functions when they are statically linked (due to compiler optimization) despite being dynamically linked programmatically. This should have been a bit easier to follow on- I know it was a bit tough and some extra leg work, but we can definitely say that at least we have a few methods of verifying specific functions or studying them to say the least (for further identification).
Last updated