PDA

View Full Version : Method like triggering ??


Emerson
September 10th, 2005, 15:00
I know I'll get hammered for asking this in this forum but I'll try my luck as I think I'll get more "artistic" responses here.

I'm trying to figure a way to way to enhance a simple script engine that I'm writing and I basicaly want a means of calling a proc when a certain memory address is hit.. I'll explain :-

Say I have a variable, pText, a pointer a string. I want to be able to some how force redirection when pText is assigned a new value.

mov 402000, eax (pText address = 402000)

When eax is written to 402000, I want to be redirected to a proc, say at 401000.

So, as an example, I could set the string to an edit control simply by writing a string pointer to an address (that is, the proc at 401000 would do it using SetWindowText API).

The actual line in my script looks like this (Somewhat VB looking)

Text1.Text = "Hello World !"

Now I'm sure someone will ask "If your parsing your own script why dont you simply place a call to the proc when compiling ?" Well, no good answer to that other than I this flash of inspiration that maybe I could some how automate some kind of Method calling mechanism.

I thought along the lines of maybe using mem addresses in a guarded page and catching the exception but its not available in all OS's (is it ?). What about installing a SEH and deliberatly causing an exception (bad programming practice ?). What about an interupt ? Again, sounds like bad programming ?!?

Thoughts anyone or is this simply a stupid idea ?

Anyway, sorry again for the somewhat unrelated reversing post but like I said, by the very nature of the subject, reversers have a more lateral approch to solving problems.

Thanks,
Emerson

LLXX
September 10th, 2005, 17:14
Hardware breakpoint on write to 402000? The later (P4) CPUs have some very advanced debugging capabilities, you should read Intel's manuals about it.

laola
September 10th, 2005, 17:26
Yeah, hardware breakpoint sounds most reasonable to me as well. As long as you don't come up with more details or additional requirements
E.g. who controls setting the value? If your script writes it, simply add some lines which place a copy of the pointer where you like.
Please elaborate a bit more on the whole picture

Emerson
September 11th, 2005, 17:07
Thanks for the reply's Guys !!

I guess my description of want I'm trying to achieve was a little off the mark as a HWBP is not really the solution I'm looking for... So here's some more details (that you didnt want ).

The following lines would compile to something like :-

Text1.Text = "Hello World"
Text1.BackColor = 0xFF00FF
Text1.ForeColoe = 0x000000

mov eax, pText
mov 402000, eax

mov eax, pBackColor
mov 402004, eax

mov eax, pForeColor
mov 402008, eax

So you see I wasnt looking for a single hit solution, more of an elegant way to detect access to a group of addresses...

I'll explain my first idea on how I could do this...

I would use VirtualAlloc to reserve a block of memory with PAGE_GUARD flag and use this block for the above addresses. So if VirtualAlloc returns a page at 1A0000, for example, then the above asm would look like the following :-

mov eax, pText
mov 1A0000, eax

mov eax, pBackColor
mov 1A0004, eax

mov eax, pForeColor
mov 1A0008, eax

Now when any of the above 'Methods' are executed, a STATUS_GUARD_PAGE_VIOLATION would be triggered. I understand that I have to reset the PAGE_GUARD flag each time. My sticking point with this is that I dont think it works with 9x and, to be honest, I'm not sure how to write the exception handler in such a way that I can execute some code before returning the EIP to the exception point and continue.

Hopefully this makes it bit clearer what I'm aiming for. I'm not convinced there is a solid solution, but then thats the point of this post. If the general opinion is there is no reliable\elegant solution, then I'll feel better that I had at least investigated my idea, and move on !

Thanks again for taking the time to reply.
Emerson

Kayaker
September 12th, 2005, 03:03
Hi

I don't know why you feel you would be hammered for asking such a question in this forum, all things weird and wonderful are welcomed here

This may fall under the same thought as your VirtualAlloc/PAGE_GUARD idea, but may also be suitable for Win9x. Say you create a file mapping object with CreateFileMapping, using INVALID_HANDLE_VALUE as the hFile parameter (so you have memory backed by the paging file) and PAGE_READONLY access. Any attempt to *write* to the mapping will result in an access violation, which you should be able to trap with an SEH.

You ask if using SEH for this kind of thing is bad programming practice. Well, protections use SEH for program flow diversions all the time, so I don't know if it's "bad" programming, or just "unorthodox use" of exception handling... In any case, on with the idee..

The problem is, if I understand correctly, that after your SEH does some twiddling you want to return execution to the faulting address, but this time you *don't* want it to fault. I don't think that you can change the access rights to the mapped memory (say to PAGE_READWRITE), but what you may be able to do is, from within your SEH, *change* the address written to to a *new* file mapping address (or some other address) which *does* have write access.

What's nice about CreateFileMapping is that you can specify a small size to be mapped, say 1 DWORD, rather than a full page, which is what VirtualAlloc will give you. (I don't really know if the mapped addresses may be paged based anyway..)


So to clarify, what I'm suggesting, which may be overly complicated, but hey you're looking for ideas, is this:

Create 2 file mapping objects for each variable you want to monitor, one with read-only access (which will trigger your SEH when a write attempt is made to it), and a second duplicate with full write access. Within your SEH you *replace* the address within the faulting instruction to the writeable mapping address, then return control. The instruction should execute properly thereafter.

Say,

invoke CreateFileMapping, 0FFFFFFFFh, NULL, PAGE_READONLY, NULL, sizeof (DWORD), NULL
mov hMap_NOTWRITEABLE, eax
invoke MapViewOfFile, hMap_NOTWRITEABLE, FILE_MAP_READ, 0 , 0, 0
mov pText_NOTWRITEABLE, eax


invoke CreateFileMapping, 0FFFFFFFFh, NULL, PAGE_READWRITE, NULL, sizeof (DWORD), NULL
mov hMap_WRITEABLE, eax
invoke MapViewOfFile, hMap_WRITEABLE, FILE_MAP_READ+FILE_MAP_WRITE, 0 , 0, 0
mov pText_WRITEABLE, eax


Now your instruction will change from:

mov eax, pText
mov pText_NOTWRITEABLE, eax // triggers SEH

to:

mov eax, pText
mov pText_WRITEABLE, eax // after SEH changes variable address


In reality, you only need 1 "unwriteable" memory address which you can keep reusing. With one SEH handler you should be able to monitor multiple faulting addresses and make the appropriate changes.

Not sure if this fits into what you're trying to achieve, but I think this should convey the idea?

Cheers,
Kayaker

Emerson
September 12th, 2005, 21:41
Hey Kayaker,

That's exactly the sort of idea I was looking for. Using file mapping never occured to me. I'm just starting to code a simple test now so I've nothing to report yet, but I thought I'd let you know that I'm following your idea through and will let you know how I'm doing if you're interested.

Nice one..
PS. Thought I'd get hammered cos its not RE related as such.

Thanks,
Emerson

Kayaker
September 12th, 2005, 23:11
Quote:
[Originally Posted by Emerson]
PS. Thought I'd get hammered cos its not RE related as such.


Oh, but I think it is RE related, certainly "RE-programming" related at least... Good luck with it and definitely let us know the results.

Regards,
Kayaker

Emerson
September 13th, 2005, 18:39
Hey Kayaker,

The concept is good

I've got a basic example working perfectly. You suggested a single "Unwritable" address but I've found a good reason to keep the 2 file maps identical which I'll explain in a bit.

I've set up the SEH frame as normal and included the addresses of both the mapped files and also map the size. I could make these global but as install my handler at the top of the chain, its not a problem. I've also changed the script to create the calls like this :-

mov eax, pText
mov ebx, pText_NOTWRITEABLE
mov [ebx], eax

It's an extra line but the format is identical every time, so I'm not bothered. Now, the reason that ebx is loaded for every call, which is obviously inefficient compared to loading it once and preserving it, is that I now have access to the register in the SEH which is most useful later.

So it works like this...

The write triggers the SEH. In the SEH, I first check to make sure the exception is an EXCEPTION_ACCESS_VIOLATION. If so, the exception address is checked to see if its in the range of the read only map. As I said earlier, I have the map addresses and the size at this point so this is easy. If its not in this range, I leave it for the next exception handler (return eax = 1). If it's my exception then I simply subtract the the exception address from the readonly map base address. Example :-

Assume:-
pNOTWRITEABLE = 850000
FaultAddress = 850008

FaultAddress - pNOTWRITEABLE = 8

Now I have the offset into the map. So by adding this offset to the base address of the ReadWrite map I can change ebx to a valid address.

Assume:-
pWRITEABLE = 860000
FaultOffset = 8 (from above)

ValidWriteAddress = pWRITEABLE + FaultOffset (860008)

Now I can simply put ValidWriteAddress in ebx which is passed in the CONTEXT structure, and return control to system. The faulting line will re-execute with ebx modified and will continue as normal. This explains why I have to load ebx before every 'call'. Otherwise it would contain a writable address from then on and the rest of the 'Method calls' wouldn't fault.

Works like a charm. Perfect !!

I said earlier that I used identical maps instead of a single "Unwritable" address and here's why.

A single faulting address wouldnt provide any kind of reference, (or the offset needed for the above write correction for that matter), which I needed to be able to determine the course of action to take. Consider this :-

Text1.Text = "Hello Word !"
Check1.Value = 1

When the original Readonly map was created, I overlayed an array of proc pointers (MyFuncArray) that is created at compile time for each control. So, using the FaultOffset (8), I can convert this into an index into my array. 8 would be the third (DWORD) array item (2, its zero based). The function pointer at MyFuncArray(2) contains the address of a function that will write the text to the control. I call this, return, continue with the SEH, and Bingo..

Well, now that it's solved, I'm kinda disappointed too cos I have to say that I have learnt a huge amount about how SEH works. I even managed to get a good grasp on unwinding the stack and other various fault recovery techniques. So, what can I learn next......

Thanks again,
Emerson

PS. I've just noticed your post count so reading the above was probably like teaching your granny to suck eggs. Still, someone else might find it interesting and its all educational, eh ?

bilbo
September 14th, 2005, 03:02
Quote:
I've just noticed your post count so reading the above was probably like teaching your granny to suck eggs.
Not always the post count is a good guarantee, but the name of the poster sure is!

Quote:
Still, someone else might find it interesting and its all educational, eh ?
Sure, look at the number of views...

Quote:
The faulting line will re-execute with ebx modified and will continue as normal. This explains why I have to load ebx before every 'call'. Otherwise it would contain a writable address from then on and the rest of the 'Method calls' wouldn't fault.
Instead of the MOV EBX trick or instead of modifying the code, you could simply increment EIP in your handler, in order to skip the faulting instruction.

Best regards, bilbo

Kayaker
September 14th, 2005, 11:59
Heck, until she's so old and decrepit that she has to suck them out of a straw, Granny can always learn new ways to eat eggs..

Emerson
September 14th, 2005, 20:15
Quote:
[Originally Posted by Kayaker]Heck, until she's so old and decrepit that she has to suck them out of a straw, Granny can always learn new ways to eat eggs..


Well this may be true, but from my limited experience of the older generation and foodstuffs such as eggs and the like, I highly recommend a well ventilated room before you provide her with any "Advanced egg consumption techniques" tutorials

Regarding the "is it bad or just unorthodox use" deliberance, I've read a number of articles\references by M$, and SEH is considered the prefered way to handle certain tasks such as automatic memory reallocation\resizing, or recovering from an access violation cos windoze decided that it would be a good idea to move the memory that you reserved earlier, because its more efficient than using IsBadWhateverPtr calls repeatedly. Which, for me as still a novice programmer, is good to know as I avoided using it to its full potential because I thought it was only there to deal with "the bad things in life".
Quote:
[Originally Posted by bilbo]
Instead of the MOV EBX trick or instead of modifying the code, you could simply increment EIP in your handler, in order to skip the faulting instruction.


I did actually think of that at the time. The reason I decided to write the data, rather than just skip it, is that it was the most convienient way for me to provide private data storage on a 'per control' basis. Assume a 'Method call' to change the backcolor of a control. The call to SetBkColor in its Paint\EraseBkGnd message would simply be a reference to this address. I need do nothing else other than invalidate it.

Thanks for the suggestion though.

Regards,
Emerson

JMI
September 14th, 2005, 21:45
Hey... don't you youngin's be making snide comments about those of us in the "older generation." Otherwise, a group of us are coming over to your house and all of us will break wind at the same time.

Regards,

bilbo
September 15th, 2005, 02:43
Emerson,

I implied "write the data" and then increment EIP, all in your SEH...
But this is not anyway a very helpful suggestion... It only spares you just one mov ebx, pText_NOTWRITEABLE instruction.

Best regards, bilbo

Emerson
September 15th, 2005, 13:47
Hey JMI,

You don't scare me with your anal vapor based weaponry, I have a naked flame and I'm not afraid to use it. Besides, combine failing eyesight with the very restrictive "special" rubber underwear that you and your 'troops' have to endure, I'm not expecting an invasion any time soon. And that's assuming you can convince them that your cause is more importaint than tending to their gardens

bilbo.
Ah, I see. It would make my script slightly smaller but would add a few cycles to the SEH. Another reason I also did it this way is that I would be able to use constants with something like :-

mov ebx, pNOTWRITEABLE
mov [ebx], 0x12345678

I dont have any way of knowing the constant in the SEH. Unless you know of a way ?

Regards,
Emerson

JMI
September 15th, 2005, 21:09
Well if you have a "naked flame", we will come over to your place for a permanent barbeque location. Most of the "old timers" in my group aren't into gardening, but many of them sure love to cook something on an outdoor flame.

And you are obviously way too young to have noticed the improvements in "elder undergarments" available these days. So typical of the young these days. More interested in showing off the new ring tones on their cell phones than actually doing something useful.

Regards,