Fix WinDbg IO in page boundaries ##debug

Before we didn't check if a virtual address read/write would go through a page boundary. This fixes it.

Also do some formatting and re-enable some useful error messages
This commit is contained in:
GustavoLCR 2019-11-25 22:14:28 -03:00 committed by radare
parent 2ec3bcf044
commit 635f27068b
3 changed files with 68 additions and 42 deletions

View File

@ -54,11 +54,7 @@ static int __write(RIO *io, RIODesc *fd, const ut8 *buf, int count) {
return -1;
}
if (windbg_get_target (fd->data)) {
ut64 va;
if (!windbg_va_to_pa (fd->data, io->off, &va)) {
return -1;
}
return windbg_write_at_phys (fd->data, buf, va, count);
return windbg_write_at_uva (fd->data, buf, io->off, count);
}
return windbg_write_at (fd->data, buf, io->off, count);
}
@ -82,11 +78,7 @@ static int __read(RIO *io, RIODesc *fd, ut8 *buf, int count) {
}
if (windbg_get_target (fd->data)) {
ut64 va;
if (!windbg_va_to_pa (fd->data, io->off, &va)) {
return -1;
}
return windbg_read_at_phys (fd->data, buf, va, count);
return windbg_read_at_uva (fd->data, buf, io->off, count);
}
return windbg_read_at (fd->data, buf, io->off, count);

View File

@ -162,12 +162,8 @@ ut64 windbg_get_target_base(WindCtx *ctx) {
return 0;
}
if (!windbg_va_to_pa (ctx, ctx->target->peb, &ppeb)) {
return 0;
}
if (!windbg_read_at_phys (ctx, (uint8_t *) &base,
ppeb + O_(P_ImageBaseAddress), 4 << ctx->is_x64)) {
if (!windbg_read_at_uva (ctx, (uint8_t *) &base,
ctx->target->peb + O_(P_ImageBaseAddress), 4 << ctx->is_x64)) {
return 0;
}
@ -418,6 +414,42 @@ RList *windbg_list_process(WindCtx *ctx) {
return ret;
}
int windbg_write_at_uva(WindCtx *ctx, const uint8_t *buf, ut64 offset, int count) {
ut64 pa;
ut32 totwritten = 0;
while (totwritten < count) {
if (!windbg_va_to_pa (ctx, offset, &pa)) {
return 0;
}
ut32 restOfPage = 0x1000 - (offset & 0xfff);
int written = windbg_write_at_phys (ctx, buf + totwritten, pa, R_MIN (count - totwritten, restOfPage));
if (!written) {
break;
}
offset += written;
totwritten += written;
}
return totwritten;
}
int windbg_read_at_uva(WindCtx *ctx, uint8_t *buf, ut64 offset, int count) {
ut64 pa;
ut32 totread = 0;
while (totread < count) {
if (!windbg_va_to_pa (ctx, offset, &pa)) {
return 0;
}
ut32 restOfPage = 0x1000 - (offset & 0xfff);
int read = windbg_read_at_phys (ctx, buf + totread, pa, R_MIN (count - totread, restOfPage));
if (!read) {
break;
}
offset += read;
totread += read;
}
return totread;
}
RList *windbg_list_threads(WindCtx *ctx) {
RList *ret;
ut64 ptr, base;
@ -431,13 +463,13 @@ RList *windbg_list_threads(WindCtx *ctx) {
}
if (!ctx->target) {
WIND_DBG eprintf ("No target process\n");
eprintf ("No target process\n");
return NULL;
}
ptr = ctx->target->eprocess;
if (!ptr) {
WIND_DBG eprintf ("No _EPROCESS\n");
eprintf ("No _EPROCESS\n");
return NULL;
}
@ -456,7 +488,7 @@ RList *windbg_list_threads(WindCtx *ctx) {
windbg_read_at (ctx, (uint8_t *) &next, ptr, 4 << ctx->is_x64);
if (!next) {
WIND_DBG eprintf ("Corrupted ThreadListEntry found at: 0x%"PFMT64x"\n", ptr);
eprintf ("Corrupted ThreadListEntry found at: 0x%"PFMT64x"\n", ptr);
break;
}

View File

@ -73,30 +73,32 @@ typedef struct {
// grep -e "^windbg_" shlr/wind/wind.c | sed -e 's/ {$/;/' -e 's/^/int /'
int windbg_get_bits(WindCtx *ctx);
ut64 windbg_get_target_base (WindCtx *ctx);
ut32 windbg_get_target (WindCtx *ctx);
bool windbg_set_target (WindCtx *ctx, ut32 pid);
RList *windbg_list_process (WindCtx *ctx);
ut64 windbg_get_target_base(WindCtx *ctx);
ut32 windbg_get_target(WindCtx *ctx);
bool windbg_set_target(WindCtx *ctx, ut32 pid);
RList *windbg_list_process(WindCtx *ctx);
RList *windbg_list_threads(WindCtx *ctx);
int windbg_get_cpus (WindCtx *ctx);
bool windbg_set_cpu (WindCtx *ctx, int cpu);
int windbg_get_cpu (WindCtx *ctx);
WindCtx * windbg_ctx_new (void *io_ptr);
void windbg_ctx_free (WindCtx **ctx);
int windbg_wait_packet (WindCtx *ctx, const ut32 type, kd_packet_t **p);
int windbg_sync (WindCtx *ctx);
bool windbg_read_ver (WindCtx *ctx);
int windbg_continue (WindCtx *ctx);
bool windbg_write_reg (WindCtx *ctx, const uint8_t *buf, int size);
int windbg_read_reg (WindCtx *ctx, uint8_t *buf, int size);
int windbg_query_mem (WindCtx *ctx, const ut64 addr, int *address_space, int *flags);
int windbg_bkpt (WindCtx *ctx, const ut64 addr, const int set, const int hw, int *handle);
int windbg_read_at (WindCtx *ctx, uint8_t *buf, const ut64 offset, const int count);
int windbg_read_at_phys (WindCtx *ctx, uint8_t *buf, const ut64 offset, const int count);
int windbg_write_at (WindCtx *ctx, const uint8_t *buf, const ut64 offset, const int count);
int windbg_write_at_phys (WindCtx *ctx, const uint8_t *buf, const ut64 offset, const int count);
bool windbg_va_to_pa (WindCtx *ctx, ut64 va, ut64 *pa);
bool windbg_break (WindCtx *ctx);
int windbg_get_cpus(WindCtx *ctx);
bool windbg_set_cpu(WindCtx *ctx, int cpu);
int windbg_get_cpu(WindCtx *ctx);
WindCtx * windbg_ctx_new(void *io_ptr);
void windbg_ctx_free(WindCtx **ctx);
int windbg_wait_packet(WindCtx *ctx, const ut32 type, kd_packet_t **p);
int windbg_sync(WindCtx *ctx);
bool windbg_read_ver(WindCtx *ctx);
int windbg_continue(WindCtx *ctx);
bool windbg_write_reg(WindCtx *ctx, const uint8_t *buf, int size);
int windbg_read_reg(WindCtx *ctx, uint8_t *buf, int size);
int windbg_query_mem(WindCtx *ctx, const ut64 addr, int *address_space, int *flags);
int windbg_bkpt(WindCtx *ctx, const ut64 addr, const int set, const int hw, int *handle);
int windbg_read_at(WindCtx *ctx, uint8_t *buf, const ut64 offset, const int count);
int windbg_read_at_uva(WindCtx *ctx, uint8_t *buf, ut64 offset, int count);
int windbg_read_at_phys(WindCtx *ctx, uint8_t *buf, const ut64 offset, const int count);
int windbg_write_at(WindCtx *ctx, const uint8_t *buf, const ut64 offset, const int count);
int windbg_write_at_uva(WindCtx *ctx, const uint8_t *buf, ut64 offset, int count);
int windbg_write_at_phys(WindCtx *ctx, const uint8_t *buf, const ut64 offset, const int count);
bool windbg_va_to_pa(WindCtx *ctx, ut64 va, ut64 *pa);
bool windbg_break(WindCtx *ctx);
int windbg_break_read(WindCtx *ctx);
bool windbg_lock_enter(WindCtx *ctx);
bool windbg_lock_leave(WindCtx *ctx);