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
About

nike

Search

Categories
Archives
« April 2014
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
   
       
Today