So basically I my nasm syntax asm code, I use some extern functions like this:

extern _printf
extern __imp__Sleep@4
call _printf
call    [__imp__Sleep@4]

Then I use nasm to assemble it into obj:

nasm -f win32 test.asm

Then I use IDA Pro to disassemble test.obj, I can see code like this:

enter image description here

See, extern function name like _printf has been kept.

But when I link this obj file:

cl /MT z:\\windows\\test.obj /link kernel32.lib libcmt.lib /SUBSYSTEM:CONSOLE

Then I use IDA Pro to disassemble test.exe, I can see code like this:

enter image description here

See, the function name of _printf has been changed.

I know basically after static link, the code of _printf has been put into the test.exe, in the subroutine of sub_409C9B

But basically I have to make the name of extern declared functions unchangeable, because I need to reverse engineering the test.exe and do some modify/remove towards those functions, and once PE exe lost the name info, I can not locate those targeting functions.

So my question is:

Why cl.exe will change the name of those functions, and is there any way to stop the change(I mean keep the function name unchangeable during the link time)?

  • 1
    That is why there exists signatures for IDA (Flirt) to detect such standard library functions. Apply them and see.
    – 0xec
    Feb 20, 2014 at 18:09

2 Answers 2


You've got some kind of XY-problem.

The truth is: it's IDA who so to say "changes" the name of (something she thinks is) a function from absolutely nothing to sub_{address}. Why on earth would PE-file have non-exported symbols stored in it? Some kind of masochism? To give a candy to reversers?

Thus, you have at least three ways of dealing with your problem:

  • pray and hope that IDA's FLIRT will heuristically recognize printf;
  • link your program with debug-info: -debug which tells linker to generate pdb-file which IDA will query for all the symbols stored for your application;
  • tell linker to -export:printf so that it's name will be in export directory and you can get it's address easily even programmatically.

When printf() is called as an external function, the Windows loader needs to look up the address of the printf() function by-name at run-time so that the caller can find the printf() code.

When printf() is called as an embedded library function, the compiler already knows the address of the printf() function at compile-time, and thus doesn't need to embed the function's name in the executable.

If you want the printf() name to automatically show in your disassembly, either export debug symbols or stick with using external DLLs. Alternatively, you may be able to use IDA's FLIRT libraries to identify the printf() function in the embedded library code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.