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

@ -426,7 +426,7 @@ static RDebugReasonType r_debug_native_wait (RDebug *dbg, int pid) {
eprintf ("(%d) Finished thread %d Exit code\n", r->pid, r->tid);
r_debug_info_free (r);
}
}
}
#else
// XXX: this is blocking, ^C will be ignored
#ifdef WAIT_ON_ALL_CHILDREN

View File

@ -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

View File

@ -324,12 +324,12 @@ repeat:
} else {
int pid = ret;
reason = linux_ptrace_event (dbg, pid, status);
if (reason == R_DEBUG_REASON_EXIT_TID) {
ptrace (PTRACE_CONT, pid, NULL, 0);
goto repeat;
}
if (reason != R_DEBUG_REASON_UNKNOWN) {
break;
}

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");
return NULL;
}
eprintf ("Opened pipe %s with fd %d\n", file+9, 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 <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 = {

View File

@ -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;
}

View File

@ -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

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 "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;
}

View File

@ -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;
}