Windbg code cleaning

This commit is contained in:
xarkes 2017-08-08 18:45:11 +02:00 committed by radare
parent beba22e6c7
commit c1f6b29e8e
9 changed files with 313 additions and 318 deletions

View File

@ -21,12 +21,11 @@
static WindCtx *wctx = NULL; static WindCtx *wctx = NULL;
static bool dbreak = false; static bool dbreak = false;
static int r_debug_windbg_step (RDebug *dbg) { static int r_debug_windbg_step(RDebug *dbg) {
return true; return true;
} }
static int r_debug_windbg_reg_read (RDebug *dbg, int type, ut8 *buf, int size) { static int r_debug_windbg_reg_read(RDebug *dbg, int type, ut8 *buf, int size) {
(void)type;
int ret = windbg_read_reg(wctx, buf, size); int ret = windbg_read_reg(wctx, buf, size);
if (!ret || size != ret) { if (!ret || size != ret) {
return -1; return -1;
@ -37,8 +36,6 @@ static int r_debug_windbg_reg_read (RDebug *dbg, int type, ut8 *buf, int size) {
} }
static int r_debug_windbg_reg_write(RDebug *dbg, int type, const ut8 *buf, int size) { static int r_debug_windbg_reg_write(RDebug *dbg, int type, const ut8 *buf, int size) {
(void)buf;
(void)size;
if (!dbg->reg) { if (!dbg->reg) {
return false; return false;
} }
@ -62,43 +59,41 @@ static void wstatic_debug_break(void *u) {
windbg_break_read (wctx); windbg_break_read (wctx);
} }
static int r_debug_windbg_wait (RDebug *dbg, int pid) { static RDebugReasonType r_debug_windbg_wait(RDebug *dbg, int pid) {
# define STATE_EXCEPTION 0x3030 RDebugReasonType reason = R_DEBUG_REASON_UNKNOWN;
kd_packet_t *pkt; kd_packet_t *pkt;
kd_stc_64 *stc; kd_stc_64 *stc;
int ret;
dbreak = false; dbreak = false;
r_cons_break_push (wstatic_debug_break, dbg);
for (;;) { for (;;) {
ret = windbg_wait_packet (wctx, KD_PACKET_TYPE_STATE_CHANGE, &pkt); int ret = windbg_wait_packet (wctx, KD_PACKET_TYPE_STATE_CHANGE64, &pkt);
if (dbreak) { if (dbreak) {
dbreak = false; dbreak = false;
windbg_break (wctx); windbg_break (wctx);
free (pkt);
continue; continue;
} }
if (ret != KD_E_OK || !pkt) { if (ret != KD_E_OK || !pkt) {
reason = R_DEBUG_REASON_ERROR;
break; break;
} }
stc = (kd_stc_64 *)pkt->data; stc = (kd_stc_64 *) pkt->data;
// Handle exceptions only if (stc->state == DbgKdExceptionStateChange) {
if (stc->state == STATE_EXCEPTION) {
windbg_set_cpu (wctx, stc->cpu); windbg_set_cpu (wctx, stc->cpu);
dbg->reason.type = R_DEBUG_REASON_INT; dbg->reason.type = R_DEBUG_REASON_INT;
dbg->reason.addr = stc->pc; dbg->reason.addr = stc->pc;
dbg->reason.tid = stc->kthread; dbg->reason.tid = stc->kthread;
dbg->reason.signum = stc->state; dbg->reason.signum = stc->state;
free (pkt); reason = R_DEBUG_REASON_INT;
break; break;
} }
windbg_continue (wctx);
free (pkt); free (pkt);
} }
r_cons_break_pop (); free (pkt);
// TODO : Set the faulty process as target return reason;
return true;
} }
static int r_debug_windbg_attach (RDebug *dbg, int pid) { static int r_debug_windbg_attach(RDebug *dbg, int pid) {
RIODesc *desc = dbg->iob.io->desc; RIODesc *desc = dbg->iob.io->desc;
if (!desc || !desc->plugin || !desc->plugin->name || !desc->data) { if (!desc || !desc->plugin || !desc->plugin->name || !desc->data) {
@ -117,29 +112,29 @@ static int r_debug_windbg_attach (RDebug *dbg, int pid) {
} }
// Handshake // Handshake
if (!windbg_sync(wctx)) { if (!windbg_sync (wctx)) {
eprintf("Could not connect to windbg\n"); eprintf ("Could not connect to windbg\n");
windbg_ctx_free(wctx); windbg_ctx_free (wctx);
return false;
}
if (!windbg_read_ver (wctx)) {
windbg_ctx_free (wctx);
return false; return false;
} }
if (!windbg_read_ver(wctx)) {
windbg_ctx_free(wctx);
return false;
}
// Make r_debug_is_dead happy // Make r_debug_is_dead happy
dbg->pid = 0; dbg->pid = 0;
return true; return true;
} }
static int r_debug_windbg_detach (RDebug *dbg, int pid) { static int r_debug_windbg_detach(RDebug *dbg, int pid) {
eprintf ("Detaching...\n");
return true; return true;
} }
static char *r_debug_windbg_reg_profile(RDebug *dbg) { static char *r_debug_windbg_reg_profile(RDebug *dbg) {
if (!dbg) return NULL; if (!dbg) return NULL;
if (dbg->arch && strcmp (dbg->arch, "x86")) if (dbg->arch && strcmp (dbg->arch, "x86")) return NULL;
return NULL;
if (dbg->bits == R_SYS_BITS_32) { if (dbg->bits == R_SYS_BITS_32) {
#include "native/reg/windows-x86.h" #include "native/reg/windows-x86.h"
} else if (dbg->bits == R_SYS_BITS_64) { } else if (dbg->bits == R_SYS_BITS_64) {
@ -148,7 +143,7 @@ static char *r_debug_windbg_reg_profile(RDebug *dbg) {
return NULL; return NULL;
} }
static int r_debug_windbg_breakpoint (RBreakpointItem *bp, int set, void *user) { static int r_debug_windbg_breakpoint(RBreakpointItem *bp, int set, void *user) {
int *tag; int *tag;
if (!bp) return false; if (!bp) return false;
// Use a 32 bit word here to keep this compatible with 32 bit hosts // Use a 32 bit word here to keep this compatible with 32 bit hosts
@ -160,7 +155,7 @@ static int r_debug_windbg_init(RDebug *dbg) {
return true; return true;
} }
static RList *r_debug_windbg_pids (RDebug *dbg, int pid) { static RList *r_debug_windbg_pids(RDebug *dbg, int pid) {
RListIter *it; RListIter *it;
WindProc *p; WindProc *p;
@ -189,7 +184,7 @@ static RList *r_debug_windbg_pids (RDebug *dbg, int pid) {
return ret; return ret;
} }
static int r_debug_windbg_select (int pid, int tid) { static int r_debug_windbg_select(int pid, int tid) {
ut32 old = windbg_get_target (wctx); ut32 old = windbg_get_target (wctx);
int ret = windbg_set_target (wctx, pid); int ret = windbg_set_target (wctx, pid);
if (!ret) { if (!ret) {
@ -209,24 +204,24 @@ RDebugPlugin r_debug_plugin_windbg = {
.license = "LGPL3", .license = "LGPL3",
.arch = "x86", .arch = "x86",
.bits = R_SYS_BITS_32 | R_SYS_BITS_64, .bits = R_SYS_BITS_32 | R_SYS_BITS_64,
.pids = r_debug_windbg_pids, .init = &r_debug_windbg_init,
.select = r_debug_windbg_select, .step = &r_debug_windbg_step,
.step = r_debug_windbg_step, .cont = &r_debug_windbg_continue,
.init = r_debug_windbg_init,
.cont = r_debug_windbg_continue,
.attach = &r_debug_windbg_attach, .attach = &r_debug_windbg_attach,
.detach = &r_debug_windbg_detach, .detach = &r_debug_windbg_detach,
.pids = &r_debug_windbg_pids,
.wait = &r_debug_windbg_wait, .wait = &r_debug_windbg_wait,
.select = &r_debug_windbg_select,
.breakpoint = &r_debug_windbg_breakpoint, .breakpoint = &r_debug_windbg_breakpoint,
.reg_read = &r_debug_windbg_reg_read, .reg_read = &r_debug_windbg_reg_read,
.reg_write = &r_debug_windbg_reg_write, .reg_write = &r_debug_windbg_reg_write,
.reg_profile = r_debug_windbg_reg_profile, .reg_profile = &r_debug_windbg_reg_profile
}; };
#ifndef CORELIB #ifndef CORELIB
RLibStruct radare_plugin = { RLibStruct radare_plugin = {
.type = R_LIB_TYPE_DBG, .type = R_LIB_TYPE_DBG,
.data = &r_debug_plugin_winddbg, .data = &r_debug_plugin_windbg,
.version = R2_VERSION .version = R2_VERSION
}; };
#endif #endif

View File

@ -42,6 +42,7 @@ static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
eprintf ("Could not open the pipe\n"); eprintf ("Could not open the pipe\n");
return NULL; return NULL;
} }
eprintf ("Opened pipe %s with fd %d\n", file+9, io_ctx);
ctx = windbg_ctx_new (io_ctx); ctx = windbg_ctx_new (io_ctx);

View File

@ -1,54 +1,51 @@
// Copyright (c) 2014, The Lemon Man, All rights reserved. LGPLv3 // Copyright (c) 2014-2017, The Lemon Man, All rights reserved. LGPLv3
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "r_types.h" #include <r_types.h>
#include "transport.h"
#if __WINDOWS__ || __CYGWIN__ || MINGW32 #if __WINDOWS__ || __CYGWIN__ || MINGW32
#include <windows.h> #include <windows.h>
#include <fcntl.h>
#include "transport.h"
static void *iob_pipe_open (const char *path) { static void *iob_pipe_open(const char *path) {
HANDLE hPipe; HANDLE hPipe;
hPipe = CreateFileA (path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); hPipe = CreateFileA (path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
eprintf ("iob_pipe_open: invocado %s\n", path); eprintf ("iob_pipe_open: invocado %s\n", path);
if (hPipe != INVALID_HANDLE_VALUE) { if (hPipe != INVALID_HANDLE_VALUE) {
return (void *)(HANDLE)hPipe; return (void *) (HANDLE) hPipe;
} else { } else {
perror ("pipe"); perror ("pipe");
} }
return NULL; return NULL;
} }
static int iob_pipe_close (void *p) { static int iob_pipe_close(void *p) {
return CloseHandle (p); return CloseHandle (p);
} }
static int iob_pipe_read (void *p, uint8_t *buf, const uint64_t count, const int timeout) { static int iob_pipe_read(void *p, uint8_t *buf, const uint64_t count, const int timeout) {
DWORD c = 0; DWORD c = 0;
if (!ReadFile (p, buf, count, &c, NULL)) if (!ReadFile (p, buf, count, &c, NULL)) {
return -1; return -1;
}
return c; return c;
} }
static int iob_pipe_write (void *p, const uint8_t *buf, const uint64_t count, const int timeout) { static int iob_pipe_write(void *p, const uint8_t *buf, const uint64_t count, const int timeout) {
DWORD cbWrited = 0; DWORD cbWrited = 0;
if (!WriteFile (p, buf, count, &cbWrited, NULL)) if (!WriteFile (p, buf, count, &cbWrited, NULL)) {
return -1; return -1;
}
return cbWrited; return cbWrited;
} }
#else #else
#include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/un.h> #include <sys/un.h>
#include "transport.h"
static void *iob_pipe_open (const char *path) { static void *iob_pipe_open(const char *path) {
int sock; int sock;
struct sockaddr_un sa; struct sockaddr_un sa;
@ -62,44 +59,52 @@ static void *iob_pipe_open (const char *path) {
sa.sun_family = AF_UNIX; sa.sun_family = AF_UNIX;
strncpy (sa.sun_path, path, sizeof(sa.sun_path)); strncpy (sa.sun_path, path, sizeof(sa.sun_path));
sa.sun_path[sizeof (sa.sun_path)-1] = 0; sa.sun_path[sizeof (sa.sun_path) - 1] = 0;
if (connect (sock, (struct sockaddr *)&sa, sizeof(struct sockaddr_un)) == -1) { if (connect (sock, (struct sockaddr *) &sa, sizeof(struct sockaddr_un)) == -1) {
perror ("connect"); perror ("connect");
close (sock); close (sock);
return 0; return 0;
} }
return (void *)(size_t)sock; //struct timeval tv;
//tv.tv_sec = 5;
//tv.tv_usec = 0;
//setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval));
return (void *) (size_t) sock;
} }
static int iob_pipe_close (void *p) { static int iob_pipe_close(void *p) {
return close ((int)(size_t)p); return close ((int) (size_t) p);
} }
static int iob_pipe_read (void *p, uint8_t *buf, const uint64_t count, const int timeout) { static int iob_pipe_read(void *p, uint8_t *buf, const uint64_t count, const int timeout) {
//return recv((int)(size_t)p, buf, count, 0);
int result; int result;
fd_set readset; fd_set readset;
int fd=(int)(size_t)p; int fd = (int) (size_t) p;
for (;;) { for (;;) {
FD_ZERO(&readset); FD_ZERO (&readset);
FD_SET(fd, &readset); FD_SET (fd, &readset);
result = select (fd + 1, &readset, NULL, NULL, NULL); result = select (fd + 1, &readset, NULL, NULL, NULL);
if (result <1) { // pipe closed if (result < 1) {
if (errno == EINTR) if (errno == EINTR) continue;
continue;
return -1; return -1;
} }
if (FD_ISSET(fd, &readset)) { if (FD_ISSET (fd, &readset)) {
return recv((int)(size_t)p, buf, count, 0); return recv ((int) (size_t) p, buf, count, 0);
} }
} }
return EINTR; return EINTR;
} }
static int iob_pipe_write (void *p, const uint8_t *buf, const uint64_t count, const int timeout) { static int iob_pipe_write(void *p, const uint8_t *buf, const uint64_t count, const int timeout) {
return send((int)(size_t)p, buf, count, 0); int ret = send ((int) (size_t) p, buf, count, 0);
if (ret < 1) {
r_sys_perror ("iob_pipe_write, send");
if (errno == EPIPE) {
exit (1);
}
}
return ret;
} }
#endif #endif
io_backend_t iob_pipe = { io_backend_t iob_pipe = {

View File

@ -1,37 +1,25 @@
// Copyright (c) 2014, The Lemon Man, All rights reserved. // Copyright (c) 2014-2017, The Lemon Man, All rights reserved. LGPLv3
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3.0 of the License, or (at your option) any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this library.
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "transport.h" #include "transport.h"
#include "kd.h" #include "kd.h"
uint32_t kd_data_checksum (const uint8_t *buf, const uint64_t buf_len) { uint32_t kd_data_checksum(const uint8_t *buf, const uint64_t buf_len) {
uint32_t i, acc; uint32_t i, acc;
if (!buf || !buf_len) if (!buf || !buf_len) {
return 0; return 0;
}
for (i = acc = 0; i < buf_len; i++) for (i = acc = 0; i < buf_len; i++) {
acc += buf[i]; acc += buf[i];
}
return acc; return acc;
} }
int kd_send_ctrl_packet (void *fp, const uint32_t type, const uint32_t id) { int kd_send_ctrl_packet(void *fp, const uint32_t type, const uint32_t id) {
kd_packet_t pkt; kd_packet_t pkt;
pkt.leader = KD_PACKET_CTRL; pkt.leader = KD_PACKET_CTRL;
@ -40,51 +28,61 @@ int kd_send_ctrl_packet (void *fp, const uint32_t type, const uint32_t id) {
pkt.id = id; pkt.id = id;
pkt.type = type; pkt.type = type;
if (iob_write(fp, (uint8_t *)&pkt, sizeof(kd_packet_t)) < 0) if (iob_write (fp, (uint8_t *) &pkt, sizeof(kd_packet_t)) < 0) {
return KD_E_IOERR; return KD_E_IOERR;
}
return KD_E_OK; return KD_E_OK;
} }
int kd_send_data_packet (void *fp, const uint32_t type, const uint32_t id, const uint8_t *req, int kd_send_data_packet(void *fp, const uint32_t type, const uint32_t id, const uint8_t *req,
const int req_len, const uint8_t *buf, const uint32_t buf_len) { const int req_len, const uint8_t *buf, const uint32_t buf_len) {
kd_packet_t pkt; kd_packet_t pkt;
if (req_len + buf_len > KD_MAX_PAYLOAD) if (req_len + buf_len > KD_MAX_PAYLOAD) {
return KD_E_MALFORMED; return KD_E_MALFORMED;
}
//kd_req_t *r = (kd_req_t*) req;
//eprintf ("==== Send ====\n%08x\n", r->req);
pkt.leader = KD_PACKET_DATA; pkt.leader = KD_PACKET_DATA;
pkt.length = req_len + buf_len; pkt.length = req_len + buf_len;
pkt.checksum = kd_data_checksum(req, req_len) + pkt.checksum = kd_data_checksum (req, req_len) +
kd_data_checksum(buf, buf_len); kd_data_checksum (buf, buf_len);
pkt.id = id; pkt.id = id;
pkt.type = type; pkt.type = type;
if (iob_write(fp, (uint8_t *)&pkt, sizeof(kd_packet_t)) < 0) if (iob_write (fp, (uint8_t *) &pkt, sizeof(kd_packet_t)) < 0) {
return KD_E_IOERR; return KD_E_IOERR;
}
if (iob_write(fp, (uint8_t *)req, req_len) < 0) if (iob_write (fp, (uint8_t *) req, req_len) < 0) {
return KD_E_IOERR; return KD_E_IOERR;
}
if (buf && iob_write(fp, (uint8_t *)buf, buf_len) < 0) if (buf && iob_write (fp, (uint8_t *) buf, buf_len) < 0) {
return KD_E_IOERR; return KD_E_IOERR;
}
if (iob_write(fp, (uint8_t *)"\xAA", 1) < 0) if (iob_write (fp, (uint8_t *) "\xAA", 1) < 0) {
return KD_E_IOERR; return KD_E_IOERR;
}
return KD_E_OK; return KD_E_OK;
} }
int kd_read_packet (void *fp, kd_packet_t **p) { int kd_read_packet(void *fp, kd_packet_t **p) {
kd_packet_t pkt; kd_packet_t pkt;
uint8_t *buf; uint8_t *buf;
*p = NULL; *p = NULL;
if (iob_read(fp, (uint8_t *)&pkt, sizeof(kd_packet_t)) < 0) if (iob_read (fp, (uint8_t *) &pkt, sizeof (kd_packet_t)) <= 0) {
return KD_E_IOERR; return KD_E_IOERR;
}
if (!kd_packet_is_valid(&pkt)) { if (!kd_packet_is_valid (&pkt)) {
eprintf ("invalid leader %08x\n", pkt.leader); eprintf ("invalid leader %08x\n", pkt.leader);
return KD_E_MALFORMED; return KD_E_MALFORMED;
} }
@ -93,12 +91,13 @@ int kd_read_packet (void *fp, kd_packet_t **p) {
if (!buf) { if (!buf) {
return KD_E_IOERR; return KD_E_IOERR;
} }
memcpy(buf, &pkt, sizeof(kd_packet_t)); memcpy (buf, &pkt, sizeof(kd_packet_t));
if (pkt.length) if (pkt.length) {
iob_read(fp, (uint8_t *)buf + sizeof(kd_packet_t), pkt.length); iob_read (fp, (uint8_t *) buf + sizeof(kd_packet_t), pkt.length);
}
if (pkt.checksum != kd_data_checksum(buf + sizeof(kd_packet_t), pkt.length)) { if (pkt.checksum != kd_data_checksum (buf + sizeof(kd_packet_t), pkt.length)) {
eprintf ("Checksum mismatch!\n"); eprintf ("Checksum mismatch!\n");
free (buf); free (buf);
return KD_E_MALFORMED; return KD_E_MALFORMED;
@ -106,26 +105,26 @@ int kd_read_packet (void *fp, kd_packet_t **p) {
if (pkt.leader == KD_PACKET_DATA) { if (pkt.leader == KD_PACKET_DATA) {
uint8_t trailer; uint8_t trailer;
iob_read(fp, (uint8_t *)&trailer, 1); iob_read (fp, (uint8_t *) &trailer, 1);
if (trailer != 0xAA) { if (trailer != 0xAA) {
printf("Missing trailer 0xAA\n"); printf ("Missing trailer 0xAA\n");
free(buf); free (buf);
return KD_E_MALFORMED; return KD_E_MALFORMED;
} }
kd_send_ctrl_packet(fp, KD_PACKET_TYPE_ACK, ((kd_packet_t *)buf)->id & ~(0x800)); kd_send_ctrl_packet (fp, KD_PACKET_TYPE_ACKNOWLEDGE, ((kd_packet_t *) buf)->id & ~(0x800));
} }
*p = (kd_packet_t *)buf; *p = (kd_packet_t *) buf;
return KD_E_OK; return KD_E_OK;
} }
int kd_packet_is_valid (const kd_packet_t *p) { int kd_packet_is_valid(const kd_packet_t *p) {
return p->leader == KD_PACKET_CTRL || p->leader == KD_PACKET_DATA; return p->leader == KD_PACKET_CTRL || p->leader == KD_PACKET_DATA;
} }
int kd_packet_is_ack (const kd_packet_t *p) { int kd_packet_is_ack(const kd_packet_t *p) {
return p->leader == KD_PACKET_CTRL && p->type == KD_PACKET_TYPE_ACK; return p->leader == KD_PACKET_CTRL && p->type == KD_PACKET_TYPE_ACKNOWLEDGE;
} }

View File

@ -1,20 +1,4 @@
// Copyright (c) 2014, The Lemon Man, All rights reserved. // Copyright (c) 2014-2017, The Lemon Man, All rights reserved. LGPLv3
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3.0 of the License, or (at your option) any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this library.
// Some documentation of the data structures has been kindly ripped off ReactOS project.
#ifndef KD_H #ifndef KD_H
#define KD_H #define KD_H
#include <r_types_base.h> #include <r_types_base.h>
@ -27,17 +11,79 @@ enum {
KD_E_IOERR = -4, KD_E_IOERR = -4,
}; };
enum KD_PACKET_TYPE {
KD_PACKET_TYPE_UNUSED = 0,
KD_PACKET_TYPE_STATE_CHANGE32 = 1,
KD_PACKET_TYPE_STATE_MANIPULATE = 2,
KD_PACKET_TYPE_DEBUG_IO = 3,
KD_PACKET_TYPE_ACKNOWLEDGE = 4,
KD_PACKET_TYPE_RESEND = 5,
KD_PACKET_TYPE_RESET = 6,
KD_PACKET_TYPE_STATE_CHANGE64 = 7,
KD_PACKET_TYPE_POLL_BREAKIN = 8,
KD_PACKET_TYPE_TRACE_IO = 9,
KD_PACKET_TYPE_CONTROL_REQUEST = 10,
KD_PACKET_TYPE_FILE_IO = 11
};
enum KD_PACKET_WAIT_STATE_CHANGE {
DbgKdMinimumStateChange = 0x00003030,
DbgKdExceptionStateChange = 0x00003030,
DbgKdLoadSymbolsStateChange = 0x00003031,
DbgKdCommandStringStateChange = 0x00003032,
DbgKdMaximumStateChange = 0x00003033
};
enum KD_PACKET_MANIPULATE_TYPE {
DbgKdMinimumManipulate = 0x00003130,
DbgKdReadVirtualMemoryApi = 0x00003130,
DbgKdWriteVirtualMemoryApi = 0x00003131,
DbgKdGetContextApi = 0x00003132,
DbgKdSetContextApi = 0x00003133,
DbgKdWriteBreakPointApi = 0x00003134,
DbgKdRestoreBreakPointApi = 0x00003135,
DbgKdContinueApi = 0x00003136,
DbgKdReadControlSpaceApi = 0x00003137,
DbgKdWriteControlSpaceApi = 0x00003138,
DbgKdReadIoSpaceApi = 0x00003139,
DbgKdWriteIoSpaceApi = 0x0000313A,
DbgKdRebootApi = 0x0000313B,
DbgKdContinueApi2 = 0x0000313C,
DbgKdReadPhysicalMemoryApi = 0x0000313D,
DbgKdWritePhysicalMemoryApi = 0x0000313E,
DbgKdQuerySpecialCallsApi = 0x0000313F,
DbgKdSetSpecialCallApi = 0x00003140,
DbgKdClearSpecialCallsApi = 0x00003141,
DbgKdSetInternalBreakPointApi = 0x00003142,
DbgKdGetInternalBreakPointApi = 0x00003143,
DbgKdReadIoSpaceExtendedApi = 0x00003144,
DbgKdWriteIoSpaceExtendedApi = 0x00003145,
DbgKdGetVersionApi = 0x00003146,
DbgKdWriteBreakPointExApi = 0x00003147,
DbgKdRestoreBreakPointExApi = 0x00003148,
DbgKdCauseBugCheckApi = 0x00003149,
DbgKdSwitchProcessor = 0x00003150,
DbgKdPageInApi = 0x00003151,
DbgKdReadMachineSpecificRegister = 0x00003152,
DbgKdWriteMachineSpecificRegister = 0x00003153,
OldVlm1 = 0x00003154,
OldVlm2 = 0x00003155,
DbgKdSearchMemoryApi = 0x00003156,
DbgKdGetBusDataApi = 0x00003157,
DbgKdSetBusDataApi = 0x00003158,
DbgKdCheckLowMemoryApi = 0x00003159,
DbgKdClearAllInternalBreakpointsApi = 0x0000315A,
DbgKdFillMemoryApi = 0x0000315B,
DbgKdQueryMemoryApi = 0x0000315C,
DbgKdSwitchPartition = 0x0000315D,
DbgKdMaximumManipulate = 0x0000315E
};
#define KD_PACKET_DATA 0x30303030 #define KD_PACKET_DATA 0x30303030
#define KD_PACKET_CTRL 0x69696969 #define KD_PACKET_CTRL 0x69696969
#define KD_MAX_PAYLOAD 0x800 #define KD_MAX_PAYLOAD 0x800
#define KD_PACKET_MAX_SIZE 4000 // Not used ? What is max payload ?
#define KD_PACKET_TYPE_MANIP 2
#define KD_PACKET_TYPE_ACK 4
#define KD_PACKET_TYPE_RESEND 5
#define KD_PACKET_TYPE_RESET 6
#define KD_PACKET_TYPE_STATE_CHANGE 7
#define KD_PACKET_TYPE_IO 11
// http://msdn.microsoft.com/en-us/library/cc704588.aspx // http://msdn.microsoft.com/en-us/library/cc704588.aspx
#define KD_RET_OK 0x00000000 #define KD_RET_OK 0x00000000

View File

@ -1,82 +1,93 @@
// Copyright (c) 2014, The Lemon Man, All rights reserved. LGPLv3 // Copyright (c) 2014-2017, The Lemon Man, All rights reserved. LGPLv3
#include <stdio.h> #include <stdio.h>
#include "transport.h" #include "transport.h"
extern io_backend_t iob_pipe; extern io_backend_t iob_pipe;
static io_backend_t *io_backends[] = { static io_backend_t *io_backends[] = {
//#if __WINDOWS__ || __CYGWIN__ || MINGW32 // #if __WINDOWS__ || __CYGWIN__ || MINGW32
//#warning TODO: add proper IO backend for windows here // #warning TODO: add proper IO backend for windows here
//#else // #else
&iob_pipe, &iob_pipe,
//#endif // #endif
NULL, NULL,
}; };
static io_backend_t *sel_backend = &iob_pipe; static io_backend_t *sel_backend = &iob_pipe;
int iob_select (const char *name) { int iob_select(const char *name) {
io_backend_t *iob; io_backend_t *iob;
iob = io_backends[0]; iob = io_backends[0];
if (!iob) if (!iob) {
return 0; return 0;
}
if (sel_backend && sel_backend->deinit) if (sel_backend && sel_backend->deinit) {
sel_backend->deinit(); sel_backend->deinit ();
}
sel_backend = iob; sel_backend = iob;
if (sel_backend->init) if (sel_backend->init) {
sel_backend->init(); sel_backend->init ();
}
return 1; return 1;
} }
void *iob_open (const char *path) { void *iob_open(const char *path) {
if (!sel_backend) if (!sel_backend) {
return NULL; return NULL;
return sel_backend->open(path); }
return sel_backend->open (path);
} }
int iob_close (void *fp) { int iob_close(void *fp) {
if (!sel_backend) if (!sel_backend) {
return E_NOIF; return E_NOIF;
return sel_backend->close(fp); }
return sel_backend->close (fp);
} }
int iob_config (void *fp, void *cfg) { int iob_config(void *fp, void *cfg) {
if (!sel_backend) if (!sel_backend) {
return E_NOIF; return E_NOIF;
return sel_backend->config(fp, cfg); }
return sel_backend->config (fp, cfg);
} }
int iob_write (void *fp, const uint8_t *buf, const uint32_t buf_len) { int iob_write(void *fp, const uint8_t *buf, const uint32_t buf_len) {
uint32_t done; uint32_t done;
if (!sel_backend) if (!sel_backend) {
return E_NOIF; return E_NOIF;
}
for (done = 0; done < buf_len;) { for (done = 0; done < buf_len;) {
int ret = sel_backend->write(fp, buf + done, buf_len - done, 100); int ret = sel_backend->write (fp, buf + done, buf_len - done, 100);
if (ret<1) break; if (ret < 1) {
break;
}
done += ret; done += ret;
} }
return done; return done;
} }
int iob_read (void *fp, uint8_t *buf, const uint32_t buf_len) { int iob_read(void *fp, uint8_t *buf, const uint32_t buf_len) {
uint32_t done; uint32_t done;
if (!sel_backend) if (!sel_backend) {
return E_NOIF; return E_NOIF;
}
for (done = 0; done < buf_len;) { for (done = 0; done < buf_len;) {
int ret = sel_backend->read(fp, buf + done, buf_len - done, 100); int ret = sel_backend->read (fp, buf + done, buf_len - done, 100);
if (ret<1) break; if (ret < 1) {
break;
}
done += ret; done += ret;
} }

View File

@ -1,18 +1,4 @@
// Copyright (c) 2014-2017, The Lemon Man, All rights reserved. LGPLv3 // Copyright (c) 2014-2017, The Lemon Man, All rights reserved. LGPLv3
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3.0 of the License, or (at your option) any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this library.
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
@ -24,7 +10,7 @@
#include "kd.h" #include "kd.h"
#define O_FLAG_XPVAD 1 #define O_FLAG_XPVAD 1
#define WIND_DBG if (false) #define WIND_DBG if (true)
#define O_(n) ctx->os_profile->f[n] #define O_(n) ctx->os_profile->f[n]
#include "profiles.h" #include "profiles.h"
@ -67,22 +53,12 @@ Profile *windbg_get_profile(int bits, int build, int sp) {
return NULL; return NULL;
} }
#define LOG_PKT(p) { \ #define LOG_REQ(r) { \
eprintf ("Leader\t: %08x\nType\t: %08x\nLength\t: %08x\nID\t: %08x\nCheck\t: %08x [%s]\n", \ eprintf ("Request : %08x\nProcessor : %08x\nReturn : %08x\n",\
(p)->leader, \ (r)->req, \
(p)->type, \ (r)->cpu, \
(p)->length, \ (r)->ret \
(p)->id, \ ); \
(e)->checksum, \
(kd_data_checksum ((p)->data, (p)->length) == (p)->checksum)? "Ok": "Wrong" \
); \
}
#define LOG_REQ(r) { \
eprintf ("Request : %08x\nProcessor : %08x\nReturn : %08x\n", \
(r)->req, \
(r)->cpu, \
(r)->ret \
); \
} }
struct _WindCtx { struct _WindCtx {
@ -194,8 +170,8 @@ static void dump_stc(kd_packet_t *p) {
(ut64) stc->pc, (ut64) stc->kthread); (ut64) stc->pc, (ut64) stc->kthread);
eprintf ("On cpu %i/%i\n", stc->cpu + 1, stc->cpu_count); eprintf ("On cpu %i/%i\n", stc->cpu + 1, stc->cpu_count);
if (stc->state == 0x3030) { if (stc->state == DbgKdExceptionStateChange) {
eprintf ("ex\n"); eprintf ("Exception\n");
eprintf ("\tCode : %08x\n", stc->exception.code); eprintf ("\tCode : %08x\n", stc->exception.code);
eprintf ("\tFlags : %08x\n", stc->exception.flags); eprintf ("\tFlags : %08x\n", stc->exception.flags);
eprintf ("\tRecord : %016"PFMT64x "\n", (ut64) stc->exception.ex_record); eprintf ("\tRecord : %016"PFMT64x "\n", (ut64) stc->exception.ex_record);
@ -210,50 +186,53 @@ static int do_io_reply(WindCtx *ctx, kd_packet_t *pkt) {
int ret; int ret;
ioc.req = 0x3430; ioc.req = 0x3430;
ioc.ret = KD_RET_ENOENT; ioc.ret = KD_RET_ENOENT;
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_IO, ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_FILE_IO,
(ctx->seq_id ^= 1), (uint8_t *) &ioc, sizeof (kd_ioc_t), NULL, 0); (ctx->seq_id ^= 1), (uint8_t *) &ioc, sizeof (kd_ioc_t), NULL, 0);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return false; return false;
} }
WIND_DBG eprintf ("Waiting for io_reply ack...\n"); WIND_DBG eprintf("Waiting for io_reply ack...\n");
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return false; return false;
} }
WIND_DBG eprintf ("Ack received, restore flow\n"); WIND_DBG eprintf("Ack received, restore flow\n");
return true; return true;
} }
int windbg_wait_packet(WindCtx *ctx, const uint32_t type, kd_packet_t **p) { int windbg_wait_packet(WindCtx *ctx, const uint32_t type, kd_packet_t **p) {
kd_packet_t *pkt; kd_packet_t *pkt = NULL;
int ret, retries = 10; int ret;
int retries = 10;
// r_sys_backtrace();
pkt = NULL;
do { do {
free (pkt); if (pkt) free (pkt);
// Try to read a whole packet // Try to read a whole packet
ret = kd_read_packet (ctx->io_ptr, &pkt); ret = kd_read_packet (ctx->io_ptr, &pkt);
// eprintf("kd_read_packet() = %i\n", ret);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
break; break;
} }
// eprintf("Received %08x, expected %08x\n", pkt->type, type); // eprintf ("Received %08x\n", pkt->type);
if (pkt->leader == KD_PACKET_DATA && pkt->type == KD_PACKET_TYPE_STATE_CHANGE) { if (pkt->type != type) {
dump_stc (pkt); eprintf ("We were not waiting for this... %08x\n", type);
} }
if (pkt->leader == KD_PACKET_DATA && pkt->type == KD_PACKET_TYPE_IO) { if (pkt->leader == KD_PACKET_DATA && pkt->type == KD_PACKET_TYPE_STATE_CHANGE64) {
// dump_stc (pkt);
eprintf ("State64\n");
}
if (pkt->leader == KD_PACKET_DATA && pkt->type == KD_PACKET_TYPE_FILE_IO) {
eprintf ("Replying IO\n");
do_io_reply (ctx, pkt); do_io_reply (ctx, pkt);
} }
// Check for RESEND // Check for RESEND
// The host didn't like our request // The host didn't like our request
if (pkt->leader == KD_PACKET_CTRL && pkt->type == KD_PACKET_TYPE_RESEND) { if (pkt->leader == KD_PACKET_CTRL && pkt->type == KD_PACKET_TYPE_RESEND) {
r_sys_backtrace ();
eprintf ("Waoh. You probably sent a malformed packet !\n");
ret = KD_E_MALFORMED; ret = KD_E_MALFORMED;
break; //break;
} }
} while (pkt->type != type && retries--); } while (pkt->type != type && retries--);
@ -333,7 +312,7 @@ RList *windbg_list_process(WindCtx *ctx) {
4 << ctx->is_x64); 4 << ctx->is_x64);
base = ptr; base = ptr;
WIND_DBG eprintf ("Process list head : 0x%016"PFMT64x "\n", ptr); WIND_DBG eprintf("Process list head : 0x%016"PFMT64x "\n", ptr);
// Walk the LIST_ENTRY // Walk the LIST_ENTRY
windbg_read_at (ctx, (uint8_t *) &ptr, ptr, 4 << ctx->is_x64); windbg_read_at (ctx, (uint8_t *) &ptr, ptr, 4 << ctx->is_x64);
@ -401,7 +380,7 @@ bool windbg_va_to_pa(WindCtx *ctx, ut64 va, ut64 *pa) {
return 0; return 0;
} }
WIND_DBG eprintf ("VA : %016"PFMT64x "\n", va); WIND_DBG eprintf("VA : %016"PFMT64x "\n", va);
if (ctx->is_x64) { if (ctx->is_x64) {
pti = (va >> 12) & 0x1ff; pti = (va >> 12) & 0x1ff;
@ -429,7 +408,7 @@ bool windbg_va_to_pa(WindCtx *ctx, ut64 va, ut64 *pa) {
tmp = ctx->target->dir_base_table; tmp = ctx->target->dir_base_table;
tmp &= ~0x1f; tmp &= ~0x1f;
WIND_DBG eprintf ("CR3 : %016"PFMT64x "\n", tmp); WIND_DBG eprintf("CR3 : %016"PFMT64x "\n", tmp);
if (ctx->is_x64) { if (ctx->is_x64) {
// PML4 lookup // PML4 lookup
@ -437,7 +416,7 @@ bool windbg_va_to_pa(WindCtx *ctx, ut64 va, ut64 *pa) {
return false; return false;
} }
tmp &= mask; tmp &= mask;
WIND_DBG eprintf ("PML4 : %016"PFMT64x "\n", tmp); WIND_DBG eprintf("PML4 : %016"PFMT64x "\n", tmp);
} }
if (ctx->pae) { if (ctx->pae) {
@ -446,14 +425,14 @@ bool windbg_va_to_pa(WindCtx *ctx, ut64 va, ut64 *pa) {
return false; return false;
} }
tmp &= mask; tmp &= mask;
WIND_DBG eprintf ("PDPE : %016"PFMT64x "\n", tmp); WIND_DBG eprintf("PDPE : %016"PFMT64x "\n", tmp);
} }
// PDT lookup // PDT lookup
if (!windbg_read_at_phys (ctx, (uint8_t *) &tmp, tmp + pdi * (4 << ctx->pae), 4 << ctx->pae)) { if (!windbg_read_at_phys (ctx, (uint8_t *) &tmp, tmp + pdi * (4 << ctx->pae), 4 << ctx->pae)) {
return false; return false;
} }
WIND_DBG eprintf ("PDE : %016"PFMT64x "\n", tmp); WIND_DBG eprintf("PDE : %016"PFMT64x "\n", tmp);
// Large page entry // Large page entry
// The page size differs between pae and non-pae systems, the former points to 2MB pages while // The page size differs between pae and non-pae systems, the former points to 2MB pages while
@ -469,7 +448,7 @@ bool windbg_va_to_pa(WindCtx *ctx, ut64 va, ut64 *pa) {
if (!windbg_read_at_phys (ctx, (uint8_t *) &tmp, (tmp & mask) + pti * (4 << ctx->pae), 4 << ctx->pae)) { if (!windbg_read_at_phys (ctx, (uint8_t *) &tmp, (tmp & mask) + pti * (4 << ctx->pae), 4 << ctx->pae)) {
return false; return false;
} }
WIND_DBG eprintf ("PTE : %016"PFMT64x "\n", tmp); WIND_DBG eprintf("PTE : %016"PFMT64x "\n", tmp);
if (tmp & PTE_VALID) { if (tmp & PTE_VALID) {
*pa = (tmp & mask) | (va & 0xfff); *pa = (tmp & mask) | (va & 0xfff);
@ -498,29 +477,26 @@ bool windbg_read_ver(WindCtx *ctx) {
req.req = 0x3146; req.req = 0x3146;
req.cpu = ctx->cpu; req.cpu = ctx->cpu;
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_MANIP, ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_STATE_MANIPULATE,
(ctx->seq_id ^= 1), (uint8_t *) &req, sizeof(kd_req_t), NULL, 0); (ctx->seq_id ^= 1), (uint8_t *) &req, sizeof(kd_req_t), NULL, 0);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_MANIP, &pkt); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_MANIPULATE, &pkt);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
kd_req_t *rr = PKT_REQ (pkt); kd_req_t *rr = PKT_REQ (pkt);
/* LOG_PKT(pkt); */
/* LOG_REQ(rr); */
if (rr->ret) { if (rr->ret) {
WIND_DBG eprintf ("%s : req returned %08x\n", __FUNCTION__, rr->ret); WIND_DBG eprintf("%s : req returned %08x\n", __FUNCTION__, rr->ret);
free (pkt); free (pkt);
return 0; return 0;
} }
@ -556,7 +532,7 @@ bool windbg_read_ver(WindCtx *ctx) {
ctx->dbg_addr = ptr; ctx->dbg_addr = ptr;
WIND_DBG eprintf ("_KDDEBUGGER_DATA64 at 0x%016"PFMT64x "\n", ctx->dbg_addr); WIND_DBG eprintf("_KDDEBUGGER_DATA64 at 0x%016"PFMT64x "\n", ctx->dbg_addr);
// Thanks to this we don't have to find a way to read the cr4 // Thanks to this we don't have to find a way to read the cr4
uint16_t pae_enabled; uint16_t pae_enabled;
@ -605,8 +581,8 @@ int windbg_sync(WindCtx *ctx) {
return 0; return 0;
} }
// Syncronize with the first KD_PACKET_TYPE_STATE_CHANGE packet // Syncronize with the first KD_PACKET_TYPE_STATE_CHANGE64 packet
windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_CHANGE, &s); windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_CHANGE64, &s);
// Reset the sequence id // Reset the sequence id
ctx->seq_id = 0x80800001; ctx->seq_id = 0x80800001;
@ -633,23 +609,21 @@ int windbg_continue(WindCtx *ctx) {
if (!ctx || !ctx->io_ptr || !ctx->syncd) { if (!ctx || !ctx->io_ptr || !ctx->syncd) {
return 0; return 0;
} }
req.req = 0x313C; req.req = DbgKdContinueApi2;
req.cpu = ctx->cpu; req.cpu = ctx->cpu;
req.r_cont.reason = 0x10001; req.r_cont.reason = 0x10001;
// The meaning of 0x400 is unknown, but Windows doesn't // The meaning of 0x400 is unknown, but Windows doesn't
// behave like suggested by ReactOS source // behave like suggested by ReactOS source
req.r_cont.tf = 0x400; req.r_cont.tf = 0x400;
WIND_DBG eprintf ("Sending continue...\n"); ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_STATE_MANIPULATE,
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_MANIP,
(ctx->seq_id ^= 1), (uint8_t *) &req, sizeof (kd_req_t), NULL, 0); (ctx->seq_id ^= 1), (uint8_t *) &req, sizeof (kd_req_t), NULL, 0);
if (ret == KD_E_OK) { if (ret == KD_E_OK) {
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret == KD_E_OK) { if (ret == KD_E_OK) {
// XXX What about DbgKdContinueApi ?
r_list_free (ctx->plist_cache); r_list_free (ctx->plist_cache);
ctx->plist_cache = NULL; ctx->plist_cache = NULL;
WIND_DBG eprintf ("Done!\n");
return true; return true;
} }
} }
@ -666,35 +640,32 @@ bool windbg_write_reg(WindCtx *ctx, const uint8_t *buf, int size) {
if (!ctx || !ctx->io_ptr || !ctx->syncd) { if (!ctx || !ctx->io_ptr || !ctx->syncd) {
return false; return false;
} }
req.req = 0x3133; req.req = DbgKdSetContextApi;
req.cpu = ctx->cpu; req.cpu = ctx->cpu;
req.r_ctx.flags = 0x1003F; req.r_ctx.flags = 0x1003F;
WIND_DBG eprintf ("Regwrite() size: %x\n", size); WIND_DBG eprintf("Regwrite() size: %x\n", size);
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_MANIP, ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_STATE_MANIPULATE,
(ctx->seq_id ^= 1), (uint8_t *) &req, sizeof(kd_req_t), buf, size); (ctx->seq_id ^= 1), (uint8_t *) &req, sizeof(kd_req_t), buf, size);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_MANIP, &pkt); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_MANIPULATE, &pkt);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
kd_req_t *rr = PKT_REQ (pkt); kd_req_t *rr = PKT_REQ (pkt);
// LOG_PKT(pkt);
// LOG_REQ(rr);
if (rr->ret) { if (rr->ret) {
WIND_DBG eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret); WIND_DBG eprintf("%s: req returned %08x\n", __FUNCTION__, rr->ret);
free (pkt); free (pkt);
return 0; return 0;
} }
@ -715,34 +686,31 @@ int windbg_read_reg(WindCtx *ctx, uint8_t *buf, int size) {
memset (&req, 0, sizeof(kd_req_t)); memset (&req, 0, sizeof(kd_req_t));
req.req = 0x3132; req.req = DbgKdGetContextApi;
req.cpu = ctx->cpu; req.cpu = ctx->cpu;
req.r_ctx.flags = 0x1003F; req.r_ctx.flags = 0x1003F;
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_MANIP, (ctx->seq_id ^= 1), (uint8_t *) &req, ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_STATE_MANIPULATE, (ctx->seq_id ^= 1), (uint8_t *) &req,
sizeof(kd_req_t), NULL, 0); sizeof(kd_req_t), NULL, 0);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_MANIP, &pkt); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_MANIPULATE, &pkt);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
kd_req_t *rr = PKT_REQ (pkt); kd_req_t *rr = PKT_REQ (pkt);
// LOG_PKT(pkt);
// LOG_REQ(rr);
if (rr->ret) { if (rr->ret) {
WIND_DBG eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret); WIND_DBG eprintf("%s: req returned %08x\n", __FUNCTION__, rr->ret);
free (pkt); free (pkt);
return 0; return 0;
} }
@ -765,37 +733,31 @@ int windbg_query_mem(WindCtx *ctx, const ut64 addr, int *address_space, int *fla
memset (&req, 0, sizeof(kd_req_t)); memset (&req, 0, sizeof(kd_req_t));
req.req = 0x315c; req.req = DbgKdQueryMemoryApi;
req.cpu = ctx->cpu; req.cpu = ctx->cpu;
req.r_query_mem.addr = addr; req.r_query_mem.addr = addr;
req.r_query_mem.address_space = 0; // Tells the kernel that 'addr' is a virtual address req.r_query_mem.address_space = 0; // Tells the kernel that 'addr' is a virtual address
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_MANIP, (ctx->seq_id ^= 1), (uint8_t *) &req, ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_STATE_MANIPULATE, (ctx->seq_id ^= 1), (uint8_t *) &req,
sizeof(kd_req_t), NULL, 0); sizeof(kd_req_t), NULL, 0);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_MANIP, &pkt); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_MANIPULATE, &pkt);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
kd_req_t *rr = PKT_REQ (pkt); kd_req_t *rr = PKT_REQ (pkt);
// LOG_PKT(pkt);
// LOG_REQ(rr);
if (rr->ret) { if (rr->ret) {
#ifdef windbg_LOG
eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
#endif
free (pkt); free (pkt);
return 0; return 0;
} }
@ -824,7 +786,7 @@ int windbg_bkpt(WindCtx *ctx, const ut64 addr, const int set, const int hw, int
return 0; return 0;
} }
req.req = set? 0x3134: 0x3135; req.req = set? DbgKdWriteBreakPointApi: DbgKdRestoreBreakPointApi;
req.cpu = ctx->cpu; req.cpu = ctx->cpu;
if (set) { if (set) {
@ -833,31 +795,25 @@ int windbg_bkpt(WindCtx *ctx, const ut64 addr, const int set, const int hw, int
req.r_del_bp.handle = *handle; req.r_del_bp.handle = *handle;
} }
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_MANIP, (ctx->seq_id ^= 1), (uint8_t *) &req, ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_STATE_MANIPULATE, (ctx->seq_id ^= 1), (uint8_t *) &req,
sizeof(kd_req_t), NULL, 0); sizeof(kd_req_t), NULL, 0);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_MANIP, &pkt); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_MANIPULATE, &pkt);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
kd_req_t *rr = PKT_REQ (pkt); kd_req_t *rr = PKT_REQ (pkt);
// LOG_PKT(pkt);
// LOG_REQ(rr);
if (rr->ret) { if (rr->ret) {
#ifdef windbg_LOG
eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
#endif
free (pkt); free (pkt);
return 0; return 0;
} }
@ -877,37 +833,31 @@ int windbg_read_at_phys(WindCtx *ctx, uint8_t *buf, const ut64 offset, const int
if (!ctx || !ctx->io_ptr || !ctx->syncd) { if (!ctx || !ctx->io_ptr || !ctx->syncd) {
return 0; return 0;
} }
req.req = 0x313D; req.req = DbgKdReadPhysicalMemoryApi;
req.cpu = ctx->cpu; req.cpu = ctx->cpu;
req.r_mem.addr = offset; req.r_mem.addr = offset;
req.r_mem.length = R_MIN (count, KD_MAX_PAYLOAD); req.r_mem.length = R_MIN (count, KD_MAX_PAYLOAD);
req.r_mem.read = 0; // Default caching option req.r_mem.read = 0; // Default caching option
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_MANIP, (ctx->seq_id ^= 1), ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_STATE_MANIPULATE, (ctx->seq_id ^= 1),
(uint8_t *) &req, sizeof(kd_req_t), NULL, 0); (uint8_t *) &req, sizeof(kd_req_t), NULL, 0);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_MANIP, &pkt); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_MANIPULATE, &pkt);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
rr = PKT_REQ (pkt); rr = PKT_REQ (pkt);
// LOG_PKT(pkt);
// LOG_REQ(rr);
if (rr->ret) { if (rr->ret) {
#ifdef windbg_LOG
eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
#endif
free (pkt); free (pkt);
return 0; return 0;
} }
@ -928,31 +878,27 @@ int windbg_read_at(WindCtx *ctx, uint8_t *buf, const ut64 offset, const int coun
if (!ctx || !ctx->io_ptr || !ctx->syncd) { if (!ctx || !ctx->io_ptr || !ctx->syncd) {
return 0; return 0;
} }
req.req = 0x3130; req.req = DbgKdReadVirtualMemoryApi;
req.cpu = ctx->cpu; req.cpu = ctx->cpu;
req.r_mem.addr = offset; req.r_mem.addr = offset;
req.r_mem.length = R_MIN (count, KD_MAX_PAYLOAD); req.r_mem.length = R_MIN (count, KD_MAX_PAYLOAD);
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_MANIP, ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_STATE_MANIPULATE,
(ctx->seq_id ^= 1), (uint8_t *) &req, sizeof(kd_req_t), NULL, 0); (ctx->seq_id ^= 1), (uint8_t *) &req, sizeof(kd_req_t), NULL, 0);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_MANIP, &pkt); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_MANIPULATE, &pkt);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
rr = PKT_REQ (pkt); rr = PKT_REQ (pkt);
// LOG_PKT(pkt);
// LOG_REQ(rr);
if (rr->ret) { if (rr->ret) {
WIND_DBG eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
free (pkt); free (pkt);
return 0; return 0;
} }
@ -975,35 +921,31 @@ int windbg_write_at(WindCtx *ctx, const uint8_t *buf, const ut64 offset, const i
} }
payload = R_MIN (count, KD_MAX_PAYLOAD - sizeof(kd_req_t)); payload = R_MIN (count, KD_MAX_PAYLOAD - sizeof(kd_req_t));
req.req = 0x3131; req.req = DbgKdWriteVirtualMemoryApi;
req.cpu = ctx->cpu; req.cpu = ctx->cpu;
req.r_mem.addr = offset; req.r_mem.addr = offset;
req.r_mem.length = payload; req.r_mem.length = payload;
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_MANIP, ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_STATE_MANIPULATE,
(ctx->seq_id ^= 1), (uint8_t *) &req, (ctx->seq_id ^= 1), (uint8_t *) &req,
sizeof(kd_req_t), buf, payload); sizeof(kd_req_t), buf, payload);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_MANIP, &pkt); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_MANIPULATE, &pkt);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
rr = PKT_REQ (pkt); rr = PKT_REQ (pkt);
// LOG_PKT(pkt);
// LOG_REQ(rr);
if (rr->ret) { if (rr->ret) {
WIND_DBG eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
free (pkt); free (pkt);
return 0; return 0;
} }
@ -1027,36 +969,32 @@ int windbg_write_at_phys(WindCtx *ctx, const uint8_t *buf, const ut64 offset, co
memset (&req, 0, sizeof(kd_req_t)); memset (&req, 0, sizeof(kd_req_t));
req.req = 0x313e; req.req = DbgKdWritePhysicalMemoryApi;
req.cpu = ctx->cpu; req.cpu = ctx->cpu;
req.r_mem.addr = offset; req.r_mem.addr = offset;
req.r_mem.length = payload; req.r_mem.length = payload;
req.r_mem.read = 0; // Default caching option req.r_mem.read = 0; // Default caching option
ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_MANIP, ret = kd_send_data_packet (ctx->io_ptr, KD_PACKET_TYPE_STATE_MANIPULATE,
(ctx->seq_id ^= 1), (uint8_t *) &req, sizeof(kd_req_t), buf, payload); (ctx->seq_id ^= 1), (uint8_t *) &req, sizeof(kd_req_t), buf, payload);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_MANIP, &pkt); ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_MANIPULATE, &pkt);
if (ret != KD_E_OK) { if (ret != KD_E_OK) {
return 0; return 0;
} }
kd_req_t *rr = PKT_REQ (pkt); kd_req_t *rr = PKT_REQ (pkt);
// LOG_PKT(pkt);
// LOG_REQ(rr);
if (rr->ret) { if (rr->ret) {
WIND_DBG eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
free (pkt); free (pkt);
return 0; return 0;
} }