Skip to main content
GameDev.net gamedev.net
🔒 Locked

Link to .exe

Started by nullsquared Dec 27, 2009 at 9:21 PM 4 replies 1.3k views
Original Post
nullsquared
nullsquared
Consider that foo.exe links to static library bar.lib. Can I now make baz.exe that uses functions from bar.lib by linking to foo.exe? AFAIK, if I know the addresses and signatures of functions in foo.exe, I can explicitly call them. But is there some more direct or automated way of doing it?
Codeka
Codeka
By the time your C/C++/whatever code is compiled into an executable, there is no such thing as "functions" anymore - it's all just one gigantic blob of x86 machine code. When you export a function from a DLL, you're explicitly telling the compiler "leave this function in tact so that I can call it from another module". If you didn't do that, the compiler is free to inline the function, mangle the arguments or even remove it completely if no other functions from that DLL use it.

Now technically, the file format for EXE and DLL is the same, so there's no technical reason why you couldn't export functions from an EXE as well, but since most executables don't need to do that, the compiler isn't neccesarily going to support that feature.

Why do you want to do this anyway? Why don't you just link baz.exe to the same lib, or compile the lib as a DLL and use the same DLL from both?
mattd
mattd
Why don't you just statically link baz.exe to bar.lib directly?

AFAIK EXEs aren't accepted by link because they're not a COFF file, and can't be used with GetProcAddress because they lack an exports table.
nullsquared
nullsquared
Quote:
Original post by Codeka
By the time your C/C++/whatever code is compiled into an executable, there is no such thing as "functions" anymore - it's all just one gigantic blob of x86 machine code.

Hm, yeah, you're right.
Quote:
When you export a function from a DLL, you're explicitly telling the compiler "leave this function in tact so that I can call it from another module".

What does this exactly mean? I mean, what makes it different from a non-exported function in an .exe?

Quote:

Why do you want to do this anyway? Why don't you just link baz.exe to the same lib, or compile the lib as a DLL and use the same DLL from both?


Just curious because I like to mess with stuff like this [grin]
KulSeran
KulSeran
Quote:

What does this exactly mean? I mean, what makes it different from a non-exported function in an .exe?

Exactly as he tried to explain afterwords.
When you make a .dll, you tell the compiler to make sure there are entry points for all functions that you've marked for export, and to make sure those entry points conform exactly as specified, and that the body of the function does exactly what you defined it to do.
If you don't tell the compiler that, it is free to do whatever it wants with the code.

*It can inline the function. No more entry point, the code is now in-place throughout the code.
*It could drop arguments that aren't ever used ever. Thus you can't know how to call the new optimized function.
*It could remove code from your function. If the compiler can deduce that some code path is never taken (if, switch, for, while), it will drop the other code paths and remove the condition. (ie, you give arguments with defaults. If you never override the default, it will inline the default value.)
*Some functions, like templated ones aren't exportable, but could exist in headers that you include alongside the .dll. The functions exist only once the compiler makes a pass over one of your .cpp files that uses the template.

Doesn't mean you can't still snoop about in the .exe for stuff after the fact, and still have some results. Lots of hacks for games do this type of thing. For instance some older games I have, i also have video-viewers for that let you watch the cinamatics. But, since it was before the standard codec ways of video, the programs just link against the game's .exe and use it to decompress the video. Other's i've seen link against the game's .exe to decompress the archive files that pack all the game assets. Since it was easier to find the code that did the work in the .exe that it was to try and reverse engineer what the code did and extract all the needed parts.
nullsquared
nullsquared
Quote:
Original post by KulSeran
Quote:

What does this exactly mean? I mean, what makes it different from a non-exported function in an .exe?

Exactly as he tried to explain afterwords.
When you make a .dll, you tell the compiler to make sure there are entry points for all functions that you've marked for export, and to make sure those entry points conform exactly as specified, and that the body of the function does exactly what you defined it to do.
If you don't tell the compiler that, it is free to do whatever it wants with the code.

*It can inline the function. No more entry point, the code is now in-place throughout the code.
*It could drop arguments that aren't ever used ever. Thus you can't know how to call the new optimized function.
*It could remove code from your function. If the compiler can deduce that some code path is never taken (if, switch, for, while), it will drop the other code paths and remove the condition. (ie, you give arguments with defaults. If you never override the default, it will inline the default value.)
*Some functions, like templated ones aren't exportable, but could exist in headers that you include alongside the .dll. The functions exist only once the compiler makes a pass over one of your .cpp files that uses the template.

Doesn't mean you can't still snoop about in the .exe for stuff after the fact, and still have some results. Lots of hacks for games do this type of thing. For instance some older games I have, i also have video-viewers for that let you watch the cinamatics. But, since it was before the standard codec ways of video, the programs just link against the game's .exe and use it to decompress the video. Other's i've seen link against the game's .exe to decompress the archive files that pack all the game assets. Since it was easier to find the code that did the work in the .exe that it was to try and reverse engineer what the code did and extract all the needed parts.


Ah, thanks. That's what I was looking for. Essentially, in the end, it's all the same - instructions at memory addresses (which is what makes disassemblers possible). However, by marking a function as a DLL export, the function is preserved exactly as-is so that it can be called from external code more easily.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.