Nikolay Igotti

pageicon Tuesday Jun 26, 2007

Memory debugger for Windows

For the sake of completeness, here's version of memory debugger for Win32. It uses vectored exception, so works only for Win2K or later.
#define _WIN32_WINNT 0x0500 

#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <stdlib.h>
#include <float.h> 

typedef enum {
  BREAK_ON_EXEC  = 0x00,
  BREAK_ON_WRITE = 0x01,
  BREAK_ON_RW    = 0x03,
} BreakFlags;

typedef enum {
  LEN_1 = 0x00,
  LEN_2 = 0x01,
  LEN_4 = 0x03,
} DataLength;
  
  
typedef struct {
  int        dr0_local:1;
  int        dr0_global:1;
  int        dr1_local:1;
  int        dr1_global:1;
  int        dr2_local:1;
  int        dr2_global:1;
  int        dr3_local:1;
  int        dr3_global:1;
  int        exact_local:1;
  int        exact_global:1;
  int        reserved:6;
  BreakFlags dr0_break:2;
  DataLength dr0_len:2;
  BreakFlags dr1_break:2;
  DataLength dr1_len:2;
  BreakFlags dr2_break:2;
  DataLength dr2_len:2;
  BreakFlags dr3_break:2;
  DataLength dr3_len:2;
} DR7;


typedef struct {
  void* addr;
  HANDLE tid;
  PVECTORED_EXCEPTION_HANDLER handler;
} params_t;


void runner(void* pv) {
  CONTEXT ctx;
  params_t* p = (params_t*)pv;
  DWORD rv;

  SuspendThread(p->tid);
  DR7 dr7 = {0};
  dr7.dr0_local = 1;
  dr7.dr0_break = BREAK_ON_WRITE;
  dr7.dr0_len   = LEN_4;

  ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
  GetThreadContext(p->tid, &ctx);	

  ctx.Dr0 = (DWORD)(intptr_t)p->addr;
  ctx.Dr6 = 0;
  ctx.Dr7 = *(DWORD*)&dr7;

  SetThreadContext(p->tid, &ctx);
   
  AddVectoredExceptionHandler(1, p->handler);
  ResumeThread(p->tid);
}

void addwatchpoint(HANDLE tid, void* address, PVECTORED_EXCEPTION_HANDLER handler)
{
  params_t p = { address, tid, handler };
  HANDLE setter = (HANDLE)_beginthread(runner, 1024*1024, &p);
  WaitForSingleObject(setter, -1);
}

volatile int var = 0;

LONG WINAPI trap(PEXCEPTION_POINTERS ExceptionInfo) {
  if (var == 50) {
    printf("caught: %d\n", var);
    while (1) {}
  }
  return EXCEPTION_CONTINUE_EXECUTION;
}

int main(int argc, char* argv[])
{
  int i;
  HANDLE me = OpenThread(THREAD_ALL_ACCESS, false, GetCurrentThreadId());
  
  addwatchpoint(me, (void*)&var, &trap);
  
  for (i=0; i<100; i++) {
    var++;
  }
  
  getchar();

  return 0;
}

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed

« December 2009
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today

Feeds

Search this blog

Links

Weblog menu

Today's referrers

Today's Page Hits: 95

Stats