Hi guys,

I'm still learning about debugging techniques and I was wondering if anyone could give me a few tips.
I want to put a watch on a memory address in another process and I'm not sure of the best way to do it.

eg. I have a DWORD at 403066 which is a loop counter. It increments relatively slowly (every 200mS) and I
would simply like to send the value to another window. I have no problem sending data from one process to
another, and I can inplement a watch if I hardcode it in the source, but that doesn't teach me much. I have no
problem using SEH to do this too, but again, this requires it to be hardcoded in the exe (like VarSpy).

I'm using my own source so I have no problem hardcoding a proc to send to the output window whilst debugging,
Its just I dont know how I can set an address to watch on-the-fly (assume I already know the address).
Can this be done using the debug API or do I need to use a totally different technique ?

Thanks,
Emerson
Posted on 2004-01-04 09:27:37 by Emerson
Humm, I don't see any specific functions for memory watching in the debug api... perhaps I didn't look close enough - you might want to ask the author of OllyDbg how he does it.

One solution, I guess, would be using SetThreadContext to manually set the DRx registers of the thread to enable a memory breakpoint (consult the IA32 manuals, volume 3: Systems Programming, iirc) - I'm not sure how clean this is, though, nor how well it would work on 9x. It should work, I guess, on NT, as NT manages the DRx registers per-thread.
Posted on 2004-01-04 10:31:08 by f0dder
Thanks f0dder,

It was Ollydbg's abililty to set a memory bp on-the-fly that I was hoping to copy. I've done quite an extensive search
but I didnt find too much of use, but then I'm not sure what Im looking for exactly. I looked at the IA32 manuals and
I think Im right in thinking only 3(?) bp's can be set at any one time. I guess this is Olly's hardware bp method.

Thanks for taking the time to reply anyway, I'll continue my quest !!

Regards,
Emerson
Posted on 2004-01-04 10:45:21 by Emerson
Yes, only very few hardware breakpoints can be set - it would have been nice if there were a bit more. I thought it was four, but 3 might be right.

Another method that can be implemented, though I dunno how effectively at ring3 level, would be to mark the entire 4k page your watched variable is in as inaccessible - and then have checks in your pagefault handler to see whether the reference is to your watched memory or something else.

This requires a fair amount of logic in the pagefault handler, is somewhat expensive (if lots of other variables in the same 4k page is used), and probably requires ring0 code. It does, however, allow for more or less infinite breakpoints. Usually you just need a few mem BPs at a time though, and the DRx method should be fine then.
Posted on 2004-01-04 10:58:36 by f0dder
mov eax,dword ptr [0403066]
function: (send eax to other process)


That's what understand of your explanation
Posted on 2004-01-04 15:35:50 by mrgone
mrgone, as I understand it: he wants to watch (break on access) a memory location in another process... this requires pagetable stuff or DRx registers + ReadProcessMemory. Unless, of course, I misunderstood the problem.
Posted on 2004-01-04 15:45:12 by f0dder
@ f0dder
You got it exactly right.

@mrgone
I'm looking for the technique used in many debuggers to set a memory read\write breakpoint
on-the-fly. Ollydbg being a good example !!

Regards,
Emerson
Posted on 2004-01-04 17:21:41 by Emerson
Yeah I did miss understand. Gee, how could you do that in user mode? I don't do much with SEH's. Do they correlate to the IDT's interrupt vectors? You know what you need to do is just put a message box where you want your break.


.data

regXXX dd 0
dispregXXX db "regXXX= : %08x",0


.data?

buffer2 db 4096 dup(?)



DisplayregXXX:

pushad
invoke wsprintf, addr buffer2,addr dispregXXX,regXXX
invoke MessageBox,0, addr buffer2,NULL,MB_OK
popad
ret



mov regXXX,eax
call DisplayregXXX

If that works for you I can show you how to get a dump of all registers in one message box.
Posted on 2004-01-05 17:16:21 by mrgone

Gee, how could you do that in user mode?

You set up DRx registers to enable the memory break.
When it hits, a debug exception is thrown, which is reflected to usermode. If not handled by a SEH, it goes to the application toplevel exception filter. If you haven't installed such a filter either, you get the typical "this program has performed an illegal instruction" thingy.

I'm still not sure how easy this is to do in R3 apps, but since OllyDbg can do it, it should be possible (hm, and was there something about hardware BPs only being supported in olly under NT? That would match my theory of global DRx on 9x and per-process/thread DRx on NT). Also, when running an app in debug mode, I think a debug event will be thrown to the debugging app instead of firing an exception in the debugged app (or perhaps it's just handled generically as an exception notification - I haven't really looked at the debugging API stuff).
Posted on 2004-01-05 17:22:34 by f0dder