views:

122

answers:

4

I'm creating a class for a Lua binding which holds a pointer and can be changed by the scripter. It will include a few functions such as :ReadString and :ReadBool, but I don't want the application to crash if I can tell that the address they supplied will cause an access violation.

Is the a good way to detect if an address is outside of the readable/writable memory? Thanks!

A function library that may be useful is the "Virtual" function libraries, for example VirtualQuery

I'm not really looking for a foolproof design, I just want to omit the obvious (null pointers, pointers way outside the possible memory location)

I understand how unsafe this library is, and I'm not looking for safety, just sanity.

A: 

There is no, and that's why you should never do things like this.

mbq
Well there's obviously a set position of every section in memory, it's not like you CAN'T POSSIBLY tell that something is outside the virtual memory's location.
Gbps
The OS may know. But it doesn't tell you - respectively, there is no way (I know of) to ask it. Provided that there is an OS and/or virtual memory at all.
delnan
There is a way to tell whether OS believes that some area is free and so blocked it; there is no way to check if some random place in memory is a good place for storing/reading your data, because you should know that.
mbq
+3  A: 

There are ways, but they do not serve the purpose you intend. That is; yes, you can determine whether an address appears to be valid at the current moment in time. But; no, you cannot determine whether that address will be valid a few clock cycles from now. Another thread could change the virtual memory map and a formerly valid address would become invalid.

The only way to properly handle the possibility of accessing suspect pointers is using whatever native exception handling is available on your platform. This may involve handling the signal SIG_BUS or it may involve using the proprietary __try and __catch extensions.

The idiom to use is the one wherein you attempt the access, and explicitly handle the resulting exception, if any does happen to occur.

You also have the problem of ensuring that the pointers you return point to your memory or to some other memory. For that, you could make your own data structure, a tree springs to mind, which stores the valid address ranges your "pointers" can achieve. Otherwise, the script code can hand you some absolute addresses and you will change memory structures by the operating system for the process environment.

The application you write about is highly suspect and you should probably start over with a less explosive design. But I thought I would tell you how to play with fire if you really want to.

Heath Hunnicutt
Well, the design itself is explosive to begin with. It's not like everyone's going to be using these functions, it's basically a library of unsafe functions to serve a specific purpose.
Gbps
I do that stuff to. So there are some matches for you. I wouldn't use the VirtualQuery approach due to the race condition. Just use __try and __catch. If you must convert a pointer to a good argument for VirtualQuery, just mask off the bits of the pointer which are less than a page size granularity, and you have the page address.
Heath Hunnicutt
Oh, you were faster. Here's a pointer to the MSDN Docs, which explains why IsBadReadPtr() is in fact a bad idea and why nobody should use it:http://msdn.microsoft.com/en-us/library/aa366713(v=VS.85).aspx
Luther Blissett
@Luther Glad to know Microsoft has faith in their libraries!
Gbps
@Gbps: well, at least they've realized this is a bad thing to do. Have you? ;)
jalf
A: 

Perhaps try using segvcatch, which can convert segfaults into C++ exceptions.

Michael Williamson
+2  A: 

Check out Raymond Chen's blog post, which goes more deeply into why this practice is bad. Most interestingly, he points out that, once a page is tested by IsBadReadPtr, further accesses to that page will not raise exceptions!

Drew Hoskins