예제 #1
0
static int r_debug_gdb_reg_write(RDebug *dbg, int type, const ut8 *buf, int size) {
	if (!reg_buf) {
		// we cannot write registers before we once read them
		return -1;
	}
	int buflen = 0;
	int bits = dbg->anal->bits;
	free(r_reg_get_bytes(dbg->reg, type, &buflen));
	// some implementations of the gdb protocol are acting weird.
	// so winedbg is not able to write registers through the <G> packet
	// and also it does not return the whole gdb register profile after
	// calling <g>
	// so this workaround resizes the small register profile buffer
	// to the whole set and fills the rest with 0
	if (buf_size < buflen) {
		ut8* new_buf = realloc (reg_buf, buflen * sizeof (ut8));
		if (!new_buf) {
			return -1;
		}
		reg_buf = new_buf;
		memset (new_buf + buf_size, 0, buflen - buf_size);
	}

	RRegItem* current = NULL;
	for (;;) {
		current = r_reg_next_diff (dbg->reg, type, reg_buf, buflen, current, bits);
		if (!current) break;
		ut64 val = r_reg_get_value (dbg->reg, current);
		int bytes = bits / 8;
		gdbr_write_reg (desc, current->name, (char*)&val, bytes);
	}
	return true;
}
예제 #2
0
static int r_debug_gdb_reg_read(RDebug *dbg, int type, ut8 *buf, int size) {
	gdbr_read_registers(desc);
	// read the len of the current area
	int buflen = 0;
	free (r_reg_get_bytes (dbg->reg, type, &buflen));
	memcpy (buf, desc->data, desc->data_len);
	if (!reg_buf) {
		reg_buf = calloc (buflen, sizeof (char));
		if (!reg_buf) {
			return -1;
		}
	}
	else {
		if (buf_size < desc->data_len) {
			ut8* new_buf = realloc (reg_buf, desc->data_len * sizeof (ut8));
			if (!new_buf) {
				return -1;
			}
			reg_buf = new_buf;
			buflen = desc->data_len;
			buf_size = desc->data_len;
		}
	}
	buflen = R_MIN (desc->data_len, buflen);
	memcpy (reg_buf, desc->data, buflen);
	return desc->data_len;
}
예제 #3
0
static int __reg_read (RDebug *dbg, int type, ut8 *buf, int size) {
	int sz;
	/* do nothing */
	ut8 *bytes = r_reg_get_bytes (dbg->reg, type, &sz);
	memcpy (buf, bytes, R_MIN (size, sz));
	free (bytes);
	return size;
}
예제 #4
0
파일: debug.c 프로젝트: Kakkoroid/radare2
/* 
 * Save 4096 bytes from %esp
 * TODO: Add support for reverse stack architectures
 * Also known as r_debug_inject()
 */
R_API ut64 r_debug_execute(RDebug *dbg, const ut8 *buf, int len, int restore) {
	int orig_sz;
	ut8 stackbackup[4096];
	ut8 *backup, *orig = NULL;
	RRegItem *ri, *risp, *ripc;
	ut64 rsp, rpc, ra0 = 0LL;
	if (r_debug_is_dead (dbg))
		return R_FALSE;
	ripc = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_PC], R_REG_TYPE_GPR);
	risp = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_SP], R_REG_TYPE_GPR);
	if (ripc) {
		r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE);
		orig = r_reg_get_bytes (dbg->reg, -1, &orig_sz);
		if (orig == NULL) {
			eprintf ("Cannot get register arena bytes\n");
			return 0LL;
		}
		rpc = r_reg_get_value (dbg->reg, ripc);
		rsp = r_reg_get_value (dbg->reg, risp);

		backup = malloc (len);
		if (backup == NULL) {
			free (orig);
			return 0LL;
		}
		dbg->iob.read_at (dbg->iob.io, rpc, backup, len);
		dbg->iob.read_at (dbg->iob.io, rsp, stackbackup, len);

		r_bp_add_sw (dbg->bp, rpc+len, dbg->bpsize, R_BP_PROT_EXEC);

		/* execute code here */
		dbg->iob.write_at (dbg->iob.io, rpc, buf, len);
	//r_bp_add_sw (dbg->bp, rpc+len, 4, R_BP_PROT_EXEC);
		r_debug_continue (dbg);
	//r_bp_del (dbg->bp, rpc+len);
		/* TODO: check if stopped in breakpoint or not */

		r_bp_del (dbg->bp, rpc+len);
		dbg->iob.write_at (dbg->iob.io, rpc, backup, len);
		if (restore) {
			dbg->iob.write_at (dbg->iob.io, rsp, stackbackup, len);
		}

		r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE);
		ri = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_A0], R_REG_TYPE_GPR);
		ra0 = r_reg_get_value (dbg->reg, ri);
		if (restore) {
			r_reg_set_bytes (dbg->reg, -1, orig, orig_sz);
		} else {
			r_reg_set_value (dbg->reg, ripc, rpc);
		}
		r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_TRUE);
		free (backup);
		free (orig);
		eprintf ("ra0=0x%08"PFMT64x"\n", ra0);
	} else eprintf ("r_debug_execute: Cannot get program counter\n");
	return (ra0);
}
예제 #5
0
static int r_debug_windbg_reg_write(RDebug *dbg, int type, const ut8 *buf, int size) {
	if (!dbg->reg) {
		return false;
	}
	int arena_size;
	ut8 *arena = r_reg_get_bytes (dbg->reg, R_REG_TYPE_ALL, &arena_size);
	if (!arena) {
		eprintf ("Could not retrieve the register arena!\n");
		return false;
	}
	int ret = windbg_write_reg (wctx, arena, arena_size);
	free (arena);
	return ret;
}
예제 #6
0
파일: reg.c 프로젝트: astrotycoon/radare2
R_API int r_debug_reg_sync(RDebug *dbg, int type, int write) {
	int i, size;
	if (!dbg || !dbg->reg || !dbg->h)
		return R_FALSE;

	// Theres no point in syncing a dead target
	if (r_debug_is_dead (dbg))
		return R_FALSE;

	// Check if the functions needed are available
	if (write && !dbg->h->reg_write)
		return R_FALSE;
	if (!write && !dbg->h->reg_read)
		return R_FALSE;

	// Sync all the types sequentially if asked
	i = (type == R_REG_TYPE_ALL) ? R_REG_TYPE_GPR : type;

	do {
		if (write) {
			ut8 *buf = r_reg_get_bytes (dbg->reg, i, &size);
			if (!buf || !dbg->h->reg_write (dbg, i, buf, size)) {
				if (i==0)
					eprintf ("r_debug_reg: error writing registers %d to %d\n", i, dbg->pid);
				return R_FALSE;
			}
		} else {
			//int bufsize = R_MAX (1024, dbg->reg->size*2); // i know. its hacky
			int bufsize = dbg->reg->size;
			ut8 *buf = malloc (bufsize);
			if (!buf) return R_FALSE;
			//we have already checked dbg->h and dbg->h->reg_read above
			size = dbg->h->reg_read (dbg, i, buf, bufsize);
			// we need to check against zero because reg_read can return R_FALSE
			if (!size) {
				eprintf ("r_debug_reg: error reading registers\n");
				free (buf);
				return R_FALSE;
			} else
				r_reg_set_bytes (dbg->reg, i, buf, R_MIN(size, bufsize));

			free (buf);
		}
		// DO NOT BREAK R_REG_TYPE_ALL PLEASE
		//   break;

		// Continue the syncronization or just stop if it was asked only for a single type of regs 
	} while ((type==R_REG_TYPE_ALL) && (i++ < R_REG_TYPE_LAST));
	return R_TRUE;
}
예제 #7
0
파일: debug_gdb.c 프로젝트: jduck/radare2
static int r_debug_gdb_reg_read(RDebug *dbg, int type, ut8 *buf, int size) {
	int copy_size;
	int buflen = 0;
	check_connection (dbg);
	gdbr_read_registers (desc);
	if (!desc) {
		return -1;
	}
	// read the len of the current area
	free (r_reg_get_bytes (dbg->reg, type, &buflen));
	if (size < desc->data_len) {
		eprintf ("r_debug_gdb_reg_read: small buffer %d vs %d\n",
			(int)size, (int)desc->data_len);
		//	return -1;
	}
	copy_size = R_MIN (desc->data_len, size);
	buflen = R_MAX (desc->data_len, buflen);
	if (reg_buf) {
		// if (buf_size < copy_size) { //desc->data_len) {
		if (buflen > buf_size) { //copy_size) {
			ut8* new_buf = realloc (reg_buf, buflen);
			if (!new_buf) {
				return -1;
			}
			reg_buf = new_buf;
			buf_size = buflen;
		}
	} else {
		reg_buf = calloc (buflen, 1);
		if (!reg_buf) {
			return -1;
		}
		buf_size = buflen;
	}
	memset ((void*)(volatile void*)buf, 0, size);
	memcpy ((void*)(volatile void*)buf, desc->data, R_MIN (copy_size, size));
	memset ((void*)(volatile void*)reg_buf, 0, buflen);
	memcpy ((void*)(volatile void*)reg_buf, desc->data, copy_size);
#if 0
	int i;
	//for(i=0;i<168;i++) {
	for(i=0;i<copy_size;i++) {
		if (!(i%16)) printf ("\n0x%08x  ", i);
		printf ("%02x ", buf[i]); //(ut8)desc->data[i]);
	}
	printf("\n");
#endif
	return desc->data_len;
}
예제 #8
0
파일: reg.c 프로젝트: futex/radare2
R_API int r_debug_reg_sync(RDebug *dbg, int type, int write) {
	int i, size;

	if (!dbg || !dbg->reg || !dbg->h)
		return R_FALSE;

	// Theres no point in syncing a dead target
	if (r_debug_is_dead(dbg))
		return R_FALSE;

	// Check if the functions needed are available
	if (write && !dbg->h->reg_write)
		return R_FALSE;
	if (!write && !dbg->h->reg_read)
		return R_FALSE;

	// Sync all the types sequentially if asked
	i = (type == R_REG_TYPE_ALL) ? R_REG_TYPE_GPR : type;

	do {
		if (write) {
			ut8 *buf = r_reg_get_bytes (dbg->reg, i, &size);
			if (!buf || !dbg->h->reg_write (dbg, i, buf, size)) {
				eprintf ("r_debug_reg: error writing registers\n");
				return R_FALSE;
			}
		} else {
			// TODO : Get an exact size of the profile
			ut8 buf[2048];
			size = dbg->h->reg_read (dbg, i, buf, sizeof (buf));
			if (!size) {
				eprintf ("r_debug_reg: error reading registers\n");
				return R_FALSE;
			}
			r_reg_set_bytes (dbg->reg, i, buf, size);
		}
		// Continue the syncronization or just stop if it was asked only for a single type of regs 
	} while(i++ < R_REG_TYPE_LAST && type != R_REG_TYPE_ALL);

	return R_TRUE;
}
예제 #9
0
파일: reg.c 프로젝트: KarjamP/radare2
R_API int r_debug_reg_sync(RDebug *dbg, int type, int write) {
	ut8 buf[4096]; // XXX hacky!
	int next, size, ret = R_FALSE;
	if (!dbg || !dbg->reg || dbg->pid == -1)
		return R_FALSE;
	if (type == -1) {
		type = R_REG_TYPE_GPR;
		next = R_REG_TYPE_DRX;
	} else next = 0;
repeat:
	if (write) {
		if (dbg && dbg->h && dbg->h->reg_write) {
			ut8 *buf = r_reg_get_bytes (dbg->reg, type, &size);
			if (!dbg->h->reg_write (dbg, type, buf, sizeof (buf)))
				eprintf ("r_debug_reg: error writing registers\n");
			else ret = R_TRUE;
		} //else eprintf ("r_debug_reg: cannot set registers\n");
	} else {
		/* read registers from debugger backend to dbg->regs */
		if (dbg && dbg->h && dbg->h->reg_read) {
			size = dbg->h->reg_read (dbg, type, buf, sizeof (buf));
			if (size == 0) {
				eprintf ("r_debug_reg: error reading registers pid=%d\n", dbg->pid);
			} else {
				ret = r_reg_set_bytes (dbg->reg, type, buf, size);
			}
		} //else eprintf ("r_debug_reg: cannot read registers\n");
	}
	if (next) {
		type = next;
		switch (next) {
		case R_REG_TYPE_FPU: next = R_REG_TYPE_DRX; break;
		case R_REG_TYPE_DRX: next = 0; break;
		default: next = 0; break;
		}
		goto repeat;
	}
	return ret;
}
예제 #10
0
파일: debug_wind.c 프로젝트: hillu/radare2
static int r_debug_wind_reg_write(RDebug *dbg, int type, const ut8 *buf, int size) {
    (void)buf;
    (void)size;
    ut8 *arena;
    int arena_size;
    int ret;

    if (!dbg->reg)
        return R_FALSE;

    arena = r_reg_get_bytes (dbg->reg, R_REG_TYPE_ALL, &arena_size);
    if (!arena) {
        eprintf ("Could not retrieve the register arena!\n");
        return R_FALSE;
    }

    ret = wind_write_reg(wctx, arena, arena_size);

    free (arena);

    return ret;
}
예제 #11
0
static int r_debug_qnx_reg_read (RDebug *dbg, int type, ut8 *buf, int size) {
	int copy_size;
	int buflen = 0;
	if (!desc) {
		return -1;
	}
	int len = qnxr_read_registers (desc);
	if (len <= 0) return -1;
	// read the len of the current area
	free (r_reg_get_bytes (dbg->reg, type, &buflen));
	if (size < len) {
		eprintf ("r_debug_qnx_reg_read: small buffer %d vs %d\n",
			 (int)size, (int)len);
	}
	copy_size = R_MIN (len, size);
	buflen = R_MAX (len, buflen);
	if (reg_buf) {
		if (buf_size < copy_size) {
			ut8 *new_buf = realloc (reg_buf, copy_size);
			if (!new_buf)
				return -1;
			reg_buf = new_buf;
			buflen = copy_size;
			buf_size = len;
		}
	} else {
		reg_buf = calloc (buflen, 1);
		if (!reg_buf)
			return -1;
		buf_size = buflen;
	}
	memset ((void *)(volatile void *) buf, 0, size);
	memcpy ((void *)(volatile void *) buf, desc->recv.data, copy_size);
	memset ((void *)(volatile void *) reg_buf, 0, buflen);
	memcpy ((void *)(volatile void *) reg_buf, desc->recv.data, copy_size);

	return len;
}
예제 #12
0
파일: dreg.c 프로젝트: aronsky/radare2
R_API int r_debug_reg_sync(RDebug *dbg, int type, int write) {
	int i, n, size;
	if (!dbg || !dbg->reg || !dbg->h) {
		return false;
	}
	// Theres no point in syncing a dead target
	if (r_debug_is_dead (dbg)) {
		return false;
	}
	// Check if the functions needed are available
	if (write && !dbg->h->reg_write) {
		return false;
	}
	if (!write && !dbg->h->reg_read) {
		return false;
	}
	// Sync all the types sequentially if asked
	i = (type == R_REG_TYPE_ALL)? R_REG_TYPE_GPR: type;
	// Check to get the correct arena when using @ into reg profile (arena!=type)
	// if request type is positive and the request regset dont have regs
	if (i >= R_REG_TYPE_GPR && dbg->reg->regset[i].regs && !dbg->reg->regset[i].regs->length) {
		// seek into the other arena for redirections.
		for (n = R_REG_TYPE_GPR; n < R_REG_TYPE_LAST; n++) {
			// get regset mask
			int mask = dbg->reg->regset[n].maskregstype;
			// convert request arena to mask value
			int v = ((int)1 << i);
			// skip checks on same request arena and check if this arena have inside the request arena type
			if (n != i && (mask & v)) {
				//eprintf(" req = %i arena = %i mask = %x search = %x \n", i, n, mask, v);
				//eprintf(" request arena %i found at arena %i\n", i, n );
				// if this arena have the request arena type, force to use this arena.
				i = n;
				break;
			}
		}
	}
	do {
		if (write) {
			ut8 *buf = r_reg_get_bytes (dbg->reg, i, &size);
			if (!buf || !dbg->h->reg_write (dbg, i, buf, size)) {
				if (!i) {
					eprintf ("r_debug_reg: error writing "
						"registers %d to %d\n", i, dbg->tid);
				}
				free (buf);
				return false;
			}
			free (buf);
		} else {
			// int bufsize = R_MAX (1024, dbg->reg->size*2); // i know. its hacky
			int bufsize = dbg->reg->size;
			//int bufsize = dbg->reg->regset[i].arena->size;
			if (bufsize > 0) {
				ut8 *buf = calloc (1 + 1, bufsize);
				if (!buf) {
					return false;
				}
				//we have already checked dbg->h and dbg->h->reg_read above
				size = dbg->h->reg_read (dbg, i, buf, bufsize);
				// we need to check against zero because reg_read can return false
				if (size > 0) {
					r_reg_set_bytes (dbg->reg, i, buf, size); //R_MIN (size, bufsize));
			//		free (buf);
			//		return true;
				}
				free (buf);
			}
		}
		// DO NOT BREAK R_REG_TYPE_ALL PLEASE
		//   break;
		// Continue the syncronization or just stop if it was asked only for a single type of regs
		i++;
	} while ((type == R_REG_TYPE_ALL) && (i < R_REG_TYPE_LAST));
	return true;
}