mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-24 05:40:10 +00:00
Windbg code cleaning
This commit is contained in:
parent
beba22e6c7
commit
c1f6b29e8e
@ -21,12 +21,11 @@
|
||||
static WindCtx *wctx = NULL;
|
||||
static bool dbreak = false;
|
||||
|
||||
static int r_debug_windbg_step (RDebug *dbg) {
|
||||
static int r_debug_windbg_step(RDebug *dbg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int r_debug_windbg_reg_read (RDebug *dbg, int type, ut8 *buf, int size) {
|
||||
(void)type;
|
||||
static int r_debug_windbg_reg_read(RDebug *dbg, int type, ut8 *buf, int size) {
|
||||
int ret = windbg_read_reg(wctx, buf, size);
|
||||
if (!ret || size != ret) {
|
||||
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) {
|
||||
(void)buf;
|
||||
(void)size;
|
||||
if (!dbg->reg) {
|
||||
return false;
|
||||
}
|
||||
@ -62,43 +59,41 @@ static void wstatic_debug_break(void *u) {
|
||||
windbg_break_read (wctx);
|
||||
}
|
||||
|
||||
static int r_debug_windbg_wait (RDebug *dbg, int pid) {
|
||||
# define STATE_EXCEPTION 0x3030
|
||||
static RDebugReasonType r_debug_windbg_wait(RDebug *dbg, int pid) {
|
||||
RDebugReasonType reason = R_DEBUG_REASON_UNKNOWN;
|
||||
kd_packet_t *pkt;
|
||||
kd_stc_64 *stc;
|
||||
int ret;
|
||||
dbreak = false;
|
||||
r_cons_break_push (wstatic_debug_break, dbg);
|
||||
|
||||
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) {
|
||||
dbreak = false;
|
||||
windbg_break (wctx);
|
||||
free (pkt);
|
||||
continue;
|
||||
}
|
||||
if (ret != KD_E_OK || !pkt) {
|
||||
reason = R_DEBUG_REASON_ERROR;
|
||||
break;
|
||||
}
|
||||
stc = (kd_stc_64 *)pkt->data;
|
||||
// Handle exceptions only
|
||||
if (stc->state == STATE_EXCEPTION) {
|
||||
stc = (kd_stc_64 *) pkt->data;
|
||||
if (stc->state == DbgKdExceptionStateChange) {
|
||||
windbg_set_cpu (wctx, stc->cpu);
|
||||
dbg->reason.type = R_DEBUG_REASON_INT;
|
||||
dbg->reason.addr = stc->pc;
|
||||
dbg->reason.tid = stc->kthread;
|
||||
dbg->reason.signum = stc->state;
|
||||
free (pkt);
|
||||
reason = R_DEBUG_REASON_INT;
|
||||
break;
|
||||
}
|
||||
windbg_continue (wctx);
|
||||
free (pkt);
|
||||
}
|
||||
r_cons_break_pop ();
|
||||
// TODO : Set the faulty process as target
|
||||
return true;
|
||||
free (pkt);
|
||||
return reason;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!desc || !desc->plugin || !desc->plugin->name || !desc->data) {
|
||||
@ -117,29 +112,29 @@ static int r_debug_windbg_attach (RDebug *dbg, int pid) {
|
||||
}
|
||||
|
||||
// Handshake
|
||||
if (!windbg_sync(wctx)) {
|
||||
eprintf("Could not connect to windbg\n");
|
||||
windbg_ctx_free(wctx);
|
||||
if (!windbg_sync (wctx)) {
|
||||
eprintf ("Could not connect to windbg\n");
|
||||
windbg_ctx_free (wctx);
|
||||
return false;
|
||||
}
|
||||
if (!windbg_read_ver (wctx)) {
|
||||
windbg_ctx_free (wctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!windbg_read_ver(wctx)) {
|
||||
windbg_ctx_free(wctx);
|
||||
return false;
|
||||
}
|
||||
// Make r_debug_is_dead happy
|
||||
dbg->pid = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
static char *r_debug_windbg_reg_profile(RDebug *dbg) {
|
||||
if (!dbg) return NULL;
|
||||
if (dbg->arch && strcmp (dbg->arch, "x86"))
|
||||
return NULL;
|
||||
if (dbg->arch && strcmp (dbg->arch, "x86")) return NULL;
|
||||
if (dbg->bits == R_SYS_BITS_32) {
|
||||
#include "native/reg/windows-x86.h"
|
||||
} else if (dbg->bits == R_SYS_BITS_64) {
|
||||
@ -148,7 +143,7 @@ static char *r_debug_windbg_reg_profile(RDebug *dbg) {
|
||||
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;
|
||||
if (!bp) return false;
|
||||
// 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;
|
||||
}
|
||||
|
||||
static RList *r_debug_windbg_pids (RDebug *dbg, int pid) {
|
||||
static RList *r_debug_windbg_pids(RDebug *dbg, int pid) {
|
||||
RListIter *it;
|
||||
WindProc *p;
|
||||
|
||||
@ -189,7 +184,7 @@ static RList *r_debug_windbg_pids (RDebug *dbg, int pid) {
|
||||
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);
|
||||
int ret = windbg_set_target (wctx, pid);
|
||||
if (!ret) {
|
||||
@ -209,24 +204,24 @@ RDebugPlugin r_debug_plugin_windbg = {
|
||||
.license = "LGPL3",
|
||||
.arch = "x86",
|
||||
.bits = R_SYS_BITS_32 | R_SYS_BITS_64,
|
||||
.pids = r_debug_windbg_pids,
|
||||
.select = r_debug_windbg_select,
|
||||
.step = r_debug_windbg_step,
|
||||
.init = r_debug_windbg_init,
|
||||
.cont = r_debug_windbg_continue,
|
||||
.init = &r_debug_windbg_init,
|
||||
.step = &r_debug_windbg_step,
|
||||
.cont = &r_debug_windbg_continue,
|
||||
.attach = &r_debug_windbg_attach,
|
||||
.detach = &r_debug_windbg_detach,
|
||||
.pids = &r_debug_windbg_pids,
|
||||
.wait = &r_debug_windbg_wait,
|
||||
.select = &r_debug_windbg_select,
|
||||
.breakpoint = &r_debug_windbg_breakpoint,
|
||||
.reg_read = &r_debug_windbg_reg_read,
|
||||
.reg_write = &r_debug_windbg_reg_write,
|
||||
.reg_profile = r_debug_windbg_reg_profile,
|
||||
.reg_profile = &r_debug_windbg_reg_profile
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_DBG,
|
||||
.data = &r_debug_plugin_winddbg,
|
||||
.data = &r_debug_plugin_windbg,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
||||
|
@ -42,6 +42,7 @@ static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
|
||||
eprintf ("Could not open the pipe\n");
|
||||
return NULL;
|
||||
}
|
||||
eprintf ("Opened pipe %s with fd %d\n", file+9, io_ctx);
|
||||
|
||||
ctx = windbg_ctx_new (io_ctx);
|
||||
|
||||
|
@ -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 <string.h>
|
||||
#include "r_types.h"
|
||||
#include <r_types.h>
|
||||
#include "transport.h"
|
||||
|
||||
#if __WINDOWS__ || __CYGWIN__ || MINGW32
|
||||
#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;
|
||||
hPipe = CreateFileA (path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
eprintf ("iob_pipe_open: invocado %s\n", path);
|
||||
if (hPipe != INVALID_HANDLE_VALUE) {
|
||||
return (void *)(HANDLE)hPipe;
|
||||
return (void *) (HANDLE) hPipe;
|
||||
} else {
|
||||
perror ("pipe");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int iob_pipe_close (void *p) {
|
||||
static int iob_pipe_close(void *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;
|
||||
if (!ReadFile (p, buf, count, &c, NULL))
|
||||
if (!ReadFile (p, buf, count, &c, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
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;
|
||||
if (!WriteFile (p, buf, count, &cbWrited, NULL))
|
||||
if (!WriteFile (p, buf, count, &cbWrited, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
return cbWrited;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.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;
|
||||
struct sockaddr_un sa;
|
||||
|
||||
@ -62,44 +59,52 @@ static void *iob_pipe_open (const char *path) {
|
||||
|
||||
sa.sun_family = AF_UNIX;
|
||||
strncpy (sa.sun_path, path, sizeof(sa.sun_path));
|
||||
sa.sun_path[sizeof (sa.sun_path)-1] = 0;
|
||||
if (connect (sock, (struct sockaddr *)&sa, sizeof(struct sockaddr_un)) == -1) {
|
||||
sa.sun_path[sizeof (sa.sun_path) - 1] = 0;
|
||||
if (connect (sock, (struct sockaddr *) &sa, sizeof(struct sockaddr_un)) == -1) {
|
||||
perror ("connect");
|
||||
close (sock);
|
||||
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) {
|
||||
return close ((int)(size_t)p);
|
||||
static int iob_pipe_close(void *p) {
|
||||
return close ((int) (size_t) p);
|
||||
}
|
||||
|
||||
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);
|
||||
static int iob_pipe_read(void *p, uint8_t *buf, const uint64_t count, const int timeout) {
|
||||
int result;
|
||||
fd_set readset;
|
||||
int fd=(int)(size_t)p;
|
||||
int fd = (int) (size_t) p;
|
||||
for (;;) {
|
||||
FD_ZERO(&readset);
|
||||
FD_SET(fd, &readset);
|
||||
FD_ZERO (&readset);
|
||||
FD_SET (fd, &readset);
|
||||
result = select (fd + 1, &readset, NULL, NULL, NULL);
|
||||
if (result <1) { // pipe closed
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (result < 1) {
|
||||
if (errno == EINTR) continue;
|
||||
return -1;
|
||||
}
|
||||
if (FD_ISSET(fd, &readset)) {
|
||||
return recv((int)(size_t)p, buf, count, 0);
|
||||
if (FD_ISSET (fd, &readset)) {
|
||||
return recv ((int) (size_t) p, buf, count, 0);
|
||||
}
|
||||
}
|
||||
return EINTR;
|
||||
}
|
||||
|
||||
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);
|
||||
static int iob_pipe_write(void *p, const uint8_t *buf, const uint64_t count, const int timeout) {
|
||||
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
|
||||
|
||||
io_backend_t iob_pipe = {
|
||||
|
@ -1,37 +1,25 @@
|
||||
// Copyright (c) 2014, The Lemon Man, All rights reserved.
|
||||
|
||||
// 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.
|
||||
|
||||
// Copyright (c) 2014-2017, The Lemon Man, All rights reserved. LGPLv3
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "transport.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;
|
||||
|
||||
if (!buf || !buf_len)
|
||||
if (!buf || !buf_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = acc = 0; i < buf_len; i++)
|
||||
for (i = acc = 0; i < buf_len; i++) {
|
||||
acc += buf[i];
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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.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_OK;
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
kd_packet_t pkt;
|
||||
|
||||
if (req_len + buf_len > KD_MAX_PAYLOAD)
|
||||
if (req_len + buf_len > KD_MAX_PAYLOAD) {
|
||||
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.length = req_len + buf_len;
|
||||
pkt.checksum = kd_data_checksum(req, req_len) +
|
||||
kd_data_checksum(buf, buf_len);
|
||||
pkt.checksum = kd_data_checksum (req, req_len) +
|
||||
kd_data_checksum (buf, buf_len);
|
||||
pkt.id = id;
|
||||
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;
|
||||
}
|
||||
|
||||
if (iob_write(fp, (uint8_t *)req, req_len) < 0)
|
||||
if (iob_write (fp, (uint8_t *) req, req_len) < 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
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_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;
|
||||
uint8_t *buf;
|
||||
|
||||
*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;
|
||||
}
|
||||
|
||||
if (!kd_packet_is_valid(&pkt)) {
|
||||
if (!kd_packet_is_valid (&pkt)) {
|
||||
eprintf ("invalid leader %08x\n", pkt.leader);
|
||||
return KD_E_MALFORMED;
|
||||
}
|
||||
@ -93,12 +91,13 @@ int kd_read_packet (void *fp, kd_packet_t **p) {
|
||||
if (!buf) {
|
||||
return KD_E_IOERR;
|
||||
}
|
||||
memcpy(buf, &pkt, sizeof(kd_packet_t));
|
||||
memcpy (buf, &pkt, sizeof(kd_packet_t));
|
||||
|
||||
if (pkt.length)
|
||||
iob_read(fp, (uint8_t *)buf + sizeof(kd_packet_t), pkt.length);
|
||||
if (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");
|
||||
free (buf);
|
||||
return KD_E_MALFORMED;
|
||||
@ -106,26 +105,26 @@ int kd_read_packet (void *fp, kd_packet_t **p) {
|
||||
|
||||
if (pkt.leader == KD_PACKET_DATA) {
|
||||
uint8_t trailer;
|
||||
iob_read(fp, (uint8_t *)&trailer, 1);
|
||||
iob_read (fp, (uint8_t *) &trailer, 1);
|
||||
|
||||
if (trailer != 0xAA) {
|
||||
printf("Missing trailer 0xAA\n");
|
||||
free(buf);
|
||||
printf ("Missing trailer 0xAA\n");
|
||||
free (buf);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int kd_packet_is_ack (const kd_packet_t *p) {
|
||||
return p->leader == KD_PACKET_CTRL && p->type == KD_PACKET_TYPE_ACK;
|
||||
int kd_packet_is_ack(const kd_packet_t *p) {
|
||||
return p->leader == KD_PACKET_CTRL && p->type == KD_PACKET_TYPE_ACKNOWLEDGE;
|
||||
}
|
||||
|
@ -1,20 +1,4 @@
|
||||
// Copyright (c) 2014, The Lemon Man, All rights reserved.
|
||||
|
||||
// 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.
|
||||
|
||||
// Copyright (c) 2014-2017, The Lemon Man, All rights reserved. LGPLv3
|
||||
#ifndef KD_H
|
||||
#define KD_H
|
||||
#include <r_types_base.h>
|
||||
@ -27,17 +11,79 @@ enum {
|
||||
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_CTRL 0x69696969
|
||||
|
||||
#define KD_MAX_PAYLOAD 0x800
|
||||
|
||||
#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
|
||||
#define KD_PACKET_MAX_SIZE 4000 // Not used ? What is max payload ?
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/cc704588.aspx
|
||||
#define KD_RET_OK 0x00000000
|
||||
|
@ -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 "transport.h"
|
||||
|
||||
extern io_backend_t iob_pipe;
|
||||
|
||||
static io_backend_t *io_backends[] = {
|
||||
//#if __WINDOWS__ || __CYGWIN__ || MINGW32
|
||||
//#warning TODO: add proper IO backend for windows here
|
||||
//#else
|
||||
// #if __WINDOWS__ || __CYGWIN__ || MINGW32
|
||||
// #warning TODO: add proper IO backend for windows here
|
||||
// #else
|
||||
&iob_pipe,
|
||||
//#endif
|
||||
// #endif
|
||||
NULL,
|
||||
};
|
||||
|
||||
static io_backend_t *sel_backend = &iob_pipe;
|
||||
|
||||
int iob_select (const char *name) {
|
||||
int iob_select(const char *name) {
|
||||
io_backend_t *iob;
|
||||
|
||||
iob = io_backends[0];
|
||||
|
||||
if (!iob)
|
||||
if (!iob) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sel_backend && sel_backend->deinit)
|
||||
sel_backend->deinit();
|
||||
if (sel_backend && sel_backend->deinit) {
|
||||
sel_backend->deinit ();
|
||||
}
|
||||
|
||||
sel_backend = iob;
|
||||
|
||||
if (sel_backend->init)
|
||||
sel_backend->init();
|
||||
if (sel_backend->init) {
|
||||
sel_backend->init ();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *iob_open (const char *path) {
|
||||
if (!sel_backend)
|
||||
void *iob_open(const char *path) {
|
||||
if (!sel_backend) {
|
||||
return NULL;
|
||||
return sel_backend->open(path);
|
||||
}
|
||||
return sel_backend->open (path);
|
||||
}
|
||||
|
||||
int iob_close (void *fp) {
|
||||
if (!sel_backend)
|
||||
int iob_close(void *fp) {
|
||||
if (!sel_backend) {
|
||||
return E_NOIF;
|
||||
return sel_backend->close(fp);
|
||||
}
|
||||
return sel_backend->close (fp);
|
||||
}
|
||||
|
||||
int iob_config (void *fp, void *cfg) {
|
||||
if (!sel_backend)
|
||||
int iob_config(void *fp, void *cfg) {
|
||||
if (!sel_backend) {
|
||||
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;
|
||||
|
||||
if (!sel_backend)
|
||||
if (!sel_backend) {
|
||||
return E_NOIF;
|
||||
}
|
||||
|
||||
for (done = 0; done < buf_len;) {
|
||||
int ret = sel_backend->write(fp, buf + done, buf_len - done, 100);
|
||||
if (ret<1) break;
|
||||
int ret = sel_backend->write (fp, buf + done, buf_len - done, 100);
|
||||
if (ret < 1) {
|
||||
break;
|
||||
}
|
||||
done += ret;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!sel_backend)
|
||||
if (!sel_backend) {
|
||||
return E_NOIF;
|
||||
}
|
||||
|
||||
for (done = 0; done < buf_len;) {
|
||||
int ret = sel_backend->read(fp, buf + done, buf_len - done, 100);
|
||||
if (ret<1) break;
|
||||
int ret = sel_backend->read (fp, buf + done, buf_len - done, 100);
|
||||
if (ret < 1) {
|
||||
break;
|
||||
}
|
||||
done += ret;
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,4 @@
|
||||
// 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 <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@ -24,7 +10,7 @@
|
||||
#include "kd.h"
|
||||
|
||||
#define O_FLAG_XPVAD 1
|
||||
#define WIND_DBG if (false)
|
||||
#define WIND_DBG if (true)
|
||||
#define O_(n) ctx->os_profile->f[n]
|
||||
#include "profiles.h"
|
||||
|
||||
@ -67,22 +53,12 @@ Profile *windbg_get_profile(int bits, int build, int sp) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define LOG_PKT(p) { \
|
||||
eprintf ("Leader\t: %08x\nType\t: %08x\nLength\t: %08x\nID\t: %08x\nCheck\t: %08x [%s]\n", \
|
||||
(p)->leader, \
|
||||
(p)->type, \
|
||||
(p)->length, \
|
||||
(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 \
|
||||
); \
|
||||
#define LOG_REQ(r) { \
|
||||
eprintf ("Request : %08x\nProcessor : %08x\nReturn : %08x\n",\
|
||||
(r)->req, \
|
||||
(r)->cpu, \
|
||||
(r)->ret \
|
||||
); \
|
||||
}
|
||||
|
||||
struct _WindCtx {
|
||||
@ -194,8 +170,8 @@ static void dump_stc(kd_packet_t *p) {
|
||||
(ut64) stc->pc, (ut64) stc->kthread);
|
||||
eprintf ("On cpu %i/%i\n", stc->cpu + 1, stc->cpu_count);
|
||||
|
||||
if (stc->state == 0x3030) {
|
||||
eprintf ("ex\n");
|
||||
if (stc->state == DbgKdExceptionStateChange) {
|
||||
eprintf ("Exception\n");
|
||||
eprintf ("\tCode : %08x\n", stc->exception.code);
|
||||
eprintf ("\tFlags : %08x\n", stc->exception.flags);
|
||||
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;
|
||||
ioc.req = 0x3430;
|
||||
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);
|
||||
if (ret != KD_E_OK) {
|
||||
return false;
|
||||
}
|
||||
WIND_DBG eprintf ("Waiting for io_reply ack...\n");
|
||||
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACK, NULL);
|
||||
WIND_DBG eprintf("Waiting for io_reply ack...\n");
|
||||
ret = windbg_wait_packet (ctx, KD_PACKET_TYPE_ACKNOWLEDGE, NULL);
|
||||
if (ret != KD_E_OK) {
|
||||
return false;
|
||||
}
|
||||
WIND_DBG eprintf ("Ack received, restore flow\n");
|
||||
WIND_DBG eprintf("Ack received, restore flow\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
int windbg_wait_packet(WindCtx *ctx, const uint32_t type, kd_packet_t **p) {
|
||||
kd_packet_t *pkt;
|
||||
int ret, retries = 10;
|
||||
|
||||
// r_sys_backtrace();
|
||||
|
||||
pkt = NULL;
|
||||
kd_packet_t *pkt = NULL;
|
||||
int ret;
|
||||
int retries = 10;
|
||||
|
||||
do {
|
||||
free (pkt);
|
||||
if (pkt) free (pkt);
|
||||
// Try to read a whole packet
|
||||
ret = kd_read_packet (ctx->io_ptr, &pkt);
|
||||
// eprintf("kd_read_packet() = %i\n", ret);
|
||||
if (ret != KD_E_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
// eprintf("Received %08x, expected %08x\n", pkt->type, type);
|
||||
if (pkt->leader == KD_PACKET_DATA && pkt->type == KD_PACKET_TYPE_STATE_CHANGE) {
|
||||
dump_stc (pkt);
|
||||
// eprintf ("Received %08x\n", pkt->type);
|
||||
if (pkt->type != type) {
|
||||
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);
|
||||
}
|
||||
|
||||
// Check for RESEND
|
||||
// The host didn't like our request
|
||||
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;
|
||||
break;
|
||||
//break;
|
||||
}
|
||||
} while (pkt->type != type && retries--);
|
||||
|
||||
@ -333,7 +312,7 @@ RList *windbg_list_process(WindCtx *ctx) {
|
||||
4 << ctx->is_x64);
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
WIND_DBG eprintf ("VA : %016"PFMT64x "\n", va);
|
||||
WIND_DBG eprintf("VA : %016"PFMT64x "\n", va);
|
||||
|
||||
if (ctx->is_x64) {
|
||||
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 &= ~0x1f;
|
||||
|
||||
WIND_DBG eprintf ("CR3 : %016"PFMT64x "\n", tmp);
|
||||
WIND_DBG eprintf("CR3 : %016"PFMT64x "\n", tmp);
|
||||
|
||||
if (ctx->is_x64) {
|
||||
// PML4 lookup
|
||||
@ -437,7 +416,7 @@ bool windbg_va_to_pa(WindCtx *ctx, ut64 va, ut64 *pa) {
|
||||
return false;
|
||||
}
|
||||
tmp &= mask;
|
||||
WIND_DBG eprintf ("PML4 : %016"PFMT64x "\n", tmp);
|
||||
WIND_DBG eprintf("PML4 : %016"PFMT64x "\n", tmp);
|
||||
}
|
||||
|
||||
if (ctx->pae) {
|
||||
@ -446,14 +425,14 @@ bool windbg_va_to_pa(WindCtx *ctx, ut64 va, ut64 *pa) {
|
||||
return false;
|
||||
}
|
||||
tmp &= mask;
|
||||
WIND_DBG eprintf ("PDPE : %016"PFMT64x "\n", tmp);
|
||||
WIND_DBG eprintf("PDPE : %016"PFMT64x "\n", tmp);
|
||||
}
|
||||
|
||||
// PDT lookup
|
||||
if (!windbg_read_at_phys (ctx, (uint8_t *) &tmp, tmp + pdi * (4 << ctx->pae), 4 << ctx->pae)) {
|
||||
return false;
|
||||
}
|
||||
WIND_DBG eprintf ("PDE : %016"PFMT64x "\n", tmp);
|
||||
WIND_DBG eprintf("PDE : %016"PFMT64x "\n", tmp);
|
||||
|
||||
// Large page entry
|
||||
// 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)) {
|
||||
return false;
|
||||
}
|
||||
WIND_DBG eprintf ("PTE : %016"PFMT64x "\n", tmp);
|
||||
WIND_DBG eprintf("PTE : %016"PFMT64x "\n", tmp);
|
||||
|
||||
if (tmp & PTE_VALID) {
|
||||
*pa = (tmp & mask) | (va & 0xfff);
|
||||
@ -498,29 +477,26 @@ bool windbg_read_ver(WindCtx *ctx) {
|
||||
req.req = 0x3146;
|
||||
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);
|
||||
if (ret != KD_E_OK) {
|
||||
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) {
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
kd_req_t *rr = PKT_REQ (pkt);
|
||||
|
||||
/* LOG_PKT(pkt); */
|
||||
/* LOG_REQ(rr); */
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
@ -556,7 +532,7 @@ bool windbg_read_ver(WindCtx *ctx) {
|
||||
|
||||
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
|
||||
uint16_t pae_enabled;
|
||||
@ -605,8 +581,8 @@ int windbg_sync(WindCtx *ctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Syncronize with the first KD_PACKET_TYPE_STATE_CHANGE packet
|
||||
windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_CHANGE, &s);
|
||||
// Syncronize with the first KD_PACKET_TYPE_STATE_CHANGE64 packet
|
||||
windbg_wait_packet (ctx, KD_PACKET_TYPE_STATE_CHANGE64, &s);
|
||||
|
||||
// Reset the sequence id
|
||||
ctx->seq_id = 0x80800001;
|
||||
@ -633,23 +609,21 @@ int windbg_continue(WindCtx *ctx) {
|
||||
if (!ctx || !ctx->io_ptr || !ctx->syncd) {
|
||||
return 0;
|
||||
}
|
||||
req.req = 0x313C;
|
||||
req.req = DbgKdContinueApi2;
|
||||
req.cpu = ctx->cpu;
|
||||
req.r_cont.reason = 0x10001;
|
||||
// The meaning of 0x400 is unknown, but Windows doesn't
|
||||
// behave like suggested by ReactOS source
|
||||
req.r_cont.tf = 0x400;
|
||||
|
||||
WIND_DBG eprintf ("Sending continue...\n");
|
||||
|
||||
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);
|
||||
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) {
|
||||
// XXX What about DbgKdContinueApi ?
|
||||
r_list_free (ctx->plist_cache);
|
||||
ctx->plist_cache = NULL;
|
||||
WIND_DBG eprintf ("Done!\n");
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
req.req = 0x3133;
|
||||
req.req = DbgKdSetContextApi;
|
||||
req.cpu = ctx->cpu;
|
||||
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);
|
||||
if (ret != KD_E_OK) {
|
||||
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) {
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
kd_req_t *rr = PKT_REQ (pkt);
|
||||
|
||||
// LOG_PKT(pkt);
|
||||
// LOG_REQ(rr);
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
@ -715,34 +686,31 @@ int windbg_read_reg(WindCtx *ctx, uint8_t *buf, int size) {
|
||||
|
||||
memset (&req, 0, sizeof(kd_req_t));
|
||||
|
||||
req.req = 0x3132;
|
||||
req.req = DbgKdGetContextApi;
|
||||
req.cpu = ctx->cpu;
|
||||
|
||||
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);
|
||||
if (ret != KD_E_OK) {
|
||||
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) {
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
kd_req_t *rr = PKT_REQ (pkt);
|
||||
|
||||
// LOG_PKT(pkt);
|
||||
// LOG_REQ(rr);
|
||||
|
||||
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);
|
||||
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));
|
||||
|
||||
req.req = 0x315c;
|
||||
req.req = DbgKdQueryMemoryApi;
|
||||
req.cpu = ctx->cpu;
|
||||
|
||||
req.r_query_mem.addr = addr;
|
||||
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);
|
||||
if (ret != KD_E_OK) {
|
||||
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) {
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
kd_req_t *rr = PKT_REQ (pkt);
|
||||
|
||||
// LOG_PKT(pkt);
|
||||
// LOG_REQ(rr);
|
||||
|
||||
if (rr->ret) {
|
||||
#ifdef windbg_LOG
|
||||
eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
|
||||
#endif
|
||||
free (pkt);
|
||||
return 0;
|
||||
}
|
||||
@ -824,7 +786,7 @@ int windbg_bkpt(WindCtx *ctx, const ut64 addr, const int set, const int hw, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
req.req = set? 0x3134: 0x3135;
|
||||
req.req = set? DbgKdWriteBreakPointApi: DbgKdRestoreBreakPointApi;
|
||||
req.cpu = ctx->cpu;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
if (ret != KD_E_OK) {
|
||||
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) {
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
kd_req_t *rr = PKT_REQ (pkt);
|
||||
|
||||
// LOG_PKT(pkt);
|
||||
// LOG_REQ(rr);
|
||||
|
||||
if (rr->ret) {
|
||||
#ifdef windbg_LOG
|
||||
eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
|
||||
#endif
|
||||
free (pkt);
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
req.req = 0x313D;
|
||||
req.req = DbgKdReadPhysicalMemoryApi;
|
||||
req.cpu = ctx->cpu;
|
||||
req.r_mem.addr = offset;
|
||||
req.r_mem.length = R_MIN (count, KD_MAX_PAYLOAD);
|
||||
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);
|
||||
if (ret != KD_E_OK) {
|
||||
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) {
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rr = PKT_REQ (pkt);
|
||||
|
||||
// LOG_PKT(pkt);
|
||||
// LOG_REQ(rr);
|
||||
|
||||
if (rr->ret) {
|
||||
#ifdef windbg_LOG
|
||||
eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
|
||||
#endif
|
||||
free (pkt);
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
req.req = 0x3130;
|
||||
req.req = DbgKdReadVirtualMemoryApi;
|
||||
req.cpu = ctx->cpu;
|
||||
req.r_mem.addr = offset;
|
||||
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);
|
||||
if (ret != KD_E_OK) {
|
||||
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) {
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
rr = PKT_REQ (pkt);
|
||||
|
||||
// LOG_PKT(pkt);
|
||||
// LOG_REQ(rr);
|
||||
|
||||
if (rr->ret) {
|
||||
WIND_DBG eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
|
||||
free (pkt);
|
||||
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));
|
||||
req.req = 0x3131;
|
||||
req.req = DbgKdWriteVirtualMemoryApi;
|
||||
req.cpu = ctx->cpu;
|
||||
req.r_mem.addr = offset;
|
||||
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,
|
||||
sizeof(kd_req_t), buf, payload);
|
||||
if (ret != KD_E_OK) {
|
||||
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) {
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rr = PKT_REQ (pkt);
|
||||
|
||||
// LOG_PKT(pkt);
|
||||
// LOG_REQ(rr);
|
||||
|
||||
if (rr->ret) {
|
||||
WIND_DBG eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
|
||||
free (pkt);
|
||||
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));
|
||||
|
||||
req.req = 0x313e;
|
||||
req.req = DbgKdWritePhysicalMemoryApi;
|
||||
req.cpu = ctx->cpu;
|
||||
|
||||
req.r_mem.addr = offset;
|
||||
req.r_mem.length = payload;
|
||||
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);
|
||||
if (ret != KD_E_OK) {
|
||||
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) {
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
kd_req_t *rr = PKT_REQ (pkt);
|
||||
|
||||
// LOG_PKT(pkt);
|
||||
// LOG_REQ(rr);
|
||||
|
||||
if (rr->ret) {
|
||||
WIND_DBG eprintf ("%s: req returned %08x\n", __FUNCTION__, rr->ret);
|
||||
free (pkt);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user