shithub: 5v

ref: f9198297ea2bc1c3971f5b3fd473e45a8fb0d10c
dir: /chk.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>
#include <mach.h>
#include "dat.h"
#include "fns.h"

static u32int
arg(int n)
{
	/* no locking necessary, since we're on the stack */
	return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4, ARD);
}

void
validmem(Segment *s, u32int off, u32int len)
{
	u32int end;

	/*
	 * when we're within a malloc or free operation, we're looking at
	 * memory that we don't want to allow user programs to touch; skip
	 * the check here.
	 */
	if(P->hookpc != 0)
		return;
	for(end = off+len; off != end; off++){
		if((s->shadow[off>>3] & 1<<(off&3)) == 0){
			print("invalid read of %#x at %#x\n", off, P->R[15] - 4);
			abort();
		}
	}
}

void
dumpmap(Segment *seg)
{
	int i;

	for(i = 0; i < (seg->size + 7)/8; i++){
		if(i % 40 == 0)
			print("\n[%04x] ", seg->start+i*8);
		print("%02ux", seg->shadow[i]);
	}
	print("\n");
}

void
markvalid(Segment *s, u32int off, u32int len)
{
	u32int end;

	for(end = off+len; off != end; off++)
		s->shadow[off>>3] |= (1<<(off&3));
}

void
markinvalid(Segment *s, u32int off, u32int len)
{
	u32int end;

	for(end = off+len; off != end; off++)
		s->shadow[off>>3] &= ~(1<<(off&3));
}

void
hookmalloc(u32int *av)
{
	Segment *seg;
	uchar *p;

	print("malloced %#x+%d\n", P->R[0], av[0]);
	p = vaddr(P->R[0], 0, 0, &seg);
	dumpmap(seg);
	markinvalid(seg, p - (uchar*)seg->data, av[0]);
	dumpmap(seg);
}


void
hookrealloc(u32int *av)
{
	Segment *seg;
	uchar *p;

	print("malloced %#x+%d => %#x+%d\n", av[0], av[1], P->R[0], av[2]);
	p = vaddr(av[0], 0, 0, &seg);
	markinvalid(seg, p - (uchar*)seg->data, av[1]);
	p = vaddr(P->R[0], 0, 0, &seg);
	markinvalid(seg, p - (uchar*)seg->data, av[2]);
}

void
hookfree(u32int *av)
{
	Segment *seg;
	uchar *p;

	print("freed %#x+%d\n", av[0], av[1]);
	p = vaddr(av[0], 0, 0, &seg);
	dumpmap(seg);
	markinvalid(seg, p - (uchar*)seg->data, av[1]);
	dumpmap(seg);
}