Skip to main content
gamedev.net
🔒 Locked

GetProcAddress() question...

Started by RegularKid Jul 27, 2007 at 10:38 AM 13 replies 3.9k views
Original Post
RegularKid
RegularKid
I've searched around but can't seem to find any info on type checking the function I get from GetProcAddress() before I call it to make sure it has the right parameters / return type. I am loading in a .dll dynamically at run-time and calling a function to run the AI in a small game I'm making. The problem is that I want these .dll's to be creatable by anyone. So, since they are prone to errors due to the fact that they are not compiled with my code, I want to be able to ensure that the function has the correct parameters / return type. Any ideas?
taby
taby
There's no guarantee with plain old DLLs. If the function is broken, it's the plugin DLL's fault plain and simple.
Evil Steve
Evil Steve
As taby said. A function returned from GetProcAddress() is just a pointer to a chunk of memory. There's no way to tell what the type of the parameters is, really.

The best you're likely to get is to have a GetAIVersion() function exported from the DLL, and if that returns a value other than you expect, you can assume the DLL is bad. Still doesn't help if someone's screwed up the parameters though.
SiCrane
SiCrane
It's actually worse than that since you don't even have any guarantees that the return value of GetProcAddress() is even a function.

If you want a safer plug-in system you may want to consider using a different language/system for your plug-ins. For example, you can embed Python as an interpreter and run plug-ins as Python scripts rather than user created DLLs.
RegularKid
RegularKid
Ok, good to know. Thanks, guys.
Zorm
Zorm
With a decent dose of exception handling you should be able to safely load any DLL and call a function inside it.

The key idea here is to make sure that the DLL can't crash your program, something along the lines of SEH can probably handle the job.
SiCrane
SiCrane
Exception handling alone can't guarantee that a malformed native DLL can't crash your program. You also have to vet all the interactions that DLL has with the state of your application for consistency. For example, a function call to a DLL may return a pointer to the stack. If your application later writes to that pointer you can get a big fat unhappy crash. And since exception handling information is read from the stack, that could include screwing up the exception handling mechanism.
Zorm
Zorm
You can of course use IsBad*Ptr, in this case perhaps IsBadCodePtr to try and help determine if something is bad before trying to execute/read/write to it. There are also other methods of preventing things from destroying the stack. I can't remember how to do it off the top of my head and I can't find the log file where the guy told me about it.

I'm not saying you'll be able to prevent a hostile DLL from crashing your application, but one that has been poorly programmed shouldn't be able too.

I'm reasonably sure one can make it so that its safe and this is a really nice solution to te plugin problem because it allows for incredible amounts of power when it comes to wanting to do something.
SiCrane
SiCrane
The bad pointer functions are coarse level memory access checks; they aren't magic. In this case, IsBadCodePtr() only checks if the process has read access to the given memory location. Giving it an address to committed memory in the stack will return false.
DaBookshah
DaBookshah
Just thought I'd say that GetProcessAddress is, really, an incredibly crude tool. I recall that it basically just reads the export table of a dll or executable, and returns the pointer associated with a given function name. That's it.

And no, there is ABSOLUTELY no way to stop a hostile DLL from crashing your program. You cannot stop it from screwing with the stack, your SEH handler, anything. If it wanted to really give you the finger, it could even completely unload the original application, and still keep running. Not to mention that those IsBad*Ptr functions are pretty stupid too.
Evil Steve
Evil Steve
Quote:
Original post by DaBookshah
Not to mention that those IsBad*Ptr functions are pretty stupid too.
Seconded. Reasons Why
Zorm
Zorm
Quote:
Original post by Evil Steve
Seconded. Reasons Why


Those are for completely different reasons and being used for a different perhaps than here. Not really applicable.

Also if you read that link and read http://blogs.msdn.com/ericlippert/archive/2006/09/27/774117.aspx you'd find another solution in VirtualQuery
SiCrane
SiCrane
VirtualQuery() is also a coarse level memory access check that also isn't magic. Using VirtualQuery() will not add any safety to using a DLL.
DaBookshah
DaBookshah
Quote:
Original post by SiCrane
VirtualQuery() is also a coarse level memory access check that also isn't magic.


Can't back this up, but I was under the impression that VirtualQuery was not 'coarse'. You check your read/write/execute permissions on a memory block, and that's that. I would have thought you could take care of guard pages, too.
SiCrane
SiCrane
VirtualQuery() will give you information about a page - if it's readable, writable, reserved, committed, etc. It is coarse in that it gives you information at the page level, but also in that the result is not a meaningful safeguard against bad DLL code. For example, a page in the stack is going to show up as readable, writable, committed and private. This is the same result as you'd get for a normal allocation in the heap. And the same result as you'd get for a page that contains only CRT heap bookkeeping information. And the same result as you'd get for a page that contains only freed heap allocations.

Topic Locked

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

Sign in to reply to this topic.