News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Questions about memory

Started by kemicza, January 27, 2011, 05:49:49 PM

Previous topic - Next topic

kemicza

Hey I have a general question about accessing memory and crashes that may occur. How can you test if a certain address is readable/writeable?

If I for example have: mov eax,dword ptr [esi+100]
then if the address "esi+100" is not readable the application will crash. How can such a thing be avoided, I mean if it can't read from that address, then just dont and return from the function. Is there anyway to handle with this?

Thanks in advance
kemicza

BogdanOntanu

Yes, there are multiple ways in Windows:
- establish an structured exception handler (SEH) and inside it handle the situation
- VirtualQuerry
- IsBadReadPtr

Most important and faster: control your pointers and/or do the pointer limits checks yourself and never try to access memory based on input from files or user without a prior check of your buffer llimits.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

redskull

From the MSDN Page for IsBadReadPtr():

"This function is obsolete and should not be used. Despite its name, it does not guarantee that the pointer is valid or that the memory pointed to is safe to use."
Strange women, lying in ponds, distributing swords, is no basis for a system of government

kemicza

Actually IsBadReadPtr was the first thing I tried that BogdanOntanu suggested, and it's exactly what I needed, and works exactly as it should :)
thanks!

redskull

That's a really, really, really bad idea.  You can't fix bad pointers.  All that function is going to do is make the existing bugs harder to find, and introduce numerous new ones.  You've been warned!
Strange women, lying in ponds, distributing swords, is no basis for a system of government

baltoro

Redskull is correct.  :eek  
Raymond Chen explains everything in great detail: IsBadXXXPtr should really be called CrashProgramRandomly
...also, this blog post from Larry Osterman: Should I check the parameters to my function?
I've seen actual production code, a complex interaction between a number of custom COM components, that used IsBadReadPtr and IsBadWritePtr all over the place (presumably to prevent the app from crashing),...and it's frightening. Trying to debug these applications is nearly impossible. However, if you are using it in a simple app, under restricted conditions, it will probably work. But, you should be aware of it's limitations.
Baltoro

hutch--

I have much the same comment as the rest, if you have to test if an address is valid or not, you have written the allocation code incorrectly. You should ALWAYS know the start address and boundaries of allocated memory and you should ALWAYS work within that range, do it otherwise and it goes BANG on you in embarrassing places.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

donkey

Quote from: baltoro on January 29, 2011, 07:28:39 PM
Redskull is correct.  :eek  
Raymond Chen explains everything in great detail: IsBadXXXPtr should really be called CrashProgramRandomly
...also, this blog post from Larry Osterman: Should I check the parameters to my function?
I've seen actual production code, a complex interaction between a number of custom COM components, that used IsBadReadPtr and IsBadWritePtr all over the place (presumably to prevent the app from crashing),...and it's frightening. Trying to debug these applications is nearly impossible. However, if you are using it in a simple app, under restricted conditions, it will probably work. But, you should be aware of it's limitations.


Raymond Chen is really overstating the case. The problem with the IsBadXXXPtr functions is mainly that they use exceptions as opposed to bounds checks to determine if the memory is available or not. Since I have yet to ever see a program posted here that uses guard pages (I have only ever written 1 that needed them) and not more than 3 or 4 in other languages, the use of exceptions is for the most part moot. However, as Hutch says, you can perform a bounds check much faster than generating an exception and even in the case of user input you should always verify any data entered to make sure its valid so it should not be an issue.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

redskull

I agree that the guard page issue (while valid) is not necessarily a big deal, but the problem is that the function merely tells you that the number you pass cooresponds to memory that is allocated; nothing about that means that it points to the RIGHT data, or that it's even a pointer at all; if you are unlucky, a loop counter could be construed as a "good pointer", yet it's just randomly pointing to garbage.  And, even if it is a pointer in its own right, there's no function in the world that can tell you it's pointing to the data you think it is.

IMHO, the minute you become unsure of what a pointer is pointing to, your program is already too far gone.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

hutch--

the logic of memory allocation in a protected mode operating system is very straight forward, from whatever scope you allocate memory you must have a working de-allocation within that same scope and with the allocated memory you have BOTH the start address and the amount allocated. That gives you the lowest and highest address that you can read and write and you should not need more than that. If you are calling a function that allocates memory and passes back the pointer you also need the length of that memory so that you know the upper address you can write to.

There are no short cuts or successful bypasses for doing this, storing BOTH the start address and the length are necessities for dealing with allocated memory. About the only exception is memory allocated on the stack as LOCAL as the procedure removes it on exit with the stack address correction.


LOCAL memPointer :DWORD
LOCAL mLength :DWORD
LOCAL upperMem :DWORD

mov mLength, 1024*1024  ; the LENGTH
invoke YourMemAlloc,mLength
mov memPointer, eax    ; the POINTER
add eax, mLength
mov upperMem, eax    ; the UPPER usable address
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php