Fix endianness for win pagedump and winkd (#3204)
This commit is contained in:
parent
111e912b99
commit
55e690990b
14 changed files with 1389 additions and 294 deletions
10
.travis.yml
10
.travis.yml
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue