|
|
|
@ -79,9 +79,9 @@ static KDDEBUGGER_DATA64 *get_kdbg(uint64_t KernBase, struct pdb_reader *pdb, |
|
|
|
bool decode = false; |
|
|
|
uint64_t kwn, kwa, KdpDataBlockEncoded; |
|
|
|
|
|
|
|
if (va_space_rw(vs, |
|
|
|
KdDebuggerDataBlock + offsetof(KDDEBUGGER_DATA64, Header), |
|
|
|
&kdbg_hdr, sizeof(kdbg_hdr), 0)) { |
|
|
|
if (!va_space_rw(vs, |
|
|
|
KdDebuggerDataBlock + offsetof(KDDEBUGGER_DATA64, Header), |
|
|
|
&kdbg_hdr, sizeof(kdbg_hdr), 0)) { |
|
|
|
eprintf("Failed to extract KDBG header\n"); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
@ -97,8 +97,8 @@ static KDDEBUGGER_DATA64 *get_kdbg(uint64_t KernBase, struct pdb_reader *pdb, |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
if (va_space_rw(vs, KiWaitNever, &kwn, sizeof(kwn), 0) || |
|
|
|
va_space_rw(vs, KiWaitAlways, &kwa, sizeof(kwa), 0)) { |
|
|
|
if (!va_space_rw(vs, KiWaitNever, &kwn, sizeof(kwn), 0) || |
|
|
|
!va_space_rw(vs, KiWaitAlways, &kwa, sizeof(kwa), 0)) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
@ -122,7 +122,7 @@ static KDDEBUGGER_DATA64 *get_kdbg(uint64_t KernBase, struct pdb_reader *pdb, |
|
|
|
|
|
|
|
kdbg = g_malloc(kdbg_hdr.Size); |
|
|
|
|
|
|
|
if (va_space_rw(vs, KdDebuggerDataBlock, kdbg, kdbg_hdr.Size, 0)) { |
|
|
|
if (!va_space_rw(vs, KdDebuggerDataBlock, kdbg, kdbg_hdr.Size, 0)) { |
|
|
|
eprintf("Failed to extract entire KDBG\n"); |
|
|
|
g_free(kdbg); |
|
|
|
return NULL; |
|
|
|
@ -286,7 +286,7 @@ static int fill_header(WinDumpHeader64 *hdr, struct pa_space *ps, |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (va_space_rw(vs, KdVersionBlock, &kvb, sizeof(kvb), 0)) { |
|
|
|
if (!va_space_rw(vs, KdVersionBlock, &kvb, sizeof(kvb), 0)) { |
|
|
|
eprintf("Failed to extract KdVersionBlock\n"); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
@ -352,8 +352,8 @@ static void fill_context(KDDEBUGGER_DATA64 *kdbg, |
|
|
|
WinContext64 ctx; |
|
|
|
QEMUCPUState *s = qe->state[i]; |
|
|
|
|
|
|
|
if (va_space_rw(vs, kdbg->KiProcessorBlock + sizeof(Prcb) * i, |
|
|
|
&Prcb, sizeof(Prcb), 0)) { |
|
|
|
if (!va_space_rw(vs, kdbg->KiProcessorBlock + sizeof(Prcb) * i, |
|
|
|
&Prcb, sizeof(Prcb), 0)) { |
|
|
|
eprintf("Failed to read CPU #%d PRCB location\n", i); |
|
|
|
continue; |
|
|
|
} |
|
|
|
@ -363,8 +363,8 @@ static void fill_context(KDDEBUGGER_DATA64 *kdbg, |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
if (va_space_rw(vs, Prcb + kdbg->OffsetPrcbContext, |
|
|
|
&Context, sizeof(Context), 0)) { |
|
|
|
if (!va_space_rw(vs, Prcb + kdbg->OffsetPrcbContext, |
|
|
|
&Context, sizeof(Context), 0)) { |
|
|
|
eprintf("Failed to read CPU #%d ContextFrame location\n", i); |
|
|
|
continue; |
|
|
|
} |
|
|
|
@ -372,7 +372,7 @@ static void fill_context(KDDEBUGGER_DATA64 *kdbg, |
|
|
|
printf("Filling context for CPU #%d...\n", i); |
|
|
|
win_context_init_from_qemu_cpu_state(&ctx, s); |
|
|
|
|
|
|
|
if (va_space_rw(vs, Context, &ctx, sizeof(ctx), 1)) { |
|
|
|
if (!va_space_rw(vs, Context, &ctx, sizeof(ctx), 1)) { |
|
|
|
eprintf("Failed to fill CPU #%d context\n", i); |
|
|
|
continue; |
|
|
|
} |
|
|
|
@ -396,8 +396,8 @@ static int pe_get_data_dir_entry(uint64_t base, void *start_addr, int idx, |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (va_space_rw(vs, base + dos_hdr->e_lfanew, |
|
|
|
&nt_hdrs, sizeof(nt_hdrs), 0)) { |
|
|
|
if (!va_space_rw(vs, base + dos_hdr->e_lfanew, |
|
|
|
&nt_hdrs, sizeof(nt_hdrs), 0)) { |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -406,9 +406,7 @@ static int pe_get_data_dir_entry(uint64_t base, void *start_addr, int idx, |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (va_space_rw(vs, |
|
|
|
base + data_dir[idx].VirtualAddress, |
|
|
|
entry, size, 0)) { |
|
|
|
if (!va_space_rw(vs, base + data_dir[idx].VirtualAddress, entry, size, 0)) { |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -470,9 +468,8 @@ static bool pe_check_pdb_name(uint64_t base, void *start_addr, |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (va_space_rw(vs, |
|
|
|
base + debug_dir.AddressOfRawData, |
|
|
|
rsds, sizeof(*rsds), 0)) { |
|
|
|
if (!va_space_rw(vs, base + debug_dir.AddressOfRawData, |
|
|
|
rsds, sizeof(*rsds), 0)) { |
|
|
|
eprintf("Failed to resolve OMFSignatureRSDS\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
@ -488,9 +485,9 @@ static bool pe_check_pdb_name(uint64_t base, void *start_addr, |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (va_space_rw(vs, base + debug_dir.AddressOfRawData + |
|
|
|
offsetof(OMFSignatureRSDS, name), pdb_name, sizeof(PDB_NAME), |
|
|
|
0)) { |
|
|
|
if (!va_space_rw(vs, base + debug_dir.AddressOfRawData + |
|
|
|
offsetof(OMFSignatureRSDS, name), |
|
|
|
pdb_name, sizeof(PDB_NAME), 0)) { |
|
|
|
eprintf("Failed to resolve PDB name\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
@ -556,8 +553,8 @@ int main(int argc, char *argv[]) |
|
|
|
|
|
|
|
printf("CPU #0 IDT is at 0x%016"PRIx64"\n", state->idt.base); |
|
|
|
|
|
|
|
if (va_space_rw(&vs, state->idt.base, |
|
|
|
&first_idt_desc, sizeof(first_idt_desc), 0)) { |
|
|
|
if (!va_space_rw(&vs, state->idt.base, |
|
|
|
&first_idt_desc, sizeof(first_idt_desc), 0)) { |
|
|
|
eprintf("Failed to get CPU #0 IDT[0]\n"); |
|
|
|
goto out_ps; |
|
|
|
} |
|
|
|
|