Calling Functions in Files?

Programming, for all ages and all languages.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Calling Functions in Files?

Post by pcmattman »

Hello all, I'm assisting writing on a project that allows a user to execute any function in any file (dll, exe, or other). For now, I'm focusing on API calls (because I can just write a lookup table and use GetProcAddress) but I'd like to know how I would go about calling the functions from an executable when the available functions are not known.

Win32 Programming, by the way.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

dlopen Maybe? It's for loading libraries......Should be a version close to it for Win32....(cygwin?)
C8H10N4O2 | #446691 | Trust the nodes.
Otter
Member
Member
Posts: 75
Joined: Sun Dec 31, 2006 11:56 am
Location: Germany

Post by Otter »

You cannot simply call a function from an exe file ... Functions from exe files depend on the complete executable image, global variables and so on. If there are no debugging symbols in the file you cannot get the offset of that function either. Could you give an example of what you want to do exactly ?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Calling Functions in Files?

Post by Solar »

pcmattman wrote:...how I would go about calling the functions from an executable when the available functions are not known.
Not at all. You have to know the function, and its parameters (by a header file, for example), in order to call it.

And mind you, you don't call a function "from a file". You call a function from a library, either static (compile-time) or dynamic (runtime). In any case, that library must be loaded into memory, and your references to the library be resolved. That is the job of the linker (static) or the dynamic linker (dynamic). Generally speaking, you don't call functions from another executable.
Every good solution is obvious once you've found it.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

OK then...

Is there anyway of finding the function ordinal and then using that to call the function, after pushing the desired arguments onto the stack?
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

well if it concerns win32 i will guess that you have to look at the PE/COFF fileformat from microsoft. http://www.microsoft.com/whdc/system/pl ... FFdwn.mspx
Author of COBOS
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

pcmattman wrote:OK then...

Is there anyway of finding the function ordinal and then using that to call the function, after pushing the desired arguments onto the stack?
You still did not provide any more information at what you are trying to achieve. You might be wanting to use a DLL, or a COM / Corba / SOAP object, or a .NET assembly. You might be wanting to use a static library. Or you might be thinking about reinventing the wheel.

The method of "finding the function ordinal" differs significantly between those methods...
Every good solution is obvious once you've found it.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

For now, I think I might retreat to just calling functions in a DLL (using LoadLibrary and GetProcAddress)... one thing though, can anyone explain why this does not work?

Code: Select all

#include <windows.h>
#include <stdio.h>

int (WINAPI* MBox)(HWND,LPCTSTR,LPCTSTR,UINT);

int main()
{
	HMODULE user32 = LoadLibrary( "user32.dll" );

	*(void**) &MBox = (void*) GetProcAddress( user32, "MessageBox" );

	MBox( NULL, "Hello", "Hi", MB_OK );

	return 0;
}
Visual C++ on a Win32 box, so don't GCC me or anything :wink:

Edit: error that comes up is an access violation, debug shows that I'm trying to call code at 0x000000 - which is obviously not right...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

The function you are looking for isnt called MessageBox, but rather MessageBoxA or MessageBoxW (the ascii and unicode versions). MSVC will pick one of these as the alias for the MessageBox call, but since you are bypassing its linker you have to choose manually

Also, you have a memory leak: you are missing the FreeLibrary() call
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Oh yeah, good point! I will add the FreeLibrary call later, just wanted to get this to work.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

I still don't quite get it why you're making it so difficult.

Code: Select all

#include <stdio.h>
#include <windows.h>

void main()
{
    MessageBox( NULL, "Hello World", "Hello World Program", MB_OK );
}
You don't have to take an address or open user32.dll manually or anything. Do you have any special reason for the *(void**) &MBox mayhem?
Every good solution is obvious once you've found it.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

I know how to do that, this is just a test of calling the API function by string. This way, a user can input a string and my program can execute it.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

:shock:

Erm...

...uh...

...why would you want to do that?

I know I'm nosy, but it simply doesn't seem to make sense to me...

Check this article on the Microsoft pages on the details of GetProcAddress. Please note where they say that, if you call a function this way, you have to check for a correct parameter list yourself to avoid stack smashing. If you allow users to enter any function name, that might be difficult to do unless MS API provides a way to query a function for its parameter requirements.

Bottom line: Security hole...
Every good solution is obvious once you've found it.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

I'll pass your concerns onto the project admin, who asked me to try to implement this system...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Like he says, he is just testing a concept

If we take a common program, like winamp, you'll notice that it supports plugins. They are located and loaded at run time as the program cant know what dlls will be present during startup - somebody mightve added or removed a homebrew module.

What it does, it loads all the dlls in the directory, then uses getprocaddress to get the additional functionality.

And what you can do with GetWinampPlugin3 in in_mp3.dll, you can do with MessageBoxA in user32.dll, and vice-versa.

And yes, using getprocaddress is bad for security, but then again, who runs winamp as admin and leaves the plugin directory open for non-admin users? (or: why not find another hole in IE instead) "You have to check for a correct parameter list" if enforced by having a fixed location of dlls, a globally unique name for the function, and just one SDK.

Bottom line: Common Sense is one of the best security measures :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply