0

I've created a memory manager that allocates memory surrounded by two pages with protection PAGE_NOACCESS. I call a function that uses this memory in a SEH block, and I catch ACCESS_VIOLATION exceptions (if any) that happens in this block. Now, in my exception handler, is it possible to retrieve the address that the program didn't have rights to access? I know you can get a pointer to the faulting instruction, but then you would have to actually parse the assembly?

This is so I know whether the violation was caused in my guarded memory (from which I can continue execution; this can be expected behavior) or if it was another (unknown) place, from which i probably would have to terminate the process. I thought about using PAGE_GUARD protection instead, which would help me identify that the memory accessed could have been from my guarded memory, but it is not certain (ie. the memory after the stack is protected with PAGE_GUARD afaik).

Any help appreciated :)

Shaggi
  • 1,121
  • 1
  • 9
  • 31
  • This is really dodgy. If your code accesses invalid memory, it is wrong and needs to be fixed, not "handled". – Kerrek SB Jun 06 '13 at 15:13
  • Sounds a bit like you are asking an XY question. What are you ACTUALLY trying to do? – Mats Petersson Jun 06 '13 at 15:15
  • My code doesn't. I'm trying to 'sandboxe' code from outside, and be sure it wont fail (program must not crash except if totally unavoidable). – Shaggi Jun 06 '13 at 15:15
  • @MatsPetersson Im trying to find the address that was being accessed and raised the exception. If i know that the accessed address was allocated from the memory manager, i can safely continue execution (from another point). – Shaggi Jun 06 '13 at 15:17
  • So if the sandboxed code does something really daft, you want to catch it and then what? Continue? With what values in the register that tried to read the bad memory? How do you know you are not corrupting something else when you continue. If it tries to access invalid memory, KILL IT! – Mats Petersson Jun 06 '13 at 15:18
  • look up __try and __except in msdn – Balog Pal Jun 06 '13 at 15:19
  • 1
    @MatsPetersson The sandboxed code is managed and can be 'registrered' and unregistrered. If the exception is caught and i handle it, i disable the code so long as i can guarantee the memory thrashed was only what i allocated (that's why i put guard pages around the allocated memory). I do not continue execution in the faulting code. It cleans up the state afterwards and the faulting code wont ever be called again. – Shaggi Jun 06 '13 at 15:22
  • @BalogPal Yes I'm using that. (http://stackoverflow.com/questions/16589146/template-function-accepting-callable-functors-with-x-parameters) – Shaggi Jun 06 '13 at 15:23
  • But what if the sandboxed code accesses memory far outside the allocated region, so far that it goes past your PAGE_NOACCESS page, but the memory happens to be valid? – Raymond Chen Jun 06 '13 at 16:02
  • If you want to keep the sandboxed process from causing trouble then sandbox it by running it in a separate process. What you're trying to do *will never work reliably* – jalf Jun 06 '13 at 16:46
  • @RaymondChen It's allowed for the plugin to do that, but i guess you mean accessing valid memory it shouldn't write to. Well, that's UB as always, and i really can't control that. I can guard some common errors (this in particular fixes off-by-one errors and loops out of control) but there's only so much i can do. – Shaggi Jun 06 '13 at 18:42
  • @jalf It's not possible to bridge it like that. Nope i won't, and I never said it will, however if i can fix a small programming mistake that i can guarantee was not critical, i can avoid crashing the host, which is pretty important. I realize this isn't the perfect and purist way, but in practice (and in context of this) there really isn't a choice. – Shaggi Jun 06 '13 at 18:45
  • To whoever downvoted this (guessing jalf or rc) sometimes you cannot dictate the design of your code, and for practical appliances you sometimes need to make dirty decisions. – Shaggi Jun 06 '13 at 18:56
  • Okay, so this is not intended to be a full security sandbox. Just a "try to catch some common programming mistakes" environment. – Raymond Chen Jun 06 '13 at 19:03
  • Yes. Maybe the term 'sandbox' was too aggressive, I didnt mean it litteraly. – Shaggi Jun 06 '13 at 19:10
  • @Shaggi I didn't downvote you, but thanks for the accusation. :) There' no *technical* reason why a separate process wouldn't work, but if there are "political" reasons why you can't go that route, then yeah, this might be the best you're going to get... Good luck with it. – jalf Jun 06 '13 at 19:12
  • Sorry then. :( There _are_ technical reasons, not that it's totally impossible, but getting processing of multiple real-time audio streams through different processes to work, that's probably a 10-fold larger project than what I'm doing right now. But thanks with the luck :) – Shaggi Jun 06 '13 at 19:31

1 Answers1

4

The attempted address is stored in ExceptionInformation[1], as per the EXCEPTION_RECORD documentation.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Thanks man. Hope I didn't insult you with my unorthodox code :) – Shaggi Jun 06 '13 at 15:26
  • I'm still not convinced that your approach is right, but which is why I commented on it. The answer to your question is still the same, but it seems a bit dodgy. – Mats Petersson Jun 06 '13 at 15:28
  • The problem is I'm being hosted and i also host code. I must not break the host even if my hosted code is faulty. This is simply an risk associated with my program, and a big fat disclaimer pops up on first use: All bets are off if you use this program. But if you use it correctly, it's amazing (imo :P). – Shaggi Jun 06 '13 at 15:31
  • Yes that wouldn't be too bad, sadly I don't have access to such luxuries both because of performance demands and the way I'm being hosted. – Shaggi Jun 06 '13 at 15:34