News:

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

Valid Memory Address

Started by oex, April 09, 2010, 11:23:37 PM

Previous topic - Next topic

oex

So.... just wondering if there is a way to tell if an address in a register is a valid memory address ie say I have:

mov esi, chr$("Random String")

mov esi, alloc(10)
and then move a string to esi

Can I test that address in esi to see if it has a string in it and say print that string somehow without crashing the app? I know I might be able to use some error checking function I forget the name of but it seems crude, maybe there is a more obvious answer to this question....

Further is there a way to see if esi contains the allocated address ie

mov esi, alloc(10)
esi = true
inc esi
esi=FALSE
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

dedndave

well - almost any location in memory will be zero terminated - - eventually   :P
you can use VirtualQuery/VirtualQueryEx to determine access rights
after that, you are writing a little proc to test for alphanumeric ASCII with punctuation - hard to set the rules for that, i guess

it would be easier to write the code so that a "no string" condition is a null terminator - then you can test for that condition

redskull

The "standard" way would be to use a SEH frame based exception handler, but I'm from the school of thought that says a bad pointer is a bug in the code, and not something that can be "handled" as a matter of course.  Of course, SEH and things like IsBadReadPtr, VirtualQuery, etc, would only throw an access violation, and not a "non-ascii string" error.  You would have to test for that yourself.

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

hutch--

Dave's suggestion is easy enough to do if you don't mind a 2 step process for strings, allocate an array of empty pointers then for each string allocate that memory and place the pointer to it in the first array. If the pointer is zero there is no string else the value is the address of the string.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

well, that wasn't what i was thinking, but i guess that'd work too
i was thinking a null string - first byte = 0

qWord

oex,
the question is not how to detect bad pointers, it is why you get bad pointers.   :U
What got in my mind seeing this topic:The wrong way to determine the size of a buffer :toothy

regards, qWord
FPU in a trice: SmplMath
It's that simple!

oex

Quote from: hutch-- on April 09, 2010, 11:59:25 PM
Dave's suggestion is easy enough to do if you don't mind a 2 step process for strings, allocate an array of empty pointers then for each string allocate that memory and place the pointer to it in the first array. If the pointer is zero there is no string else the value is the address of the string.

Yeah I was trying to avoid this allocation of an array assuming windows must have analysis functions.... I have used this method in the past especially in my debugging functionality however I have always left strings out as a seperate 'object type' that I keep track of in my head :lol. Usually they are kinda important to keep an eye on as are the functions that receive sz....

Looking at the situation again now I kinda prefer the idea (at least in my debugger not my actual apps) of forward looking at the memory to determine it's properties and displaying as required rather than logging as I go....

I think SetUnhandledExceptionFilter was the boxing glove function I was thinking of before to pick up this pin, a hazy memory of past usage in a forum download so the functions above have been most illuminating.... Though IsBadReadPtr users might want to check the M$ page "IsBadXxxPtr should really be called CrashProgramRandomly" http://msdn.microsoft.com/en-us/library/aa366713(VS.85).aspx :lol
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

oex

Quote from: qWord on April 10, 2010, 12:57:33 AM
oex,
the question is not how to detect bad pointers, it is why you get bad pointers.   :U
What got in my mind seeing this topic:The wrong way to determine the size of a buffer :toothy

regards, qWord

:P My code is flawless :lol I dont get them I just want to write code that analises without my input in my debugger.... Obviously on the offchance an error should occur (maybe through act of god or something similarly unlikely) the debugger doesnt know what data is coming up next so to be able to read and analyse the memory could be rather usefull
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

oex

ie my breakpoint function might display:

EAX: -1                  FF FF FF FF            
EBX: 1                   01 00 00 00        ☺
ECX: 1244892             DC FE 12 00        ▄■↕
EDX: 2089870612          14 E5 90 7C        ¶σÉ|

if eax were a pointer to a string it would be nice to also print maybe the first 20 chars of that string....

I dont use Olly and the like
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

clive

Quote from: redskull
The "standard" way would be to use a SEH frame based exception handler, but I'm from the school of thought that says a bad pointer is a bug in the code, and not something that can be "handled" as a matter of course.

Indeed, if I'm doing something that might cause the processor to fault, SEH is the way to go. Especially if the alternative is a pretty blue screen.

case IOCTL_MONKEY_PUT_MSR:
{
ULONG Param[3];

if (inLength < (sizeof(ULONG) * 3))
{
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;

break;
}

RtlCopyMemory(Param, ioBuffer, (sizeof(ULONG) * 3));

try
{
_asm
{
mov ecx,Param[0]
mov eax,Param[4]
mov edx,Param[8]
wrmsr
}
}

except(EXCEPTION_EXECUTE_HANDLER)
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}

break;
}


And I'm from the school that does things in C when it is simpler, easier and appropriate.

-Clive
It could be a random act of randomness. Those happen a lot as well.

jj2007

Quote from: redskull on April 09, 2010, 11:54:49 PM
I'm from the school of thought that says a bad pointer is a bug in the code, and not something that can be "handled" as a matter of course.  Of course, SEH and things like IsBadReadPtr, VirtualQuery, etc

Yes, let it crash. Olly is your friend. In my library, I use IsBadPtr in exactly one situation: Just before the "Fatal error" MessageBox followed by ExitProcess, and only to test if the additional info string is valid.

Ghandi

I thought that memory allocation functions returned a NULL value on failure, that is a simple check you could perform.


mov esi,alloc(10)
test esi,esi
  jz alloc_failure

;ESI contains allocated memory

;Don't forget to free the memory when finished with it.

alloc_failure:

Icezelion also shows setting up a SEH to catch any errors when taking the e_lfanew member of the speculated DOS header, i can't recall the exact tutorial(s) which contain this but it wouldn't hurt to flick through them and see what i mean. If you set up the SEH and then attempt accessing the buffer (after checking it even exists first) and if your SEH is triggered you can display appropriate error message before cleanup and exit of routine/application.


HR,
Ghandi

clive

Indeed, testing values like 0x0000000 and 0xFFFFFFFF, etc would represent a cheap initial test. You could also look to see if they fall within the scope of the executables static image, or belonged to the process.

I think the initial question was more one about registers with random/arbitrary contents.

When touching user space memory (from some arbitrary context) in kernel space, I used some thing along the lines of this.

Mdl = IoAllocateMdl(Addr, Length, FALSE, FALSE, NULL);

if (Mdl)
{
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);

VirtAddr = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);

if (VirtAddr)
{
Success = TRUE;
}
else
{
MmUnlockPages(Mdl);

IoFreeMdl(Mdl);

Mdl = NULL;
}
}


This kind of thing worked well, especially if you wanted to maintain access to the memory and the user space context changed to some other process along the way. The basic function is to create a "window" into the user space, at an address the kernel can always access. One or more of the tests will fail along the way if the address is not accessible by the users process.

-Clive
It could be a random act of randomness. Those happen a lot as well.