I'm just learning Olly/IDA and writing simple programs in C and looking at the .EXE code in Ollydbg and IDA. Below I have a simple printf Hello World program which I compile in Visual Studio 6. I can see the chain of events starting with things like kernel32.dll calls to get the Windows version number, set up the heap, get the command line, etc. I recognize the main() function and see string variables being put on the stack and can deduce the function at 00401010 is printf(), confirmed by IDA if I look at the "Names Window" for that address, but Olly doesn't explicitly tell me.
#include <stdio.h>
void main(void)
{
printf("blah blah\n");
return;
}
And in Olly here is the assembly for my main() function:
CPU Disasm
Address Hex dump Command Comments
00401000 /$ 68 30604000 PUSH OFFSET 00406030 ; ASCII "blah blah"
00401005 |. E8 06000000 CALL 00401010
0040100A |. 59 POP ECX
0040100B \. C3 RETN
So those assembly instructions above is all that correspond to the C code I wrote. The rest of the .EXE is filled with lots of other code that I'd like to be able to recognized and distinguish the application from LIBC functions like printf(). I know that the compiler will generate OS dependent setup and teardown stuff (like the windows version #, heap, etc), but I figure that after a few programs and learning the PE program standard I should be able to recognize that (plus Olly takes you past that to the application code anyways).
Here, for example, is what I believe to be the top function for the LIBC printf() function, called by CALL 00401010:
CPU Disasm
Address Hex dump Command Comments
00401010 /$ 53 PUSH EBX
00401011 |. 56 PUSH ESI
00401012 |. BE 70604000 MOV ESI,OFFSET 00406070
00401017 |. 57 PUSH EDI
00401018 |. 56 PUSH ESI
00401019 |. E8 4B010000 CALL 00401169
0040101E |. 8BF8 MOV EDI,EAX
00401020 |. 8D4424 18 LEA EAX,[ARG.2]
00401024 |. 50 PUSH EAX
00401025 |. FF7424 18 PUSH DWORD PTR SS:[ARG.1]
00401029 |. 56 PUSH ESI
0040102A |. E8 04020000 CALL 00401233
0040102F |. 56 PUSH ESI
00401030 |. 57 PUSH EDI
00401031 |. 8BD8 MOV EBX,EAX
00401033 |. E8 BE010000 CALL 004011F6
00401038 |. 83C4 18 ADD ESP,18
0040103B |. 8BC3 MOV EAX,EBX
0040103D |. 5F POP EDI
0040103E |. 5E POP ESI
0040103F |. 5B POP EBX
00401040 \. C3 RETN
If I open my EXE in IDA and look in the "Names Window" I see this code starting at 00401010 as "_printf", if I double-click on it I see the following:
That is just the top level, if I follow it down a few levels (following CALL instructions to deeper functions) far enough I find OS functions like KERNEL32.WriteFile() which actually make the string appear in the CMD window.
My question is: how can I recognize library functions like printf() and distinguish them from the application code? It would be nice if they could appear labelled. I know there are scripts and plugins for Olly but so far (in my early learning) I haven't found how to do this.
So far I only know to take the same EXE into IDA and look at the address in the "Names Window" to see if it's the first level function of a CLIB function. But then it would take some work to label functions called by this function as also being part of the standard C library, and not the user code.
It's not a big deal looking up the address in IDA, but there's still a huge amount of code that is lower level functions that it would be nice if I could know quickly are part of CLIB and not the application code.
I'm going to guess it's something like building up an Ollydbg .UDD file or downloading a plugin or script. Sorry if it's obvious in some docs but so far I haven't found it.
All that said, I can imagine that the linker may change things such that the exact pattern may not exist in memory each time, if some optimization is done.