Fix endianness for win pagedump and winkd (#3204)

This commit is contained in:
Giovanni 2022-12-09 11:41:28 +01:00 committed by GitHub
parent 111e912b99
commit 55e690990b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 1389 additions and 294 deletions

View file

@ -42,16 +42,6 @@ jobs:
- binutils-x86-64-linux-gnu
- binutils-powerpc64le-linux-gnu
allow_failures:
# Linux with GCC on System Z
- os: linux
arch: s390x
env: COMPILER_NAME=gcc CXX=g++ CC=gcc CFLAGS="-DRZ_ASSERT_STDOUT=1" RZ_X86_AS=x86_64-w64-mingw32-as
addons:
apt:
packages:
- binutils-mingw-w64-x86-64
cache:
- ccache

View file

@ -46,6 +46,11 @@ static bool rz_bin_dmp64_init_triage(struct rz_bin_dmp64_obj_t *obj) {
return true;
}
static void dmp64_memory_run_endian_to_host(dmp_p_memory_run *run) {
run->BasePage = rz_read_le64((ut8 *)&run->BasePage);
run->PageCount = rz_read_le64((ut8 *)&run->PageCount);
}
static int rz_bin_dmp64_init_memory_runs(struct rz_bin_dmp64_obj_t *obj) {
int i, j;
dmp64_p_memory_desc *mem_desc = &obj->header->PhysicalMemoryBlock;
@ -73,7 +78,8 @@ static int rz_bin_dmp64_init_memory_runs(struct rz_bin_dmp64_obj_t *obj) {
ut64 num_page = 0;
ut64 base = sizeof(dmp64_header);
for (i = 0; i < num_runs; i++) {
dmp_p_memory_run *run = &(runs[i]);
dmp_p_memory_run *run = &runs[i];
dmp64_memory_run_endian_to_host(run);
for (j = 0; j < run->PageCount; j++) {
dmp_page_desc *page = RZ_NEW0(dmp_page_desc);
if (!page) {
@ -94,17 +100,75 @@ static int rz_bin_dmp64_init_memory_runs(struct rz_bin_dmp64_obj_t *obj) {
return true;
}
static void dmp64_memory_desc_endian_to_host(dmp64_p_memory_desc *desc) {
desc->NumberOfRuns = rz_read_le32((ut8 *)&desc->NumberOfRuns);
desc->NumberOfPages = rz_read_le64((ut8 *)&desc->NumberOfPages);
dmp64_memory_run_endian_to_host(&desc->Run[0]);
}
static void dmp64_windows_exception_record64_endian_to_host(struct windows_exception_record64 *rec) {
rec->exception_code = rz_read_le32((ut8 *)&rec->exception_code);
rec->exception_flags = rz_read_le32((ut8 *)&rec->exception_flags);
rec->exception_record = rz_read_le64((ut8 *)&rec->exception_record);
rec->exception_address = rz_read_le64((ut8 *)&rec->exception_address);
rec->number_parameters = rz_read_le32((ut8 *)&rec->number_parameters);
for (size_t i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; ++i) {
rec->exception_information[i] = rz_read_le64((ut8 *)&rec->exception_information[i]);
}
}
static int rz_bin_dmp64_init_header(struct rz_bin_dmp64_obj_t *obj) {
if (!(obj->header = RZ_NEW0(dmp64_header))) {
dmp64_header *dhdr = NULL;
if (!(dhdr = RZ_NEW0(dmp64_header))) {
RZ_LOG_ERROR("Cannot allocate dmp64_header.\n");
return false;
}
if (rz_buf_read_at(obj->b, 0, (ut8 *)obj->header, sizeof(dmp64_header)) < 0) {
if (rz_buf_read_at(obj->b, 0, (ut8 *)dhdr, sizeof(dmp64_header)) != sizeof(dmp64_header)) {
RZ_LOG_ERROR("cannot read dmp64 header\n");
return false;
}
obj->dtb = obj->header->DirectoryTableBase;
dhdr->MajorVersion = rz_read_le32((ut8 *)&dhdr->MajorVersion);
dhdr->MinorVersion = rz_read_le32((ut8 *)&dhdr->MinorVersion);
dhdr->DirectoryTableBase = rz_read_le64((ut8 *)&dhdr->DirectoryTableBase);
dhdr->PfnDataBase = rz_read_le64((ut8 *)&dhdr->PfnDataBase);
dhdr->PsLoadedModuleList = rz_read_le64((ut8 *)&dhdr->PsLoadedModuleList);
dhdr->PsActiveProcessHead = rz_read_le64((ut8 *)&dhdr->PsActiveProcessHead);
dhdr->MachineImageType = rz_read_le32((ut8 *)&dhdr->MachineImageType);
dhdr->NumberProcessors = rz_read_le32((ut8 *)&dhdr->NumberProcessors);
dhdr->BugCheckCode = rz_read_le32((ut8 *)&dhdr->BugCheckCode);
dhdr->BugCheckParameter1 = rz_read_le64((ut8 *)&dhdr->BugCheckParameter1);
dhdr->BugCheckParameter2 = rz_read_le64((ut8 *)&dhdr->BugCheckParameter2);
dhdr->BugCheckParameter3 = rz_read_le64((ut8 *)&dhdr->BugCheckParameter3);
dhdr->BugCheckParameter4 = rz_read_le64((ut8 *)&dhdr->BugCheckParameter4);
dhdr->KdDebuggerDataBlock = rz_read_le64((ut8 *)&dhdr->KdDebuggerDataBlock);
if (memcmp(dhdr->PhysicalMemoryBlockBuffer, DMP_UNUSED_MAGIC, 4)) {
// it's a valid PhysicalMemoryBlock
dmp64_memory_desc_endian_to_host(&dhdr->PhysicalMemoryBlock);
}
dmp64_windows_exception_record64_endian_to_host(&dhdr->Exception);
dhdr->DumpType = rz_read_le32((ut8 *)&dhdr->DumpType);
dhdr->RequiredDumpSpace = rz_read_le64((ut8 *)&dhdr->RequiredDumpSpace);
dhdr->SystemTime = rz_read_le64((ut8 *)&dhdr->SystemTime);
dhdr->SystemUpTime = rz_read_le64((ut8 *)&dhdr->SystemUpTime);
dhdr->MiniDumpFields = rz_read_le32((ut8 *)&dhdr->MiniDumpFields);
dhdr->SecondaryDataState = rz_read_le32((ut8 *)&dhdr->SecondaryDataState);
dhdr->ProductType = rz_read_le32((ut8 *)&dhdr->ProductType);
dhdr->SuiteMask = rz_read_le32((ut8 *)&dhdr->SuiteMask);
dhdr->WriterStatus = rz_read_le32((ut8 *)&dhdr->WriterStatus);
obj->header = dhdr;
obj->dtb = dhdr->DirectoryTableBase;
return true;
}
@ -145,7 +209,7 @@ static bool rz_bin_dmp64_init_triage_drivers(struct rz_bin_dmp64_obj_t *obj) {
}
ut8 *file = calloc(str.count + 1, sizeof(ut16));
ut8 *file_utf8 = calloc(str.count + 1, sizeof(ut16));
if (!file) {
if (!file || !file_utf8) {
free(driver);
free(file);
free(file_utf8);
@ -214,10 +278,9 @@ static int rz_bin_dmp64_init_bmp_pages(struct rz_bin_dmp64_obj_t *obj) {
rz_bitmap_set_bytes(bitmap, obj->bitmap, num_pages / 8);
ut64 num_bitset = 0;
ut64 i;
bool create_new_page = true;
dmp_page_desc *page;
for (i = 0; i < num_pages; i++) {
for (ut64 i = 0; i < num_pages; i++) {
if (!rz_bitmap_test(bitmap, i)) {
create_new_page = true;
continue;
@ -244,7 +307,9 @@ static int rz_bin_dmp64_init_bmp_pages(struct rz_bin_dmp64_obj_t *obj) {
create_new_page = false;
}
if (obj->bmp_header->TotalPresentPages != num_bitset) {
RZ_LOG_ERROR("The total present pages number in the header does not match with the counted one.\n");
RZ_LOG_ERROR("The total present pages number (%" PFMT64u ") in the header "
"does not match with the counted one (%" PFMT64u ").\n",
obj->bmp_header->TotalPresentPages, num_bitset);
rz_bitmap_free(bitmap);
return false;
}
@ -262,11 +327,16 @@ static int rz_bin_dmp64_init_bmp_header(struct rz_bin_dmp64_obj_t *obj) {
RZ_LOG_ERROR("Cannot read bmp_header\n");
return false;
}
if (memcmp(obj->bmp_header, DMP_BMP_MAGIC, 8) &&
memcmp(obj->bmp_header, DMP_BMP_FULL_MAGIC, 8)) {
if (memcmp((ut8 *)obj->bmp_header, DMP_BMP_MAGIC, 8) &&
memcmp((ut8 *)obj->bmp_header, DMP_BMP_FULL_MAGIC, 8)) {
RZ_LOG_ERROR("Invalid Bitmap Magic\n");
return false;
}
obj->bmp_header->FirstPage = rz_read_le64((ut8 *)&obj->bmp_header->FirstPage);
obj->bmp_header->TotalPresentPages = rz_read_le64((ut8 *)&obj->bmp_header->TotalPresentPages);
obj->bmp_header->Pages = rz_read_le64((ut8 *)&obj->bmp_header->Pages);
ut64 bitmapsize = obj->bmp_header->Pages / 8;
obj->bitmap = calloc(1, bitmapsize);
if (rz_buf_read_at(obj->b, sizeof(dmp64_header) + rz_offsetof(dmp_bmp_header, Bitmap), obj->bitmap, bitmapsize) < 0) {

View file

@ -488,16 +488,15 @@ RZ_PACKED(
ut32 exception_information[EXCEPTION_MAXIMUM_PARAMETERS];
});
RZ_PACKED(
struct windows_exception_record64 {
ut32 exception_code;
ut32 exception_flags;
ut64 exception_record;
ut64 exception_address;
ut32 number_parameters;
ut32 __unusedAlignment;
ut64 exception_information[EXCEPTION_MAXIMUM_PARAMETERS];
});
struct windows_exception_record64 {
ut32 exception_code;
ut32 exception_flags;
ut64 exception_record;
ut64 exception_address;
ut32 number_parameters;
ut32 __unusedAlignment;
ut64 exception_information[EXCEPTION_MAXIMUM_PARAMETERS];
};
RZ_PACKED(
struct exception_pointers_i386 {

View file

@ -4,6 +4,34 @@
#define RZ_BIN_PE64 1
#include "bin_pe.inc"
// equivalent of PE64_UNWIND_INFO but endian-free
typedef struct windows_x64_unwind_info_t {
ut8 Version; // : 3;
ut8 Flags; // : 5;
ut8 SizeOfProlog;
ut8 CountOfCodes;
ut8 FrameRegister; // : 4;
ut8 FrameOffset; // : 4;
} WinUnwindInfo;
static bool windows_unwind_info_read(WinUnwindInfo *info, RzBuffer *b, ut64 at) {
ut8 tmp[sizeof(PE64_UNWIND_INFO)] = { 0 };
if (!rz_buf_read_at(b, at, tmp, sizeof(tmp))) {
return false;
}
// The ordering of bits in C bitfields is implementation defined.
// this ensures the endianness (here is little endian) is kept
info->Version = tmp[0] & 0x07;
info->Flags = tmp[0] >> 3;
info->SizeOfProlog = tmp[1];
info->CountOfCodes = tmp[2];
info->FrameRegister = tmp[3] & 0x0F;
info->FrameOffset = tmp[3] >> 4;
return true;
}
static bool check_buffer(RzBuffer *b) {
ut64 length = rz_buf_size(b);
if (length <= 0x3d) {
@ -462,8 +490,8 @@ static RzList /*<RzBinTrycatch *>*/ *trycatch(RzBinFile *bf) {
if (unwind_data_paddr > unwind_data_section->paddr + unwind_data_section->size) {
continue;
}
PE64_UNWIND_INFO info;
suc = rz_buf_read_at(bin->b, unwind_data_paddr, (ut8 *)&info, sizeof(info));
WinUnwindInfo info;
suc = windows_unwind_info_read(&info, bin->b, unwind_data_paddr);
if (!suc || info.Version != 1 || (!(info.Flags & PE64_UNW_FLAG_EHANDLER) && !(info.Flags & PE64_UNW_FLAG_CHAININFO))) {
continue;
}
@ -484,7 +512,7 @@ static RzList /*<RzBinTrycatch *>*/ *trycatch(RzBinFile *bf) {
break;
}
unwind_data_paddr = rva_to_paddr(unwind_data_section, rfcn.UnwindData);
suc = rz_buf_read_at(bin->b, unwind_data_paddr, (ut8 *)&info, sizeof(info));
suc = windows_unwind_info_read(&info, bin->b, unwind_data_paddr);
if (!suc || info.Version != 1) {
break;
}

View file

@ -50,23 +50,28 @@ static bool rz_debug_dmp_init(RzDebug *dbg, void **user) {
ut64 TopOfStack = 0;
ut32 NumberProcessors = 0;
ctx->target = TARGET_BACKEND;
dbg->corebind.cmd(dbg->corebind.core, "e io.va=0");
RzBuffer *b = rz_buf_new_with_io(&dbg->iob);
rz_buf_read_le64_at(b, rz_offsetof(dmp64_header, DirectoryTableBase), &ctx->kernelDirectoryTable);
rz_buf_read_le64_at(b, rz_offsetof(dmp64_header, PsActiveProcessHead), &ctx->windctx.PsActiveProcessHead);
rz_buf_read_le64_at(b, rz_offsetof(dmp64_header, PsLoadedModuleList), &ctx->windctx.PsLoadedModuleList);
rz_buf_read_le64_at(b, rz_offsetof(dmp64_header, KdDebuggerDataBlock), &ctx->windctx.KdDebuggerDataBlock);
rz_buf_read_le32_at(b, rz_offsetof(dmp64_header, NumberProcessors), &NumberProcessors);
rz_buf_read_le32_at(b, rz_offsetof(dmp64_header, DumpType), &ctx->type);
rz_buf_read_le32_at(b, rz_offsetof(dmp64_header, MachineImageType), &MachineImageType);
rz_buf_read_le32_at(b, rz_offsetof(dmp64_header, MinorVersion), &MinorVersion);
rz_buf_read_le32_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, ServicePackBuild), &ServicePackBuild);
rz_buf_read_le32_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, ProcessOffset), &ProcessOffset);
rz_buf_read_le32_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, ThreadOffset), &ThreadOffset);
rz_buf_read_le32_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, CallStackOffset), &CallStackOffset);
rz_buf_read_le32_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, SizeOfCallStack), &SizeOfCallStack);
rz_buf_read_le64_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, TopOfStack), &TopOfStack);
rz_buf_free(b);
struct rz_bin_dmp64_obj_t *obj = (struct rz_bin_dmp64_obj_t *)core->bin->cur->o->bin_obj;
ctx->kernelDirectoryTable = obj->header->DirectoryTableBase;
ctx->windctx.PsActiveProcessHead = obj->header->PsActiveProcessHead;
ctx->windctx.PsLoadedModuleList = obj->header->PsLoadedModuleList;
ctx->windctx.KdDebuggerDataBlock = obj->header->KdDebuggerDataBlock;
NumberProcessors = obj->header->NumberProcessors;
ctx->type = obj->header->DumpType;
MachineImageType = obj->header->MachineImageType;
MinorVersion = obj->header->MinorVersion;
if (obj->triage64_header) {
ServicePackBuild = obj->triage64_header->ServicePackBuild;
ProcessOffset = obj->triage64_header->ProcessOffset;
ThreadOffset = obj->triage64_header->ThreadOffset;
CallStackOffset = obj->triage64_header->CallStackOffset;
SizeOfCallStack = obj->triage64_header->SizeOfCallStack;
TopOfStack = obj->triage64_header->TopOfStack;
}
dbg->corebind.cfgSetI(dbg->corebind.core, "io.va", 0);
RzIOMap *map = rz_io_map_get(core->io, 0);
if (map) {
@ -328,50 +333,377 @@ static inline bool is_kernel_address_present(WindCtx *ctx, ut64 at) {
return true;
}
static int rz_debug_dmp_reg_read(RzDebug *dbg, int type, ut8 *buf, int size) {
#define reg_set(r, n, v) reg_set_bitv(r, n, (const ut8 *)&v)
static void reg_set_bitv(RzReg *reg, const char *name, const ut8 *buf) {
RzRegItem *item = rz_reg_get(reg, name, -1);
if (!item) {
RZ_LOG_ERROR("debug: dmp: find register '%s'\n", name);
return;
}
RzBitVector *bv = rz_bv_new_from_bytes_le(buf, 0, item->size);
if (!bv) {
RZ_LOG_ERROR("debug: dmp: Failed to allocate RzBitVector for register '%s'\n", name);
return;
}
rz_reg_set_bv(reg, item, bv);
rz_bv_free(bv);
}
static void debug_dmp_set_arm64_registers(RzReg *reg, struct context_type_arm64 *ctx) {
reg_set(reg, "cpsr", ctx->Cpsr);
reg_set(reg, "x0", ctx->X0);
reg_set(reg, "x1", ctx->X1);
reg_set(reg, "x2", ctx->X2);
reg_set(reg, "x3", ctx->X3);
reg_set(reg, "x4", ctx->X4);
reg_set(reg, "x5", ctx->X5);
reg_set(reg, "x6", ctx->X6);
reg_set(reg, "x7", ctx->X7);
reg_set(reg, "x8", ctx->X8);
reg_set(reg, "x9", ctx->X9);
reg_set(reg, "x10", ctx->X10);
reg_set(reg, "x11", ctx->X11);
reg_set(reg, "x12", ctx->X12);
reg_set(reg, "x13", ctx->X13);
reg_set(reg, "x14", ctx->X14);
reg_set(reg, "x15", ctx->X15);
reg_set(reg, "x16", ctx->X16);
reg_set(reg, "x17", ctx->X17);
reg_set(reg, "x18", ctx->X18);
reg_set(reg, "x19", ctx->X19);
reg_set(reg, "x20", ctx->X20);
reg_set(reg, "x21", ctx->X21);
reg_set(reg, "x22", ctx->X22);
reg_set(reg, "x23", ctx->X23);
reg_set(reg, "x24", ctx->X24);
reg_set(reg, "x25", ctx->X25);
reg_set(reg, "x26", ctx->X26);
reg_set(reg, "x27", ctx->X27);
reg_set(reg, "x28", ctx->X28);
reg_set(reg, "fp", ctx->Fp);
reg_set(reg, "lr", ctx->Lr);
reg_set(reg, "sp", ctx->Sp);
reg_set(reg, "pc", ctx->Pc);
// floating point/neon registers
reg_set(reg, "v0", ctx->V[0]);
reg_set(reg, "v1", ctx->V[1]);
reg_set(reg, "v2", ctx->V[2]);
reg_set(reg, "v3", ctx->V[3]);
reg_set(reg, "v4", ctx->V[4]);
reg_set(reg, "v5", ctx->V[5]);
reg_set(reg, "v6", ctx->V[6]);
reg_set(reg, "v7", ctx->V[7]);
reg_set(reg, "v8", ctx->V[8]);
reg_set(reg, "v9", ctx->V[9]);
reg_set(reg, "v10", ctx->V[10]);
reg_set(reg, "v11", ctx->V[11]);
reg_set(reg, "v12", ctx->V[12]);
reg_set(reg, "v13", ctx->V[13]);
reg_set(reg, "v14", ctx->V[14]);
reg_set(reg, "v15", ctx->V[15]);
reg_set(reg, "v16", ctx->V[16]);
reg_set(reg, "v17", ctx->V[17]);
reg_set(reg, "v18", ctx->V[18]);
reg_set(reg, "v19", ctx->V[19]);
reg_set(reg, "v20", ctx->V[20]);
reg_set(reg, "v21", ctx->V[21]);
reg_set(reg, "v22", ctx->V[22]);
reg_set(reg, "v23", ctx->V[23]);
reg_set(reg, "v24", ctx->V[24]);
reg_set(reg, "v25", ctx->V[25]);
reg_set(reg, "v26", ctx->V[26]);
reg_set(reg, "v27", ctx->V[27]);
reg_set(reg, "v28", ctx->V[28]);
reg_set(reg, "v29", ctx->V[29]);
reg_set(reg, "v30", ctx->V[30]);
reg_set(reg, "v31", ctx->V[31]);
reg_set(reg, "fpcr", ctx->Fpcr);
reg_set(reg, "fpsr", ctx->Fpsr);
// debug registers
reg_set(reg, "bcr0", ctx->Bcr[0]);
reg_set(reg, "bcr1", ctx->Bcr[1]);
reg_set(reg, "bcr2", ctx->Bcr[2]);
reg_set(reg, "bcr3", ctx->Bcr[3]);
reg_set(reg, "bcr4", ctx->Bcr[4]);
reg_set(reg, "bcr5", ctx->Bcr[5]);
reg_set(reg, "bcr6", ctx->Bcr[6]);
reg_set(reg, "bcr7", ctx->Bcr[7]);
reg_set(reg, "bvr0", ctx->Bvr[0]);
reg_set(reg, "bvr1", ctx->Bvr[1]);
reg_set(reg, "bvr2", ctx->Bvr[2]);
reg_set(reg, "bvr3", ctx->Bvr[3]);
reg_set(reg, "bvr4", ctx->Bvr[4]);
reg_set(reg, "bvr5", ctx->Bvr[5]);
reg_set(reg, "bvr6", ctx->Bvr[6]);
reg_set(reg, "bvr7", ctx->Bvr[7]);
reg_set(reg, "wcr0", ctx->Wcr[0]);
reg_set(reg, "wcr1", ctx->Wcr[1]);
reg_set(reg, "wvr0", ctx->Wvr[0]);
reg_set(reg, "wvr1", ctx->Wvr[1]);
}
static void debug_dmp_set_arm32_registers(RzReg *reg, struct context_type_arm *ctx) {
reg_set(reg, "r0", ctx->r0);
reg_set(reg, "r1", ctx->r1);
reg_set(reg, "r2", ctx->r2);
reg_set(reg, "r3", ctx->r3);
reg_set(reg, "r4", ctx->r4);
reg_set(reg, "r5", ctx->r5);
reg_set(reg, "r6", ctx->r6);
reg_set(reg, "r7", ctx->r7);
reg_set(reg, "r8", ctx->r8);
reg_set(reg, "r9", ctx->r9);
reg_set(reg, "r10", ctx->r10);
reg_set(reg, "r11", ctx->r11);
reg_set(reg, "ip", ctx->r12); // ip = r12
reg_set(reg, "sp", ctx->sp);
reg_set(reg, "lr", ctx->lr);
reg_set(reg, "pc", ctx->pc);
reg_set(reg, "cpsr", ctx->cpsr);
reg_set(reg, "fpscr", ctx->fpscr);
// neon registers
reg_set(reg, "q0", ctx->q[0]);
reg_set(reg, "q1", ctx->q[1]);
reg_set(reg, "q2", ctx->q[2]);
reg_set(reg, "q3", ctx->q[3]);
reg_set(reg, "q4", ctx->q[4]);
reg_set(reg, "q5", ctx->q[5]);
reg_set(reg, "q6", ctx->q[6]);
reg_set(reg, "q7", ctx->q[7]);
reg_set(reg, "q8", ctx->q[8]);
reg_set(reg, "q9", ctx->q[9]);
reg_set(reg, "q10", ctx->q[10]);
reg_set(reg, "q11", ctx->q[11]);
reg_set(reg, "q12", ctx->q[12]);
reg_set(reg, "q13", ctx->q[13]);
reg_set(reg, "q14", ctx->q[14]);
reg_set(reg, "q15", ctx->q[15]);
// debug registers
reg_set(reg, "bcr0", ctx->bcr[0]);
reg_set(reg, "bcr1", ctx->bcr[1]);
reg_set(reg, "bcr2", ctx->bcr[2]);
reg_set(reg, "bcr3", ctx->bcr[3]);
reg_set(reg, "bcr4", ctx->bcr[4]);
reg_set(reg, "bcr5", ctx->bcr[5]);
reg_set(reg, "bcr6", ctx->bcr[6]);
reg_set(reg, "bcr7", ctx->bcr[7]);
reg_set(reg, "bvr0", ctx->bvr[0]);
reg_set(reg, "bvr1", ctx->bvr[1]);
reg_set(reg, "bvr2", ctx->bvr[2]);
reg_set(reg, "bvr3", ctx->bvr[3]);
reg_set(reg, "bvr4", ctx->bvr[4]);
reg_set(reg, "bvr5", ctx->bvr[5]);
reg_set(reg, "bvr6", ctx->bvr[6]);
reg_set(reg, "bvr7", ctx->bvr[7]);
reg_set(reg, "wcr0", ctx->wcr[0]);
reg_set(reg, "wvr0", ctx->wvr[0]);
}
static void debug_dmp_set_amd64_registers(RzReg *reg, struct context_type_amd64 *ctx) {
// segment + flags registers
reg_set(reg, "mxcsr", ctx->mx_csr);
reg_set(reg, "cs", ctx->seg_cs);
reg_set(reg, "ds", ctx->seg_ds);
reg_set(reg, "es", ctx->seg_es);
reg_set(reg, "fs", ctx->seg_fs);
reg_set(reg, "gs", ctx->seg_gs);
reg_set(reg, "ss", ctx->seg_ss);
reg_set(reg, "eflags", ctx->e_flags);
// debug registers
reg_set(reg, "dr0", ctx->dr0);
reg_set(reg, "dr1", ctx->dr1);
reg_set(reg, "dr2", ctx->dr2);
reg_set(reg, "dr3", ctx->dr3);
reg_set(reg, "dr6", ctx->dr6);
reg_set(reg, "dr7", ctx->dr7);
// gpr registers
reg_set(reg, "rax", ctx->rax);
reg_set(reg, "rcx", ctx->rcx);
reg_set(reg, "rdx", ctx->rdx);
reg_set(reg, "rbx", ctx->rbx);
reg_set(reg, "rsp", ctx->rsp);
reg_set(reg, "rbp", ctx->rbp);
reg_set(reg, "rsi", ctx->rsi);
reg_set(reg, "rdi", ctx->rdi);
reg_set(reg, "r8", ctx->r8);
reg_set(reg, "r9", ctx->r9);
reg_set(reg, "r10", ctx->r10);
reg_set(reg, "r11", ctx->r11);
reg_set(reg, "r12", ctx->r12);
reg_set(reg, "r13", ctx->r13);
reg_set(reg, "r14", ctx->r14);
reg_set(reg, "r15", ctx->r15);
reg_set(reg, "rip", ctx->rip);
}
static void debug_dmp_set_i386_registers(RzReg *reg, struct context_type_i386 *ctx) {
// debug registers
reg_set(reg, "dr0", ctx->dr0);
reg_set(reg, "dr1", ctx->dr1);
reg_set(reg, "dr2", ctx->dr2);
reg_set(reg, "dr3", ctx->dr3);
reg_set(reg, "dr6", ctx->dr6);
reg_set(reg, "dr7", ctx->dr7);
// windows floating point save area
reg_set(reg, "ctw", ctx->float_save.control_word);
reg_set(reg, "stw", ctx->float_save.status_word);
reg_set(reg, "tag", ctx->float_save.tag_word);
reg_set(reg, "ero", ctx->float_save.error_offset);
reg_set(reg, "ers", ctx->float_save.error_selector);
reg_set(reg, "dao", ctx->float_save.data_offset);
reg_set(reg, "das", ctx->float_save.data_selector);
reg_set(reg, "st0", ctx->float_save.register_area[0]);
reg_set(reg, "st1", ctx->float_save.register_area[10]);
reg_set(reg, "st2", ctx->float_save.register_area[20]);
reg_set(reg, "st3", ctx->float_save.register_area[30]);
reg_set(reg, "st4", ctx->float_save.register_area[40]);
reg_set(reg, "st5", ctx->float_save.register_area[50]);
reg_set(reg, "st6", ctx->float_save.register_area[60]);
reg_set(reg, "st7", ctx->float_save.register_area[70]);
reg_set(reg, "spare", ctx->float_save.spare_0);
// segment registers
reg_set(reg, "gs", ctx->seg_gs);
reg_set(reg, "fs", ctx->seg_fs);
reg_set(reg, "es", ctx->seg_es);
reg_set(reg, "ds", ctx->seg_ds);
reg_set(reg, "cs", ctx->seg_cs);
reg_set(reg, "ss", ctx->seg_ss);
// gpr registers
reg_set(reg, "edi", ctx->edi);
reg_set(reg, "esi", ctx->esi);
reg_set(reg, "ebx", ctx->ebx);
reg_set(reg, "edx", ctx->edx);
reg_set(reg, "ecx", ctx->ecx);
reg_set(reg, "eax", ctx->eax);
reg_set(reg, "ebp", ctx->ebp);
reg_set(reg, "eip", ctx->eip);
reg_set(reg, "esp", ctx->esp);
reg_set(reg, "eflags", ctx->e_flags);
// mmx regs
reg_set(reg, "xmm0", ctx->extended_registers[0]);
reg_set(reg, "xmm1", ctx->extended_registers[16]);
reg_set(reg, "xmm2", ctx->extended_registers[32]);
reg_set(reg, "xmm3", ctx->extended_registers[48]);
reg_set(reg, "xmm4", ctx->extended_registers[64]);
reg_set(reg, "xmm5", ctx->extended_registers[80]);
reg_set(reg, "xmm6", ctx->extended_registers[96]);
reg_set(reg, "xmm7", ctx->extended_registers[112]);
}
static void debug_dmp_set_current_context(WindCtx *ctx, RzReg *reg, ut8 *buf) {
if (ctx->is_arm && ctx->is_64bit) {
// ARM 64
return debug_dmp_set_arm64_registers(reg, (struct context_type_arm64 *)buf);
} else if (ctx->is_arm && !ctx->is_64bit) {
// ARM 32
return debug_dmp_set_arm32_registers(reg, (struct context_type_arm *)buf);
} else if (ctx->is_64bit) {
// AMD 64
return debug_dmp_set_amd64_registers(reg, (struct context_type_amd64 *)buf);
}
// i386
return debug_dmp_set_i386_registers(reg, (struct context_type_i386 *)buf);
}
static size_t debug_dmp_get_current_context_size(WindCtx *ctx) {
if (ctx->is_arm && ctx->is_64bit) {
// ARM 64
return sizeof(struct context_type_arm64);
} else if (ctx->is_arm && !ctx->is_64bit) {
// ARM 32
return sizeof(struct context_type_arm);
} else if (ctx->is_64bit) {
// AMD 64
return sizeof(struct context_type_amd64);
}
// i386
return sizeof(struct context_type_i386);
}
static bool debug_dmp_sync_registers(RzDebug *dbg, RzReg *reg, bool to_debugger) {
if (to_debugger) {
// the dmp plugin does not allow to write to the debugger, since it is not a real debugger.
return false;
}
DmpCtx *dmp = dbg->plugin_data;
WindCtx *ctx = &dmp->windctx;
if (!is_kernel_address_present(ctx, ctx->target_thread.ethread)) {
return 0;
return false;
}
const ut64 current_thread_offset = ctx->is_64bit ? 8 : 4;
ut64 *kprcb;
rz_vector_foreach(&dmp->KiProcessorBlock, kprcb) {
const ut64 current_thread = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, *kprcb + current_thread_offset);
if (current_thread == ctx->target_thread.ethread) {
const ut64 current_context = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, *kprcb + dmp->kprcb_context_offset);
if (current_context) {
return ctx->read_at_kernel_virtual(ctx->user, current_context, buf, size);
}
RZ_LOG_WARN("Failed to get KPRCB Context pointer at 0x%" PFMT64x "\n", current_context);
if (current_thread != ctx->target_thread.ethread) {
continue;
}
const ut64 current_context = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, *kprcb + dmp->kprcb_context_offset);
if (!current_context) {
RZ_LOG_WARN("debug: dmp: KPRCB context pointer is zero at 0x%" PFMT64x "\n", *kprcb + dmp->kprcb_context_offset);
continue;
}
const size_t size = debug_dmp_get_current_context_size(ctx);
ut8 *buffer = malloc(size);
if (!buffer) {
RZ_LOG_ERROR("debug: dmp: Failed to allocate buffer for setting rizin registers\n");
return false;
}
bool success = false;
if (ctx->read_at_kernel_virtual(ctx->user, current_context, buffer, size)) {
debug_dmp_set_current_context(ctx, reg, buffer);
success = true;
}
free(buffer);
return success;
}
if (dmp->type == DMP_DUMPTYPE_TRIAGE || !ctx->target_thread.uniqueid) {
memcpy(buf, dmp->context, RZ_MIN(size, dmp->context_sz));
return size;
debug_dmp_set_current_context(ctx, reg, dmp->context);
return true;
}
const int kernel_stack_offset = ctx->is_64bit ? 0x58 : 0x48;
if (ctx->is_arm) {
if (ctx->is_64bit) {
struct context_type_arm64 *regs = (struct context_type_arm64 *)buf;
regs->Sp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
regs->Fp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + dmp->kthread_switch_frame_offset);
regs->Pc = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + dmp->kthread_switch_frame_offset + 8);
} else {
struct context_type_arm *regs = (struct context_type_arm *)buf;
regs->sp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
regs->pc = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + dmp->kthread_switch_frame_offset + 4);
}
if (ctx->is_arm && ctx->is_64bit) {
// ARM 64
ut64 Sp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
ut64 Fp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + dmp->kthread_switch_frame_offset);
ut64 Pc = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + dmp->kthread_switch_frame_offset + 8);
reg_set(reg, "fp", Fp);
reg_set(reg, "sp", Sp);
reg_set(reg, "pc", Pc);
} else if (ctx->is_arm && !ctx->is_64bit) {
// ARM 32
ut32 sp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
ut32 pc = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + dmp->kthread_switch_frame_offset + 4);
reg_set(reg, "sp", sp);
reg_set(reg, "pc", pc);
} else if (ctx->is_64bit) {
// AMD 64
ut64 rsp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
reg_set(reg, "rsp", rsp);
} else {
if (ctx->is_64bit) {
struct context_type_amd64 *regs = (struct context_type_amd64 *)buf;
regs->rsp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
} else {
struct context_type_i386 *regs = (struct context_type_i386 *)buf;
regs->esp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
}
// i386
ut32 esp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
reg_set(reg, "esp", esp);
}
return size;
return true;
}
static char *rz_debug_dmp_reg_profile(RzDebug *dbg) {
@ -505,8 +837,8 @@ static bool rz_debug_dmp_kill(RzDebug *dbg, int pid, int tid, int sig) {
return true;
}
static int is_pc_inside_windmodule(const void *value, const void *list_data) {
const ut64 pc = *(const ut64 *)value;
static int is_pc_inside_windmodule(const struct context_type_amd64 *context, const void *list_data) {
const ut64 pc = context->rip;
const WindModule *module = list_data;
return !(pc >= module->addr && pc < (module->addr + module->size));
}
@ -531,7 +863,7 @@ RzList /*<RzDebugFrame *>*/ *rz_debug_dmp_frames(RzDebug *dbg, ut64 at) {
if (!modules) {
modules = dmp_get_modules(ctx);
}
RzListIter *it = rz_list_find(modules, &context.rip, is_pc_inside_windmodule);
RzListIter *it = rz_list_find(modules, &context, (RzListComparator)is_pc_inside_windmodule);
if (!it) {
break;
}
@ -570,7 +902,7 @@ RzDebugPlugin rz_debug_plugin_dmp = {
.attach = &rz_debug_dmp_attach,
.pids = &rz_debug_dmp_pids,
.select = &rz_debug_dmp_select,
.reg_read = &rz_debug_dmp_reg_read,
.sync_registers = &debug_dmp_sync_registers,
.reg_profile = &rz_debug_dmp_reg_profile,
.threads = &rz_debug_dmp_threads,
.modules_get = &rz_debug_dmp_modules,

View file

@ -28,18 +28,18 @@ static int rz_debug_winkd_reg_write(RZ_BORROW RZ_NONNULL RzDebug *dbg, int type,
if (kdctx->windctx.is_arm) {
if (kdctx->windctx.is_64bit) {
const struct context_type_arm64 *ctx = (void *)buf;
flags = ctx->ContextFlags;
flags = rz_read_le32(&ctx->ContextFlags);
} else {
const struct context_type_arm *ctx = (void *)buf;
flags = ctx->context_flags;
flags = rz_read_le32(&ctx->context_flags);
}
} else {
if (kdctx->windctx.is_64bit) {
const struct context_type_amd64 *ctx = (void *)buf;
flags = ctx->context_flags;
flags = rz_read_le32(&ctx->context_flags);
} else {
const struct context_type_i386 *ctx = (void *)buf;
flags = ctx->context_flags;
flags = rz_read_le32(&ctx->context_flags);
}
}
return winkd_write_reg(kdctx, flags, buf, size);

View file

@ -5,6 +5,207 @@
#include <mdmp_windefs.h>
#include <librz/bin/format/pe/pe64.h>
// the original PE64_UNWIND_CODE is a union
typedef struct windows_x64_unwind_code_t {
ut8 CodeOffset;
ut8 UnwindOp; // : 4;
ut8 OpInfo; // : 4;
ut16 FrameOffset;
ut64 offset;
} Win64UnwindCode;
typedef struct windows_x64_unwind_info_t {
ut8 Version; // : 3;
ut8 Flags; // : 5;
ut8 SizeOfProlog;
ut8 CountOfCodes;
ut8 FrameRegister; // : 4;
ut8 FrameOffset; // : 4;
Win64UnwindCode *code;
} Win64UnwindInfo;
enum {
AMD64_INDEX_RAX = 0,
AMD64_INDEX_RCX,
AMD64_INDEX_RDX,
AMD64_INDEX_RBX,
AMD64_INDEX_RSP,
AMD64_INDEX_RBP,
AMD64_INDEX_RSI,
AMD64_INDEX_RDI,
AMD64_INDEX_R8,
AMD64_INDEX_R9,
AMD64_INDEX_R10,
AMD64_INDEX_R11,
AMD64_INDEX_R12,
AMD64_INDEX_R13,
AMD64_INDEX_R14,
AMD64_INDEX_R15,
AMD64_INDEX_RIP,
};
static Win64UnwindCode *windows_x64_unwind_code_new(RzDebug *dbg, ut64 at, ut32 count) {
ut8 code[sizeof(ut16)] = { 0 };
Win64UnwindCode *uc = RZ_NEWS0(Win64UnwindCode, count);
if (!uc) {
return NULL;
}
for (ut32 i = 0; i < count; ++i, at += sizeof(ut16)) {
if (!dbg->iob.read_at(dbg->iob.io, at, code, sizeof(code))) {
free(uc);
return NULL;
}
uc[i].CodeOffset = code[0];
uc[i].UnwindOp = code[1] & 0x0F;
uc[i].OpInfo = code[1] >> 4;
uc[i].FrameOffset = rz_read_le16(code);
uc[i].offset = at;
}
return uc;
}
static Win64UnwindInfo *windows_x64_unwind_info_new(RzDebug *dbg, ut64 at) {
ut8 tmp[sizeof(PE64_UNWIND_INFO)] = { 0 };
if (!dbg->iob.read_at(dbg->iob.io, at, tmp, sizeof(tmp))) {
return NULL;
}
Win64UnwindInfo *info = RZ_NEW0(Win64UnwindInfo);
if (!info) {
return NULL;
}
// The ordering of bits in C bitfields is implementation defined.
// this ensures the endianness (here is little endian) is kept
info->Version = tmp[0] & 0x07;
info->Flags = tmp[0] >> 3;
info->SizeOfProlog = tmp[1];
info->CountOfCodes = tmp[2];
info->FrameRegister = tmp[3] & 0x0F;
info->FrameOffset = tmp[3] >> 4;
info->code = windows_x64_unwind_code_new(dbg, at + 4, info->CountOfCodes);
if (!info->code) {
free(info);
return NULL;
}
return info;
}
#define windows_x64_unwind_code_free free
static void windows_x64_unwind_info_free(Win64UnwindInfo *info) {
if (!info) {
return;
}
windows_x64_unwind_code_free(info->code);
free(info);
}
static void set_amd64_register(struct context_type_amd64 *context, ut8 reg_idx, ut64 value) {
switch (reg_idx) {
case AMD64_INDEX_RAX:
context->rax = value;
return;
case AMD64_INDEX_RCX:
context->rcx = value;
return;
case AMD64_INDEX_RDX:
context->rdx = value;
return;
case AMD64_INDEX_RBX:
context->rbx = value;
return;
case AMD64_INDEX_RSP:
context->rsp = value;
return;
case AMD64_INDEX_RBP:
context->rbp = value;
return;
case AMD64_INDEX_RSI:
context->rsi = value;
return;
case AMD64_INDEX_RDI:
context->rdi = value;
return;
case AMD64_INDEX_R8:
context->r8 = value;
return;
case AMD64_INDEX_R9:
context->r9 = value;
return;
case AMD64_INDEX_R10:
context->r10 = value;
return;
case AMD64_INDEX_R11:
context->r11 = value;
return;
case AMD64_INDEX_R12:
context->r12 = value;
return;
case AMD64_INDEX_R13:
context->r13 = value;
return;
case AMD64_INDEX_R14:
context->r14 = value;
return;
case AMD64_INDEX_R15:
context->r15 = value;
return;
case AMD64_INDEX_RIP:
context->rip = value;
return;
default:
RZ_LOG_ERROR("debug: cannot set amd64 register due unknown index %u\n", reg_idx);
return;
}
}
static ut64 get_amd64_register(const struct context_type_amd64 *context, ut8 reg_idx) {
switch (reg_idx) {
case AMD64_INDEX_RAX:
return context->rax;
case AMD64_INDEX_RCX:
return context->rcx;
case AMD64_INDEX_RDX:
return context->rdx;
case AMD64_INDEX_RBX:
return context->rbx;
case AMD64_INDEX_RSP:
return context->rsp;
case AMD64_INDEX_RBP:
return context->rbp;
case AMD64_INDEX_RSI:
return context->rsi;
case AMD64_INDEX_RDI:
return context->rdi;
case AMD64_INDEX_R8:
return context->r8;
case AMD64_INDEX_R9:
return context->r9;
case AMD64_INDEX_R10:
return context->r10;
case AMD64_INDEX_R11:
return context->r11;
case AMD64_INDEX_R12:
return context->r12;
case AMD64_INDEX_R13:
return context->r13;
case AMD64_INDEX_R14:
return context->r14;
case AMD64_INDEX_R15:
return context->r15;
case AMD64_INDEX_RIP:
return context->rip;
default:
RZ_LOG_ERROR("debug: cannot get amd64 register due unknown index %u\n", reg_idx);
return 0;
}
}
static int is_pc_inside_module(const void *value, const void *list_data) {
const ut64 pc = *(const ut64 *)value;
const RzDebugMap *module = list_data;
@ -14,8 +215,8 @@ static int is_pc_inside_module(const void *value, const void *list_data) {
#define CMP(x, y) (st64)((st64)x - ((PE64_RUNTIME_FUNCTION *)y)->EndAddress)
#define READ_AT(address, buf, size) dbg->iob.read_at(dbg->iob.io, address, buf, size)
static inline bool init_module_runtime_functions(RzDebug *dbg, RzVector /*<PE64_RUNTIME_FUNCTION>*/ *functions, ut64 module_base) {
ut8 buf[4];
static bool init_module_runtime_functions(RzDebug *dbg, RzVector /*<PE64_RUNTIME_FUNCTION>*/ *functions, ut64 module_base) {
ut8 buf[sizeof(ut32)] = { 0 };
const ut64 lfanew_offset = module_base + rz_offsetof(Pe64_image_dos_header, e_lfanew);
READ_AT(lfanew_offset, buf, sizeof(buf));
@ -50,8 +251,7 @@ static inline bool init_module_runtime_functions(RzDebug *dbg, RzVector /*<PE64_
return false;
}
ut64 offset;
for (offset = 0; offset < exception_table_size; offset += sizeof(PE64_RUNTIME_FUNCTION)) {
for (ut64 offset = 0; offset < exception_table_size; offset += sizeof(PE64_RUNTIME_FUNCTION)) {
PE64_RUNTIME_FUNCTION rfcn;
rfcn.BeginAddress = rz_read_le32(section + offset + rz_offsetof(PE64_RUNTIME_FUNCTION, BeginAddress));
rfcn.EndAddress = rz_read_le32(section + offset + rz_offsetof(PE64_RUNTIME_FUNCTION, EndAddress));
@ -65,70 +265,68 @@ static inline bool init_module_runtime_functions(RzDebug *dbg, RzVector /*<PE64_
return true;
}
static inline ut64 read_register(RzDebug *dbg, ut64 at) {
ut8 buf[8];
dbg->iob.read_at(dbg->iob.io, at, buf, sizeof(buf));
static ut64 read_register_from_memory(RzDebug *dbg, ut64 at) {
ut8 buf[8] = { 0 };
if (!dbg->iob.read_at(dbg->iob.io, at, buf, sizeof(buf))) {
return 0;
}
return rz_read_le64(buf);
}
static inline ut32 read_slot32(RzDebug *dbg, PE64_UNWIND_INFO *info, int *index) {
ut32 ret = rz_read_le32(&info->UnwindCode[*index]);
static ut32 read_unwind_code_slot_32(RzDebug *dbg, const Win64UnwindInfo *info, int *index) {
ut8 tmp[sizeof(ut32)] = { 0 };
ut64 offset = info->code[*index].offset;
if (!dbg->iob.read_at(dbg->iob.io, offset, tmp, sizeof(tmp))) {
return 0;
}
ut32 ret = rz_read_le32(tmp);
*index += 2;
return ret;
}
static inline ut16 read_slot16(RzDebug *dbg, PE64_UNWIND_INFO *info, int *index) {
ut16 ret = rz_read_le16(&info->UnwindCode[*index]);
static ut16 read_unwind_code_slot_16(RzDebug *dbg, const Win64UnwindInfo *info, int *index) {
ut8 tmp[sizeof(ut16)] = { 0 };
ut64 offset = info->code[*index].offset;
if (!dbg->iob.read_at(dbg->iob.io, offset, tmp, sizeof(tmp))) {
return 0;
}
ut16 ret = rz_read_le16(tmp);
*index += 1;
return ret;
}
// Decides if current rsp or another register is used as the frame base (eg. rbp, etc)
static inline ut64 get_frame_base(const PE64_UNWIND_INFO *info, const struct context_type_amd64 *context, const ut64 function_address) {
static ut64 get_frame_base(const Win64UnwindInfo *info, const struct context_type_amd64 *context, const ut64 function_address) {
const ut64 rip_offset_to_function = context->rip - function_address;
const ut64 *integer_registers = &context->rax;
if (!info->FrameRegister) {
// There is no register being used as the frame base, use rsp
return context->rsp;
} else if ((rip_offset_to_function >= info->SizeOfProlog) || ((info->Flags & PE64_UNW_FLAG_CHAININFO) != 0)) {
// There is a register being used as a frame base, and we definetly already set it
return integer_registers[info->FrameRegister] - info->FrameOffset * 16;
} else {
// There is a register being used as a frame base, unknown if we set it yet
int i;
// Find unwind of where frame register is being set
for (i = 0; i < info->CountOfCodes; i++) {
if (info->UnwindCode[i].UnwindOp == UWOP_SET_FPREG) {
break;
}
}
// Check if we already set the frame register
if (rip_offset_to_function >= info->UnwindCode[i].CodeOffset) {
return integer_registers[info->FrameRegister] - info->FrameOffset * 16;
} else {
return context->rsp;
ut64 value = get_amd64_register(context, info->FrameRegister);
return value - info->FrameOffset * 16;
}
// There is a register being used as a frame base, unknown if we set it yet
int i;
Win64UnwindCode *code = NULL;
// Find unwind of where frame register is being set
for (i = 0; i < info->CountOfCodes; i++) {
if (code[i].UnwindOp == UWOP_SET_FPREG) {
break;
}
}
// Check if we already set the frame register
if (rip_offset_to_function >= code[i].CodeOffset) {
ut64 value = get_amd64_register(context, info->FrameRegister);
return value - info->FrameOffset * 16;
}
return context->rsp;
}
static inline PE64_UNWIND_INFO *read_unwind_info(RzDebug *dbg, ut64 at) {
PE64_UNWIND_INFO *info = RZ_NEW0(PE64_UNWIND_INFO);
if (!info) {
return NULL;
}
READ_AT(at, (ut8 *)info, sizeof(*info));
const size_t unwind_code_array_sz = info->CountOfCodes * sizeof(PE64_UNWIND_CODE);
void *tmp = realloc(info, sizeof(PE64_UNWIND_INFO) + unwind_code_array_sz);
if (!tmp) {
free(info);
return NULL;
}
info = tmp;
READ_AT(at + rz_offsetof(PE64_UNWIND_INFO, UnwindCode), (ut8 *)info->UnwindCode, unwind_code_array_sz);
return info;
}
static inline bool unwind_function(
static inline bool
unwind_function(
RzDebug *dbg,
RzDebugFrame *frame,
PE64_RUNTIME_FUNCTION *rfcn,
@ -137,107 +335,110 @@ static inline bool unwind_function(
const ut64 function_address) {
bool is_chained = false;
ut64 *integer_registers = &context->rax;
ut64 machine_frame_start;
ut64 machine_frame_start = 0;
bool is_machine_frame = false;
ut64 unwind_info_address = module_address + rfcn->UnwindInfoAddress;
Win64UnwindInfo *info = NULL;
// Read initial unwind info structure
PE64_UNWIND_INFO *info = read_unwind_info(dbg, unwind_info_address);
if (!info) {
return false;
}
do {
// Read initial unwind info structure
info = windows_x64_unwind_info_new(dbg, unwind_info_address);
if (!info) {
return false;
}
// Get address that is used as the base for stack accesses
ut64 frame_base = get_frame_base(info, context, function_address);
// Get address that is used as the base for stack accesses
ut64 frame_base = get_frame_base(info, context, function_address);
process_chained_info:
if (info->Version != 1 && info->Version != 2) {
// Version 1 found in user-space, version 2 in kernel
RZ_LOG_ERROR("Unwind info version (%" PFMT32d ") for function 0x%" PFMT64x " is not recognized\n",
(ut32)info->Version, function_address);
free(info);
return false;
}
int i = 0;
while (i < info->CountOfCodes) {
const PE64_UNWIND_CODE code = info->UnwindCode[i];
i++;
// Check if we are already past the prolog instruction
// If we are processing a chained scope, always process all of them
if (!is_chained && context->rip < function_address + code.CodeOffset) {
// Skip, as it wasn't executed yet
switch (code.UnwindOp) {
case UWOP_ALLOC_LARGE:
i++;
if (code.OpInfo) {
if (info->Version != 1 && info->Version != 2) {
// Version 1 found in user-space, version 2 in kernel
RZ_LOG_ERROR("Unwind info version (%" PFMT32d ") for function 0x%" PFMT64x " is not recognized\n",
(ut32)info->Version, function_address);
free(info);
return false;
}
int i = 0;
while (i < info->CountOfCodes) {
Win64UnwindCode *code = &info->code[i];
i++;
// Check if we are already past the prolog instruction
// If we are processing a chained scope, always process all of them
if (!is_chained && context->rip < function_address + code->CodeOffset) {
// Skip, as it wasn't executed yet
switch (code->UnwindOp) {
case UWOP_ALLOC_LARGE:
i++;
if (code->OpInfo) {
i++;
}
break;
case UWOP_SAVE_XMM128:
case UWOP_SAVE_NONVOL:
case UWOP_UNKNOWN1:
i++;
break;
case UWOP_SAVE_XMM128_FAR:
case UWOP_SAVE_NONVOL_FAR:
case UWOP_UNKNOWN2:
i += 2;
break;
default:
break;
}
continue;
}
ut16 offset;
switch (code->UnwindOp) {
case UWOP_PUSH_NONVOL: /* info == register number */
set_amd64_register(context, code->OpInfo, read_register_from_memory(dbg, context->rsp));
context->rsp += 8;
break;
case UWOP_ALLOC_LARGE: /* info == unscaled or scaled, alloc size in next 1 or 2 slots */
if (code->OpInfo) {
context->rsp += read_unwind_code_slot_32(dbg, info, &i);
} else {
context->rsp += read_unwind_code_slot_16(dbg, info, &i) * 8;
}
break;
case UWOP_SAVE_XMM128:
case UWOP_SAVE_NONVOL:
case UWOP_UNKNOWN1:
case UWOP_ALLOC_SMALL: /* info == size of allocation / 8 - 1 */
context->rsp += (code->OpInfo * 8) + 8;
break;
case UWOP_SET_FPREG: /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
frame->bp = get_amd64_register(context, info->FrameRegister);
context->rsp = frame->bp - info->FrameOffset * 16;
break;
case UWOP_SAVE_NONVOL: /* info == register number, offset in next slot */
offset = read_unwind_code_slot_16(dbg, info, &i) * 8;
set_amd64_register(context, code->OpInfo, read_register_from_memory(dbg, frame_base + offset));
break;
case UWOP_SAVE_XMM128: /* info == XMM reg number, offset in next slot */
case UWOP_UNKNOWN1: /* 1 extra slot */
i++;
break;
case UWOP_SAVE_XMM128_FAR:
case UWOP_SAVE_NONVOL_FAR:
case UWOP_UNKNOWN2:
case UWOP_SAVE_NONVOL_FAR: /* info == register number, offset in next 2 slots */
offset = read_unwind_code_slot_32(dbg, info, &i);
set_amd64_register(context, code->OpInfo, read_register_from_memory(dbg, frame_base + offset));
break;
case UWOP_SAVE_XMM128_FAR: /* info == XMM reg number, offset in next 2 slots */
case UWOP_UNKNOWN2: /* 2 extra slots */
i += 2;
break;
default:
case UWOP_PUSH_MACHFRAME: /* info == 0: no error-code, 1: error-code */
if (code->OpInfo) {
context->rsp += 8;
}
is_machine_frame = true;
machine_frame_start = context->rsp + 40;
context->rip = read_register_from_memory(dbg, context->rsp);
context->rsp = read_register_from_memory(dbg, context->rsp + 24);
break;
}
continue;
}
ut16 offset;
switch (code.UnwindOp) {
case UWOP_PUSH_NONVOL: /* info == register number */
integer_registers[code.OpInfo] = read_register(dbg, context->rsp);
context->rsp += 8;
break;
case UWOP_ALLOC_LARGE: /* info == unscaled or scaled, alloc size in next 1 or 2 slots */
if (code.OpInfo) {
context->rsp += read_slot32(dbg, info, &i);
} else {
context->rsp += read_slot16(dbg, info, &i) * 8;
}
break;
case UWOP_ALLOC_SMALL: /* info == size of allocation / 8 - 1 */
context->rsp += code.OpInfo * 8 + 8;
break;
case UWOP_SET_FPREG: /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
frame->bp = integer_registers[info->FrameRegister];
context->rsp = integer_registers[info->FrameRegister] - info->FrameOffset * 16;
break;
case UWOP_SAVE_NONVOL: /* info == register number, offset in next slot */
offset = read_slot16(dbg, info, &i) * 8;
integer_registers[code.OpInfo] = read_register(dbg, frame_base + offset);
break;
case UWOP_SAVE_XMM128: /* info == XMM reg number, offset in next slot */
case UWOP_UNKNOWN1: /* 1 extra slot */
i++;
break;
case UWOP_SAVE_NONVOL_FAR: /* info == register number, offset in next 2 slots */
offset = read_slot32(dbg, info, &i);
integer_registers[code.OpInfo] = read_register(dbg, frame_base + offset);
break;
case UWOP_SAVE_XMM128_FAR: /* info == XMM reg number, offset in next 2 slots */
case UWOP_UNKNOWN2: /* 2 extra slots */
i += 2;
break;
case UWOP_PUSH_MACHFRAME: /* info == 0: no error-code, 1: error-code */
if (code.OpInfo) {
context->rsp += 8;
}
is_machine_frame = true;
machine_frame_start = context->rsp + 40;
context->rip = read_register(dbg, context->rsp);
context->rsp = read_register(dbg, context->rsp + 24);
if (!(info->Flags & PE64_UNW_FLAG_CHAININFO)) {
break;
}
}
if (info->Flags & PE64_UNW_FLAG_CHAININFO) {
if (i % 2) {
i++;
}
@ -248,28 +449,33 @@ process_chained_info:
READ_AT(chained_fcn_address, buf, sizeof(buf));
// Get unwind info from the chained RUNTIME_FUNCTION
unwind_info_address = module_address + rz_read_le32(buf + rz_offsetof(PE64_RUNTIME_FUNCTION, UnwindInfoAddress));
free(info);
info = read_unwind_info(dbg, unwind_info_address);
if (!info) {
return false;
}
unwind_info_address = module_address + rz_read_at_le32(buf, rz_offsetof(PE64_RUNTIME_FUNCTION, UnwindInfoAddress));
RZ_FREE_CUSTOM(info, windows_x64_unwind_info_free);
// Make sure we process all the chained unwind ops
is_chained = true;
goto process_chained_info;
}
} while (1);
if (is_machine_frame) {
frame->size = machine_frame_start - frame->sp;
} else {
frame->size = context->rsp - frame->sp;
context->rip = read_register(dbg, context->rsp);
context->rip = read_register_from_memory(dbg, context->rsp);
context->rsp += 8;
}
free(info);
windows_x64_unwind_info_free(info);
return true;
}
static ut64 get_register_value(RzDebug *dbg, const char *reg_name) {
RzRegItem *reg = rz_reg_get(dbg->reg, reg_name, -1);
if (!reg) {
rz_warn_if_reached();
return 0;
}
return rz_reg_get_value(dbg->reg, reg);
}
static bool backtrace_windows_x64(RZ_IN RzDebug *dbg, RZ_INOUT RzList /*<RzDebugFrame *>*/ **out_frames, RZ_INOUT struct context_type_amd64 *context) {
RzList *frames = *out_frames ? *out_frames : rz_list_newf(free);
*out_frames = frames;
@ -281,15 +487,41 @@ static bool backtrace_windows_x64(RZ_IN RzDebug *dbg, RZ_INOUT RzList /*<RzDebug
return true;
}
if (!context->rsp) {
int arena_size;
ut8 *arena = rz_reg_get_bytes(dbg->reg, RZ_REG_TYPE_GPR, &arena_size);
if (!arena || arena_size < sizeof(*context)) {
rz_list_free(modules);
free(arena);
return true;
}
memcpy(context, arena, sizeof(*context));
free(arena);
context->mx_csr = get_register_value(dbg, "mxcsr");
context->seg_cs = get_register_value(dbg, "cs");
context->seg_ds = get_register_value(dbg, "ds");
context->seg_es = get_register_value(dbg, "es");
context->seg_fs = get_register_value(dbg, "fs");
context->seg_gs = get_register_value(dbg, "gs");
context->seg_ss = get_register_value(dbg, "ss");
context->e_flags = get_register_value(dbg, "eflags");
context->dr0 = get_register_value(dbg, "dr0");
context->dr1 = get_register_value(dbg, "dr1");
context->dr2 = get_register_value(dbg, "dr2");
context->dr3 = get_register_value(dbg, "dr3");
context->dr6 = get_register_value(dbg, "dr6");
context->dr7 = get_register_value(dbg, "dr7");
context->rax = get_register_value(dbg, "rax");
context->rcx = get_register_value(dbg, "rcx");
context->rdx = get_register_value(dbg, "rdx");
context->rbx = get_register_value(dbg, "rbx");
context->rsp = get_register_value(dbg, "rsp");
context->rbp = get_register_value(dbg, "rbp");
context->rsi = get_register_value(dbg, "rsi");
context->rdi = get_register_value(dbg, "rdi");
context->r8 = get_register_value(dbg, "r8");
context->r9 = get_register_value(dbg, "r9");
context->r10 = get_register_value(dbg, "r10");
context->r11 = get_register_value(dbg, "r11");
context->r12 = get_register_value(dbg, "r12");
context->r13 = get_register_value(dbg, "r13");
context->r14 = get_register_value(dbg, "r14");
context->r15 = get_register_value(dbg, "r15");
context->rip = get_register_value(dbg, "rip");
}
RzDebugMap *last_module = NULL;
RzVector functions;
@ -329,7 +561,7 @@ static bool backtrace_windows_x64(RZ_IN RzDebug *dbg, RZ_INOUT RzList /*<RzDebug
if (index == rz_vector_len(&functions)) {
// Leaf function
frame->size = 0;
context->rip = read_register(dbg, context->rsp);
context->rip = read_register_from_memory(dbg, context->rsp);
context->rsp += 8;
} else {
// Not a leaf function

View file

@ -73,6 +73,4 @@ return strdup(
"drx bvr6 .32 392 0\n"
"drx bvr7 .32 396 0\n"
"drx wcr0 .32 400 0\n"
"drx wcr1 .32 404 0\n"
"drx wvr0 .32 408 0\n"
"drx wvr1 .32 412 0\n");
"drx wvr0 .32 404 0\n");

View file

@ -227,7 +227,7 @@ RZ_API ut64 rz_reg_get_value_by_role(RZ_NONNULL RzReg *reg, RzRegisterId role);
RZ_API bool rz_reg_set_value_by_role(RZ_NONNULL RzReg *reg, RzRegisterId role, ut64 value);
/* byte arena */
RZ_API ut8 *rz_reg_get_bytes(RzReg *reg, int type, int *size);
RZ_API RZ_OWN ut8 *rz_reg_get_bytes(RZ_NONNULL RzReg *reg, int type, RZ_NULLABLE int *size);
RZ_API bool rz_reg_set_bytes(RzReg *reg, int type, const ut8 *buf, const int len);
RZ_API bool rz_reg_read_regs(RzReg *reg, ut8 *buf, const int len);
RZ_API int rz_reg_arena_set_bytes(RzReg *reg, const char *str);

View file

@ -5,10 +5,10 @@
#if RZ_SYS_BITS == 4
#define BITWORD_BITS_SHIFT 5
#define RBitword ut32
#define RzBitword ut32
#else
#define BITWORD_BITS_SHIFT 6
#define RBitword ut64
#define RzBitword ut64
#endif
#ifdef __cplusplus
@ -17,7 +17,7 @@ extern "C" {
typedef struct rz_bitmap_t {
size_t length;
RBitword *bitmap;
RzBitword *bitmap;
} RzBitmap;
RZ_API RZ_OWN RzBitmap *rz_bitmap_new(size_t len);

View file

@ -4,8 +4,19 @@
#include <rz_reg.h>
#include <rz_util/rz_str.h>
/* non-endian safe - used for raw mapping with system registers */
RZ_API ut8 *rz_reg_get_bytes(RzReg *reg, int type, int *size) {
/**
* \brief Returns a copy of the raw arena memory area
* non-endian safe - used for raw mapping with system registers
*
* \param reg The register
* \param[in] type The type
* \param size The size
*
* \return On success returns a valid pointer, otherwise NULL.
*/
RZ_API RZ_OWN ut8 *rz_reg_get_bytes(RZ_NONNULL RzReg *reg, int type, RZ_NULLABLE int *size) {
rz_return_val_if_fail(reg, NULL);
RzRegArena *arena;
int i, sz, osize;
ut8 *buf, *newbuf;

View file

@ -6,7 +6,15 @@
#define BITMAP_TEST 0
#define BITWORD_BITS (sizeof(RBitword) * 8)
#if RZ_SYS_BITS == 4
#define bitword_read rz_read_le32
#define bitword_write rz_write_le32
#else
#define bitword_read rz_read_le64
#define bitword_write rz_write_le64
#endif
#define BITWORD_BITS (sizeof(RzBitword) * 8)
#define BITWORD_BITS_MASK (BITWORD_BITS - 1)
#define BITWORD_MULT(bit) (((bit) + (BITWORD_BITS_MASK)) & ~(BITWORD_BITS_MASK))
#define BITWORD_TEST(x, y) (((x) >> (y)) & 1)
@ -23,7 +31,7 @@ RZ_API RZ_OWN RzBitmap *rz_bitmap_new(size_t len) {
return NULL;
}
b->bitmap = calloc(BITMAP_WORD_COUNT(len), sizeof(RBitword));
b->bitmap = calloc(BITMAP_WORD_COUNT(len), sizeof(RzBitword));
if (!b->bitmap) {
free(b);
return NULL;
@ -34,9 +42,11 @@ RZ_API RZ_OWN RzBitmap *rz_bitmap_new(size_t len) {
RZ_API void rz_bitmap_set_bytes(RZ_NONNULL RzBitmap *b, RZ_NONNULL const ut8 *buf, size_t len) {
rz_return_if_fail(b && buf && len >= 0);
if (b->length < len) {
len = b->length;
size_t blen = b->length << BITWORD_BITS_SHIFT;
if (blen < len) {
len = blen;
}
memcpy(b->bitmap, buf, len);
}
@ -51,23 +61,28 @@ RZ_API void rz_bitmap_free(RZ_NULLABLE RzBitmap *b) {
RZ_API void rz_bitmap_set(RZ_NONNULL RzBitmap *b, size_t bit) {
rz_return_if_fail(b && bit >= 0);
if (bit < b->length) {
b->bitmap[(bit >> BITWORD_BITS_SHIFT)] |=
((RBitword)1 << (bit & BITWORD_BITS_MASK));
const size_t pos = bit >> BITWORD_BITS_SHIFT;
RzBitword value = bitword_read(&b->bitmap[pos]);
value |= ((RzBitword)1 << (bit & BITWORD_BITS_MASK));
bitword_write(&b->bitmap[pos], value);
}
}
RZ_API void rz_bitmap_unset(RZ_NONNULL RzBitmap *b, size_t bit) {
rz_return_if_fail(b && bit >= 0);
if (bit < b->length) {
b->bitmap[(bit >> BITWORD_BITS_SHIFT)] &=
~((RBitword)1 << (bit & BITWORD_BITS_MASK));
const size_t pos = bit >> BITWORD_BITS_SHIFT;
RzBitword value = bitword_read(&b->bitmap[pos]);
value &= ~((RzBitword)1 << (bit & BITWORD_BITS_MASK));
bitword_write(&b->bitmap[pos], value);
}
}
RZ_API int rz_bitmap_test(RZ_NONNULL RzBitmap *b, size_t bit) {
rz_return_val_if_fail(b && bit >= 0, -1);
if (bit < b->length) {
RBitword bword = b->bitmap[(bit >> BITWORD_BITS_SHIFT)];
const size_t pos = bit >> BITWORD_BITS_SHIFT;
RzBitword bword = bitword_read(&b->bitmap[pos]);
return BITWORD_TEST(bword, (bit & BITWORD_BITS_MASK));
}
return -1;

View file

@ -38,17 +38,18 @@ bool winkd_lock_leave(RZ_BORROW RZ_NONNULL KdCtx *ctx) {
}
int winkd_get_sp(RZ_BORROW RZ_NONNULL WindCtx *ctx) {
ut64 ptr = 0;
ut8 buf[sizeof(ut64)] = { 0 };
// Grab the CmNtCSDVersion field to extract the Service Pack number
if (!ctx->read_at_kernel_virtual(ctx->user, ctx->KdDebuggerDataBlock + K_CmNtCSDVersion, (ut8 *)&ptr, 8)) {
if (!ctx->read_at_kernel_virtual(ctx->user, ctx->KdDebuggerDataBlock + K_CmNtCSDVersion, buf, sizeof(ut64))) {
RZ_LOG_DEBUG("Failed to read at %" PFMT64x "\n", ctx->KdDebuggerDataBlock + K_CmNtCSDVersion);
return 0;
}
ut64 res;
if (!ctx->read_at_kernel_virtual(ctx->user, ptr, (ut8 *)&res, 8)) {
ut64 ptr = rz_read_le64(buf);
if (!ctx->read_at_kernel_virtual(ctx->user, ptr, buf, sizeof(ut64))) {
RZ_LOG_DEBUG("Failed to read at %" PFMT64x "\n", ptr);
return 0;
}
ut64 res = rz_read_le64(buf);
if (res == UT64_MAX) {
return 0;
}
@ -164,14 +165,14 @@ ut32 winkd_get_target_thread(RZ_BORROW RZ_NONNULL WindCtx *ctx) {
}
ut64 winkd_get_target_base(RZ_BORROW RZ_NONNULL WindCtx *ctx) {
ut64 base = 0;
ut8 tmp[8] = { 0 };
ut64 address = ctx->target.peb + O_(P_ImageBaseAddress);
if (!winkd_read_at_uva(ctx, ctx->target.peb + O_(P_ImageBaseAddress),
(ut8 *)&base, 4 << ctx->is_64bit)) {
if (!winkd_read_at_uva(ctx, address, tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32))) {
return 0;
}
return base;
return rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
}
KdCtx *winkd_kdctx_new(RZ_BORROW RZ_NONNULL io_desc_t *desc) {
@ -389,7 +390,7 @@ int winkd_wait_packet(RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut32 type, RZ_NULLA
void winkd_walk_vadtree(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address, ut64 parent, RzList *out) {
ut8 buf[4];
const ut8 ptr_size = ctx->is_64bit ? 8 : 4;
const ut8 ptr_size = ctx->is_64bit ? sizeof(ut64) : sizeof(ut32);
const ut64 self = address;
const ut64 tag_addr = self - ptr_size - 4;
@ -627,6 +628,7 @@ RzList /*<WindModule *>*/ *winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
if (!ret) {
return NULL;
}
ut8 tmp[8] = { 0 };
ut64 ptr, base;
int list_entry_off = 0;
const bool is_target_kernel = ctx->target.uniqueid <= 4;
@ -635,11 +637,11 @@ RzList /*<WindModule *>*/ *winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
RZ_LOG_ERROR("No PsLoadedModuleList\n");
return ret;
}
ptr = ctx->PsLoadedModuleList;
base = ptr;
if (!ctx->read_at_kernel_virtual(ctx->user, ptr, (ut8 *)&ptr, 4 << ctx->is_64bit)) {
RZ_LOG_ERROR("PsLoadedModuleList not present in mappings\n");
base = ctx->PsLoadedModuleList;
if (!ctx->read_at_kernel_virtual(ctx->user, base, tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32))) {
RZ_LOG_ERROR("PsLoadedModuleList not present in mappings (0x%08" PFMT64x ")\n", base);
}
ptr = rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
if (ptr == base) {
return ret;
}
@ -662,11 +664,12 @@ RzList /*<WindModule *>*/ *winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
// Grab the _PEB_LDR_DATA from PEB
ut64 ldroff = ctx->is_64bit ? 0x18 : 0xC;
if (!winkd_read_at_uva(ctx, ctx->target.peb + ldroff, (ut8 *)&ptr, 4 << ctx->is_64bit)) {
if (!winkd_read_at_uva(ctx, ctx->target.peb + ldroff, tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32))) {
RZ_LOG_ERROR("PEB not present in target mappings\n");
return ret;
}
ptr = rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
RZ_LOG_DEBUG("_PEB_LDR_DATA : 0x%016" PFMT64x "\n", ptr);
// LIST_ENTRY InMemoryOrderModuleList
@ -674,10 +677,11 @@ RzList /*<WindModule *>*/ *winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
base = ptr + mlistoff;
winkd_read_at_uva(ctx, base, (ut8 *)&ptr, 4 << ctx->is_64bit);
winkd_read_at_uva(ctx, base, tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32));
ptr = rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
// Offset of InMemoryOrderLinks inside _LDR_DATA_TABLE_ENTRY
list_entry_off = (4 << ctx->is_64bit) * 2;
list_entry_off = (ctx->is_64bit ? (sizeof(ut64) << 1) : (sizeof(ut32) << 1));
}
RZ_LOG_DEBUG("InMemoryOrderModuleList : 0x%016" PFMT64x "\n", ptr);
@ -691,8 +695,8 @@ RzList /*<WindModule *>*/ *winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
: 0x44;
do {
ut64 next = 0;
read_at_uva_or_kernel(ctx, ptr, (ut8 *)&next, 4 << ctx->is_64bit);
read_at_uva_or_kernel(ctx, ptr, tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32));
ut64 next = rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
RZ_LOG_DEBUG("_%sLDR_DATA_TABLE_ENTRY : 0x%016" PFMT64x "\n", is_target_kernel ? "K" : "", next);
if (!next || next == UT64_MAX) {
@ -706,18 +710,24 @@ RzList /*<WindModule *>*/ *winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
if (!mod) {
break;
}
read_at_uva_or_kernel(ctx, ptr + baseoff, (ut8 *)&mod->addr, 4 << ctx->is_64bit);
read_at_uva_or_kernel(ctx, ptr + sizeoff, (ut8 *)&mod->size, 4);
read_at_uva_or_kernel(ctx, ptr + timestampoff, (ut8 *)&mod->timestamp, 4);
ut16 length;
read_at_uva_or_kernel(ctx, ptr + nameoff, (ut8 *)&length, sizeof(ut16));
read_at_uva_or_kernel(ctx, ptr + baseoff, tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32));
mod->addr = rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
read_at_uva_or_kernel(ctx, ptr + sizeoff, tmp, 4);
mod->size = rz_read_le32(tmp);
read_at_uva_or_kernel(ctx, ptr + timestampoff, tmp, 4);
mod->timestamp = rz_read_le32(tmp);
read_at_uva_or_kernel(ctx, ptr + nameoff, tmp, sizeof(ut16));
ut64 length = rz_read_le16(tmp);
ut64 bufferaddr = 0;
int align = ctx->is_64bit ? sizeof(ut64) : sizeof(ut32);
read_at_uva_or_kernel(ctx, ptr + nameoff + align, (ut8 *)&bufferaddr, 4 << ctx->is_64bit);
read_at_uva_or_kernel(ctx, ptr + nameoff + align, tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32));
ut64 bufferaddr = rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
ut8 *unname = calloc((ut64)length + 2, 1);
ut8 *unname = calloc(length + 2, 1);
if (!unname) {
break;
}
@ -737,6 +747,7 @@ RzList /*<WindModule *>*/ *winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
}
WindThread *winkd_get_thread_at(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address) {
ut8 tmp[8] = { 0 };
int running_offset;
if (ctx->profile->build < 9200) {
running_offset = ctx->is_64bit ? 0x49 : 0x39;
@ -752,18 +763,19 @@ WindThread *winkd_get_thread_at(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address)
RZ_LOG_WARN("KOBJECT at 0x%" PFMT64x " is not a thread.\n", address);
return NULL;
}
ut64 entrypoint = 0;
if (!ctx->read_at_kernel_virtual(ctx->user, address + O_(ET_Win32StartAddress), (ut8 *)&entrypoint, 4 << ctx->is_64bit)) {
if (!ctx->read_at_kernel_virtual(ctx->user, address + O_(ET_Win32StartAddress), tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32))) {
RZ_LOG_WARN("Failed to read Win32StartAddress at: 0x%" PFMT64x "\n", address + O_(ET_Win32StartAddress));
return NULL;
}
ut64 uniqueid = 0;
if (!ctx->read_at_kernel_virtual(ctx->user, address + O_(ET_Cid) + O_(C_UniqueThread), (ut8 *)&uniqueid, 4 << ctx->is_64bit)) {
ut64 entrypoint = rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
if (!ctx->read_at_kernel_virtual(ctx->user, address + O_(ET_Cid) + O_(C_UniqueThread), tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32))) {
RZ_LOG_WARN("Failed to read UniqueThread at: 0x%" PFMT64x "\n", address + O_(ET_Cid) + O_(C_UniqueThread));
return NULL;
}
bool running = false;
if (!ctx->read_at_kernel_virtual(ctx->user, address + running_offset, (ut8 *)&running, 1)) {
ut64 uniqueid = rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
ut8 running = 0;
if (!ctx->read_at_kernel_virtual(ctx->user, address + running_offset, &running, 1)) {
RZ_LOG_WARN("Failed to read KTHREAD.Running at: 0x%" PFMT64x "\n", address + running_offset);
return NULL;
}
@ -780,6 +792,7 @@ WindThread *winkd_get_thread_at(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address)
}
RzList /*<WindThread *>*/ *winkd_list_threads(RZ_BORROW RZ_NONNULL WindCtx *ctx) {
ut8 tmp[8] = { 0 };
RzList *ret;
ut64 ptr, base;
bool current_thread_found = false;
@ -794,7 +807,8 @@ RzList /*<WindThread *>*/ *winkd_list_threads(RZ_BORROW RZ_NONNULL WindCtx *ctx)
}
// Grab the ThreadListHead from _EPROCESS
ctx->read_at_kernel_virtual(ctx->user, ptr + O_(E_ThreadListHead), (ut8 *)&ptr, 4 << ctx->is_64bit);
ctx->read_at_kernel_virtual(ctx->user, ptr + O_(E_ThreadListHead), tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32));
ptr = rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
if (!ptr) {
RZ_LOG_ERROR("No ThreadListHead for target\n");
if (ctx->target_thread.ethread) {
@ -809,9 +823,8 @@ RzList /*<WindThread *>*/ *winkd_list_threads(RZ_BORROW RZ_NONNULL WindCtx *ctx)
ret = rz_list_newf(free);
do {
ut64 next = 0;
ctx->read_at_kernel_virtual(ctx->user, ptr, (ut8 *)&next, 4 << ctx->is_64bit);
ctx->read_at_kernel_virtual(ctx->user, ptr, tmp, ctx->is_64bit ? sizeof(ut64) : sizeof(ut32));
ut64 next = rz_read_ble(tmp, false, ctx->is_64bit ? 64 : 32);
if (!next || next == UT64_MAX) {
RZ_LOG_WARN("Corrupted ThreadListEntry found at: 0x%" PFMT64x "\n", ptr);
break;
@ -861,6 +874,8 @@ bool winkd_va_to_pa(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 directory_table, ut6
ut64 pml4i, pdpi, pdi, pti;
ut64 tmp, mask;
ut8 buf64[sizeof(ut64)] = { 0 };
if (ctx->is_64bit) {
pti = (va >> 12) & 0x1ff;
pdi = (va >> 21) & 0x1ff;
@ -889,27 +904,31 @@ bool winkd_va_to_pa(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 directory_table, ut6
if (ctx->is_64bit) {
// PML4 lookup
if (!ctx->read_at_physical(ctx->user, tmp + pml4i * 8, (ut8 *)&tmp, 8)) {
if (!ctx->read_at_physical(ctx->user, tmp + pml4i * 8, buf64, sizeof(buf64))) {
return false;
}
tmp = rz_read_le64(buf64);
tmp &= mask;
}
if (ctx->is_pae) {
// PDPT lookup
if (!ctx->read_at_physical(ctx->user, tmp + pdpi * 8, (ut8 *)&tmp, 8)) {
if (!ctx->read_at_physical(ctx->user, tmp + pdpi * 8, buf64, sizeof(buf64))) {
return false;
}
tmp = rz_read_le64(buf64);
tmp &= mask;
}
const int read_size = ctx->is_pae ? 8 : 4;
// PDT lookup
if (!ctx->read_at_physical(ctx->user, tmp + pdi * read_size, (ut8 *)&tmp, read_size)) {
if (!ctx->read_at_physical(ctx->user, tmp + pdi * read_size, buf64, read_size)) {
return false;
}
tmp = ctx->is_pae ? rz_read_le64(buf64) : rz_read_le32(buf64);
// Large page entry
// The page size differs between pae and non-pae systems, the former points to 2MB pages while
// the latter points to 4MB pages
@ -920,10 +939,12 @@ bool winkd_va_to_pa(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 directory_table, ut6
}
// PT lookup
if (!ctx->read_at_physical(ctx->user, (tmp & mask) + pti * read_size, (ut8 *)&tmp, read_size)) {
if (!ctx->read_at_physical(ctx->user, (tmp & mask) + pti * read_size, buf64, read_size)) {
return false;
}
tmp = ctx->is_pae ? rz_read_le64(buf64) : rz_read_le32(buf64);
if (tmp & PTE_VALID) {
*pa = (tmp & mask) | (va & 0xfff);
return true;

View file

@ -354,6 +354,7 @@ s rip
e asm.sub.names=false
pi 4
dbt
oml
EOF
EXPECT=<<EOF
DUMP_HEADER64:
@ -407,5 +408,403 @@ int3
2 0xfffff80510c50204 sp: 0xfffff80513568740 776 [??] pdb.ntkrnlmp.KiInitializeKernel+1364
3 0xfffff80510c45219 sp: 0xfffff80513568a50 1448 [??] pdb.ntkrnlmp.KiSystemStartup+521
4 0x0 sp: 0xfffff80513569000 0 [??]
1 fd: 4 +0x0000a038 0x00001000 - 0x00014fff r-- fmap.page.0x1000
2 fd: 4 +0x0001e038 0x00017000 - 0x00018fff r-- fmap.page.0x17000
3 fd: 4 +0x00020038 0x00153000 - 0x00155fff r-- fmap.page.0x153000
4 fd: 4 +0x00023038 0x0018f000 - 0x0018ffff r-- fmap.page.0x18f000
5 fd: 4 +0x00024038 0x001d5000 - 0x001d6fff r-- fmap.page.0x1d5000
6 fd: 4 +0x00026038 0x0020d000 - 0x0020ffff r-- fmap.page.0x20d000
7 fd: 4 +0x00029038 0x00256000 - 0x00258fff r-- fmap.page.0x256000
8 fd: 4 +0x0002c038 0x00281000 - 0x00283fff r-- fmap.page.0x281000
9 fd: 4 +0x0002f038 0x00285000 - 0x00287fff r-- fmap.page.0x285000
10 fd: 4 +0x00032038 0x0029a000 - 0x0029dfff r-- fmap.page.0x29a000
11 fd: 4 +0x00036038 0x002b3000 - 0x002b6fff r-- fmap.page.0x2b3000
12 fd: 4 +0x0003a038 0x00322000 - 0x00324fff r-- fmap.page.0x322000
13 fd: 4 +0x0003d038 0x00361000 - 0x00361fff r-- fmap.page.0x361000
14 fd: 4 +0x0003e038 0x003a2000 - 0x003a2fff r-- fmap.page.0x3a2000
15 fd: 4 +0x0003f038 0x003e0000 - 0x003e1fff r-- fmap.page.0x3e0000
16 fd: 4 +0x00041038 0x0045f000 - 0x0045ffff r-- fmap.page.0x45f000
17 fd: 4 +0x00042038 0x004de000 - 0x004dffff r-- fmap.page.0x4de000
18 fd: 4 +0x00044038 0x0055c000 - 0x0055efff r-- fmap.page.0x55c000
19 fd: 4 +0x00047038 0x005db000 - 0x005dcfff r-- fmap.page.0x5db000
20 fd: 4 +0x00049038 0x00619000 - 0x00619fff r-- fmap.page.0x619000
21 fd: 4 +0x0004a038 0x0065a000 - 0x0065bfff r-- fmap.page.0x65a000
22 fd: 4 +0x0004c038 0x00698000 - 0x00699fff r-- fmap.page.0x698000
23 fd: 4 +0x0004e038 0x006c0000 - 0x006c0fff r-- fmap.page.0x6c0000
24 fd: 4 +0x0004f038 0x006ca000 - 0x006cafff r-- fmap.page.0x6ca000
25 fd: 4 +0x00050038 0x006cc000 - 0x006cdfff r-- fmap.page.0x6cc000
26 fd: 4 +0x00052038 0x006d4000 - 0x006d4fff r-- fmap.page.0x6d4000
27 fd: 4 +0x00053038 0x006d6000 - 0x006d7fff r-- fmap.page.0x6d6000
28 fd: 4 +0x00055038 0x006e1000 - 0x006e2fff r-- fmap.page.0x6e1000
29 fd: 4 +0x00057038 0x006e9000 - 0x006eafff r-- fmap.page.0x6e9000
30 fd: 4 +0x00059038 0x00700000 - 0x00700fff r-- fmap.page.0x700000
31 fd: 4 +0x0005a038 0x00710000 - 0x00715fff r-- fmap.page.0x710000
32 fd: 4 +0x00060038 0x0071a000 - 0x0071dfff r-- fmap.page.0x71a000
33 fd: 4 +0x00064038 0x00752000 - 0x00753fff r-- fmap.page.0x752000
34 fd: 4 +0x00066038 0x00758000 - 0x00760fff r-- fmap.page.0x758000
35 fd: 4 +0x0006f038 0x00763000 - 0x00768fff r-- fmap.page.0x763000
36 fd: 4 +0x00075038 0x0076b000 - 0x0076ffff r-- fmap.page.0x76b000
37 fd: 4 +0x0007a038 0x007b2000 - 0x007b2fff r-- fmap.page.0x7b2000
38 fd: 4 +0x0007b038 0x007b4000 - 0x007b4fff r-- fmap.page.0x7b4000
39 fd: 4 +0x0007c038 0x007bf000 - 0x007c1fff r-- fmap.page.0x7bf000
40 fd: 4 +0x0007f038 0x007d0000 - 0x007d2fff r-- fmap.page.0x7d0000
41 fd: 4 +0x00082038 0x007f3000 - 0x007f3fff r-- fmap.page.0x7f3000
42 fd: 4 +0x00083038 0x00800000 - 0x00800fff r-- fmap.page.0x800000
43 fd: 4 +0x00084038 0x0080b000 - 0x0080bfff r-- fmap.page.0x80b000
44 fd: 4 +0x00085038 0x00810000 - 0x00810fff r-- fmap.page.0x810000
45 fd: 4 +0x00086038 0x00840000 - 0x00840fff r-- fmap.page.0x840000
46 fd: 4 +0x00087038 0x00ba4000 - 0x00ba4fff r-- fmap.page.0xba4000
47 fd: 4 +0x00088038 0x00bbf000 - 0x00bbffff r-- fmap.page.0xbbf000
48 fd: 4 +0x00089038 0x00bd5000 - 0x00bd5fff r-- fmap.page.0xbd5000
49 fd: 4 +0x0008a038 0x00bda000 - 0x00be9fff r-- fmap.page.0xbda000
50 fd: 4 +0x0009a038 0x00bf2000 - 0x00bf2fff r-- fmap.page.0xbf2000
51 fd: 4 +0x0009b038 0x00bf4000 - 0x00bf4fff r-- fmap.page.0xbf4000
52 fd: 4 +0x0009c038 0x00bfa000 - 0x00bfefff r-- fmap.page.0xbfa000
53 fd: 4 +0x000a1038 0x00c13000 - 0x00c14fff r-- fmap.page.0xc13000
54 fd: 4 +0x000a3038 0x00c16000 - 0x00c19fff r-- fmap.page.0xc16000
55 fd: 4 +0x000a7038 0x00c23000 - 0x00c23fff r-- fmap.page.0xc23000
56 fd: 4 +0x000a8038 0x00c27000 - 0x00c27fff r-- fmap.page.0xc27000
57 fd: 4 +0x000a9038 0x00c2a000 - 0x00c36fff r-- fmap.page.0xc2a000
58 fd: 4 +0x000b6038 0x00c3a000 - 0x00c3afff r-- fmap.page.0xc3a000
59 fd: 4 +0x000b7038 0x00c40000 - 0x00c41fff r-- fmap.page.0xc40000
60 fd: 4 +0x000b9038 0x00c47000 - 0x00c52fff r-- fmap.page.0xc47000
61 fd: 4 +0x000c5038 0x00c63000 - 0x00c63fff r-- fmap.page.0xc63000
62 fd: 4 +0x000c6038 0x00c6b000 - 0x00c6efff r-- fmap.page.0xc6b000
63 fd: 4 +0x000ca038 0x00c70000 - 0x00c71fff r-- fmap.page.0xc70000
64 fd: 4 +0x000cc038 0x00c75000 - 0x00c79fff r-- fmap.page.0xc75000
65 fd: 4 +0x000d1038 0x00c80000 - 0x00c86fff r-- fmap.page.0xc80000
66 fd: 4 +0x000d8038 0x00c8c000 - 0x00c8dfff r-- fmap.page.0xc8c000
67 fd: 4 +0x000da038 0x00cb7000 - 0x00cb8fff r-- fmap.page.0xcb7000
68 fd: 4 +0x000dc038 0x00cc0000 - 0x00cc6fff r-- fmap.page.0xcc0000
69 fd: 4 +0x000e3038 0x00ccc000 - 0x00cccfff r-- fmap.page.0xccc000
70 fd: 4 +0x000e4038 0x00ccf000 - 0x00ccffff r-- fmap.page.0xccf000
71 fd: 4 +0x000e5038 0x00d0c000 - 0x00d0cfff r-- fmap.page.0xd0c000
72 fd: 4 +0x000e6038 0x00d2a000 - 0x00d2bfff r-- fmap.page.0xd2a000
73 fd: 4 +0x000e8038 0x00d68000 - 0x00d69fff r-- fmap.page.0xd68000
74 fd: 4 +0x000ea038 0x00daa000 - 0x00daafff r-- fmap.page.0xdaa000
75 fd: 4 +0x000eb038 0x00de7000 - 0x00de8fff r-- fmap.page.0xde7000
76 fd: 4 +0x000ed038 0x00e65000 - 0x00e67fff r-- fmap.page.0xe65000
77 fd: 4 +0x000f0038 0x00ee5000 - 0x00ee5fff r-- fmap.page.0xee5000
78 fd: 4 +0x000f1038 0x00f2d000 - 0x00f2efff r-- fmap.page.0xf2d000
79 fd: 4 +0x000f3038 0x00fab000 - 0x00fadfff r-- fmap.page.0xfab000
80 fd: 4 +0x000f6038 0x01000000 - 0x01207fff r-- fmap.page.0x1000000
81 fd: 4 +0x002fe038 0x0122e000 - 0x0122ffff r-- fmap.page.0x122e000
82 fd: 4 +0x00300038 0x012f0000 - 0x012f0fff r-- fmap.page.0x12f0000
83 fd: 4 +0x00301038 0x01333000 - 0x01333fff r-- fmap.page.0x1333000
84 fd: 4 +0x00302038 0x01370000 - 0x01371fff r-- fmap.page.0x1370000
85 fd: 4 +0x00304038 0x01386000 - 0x013a3fff r-- fmap.page.0x1386000
86 fd: 4 +0x00322038 0x013a8000 - 0x013b3fff r-- fmap.page.0x13a8000
87 fd: 4 +0x0032e038 0x013b6000 - 0x013bafff r-- fmap.page.0x13b6000
88 fd: 4 +0x00333038 0x013db000 - 0x013fdfff r-- fmap.page.0x13db000
89 fd: 4 +0x00356038 0x0143c000 - 0x0143dfff r-- fmap.page.0x143c000
90 fd: 4 +0x00358038 0x0147a000 - 0x0147afff r-- fmap.page.0x147a000
91 fd: 4 +0x00359038 0x014bb000 - 0x014bcfff r-- fmap.page.0x14bb000
92 fd: 4 +0x0035b038 0x014fa000 - 0x014fafff r-- fmap.page.0x14fa000
93 fd: 4 +0x0035c038 0x01539000 - 0x01539fff r-- fmap.page.0x1539000
94 fd: 4 +0x0035d038 0x015b6000 - 0x015b9fff r-- fmap.page.0x15b6000
95 fd: 4 +0x00361038 0x01634000 - 0x01634fff r-- fmap.page.0x1634000
96 fd: 4 +0x00362038 0x01636000 - 0x01637fff r-- fmap.page.0x1636000
97 fd: 4 +0x00364038 0x01675000 - 0x01675fff r-- fmap.page.0x1675000
98 fd: 4 +0x00365038 0x016b2000 - 0x016b4fff r-- fmap.page.0x16b2000
99 fd: 4 +0x00368038 0x016f1000 - 0x016f1fff r-- fmap.page.0x16f1000
100 fd: 4 +0x00369038 0x01700000 - 0x01706fff r-- fmap.page.0x1700000
101 fd: 4 +0x00370038 0x01710000 - 0x01718fff r-- fmap.page.0x1710000
102 fd: 4 +0x00379038 0x0171a000 - 0x0171dfff r-- fmap.page.0x171a000
103 fd: 4 +0x0037d038 0x01720000 - 0x01724fff r-- fmap.page.0x1720000
104 fd: 4 +0x00382038 0x01726000 - 0x01726fff r-- fmap.page.0x1726000
105 fd: 4 +0x00383038 0x01728000 - 0x0172ffff r-- fmap.page.0x1728000
106 fd: 4 +0x0038b038 0x0173f000 - 0x01742fff r-- fmap.page.0x173f000
107 fd: 4 +0x0038f038 0x01744000 - 0x01745fff r-- fmap.page.0x1744000
108 fd: 4 +0x00391038 0x01750000 - 0x01754fff r-- fmap.page.0x1750000
109 fd: 4 +0x00396038 0x01757000 - 0x01758fff r-- fmap.page.0x1757000
110 fd: 4 +0x00398038 0x0175a000 - 0x0175dfff r-- fmap.page.0x175a000
111 fd: 4 +0x0039c038 0x01760000 - 0x01764fff r-- fmap.page.0x1760000
112 fd: 4 +0x003a1038 0x01767000 - 0x01767fff r-- fmap.page.0x1767000
113 fd: 4 +0x003a2038 0x01769000 - 0x01770fff r-- fmap.page.0x1769000
114 fd: 4 +0x003aa038 0x01772000 - 0x01773fff r-- fmap.page.0x1772000
115 fd: 4 +0x003ac038 0x01780000 - 0x01782fff r-- fmap.page.0x1780000
116 fd: 4 +0x003af038 0x01784000 - 0x01784fff r-- fmap.page.0x1784000
117 fd: 4 +0x003b0038 0x01791000 - 0x01794fff r-- fmap.page.0x1791000
118 fd: 4 +0x003b4038 0x0179b000 - 0x0179dfff r-- fmap.page.0x179b000
119 fd: 4 +0x003b7038 0x017a0000 - 0x017a3fff r-- fmap.page.0x17a0000
120 fd: 4 +0x003bb038 0x017a7000 - 0x017a7fff r-- fmap.page.0x17a7000
121 fd: 4 +0x003bc038 0x017aa000 - 0x017aafff r-- fmap.page.0x17aa000
122 fd: 4 +0x003bd038 0x017ac000 - 0x017adfff r-- fmap.page.0x17ac000
123 fd: 4 +0x003bf038 0x017bd000 - 0x017bdfff r-- fmap.page.0x17bd000
124 fd: 4 +0x003c0038 0x017bf000 - 0x017c1fff r-- fmap.page.0x17bf000
125 fd: 4 +0x003c3038 0x017fe000 - 0x017fefff r-- fmap.page.0x17fe000
126 fd: 4 +0x003c4038 0x01800000 - 0x02ed4fff r-- fmap.page.0x1800000
127 fd: 4 +0x01a99038 0x02ee0000 - 0x02ee1fff r-- fmap.page.0x2ee0000
128 fd: 4 +0x01a9b038 0x02ee5000 - 0x02ee7fff r-- fmap.page.0x2ee5000
129 fd: 4 +0x01a9e038 0x02ee9000 - 0x02eeafff r-- fmap.page.0x2ee9000
130 fd: 4 +0x01aa0038 0x02eec000 - 0x02eeffff r-- fmap.page.0x2eec000
131 fd: 4 +0x01aa4038 0x02ef3000 - 0x02f07fff r-- fmap.page.0x2ef3000
132 fd: 4 +0x01ab9038 0x02f10000 - 0x02f20fff r-- fmap.page.0x2f10000
133 fd: 4 +0x01aca038 0x02f22000 - 0x02f22fff r-- fmap.page.0x2f22000
134 fd: 4 +0x01acb038 0x02f25000 - 0x02f25fff r-- fmap.page.0x2f25000
135 fd: 4 +0x01acc038 0x02f28000 - 0x02f28fff r-- fmap.page.0x2f28000
136 fd: 4 +0x01acd038 0x02f2a000 - 0x02f2afff r-- fmap.page.0x2f2a000
137 fd: 4 +0x01ace038 0x02f2c000 - 0x02f2cfff r-- fmap.page.0x2f2c000
138 fd: 4 +0x01acf038 0x02f2e000 - 0x02f40fff r-- fmap.page.0x2f2e000
139 fd: 4 +0x01ae2038 0x02f42000 - 0x02f43fff r-- fmap.page.0x2f42000
140 fd: 4 +0x01ae4038 0x02f50000 - 0x02f51fff r-- fmap.page.0x2f50000
141 fd: 4 +0x01ae6038 0x02f53000 - 0x02f53fff r-- fmap.page.0x2f53000
142 fd: 4 +0x01ae7038 0x02f55000 - 0x02f55fff r-- fmap.page.0x2f55000
143 fd: 4 +0x01ae8038 0x02f57000 - 0x02f65fff r-- fmap.page.0x2f57000
144 fd: 4 +0x01af7038 0x02f67000 - 0x02f67fff r-- fmap.page.0x2f67000
145 fd: 4 +0x01af8038 0x02f69000 - 0x02f6bfff r-- fmap.page.0x2f69000
146 fd: 4 +0x01afb038 0x02f6d000 - 0x02f6dfff r-- fmap.page.0x2f6d000
147 fd: 4 +0x01afc038 0x02f71000 - 0x02f73fff r-- fmap.page.0x2f71000
148 fd: 4 +0x01aff038 0x02f76000 - 0x02f76fff r-- fmap.page.0x2f76000
149 fd: 4 +0x01b00038 0x02f81000 - 0x02f81fff r-- fmap.page.0x2f81000
150 fd: 4 +0x01b01038 0x02f90000 - 0x02f91fff r-- fmap.page.0x2f90000
151 fd: 4 +0x01b03038 0x02f95000 - 0x02f9bfff r-- fmap.page.0x2f95000
152 fd: 4 +0x01b0a038 0x02f9d000 - 0x02fa3fff r-- fmap.page.0x2f9d000
153 fd: 4 +0x01b11038 0x02fa5000 - 0x02fa7fff r-- fmap.page.0x2fa5000
154 fd: 4 +0x01b14038 0x02faa000 - 0x02fadfff r-- fmap.page.0x2faa000
155 fd: 4 +0x01b18038 0x02fb0000 - 0x02fb3fff r-- fmap.page.0x2fb0000
156 fd: 4 +0x01b1c038 0x02fb6000 - 0x02fb6fff r-- fmap.page.0x2fb6000
157 fd: 4 +0x01b1d038 0x02fc0000 - 0x02fc0fff r-- fmap.page.0x2fc0000
158 fd: 4 +0x01b1e038 0x02fc2000 - 0x02fc2fff r-- fmap.page.0x2fc2000
159 fd: 4 +0x01b1f038 0x02fd0000 - 0x02fd1fff r-- fmap.page.0x2fd0000
160 fd: 4 +0x01b21038 0x02fd4000 - 0x02fdefff r-- fmap.page.0x2fd4000
161 fd: 4 +0x01b2c038 0x02fe1000 - 0x02fe6fff r-- fmap.page.0x2fe1000
162 fd: 4 +0x01b32038 0x02fe8000 - 0x02fecfff r-- fmap.page.0x2fe8000
163 fd: 4 +0x01b37038 0x02fef000 - 0x02ff0fff r-- fmap.page.0x2fef000
164 fd: 4 +0x01b39038 0x02ff2000 - 0x02ff3fff r-- fmap.page.0x2ff2000
165 fd: 4 +0x01b3b038 0x03000000 - 0x0300bfff r-- fmap.page.0x3000000
166 fd: 4 +0x01b47038 0x03010000 - 0x03058fff r-- fmap.page.0x3010000
167 fd: 4 +0x01b90038 0x03060000 - 0x03060fff r-- fmap.page.0x3060000
168 fd: 4 +0x01b91038 0x03092000 - 0x03092fff r-- fmap.page.0x3092000
169 fd: 4 +0x01b92038 0x03094000 - 0x03094fff r-- fmap.page.0x3094000
170 fd: 4 +0x01b93038 0x030c4000 - 0x030c4fff r-- fmap.page.0x30c4000
171 fd: 4 +0x01b94038 0x03180000 - 0x03180fff r-- fmap.page.0x3180000
172 fd: 4 +0x01b95038 0x031c0000 - 0x031c0fff r-- fmap.page.0x31c0000
173 fd: 4 +0x01b96038 0x03261000 - 0x03261fff r-- fmap.page.0x3261000
174 fd: 4 +0x01b97038 0x036c8000 - 0x036cafff r-- fmap.page.0x36c8000
175 fd: 4 +0x01b9a038 0x03747000 - 0x03748fff r-- fmap.page.0x3747000
176 fd: 4 +0x01b9c038 0x037c5000 - 0x037c7fff r-- fmap.page.0x37c5000
177 fd: 4 +0x01b9f038 0x03800000 - 0x03808fff r-- fmap.page.0x3800000
178 fd: 4 +0x01ba8038 0x0380f000 - 0x03810fff r-- fmap.page.0x380f000
179 fd: 4 +0x01baa038 0x03812000 - 0x03812fff r-- fmap.page.0x3812000
180 fd: 4 +0x01bab038 0x03815000 - 0x0381dfff r-- fmap.page.0x3815000
181 fd: 4 +0x01bb4038 0x03820000 - 0x03820fff r-- fmap.page.0x3820000
182 fd: 4 +0x01bb5038 0x03826000 - 0x03826fff r-- fmap.page.0x3826000
183 fd: 4 +0x01bb6038 0x03828000 - 0x0382afff r-- fmap.page.0x3828000
184 fd: 4 +0x01bb9038 0x0382c000 - 0x0382cfff r-- fmap.page.0x382c000
185 fd: 4 +0x01bba038 0x0382e000 - 0x0382efff r-- fmap.page.0x382e000
186 fd: 4 +0x01bbb038 0x03830000 - 0x03830fff r-- fmap.page.0x3830000
187 fd: 4 +0x01bbc038 0x03832000 - 0x03835fff r-- fmap.page.0x3832000
188 fd: 4 +0x01bc0038 0x03837000 - 0x0383ffff r-- fmap.page.0x3837000
189 fd: 4 +0x01bc9038 0x03843000 - 0x03845fff r-- fmap.page.0x3843000
190 fd: 4 +0x01bcc038 0x0389e000 - 0x0389ffff r-- fmap.page.0x389e000
191 fd: 4 +0x01bce038 0x0391d000 - 0x0391efff r-- fmap.page.0x391d000
192 fd: 4 +0x01bd0038 0x0399b000 - 0x0399dfff r-- fmap.page.0x399b000
193 fd: 4 +0x01bd3038 0x03a1b000 - 0x03a1bfff r-- fmap.page.0x3a1b000
194 fd: 4 +0x01bd4038 0x03a5a000 - 0x03a5afff r-- fmap.page.0x3a5a000
195 fd: 4 +0x01bd5038 0x03a98000 - 0x03a99fff r-- fmap.page.0x3a98000
196 fd: 4 +0x01bd7038 0x03ada000 - 0x03adafff r-- fmap.page.0x3ada000
197 fd: 4 +0x01bd8038 0x03b17000 - 0x03b18fff r-- fmap.page.0x3b17000
198 fd: 4 +0x01bda038 0x03b55000 - 0x03b55fff r-- fmap.page.0x3b55000
199 fd: 4 +0x01bdb038 0x03b96000 - 0x03b97fff r-- fmap.page.0x3b96000
200 fd: 4 +0x01bdd038 0x03bd4000 - 0x03bd5fff r-- fmap.page.0x3bd4000
201 fd: 4 +0x01bdf038 0x03c54000 - 0x03c54fff r-- fmap.page.0x3c54000
202 fd: 4 +0x01be0038 0x03c92000 - 0x03c93fff r-- fmap.page.0x3c92000
203 fd: 4 +0x01be2038 0x03d0a000 - 0x03d0cfff r-- fmap.page.0x3d0a000
204 fd: 4 +0x01be5038 0x03d0f000 - 0x03d0ffff r-- fmap.page.0x3d0f000
205 fd: 4 +0x01be6038 0x03d11000 - 0x03d12fff r-- fmap.page.0x3d11000
206 fd: 4 +0x01be8038 0x03d46000 - 0x03d46fff r-- fmap.page.0x3d46000
207 fd: 4 +0x01be9038 0x03d48000 - 0x03d4cfff r-- fmap.page.0x3d48000
208 fd: 4 +0x01bee038 0x03d4e000 - 0x03d4efff r-- fmap.page.0x3d4e000
209 fd: 4 +0x01bef038 0x03d81000 - 0x03d81fff r-- fmap.page.0x3d81000
210 fd: 4 +0x01bf0038 0x03d83000 - 0x03d84fff r-- fmap.page.0x3d83000
211 fd: 4 +0x01bf2038 0x03d89000 - 0x03d8afff r-- fmap.page.0x3d89000
212 fd: 4 +0x01bf4038 0x03d8c000 - 0x03d8efff r-- fmap.page.0x3d8c000
213 fd: 4 +0x01bf7038 0x03d90000 - 0x03d91fff r-- fmap.page.0x3d90000
214 fd: 4 +0x01bf9038 0x03dcf000 - 0x03dcffff r-- fmap.page.0x3dcf000
215 fd: 4 +0x01bfa038 0x03e01000 - 0x03e01fff r-- fmap.page.0x3e01000
216 fd: 4 +0x01bfb038 0x03e04000 - 0x03e04fff r-- fmap.page.0x3e04000
217 fd: 4 +0x01bfc038 0x03e06000 - 0x03e07fff r-- fmap.page.0x3e06000
218 fd: 4 +0x01bfe038 0x03e09000 - 0x03e09fff r-- fmap.page.0x3e09000
219 fd: 4 +0x01bff038 0x03e0c000 - 0x03e0efff r-- fmap.page.0x3e0c000
220 fd: 4 +0x01c02038 0x03e4e000 - 0x03e4ffff r-- fmap.page.0x3e4e000
221 fd: 4 +0x01c04038 0x03e8c000 - 0x03e8cfff r-- fmap.page.0x3e8c000
222 fd: 4 +0x01c05038 0x03ecd000 - 0x03ecefff r-- fmap.page.0x3ecd000
223 fd: 4 +0x01c07038 0x03f0b000 - 0x03f0cfff r-- fmap.page.0x3f0b000
224 fd: 4 +0x01c09038 0x03f41000 - 0x03f41fff r-- fmap.page.0x3f41000
225 fd: 4 +0x01c0a038 0x03f44000 - 0x03f46fff r-- fmap.page.0x3f44000
226 fd: 4 +0x01c0d038 0x03f48000 - 0x03f49fff r-- fmap.page.0x3f48000
227 fd: 4 +0x01c0f038 0x03f4c000 - 0x03f4cfff r-- fmap.page.0x3f4c000
228 fd: 4 +0x01c10038 0x03f4e000 - 0x03f4efff r-- fmap.page.0x3f4e000
229 fd: 4 +0x01c11038 0x03f8b000 - 0x03f8bfff r-- fmap.page.0x3f8b000
230 fd: 4 +0x01c12038 0x03fc9000 - 0x03fcafff r-- fmap.page.0x3fc9000
231 fd: 4 +0x01c14038 0x03ff7000 - 0x03ff7fff r-- fmap.page.0x3ff7000
232 fd: 4 +0x01c15038 0x04001000 - 0x04006fff r-- fmap.page.0x4001000
233 fd: 4 +0x01c1b038 0x04008000 - 0x0400ffff r-- fmap.page.0x4008000
234 fd: 4 +0x01c23038 0x04035000 - 0x04035fff r-- fmap.page.0x4035000
235 fd: 4 +0x01c24038 0x04037000 - 0x04037fff r-- fmap.page.0x4037000
236 fd: 4 +0x01c25038 0x04039000 - 0x0403bfff r-- fmap.page.0x4039000
237 fd: 4 +0x01c28038 0x0403f000 - 0x0403ffff r-- fmap.page.0x403f000
238 fd: 4 +0x01c29038 0x04048000 - 0x04049fff r-- fmap.page.0x4048000
239 fd: 4 +0x01c2b038 0x04074000 - 0x04075fff r-- fmap.page.0x4074000
240 fd: 4 +0x01c2d038 0x0407a000 - 0x0407bfff r-- fmap.page.0x407a000
241 fd: 4 +0x01c2f038 0x0407e000 - 0x0407ffff r-- fmap.page.0x407e000
242 fd: 4 +0x01c31038 0x04087000 - 0x04087fff r-- fmap.page.0x4087000
243 fd: 4 +0x01c32038 0x04099000 - 0x04099fff r-- fmap.page.0x4099000
244 fd: 4 +0x01c33038 0x0409f000 - 0x0409ffff r-- fmap.page.0x409f000
245 fd: 4 +0x01c34038 0x040b1000 - 0x040b1fff r-- fmap.page.0x40b1000
246 fd: 4 +0x01c35038 0x040b4000 - 0x040b4fff r-- fmap.page.0x40b4000
247 fd: 4 +0x01c36038 0x040b8000 - 0x040bbfff r-- fmap.page.0x40b8000
248 fd: 4 +0x01c3a038 0x040bd000 - 0x040bdfff r-- fmap.page.0x40bd000
249 fd: 4 +0x01c3b038 0x040bf000 - 0x040bffff r-- fmap.page.0x40bf000
250 fd: 4 +0x01c3c038 0x040c6000 - 0x040c6fff r-- fmap.page.0x40c6000
251 fd: 4 +0x01c3d038 0x040c8000 - 0x040c8fff r-- fmap.page.0x40c8000
252 fd: 4 +0x01c3e038 0x040d5000 - 0x040d6fff r-- fmap.page.0x40d5000
253 fd: 4 +0x01c40038 0x040d9000 - 0x040d9fff r-- fmap.page.0x40d9000
254 fd: 4 +0x01c41038 0x040f1000 - 0x040f1fff r-- fmap.page.0x40f1000
255 fd: 4 +0x01c42038 0x040f4000 - 0x040f8fff r-- fmap.page.0x40f4000
256 fd: 4 +0x01c47038 0x040fa000 - 0x040fffff r-- fmap.page.0x40fa000
257 fd: 4 +0x01c4d038 0x04101000 - 0x04104fff r-- fmap.page.0x4101000
258 fd: 4 +0x01c51038 0x04106000 - 0x0410bfff r-- fmap.page.0x4106000
259 fd: 4 +0x01c57038 0x0410d000 - 0x0410ffff r-- fmap.page.0x410d000
260 fd: 4 +0x01c5a038 0x04115000 - 0x04115fff r-- fmap.page.0x4115000
261 fd: 4 +0x01c5b038 0x04117000 - 0x04119fff r-- fmap.page.0x4117000
262 fd: 4 +0x01c5e038 0x0411b000 - 0x0411bfff r-- fmap.page.0x411b000
263 fd: 4 +0x01c5f038 0x0411d000 - 0x0411efff r-- fmap.page.0x411d000
264 fd: 4 +0x01c61038 0x04128000 - 0x04128fff r-- fmap.page.0x4128000
265 fd: 4 +0x01c62038 0x0412a000 - 0x0412afff r-- fmap.page.0x412a000
266 fd: 4 +0x01c63038 0x04131000 - 0x04133fff r-- fmap.page.0x4131000
267 fd: 4 +0x01c66038 0x04137000 - 0x0413afff r-- fmap.page.0x4137000
268 fd: 4 +0x01c6a038 0x0413c000 - 0x0413dfff r-- fmap.page.0x413c000
269 fd: 4 +0x01c6c038 0x0413f000 - 0x0413ffff r-- fmap.page.0x413f000
270 fd: 4 +0x01c6d038 0x04146000 - 0x04146fff r-- fmap.page.0x4146000
271 fd: 4 +0x01c6e038 0x04154000 - 0x04155fff r-- fmap.page.0x4154000
272 fd: 4 +0x01c70038 0x04157000 - 0x04159fff r-- fmap.page.0x4157000
273 fd: 4 +0x01c73038 0x0415b000 - 0x0415bfff r-- fmap.page.0x415b000
274 fd: 4 +0x01c74038 0x0415d000 - 0x0415efff r-- fmap.page.0x415d000
275 fd: 4 +0x01c76038 0x04160000 - 0x04160fff r-- fmap.page.0x4160000
276 fd: 4 +0x01c77038 0x0416a000 - 0x0416afff r-- fmap.page.0x416a000
277 fd: 4 +0x01c78038 0x0416f000 - 0x0416ffff r-- fmap.page.0x416f000
278 fd: 4 +0x01c79038 0x04171000 - 0x04171fff r-- fmap.page.0x4171000
279 fd: 4 +0x01c7a038 0x04173000 - 0x04174fff r-- fmap.page.0x4173000
280 fd: 4 +0x01c7c038 0x04178000 - 0x04178fff r-- fmap.page.0x4178000
281 fd: 4 +0x01c7d038 0x0417a000 - 0x0417cfff r-- fmap.page.0x417a000
282 fd: 4 +0x01c80038 0x0417e000 - 0x0417ffff r-- fmap.page.0x417e000
283 fd: 4 +0x01c82038 0x04185000 - 0x04185fff r-- fmap.page.0x4185000
284 fd: 4 +0x01c83038 0x04190000 - 0x04190fff r-- fmap.page.0x4190000
285 fd: 4 +0x01c84038 0x04192000 - 0x04192fff r-- fmap.page.0x4192000
286 fd: 4 +0x01c85038 0x04194000 - 0x04194fff r-- fmap.page.0x4194000
287 fd: 4 +0x01c86038 0x04197000 - 0x04197fff r-- fmap.page.0x4197000
288 fd: 4 +0x01c87038 0x04199000 - 0x0419afff r-- fmap.page.0x4199000
289 fd: 4 +0x01c89038 0x0419c000 - 0x0419dfff r-- fmap.page.0x419c000
290 fd: 4 +0x01c8b038 0x0419f000 - 0x041a0fff r-- fmap.page.0x419f000
291 fd: 4 +0x01c8d038 0x041a2000 - 0x041a2fff r-- fmap.page.0x41a2000
292 fd: 4 +0x01c8e038 0x041a4000 - 0x041a4fff r-- fmap.page.0x41a4000
293 fd: 4 +0x01c8f038 0x041a8000 - 0x041a8fff r-- fmap.page.0x41a8000
294 fd: 4 +0x01c90038 0x041aa000 - 0x041abfff r-- fmap.page.0x41aa000
295 fd: 4 +0x01c92038 0x041ae000 - 0x041aefff r-- fmap.page.0x41ae000
296 fd: 4 +0x01c93038 0x041b0000 - 0x041b1fff r-- fmap.page.0x41b0000
297 fd: 4 +0x01c95038 0x041b3000 - 0x041b3fff r-- fmap.page.0x41b3000
298 fd: 4 +0x01c96038 0x041b6000 - 0x041bdfff r-- fmap.page.0x41b6000
299 fd: 4 +0x01c9e038 0x041bf000 - 0x041c2fff r-- fmap.page.0x41bf000
300 fd: 4 +0x01ca2038 0x041c4000 - 0x041c4fff r-- fmap.page.0x41c4000
301 fd: 4 +0x01ca3038 0x041c6000 - 0x041c8fff r-- fmap.page.0x41c6000
302 fd: 4 +0x01ca6038 0x041cb000 - 0x041cbfff r-- fmap.page.0x41cb000
303 fd: 4 +0x01ca7038 0x041ce000 - 0x041cffff r-- fmap.page.0x41ce000
304 fd: 4 +0x01ca9038 0x04265000 - 0x04266fff r-- fmap.page.0x4265000
305 fd: 4 +0x01cab038 0x042a4000 - 0x042a4fff r-- fmap.page.0x42a4000
306 fd: 4 +0x01cac038 0x042e1000 - 0x042e1fff r-- fmap.page.0x42e1000
307 fd: 4 +0x01cad038 0x042e3000 - 0x042e3fff r-- fmap.page.0x42e3000
308 fd: 4 +0x01cae038 0x04324000 - 0x04324fff r-- fmap.page.0x4324000
309 fd: 4 +0x01caf038 0x04360000 - 0x04363fff r-- fmap.page.0x4360000
310 fd: 4 +0x01cb3038 0x043e0000 - 0x043e0fff r-- fmap.page.0x43e0000
311 fd: 4 +0x01cb4038 0x04429000 - 0x04429fff r-- fmap.page.0x4429000
312 fd: 4 +0x01cb5038 0x0446a000 - 0x0446afff r-- fmap.page.0x446a000
313 fd: 4 +0x01cb6038 0x044a8000 - 0x044a9fff r-- fmap.page.0x44a8000
314 fd: 4 +0x01cb8038 0x044e7000 - 0x044e7fff r-- fmap.page.0x44e7000
315 fd: 4 +0x01cb9038 0x04566000 - 0x04567fff r-- fmap.page.0x4566000
316 fd: 4 +0x01cbb038 0x045ea000 - 0x045ecfff r-- fmap.page.0x45ea000
317 fd: 4 +0x01cbe038 0x04670000 - 0x04670fff r-- fmap.page.0x4670000
318 fd: 4 +0x01cbf038 0x046ef000 - 0x046effff r-- fmap.page.0x46ef000
319 fd: 4 +0x01cc0038 0x0476d000 - 0x0476ffff r-- fmap.page.0x476d000
320 fd: 4 +0x01cc3038 0x047ec000 - 0x047edfff r-- fmap.page.0x47ec000
321 fd: 4 +0x01cc5038 0x04844000 - 0x04845fff r-- fmap.page.0x4844000
322 fd: 4 +0x01cc7038 0x048c2000 - 0x048c4fff r-- fmap.page.0x48c2000
323 fd: 4 +0x01cca038 0x04941000 - 0x04942fff r-- fmap.page.0x4941000
324 fd: 4 +0x01ccc038 0x049c0000 - 0x049c1fff r-- fmap.page.0x49c0000
325 fd: 4 +0x01cce038 0x04a7f000 - 0x04a7ffff r-- fmap.page.0x4a7f000
326 fd: 4 +0x01ccf038 0x04afe000 - 0x04afffff r-- fmap.page.0x4afe000
327 fd: 4 +0x01cd1038 0x04b7c000 - 0x04b7efff r-- fmap.page.0x4b7c000
328 fd: 4 +0x01cd4038 0x04bfb000 - 0x04bfcfff r-- fmap.page.0x4bfb000
329 fd: 4 +0x01cd6038 0x04c79000 - 0x04c7bfff r-- fmap.page.0x4c79000
330 fd: 4 +0x01cd9038 0x04cf8000 - 0x04cf9fff r-- fmap.page.0x4cf8000
331 fd: 4 +0x01cdb038 0x04d76000 - 0x04d78fff r-- fmap.page.0x4d76000
332 fd: 4 +0x01cde038 0x04df5000 - 0x04df6fff r-- fmap.page.0x4df5000
333 fd: 4 +0x01ce0038 0x04e70000 - 0x04e72fff r-- fmap.page.0x4e70000
334 fd: 4 +0x01ce3038 0x04eaf000 - 0x04eaffff r-- fmap.page.0x4eaf000
335 fd: 4 +0x01ce4038 0x04ef0000 - 0x04ef0fff r-- fmap.page.0x4ef0000
336 fd: 4 +0x01ce5038 0x04f73000 - 0x04f75fff r-- fmap.page.0x4f73000
337 fd: 4 +0x01ce8038 0x04ff3000 - 0x04ff3fff r-- fmap.page.0x4ff3000
338 fd: 4 +0x01ce9038 0x05032000 - 0x05032fff r-- fmap.page.0x5032000
339 fd: 4 +0x01cea038 0x050ad000 - 0x050affff r-- fmap.page.0x50ad000
340 fd: 4 +0x01ced038 0x0512c000 - 0x0512dfff r-- fmap.page.0x512c000
341 fd: 4 +0x01cef038 0x051aa000 - 0x051acfff r-- fmap.page.0x51aa000
342 fd: 4 +0x01cf2038 0x05222000 - 0x05223fff r-- fmap.page.0x5222000
343 fd: 4 +0x01cf4038 0x05261000 - 0x05261fff r-- fmap.page.0x5261000
344 fd: 4 +0x01cf5038 0x0529d000 - 0x0529ffff r-- fmap.page.0x529d000
345 fd: 4 +0x01cf8038 0x052e0000 - 0x052e1fff r-- fmap.page.0x52e0000
346 fd: 4 +0x01cfa038 0x0531c000 - 0x0531dfff r-- fmap.page.0x531c000
347 fd: 4 +0x01cfc038 0x05360000 - 0x05360fff r-- fmap.page.0x5360000
348 fd: 4 +0x01cfd038 0x0539a000 - 0x0539cfff r-- fmap.page.0x539a000
349 fd: 4 +0x01d00038 0x05869000 - 0x0586afff r-- fmap.page.0x5869000
350 fd: 4 +0x01d02038 0x058e7000 - 0x058e9fff r-- fmap.page.0x58e7000
351 fd: 4 +0x01d05038 0x05966000 - 0x05967fff r-- fmap.page.0x5966000
352 fd: 4 +0x01d07038 0x059e4000 - 0x059e6fff r-- fmap.page.0x59e4000
353 fd: 4 +0x01d0a038 0x05a63000 - 0x05a64fff r-- fmap.page.0x5a63000
354 fd: 4 +0x01d0c038 0x05b19000 - 0x05b1afff r-- fmap.page.0x5b19000
355 fd: 4 +0x01d0e038 0x05b97000 - 0x05b99fff r-- fmap.page.0x5b97000
356 fd: 4 +0x01d11038 0x05c16000 - 0x05c17fff r-- fmap.page.0x5c16000
357 fd: 4 +0x01d13038 0x05c94000 - 0x05c96fff r-- fmap.page.0x5c94000
358 fd: 4 +0x01d16038 0x05d13000 - 0x05d14fff r-- fmap.page.0x5d13000
359 fd: 4 +0x01d18038 0x05d91000 - 0x05d93fff r-- fmap.page.0x5d91000
360 fd: 4 +0x01d1b038 0x05e11000 - 0x05e11fff r-- fmap.page.0x5e11000
361 fd: 4 +0x01d1c038 0x05e3f000 - 0x05e3ffff r-- fmap.page.0x5e3f000
362 fd: 4 +0x01d1d038 0x05e50000 - 0x05e50fff r-- fmap.page.0x5e50000
363 fd: 4 +0x01d1e038 0x05e8e000 - 0x05e8ffff r-- fmap.page.0x5e8e000
364 fd: 4 +0x01d20038 0x05ed0000 - 0x05ed0fff r-- fmap.page.0x5ed0000
365 fd: 4 +0x01d21038 0x05f0d000 - 0x05f0efff r-- fmap.page.0x5f0d000
366 fd: 4 +0x01d23038 0x05f8b000 - 0x05f8dfff r-- fmap.page.0x5f8b000
367 fd: 4 +0x01d26038 0x0600a000 - 0x0600bfff r-- fmap.page.0x600a000
368 fd: 4 +0x01d28038 0x06088000 - 0x0608afff r-- fmap.page.0x6088000
369 fd: 4 +0x01d2b038 0x06107000 - 0x06108fff r-- fmap.page.0x6107000
370 fd: 4 +0x01d2d038 0x06185000 - 0x06187fff r-- fmap.page.0x6185000
371 fd: 4 +0x01d30038 0x061c2000 - 0x061c4fff r-- fmap.page.0x61c2000
372 fd: 4 +0x01d33038 0x06241000 - 0x06242fff r-- fmap.page.0x6241000
373 fd: 4 +0x01d35038 0x062c1000 - 0x062c1fff r-- fmap.page.0x62c1000
374 fd: 4 +0x01d36038 0x06332000 - 0x06334fff r-- fmap.page.0x6332000
375 fd: 4 +0x01d39038 0x06375000 - 0x06375fff r-- fmap.page.0x6375000
376 fd: 4 +0x01d3a038 0x063b2000 - 0x063b3fff r-- fmap.page.0x63b2000
377 fd: 4 +0x01d3c038 0x063f0000 - 0x063f1fff r-- fmap.page.0x63f0000
378 fd: 4 +0x01d3e038 0x06400000 - 0x06460fff r-- fmap.page.0x6400000
379 fd: 4 +0x01d9f038 0x06462000 - 0x06468fff r-- fmap.page.0x6462000
380 fd: 4 +0x01da6038 0x0646a000 - 0x06486fff r-- fmap.page.0x646a000
381 fd: 4 +0x01dc3038 0x064b9000 - 0x064b9fff r-- fmap.page.0x64b9000
382 fd: 4 +0x01dc4038 0x064bb000 - 0x064bbfff r-- fmap.page.0x64bb000
383 fd: 4 +0x01dc5038 0x06536000 - 0x06536fff r-- fmap.page.0x6536000
384 fd: 4 +0x01dc6038 0x06538000 - 0x06539fff r-- fmap.page.0x6538000
385 fd: 4 +0x01dc8038 0x065b6000 - 0x065b8fff r-- fmap.page.0x65b6000
386 fd: 4 +0x01dcb038 0x065f5000 - 0x065f5fff r-- fmap.page.0x65f5000
387 fd: 4 +0x01dcc038 0x1003f000 - 0x1003ffff r-- fmap.page.0x1003f000
388 fd: 4 +0x01dcd038 0x1007e000 - 0x1007efff r-- fmap.page.0x1007e000
389 fd: 4 +0x01dce038 0x100bc000 - 0x100bdfff r-- fmap.page.0x100bc000
390 fd: 4 +0x01dd0038 0x100fe000 - 0x100fefff r-- fmap.page.0x100fe000
391 fd: 4 +0x01dd1038 0x1013b000 - 0x1013cfff r-- fmap.page.0x1013b000
392 fd: 4 +0x01dd3038 0x1017a000 - 0x1017afff r-- fmap.page.0x1017a000
393 fd: 4 +0x01dd4038 0x3be00000 - 0x3c9fffff r-- fmap.page.0x3be00000
394 fd: 4 +0x029d4038 0x3d444000 - 0x3d445fff r-- fmap.page.0x3d444000
395 fd: 4 +0x029d6038 0x3d4c1000 - 0x3edd5fff r-- fmap.page.0x3d4c1000
396 fd: 4 +0x042eb038 0x3ede3000 - 0x3eecbfff r-- fmap.page.0x3ede3000
397 fd: 4 +0x043d4038 0x3ef1b000 - 0x3ff9afff r-- fmap.page.0x3ef1b000
398 fd: 4 +0x05454038 0x3ffff000 - 0x3fffffff r-- fmap.page.0x3ffff000
EOF
RUN