QEMU-Nyx-fork/nyx/printk.c
2022-01-11 04:16:34 +01:00

104 lines
2.5 KiB
C

#include "qemu/osdep.h"
#include <linux/kvm.h>
#include "qemu-common.h"
#include "nyx/memory_access.h"
#include "nyx/hypercall/hypercall.h"
#include "nyx/printk.h"
enum reg_types{RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15, RIP};
uint8_t types[] = {RSI, RDX, RCX, R8, R9} ;
/* calling convention: RDI, RSI, RDX, RCX, R8, R9 */
/* https://www.kernel.org/doc/Documentation/printk-formats.txt :-( */
bool kafl_linux_printk(CPUState *cpu){
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
char printk_buf[0x1000];
uint8_t rsp_buf[0x1000];
uint8_t rdi_buf[0x1000];
uint8_t rsi_buf[0x1000];
uint8_t rdx_buf[0x1000];
uint8_t rcx_buf[0x1000];
uint8_t r8_buf[0x1000];
uint8_t r9_buf[0x1000];
read_virtual_memory((uint64_t)env->regs[RSP], (uint8_t*)rsp_buf, 0x1000, cpu);
read_virtual_memory((uint64_t)env->regs[RDI], (uint8_t*)rdi_buf, 0x1000, cpu);
uint8_t* buf[] = {rsi_buf, rdx_buf, rcx_buf, r8_buf, r9_buf};
for(uint16_t i = 0, type = 0; i < 0x1000 && rdi_buf[i] != '\x00'; i++){
if(i > 1 && rdi_buf[i-2] == '%' && rdi_buf[i-1] != '%'){
if(rdi_buf[i-1] == 's' || rdi_buf[i-1] == 'p' || rdi_buf[i-1] == '.'){
if(rdi_buf[i] == 'B'){
rdi_buf[i-1] = 'l';
rdi_buf[i] = 'x';
buf[type] = (uint8_t*)env->regs[types[type]];
}
else if(rdi_buf[i-1] == 'p' && rdi_buf[i] == 'V'){
rdi_buf[i-1] = 's';
rdi_buf[i] = ' ';
read_virtual_memory((uint64_t)env->regs[types[type]], (uint8_t*)buf[type], 0x1000, cpu);
uint64_t tmp = *((uint64_t*)buf[type]);
read_virtual_memory(tmp, (uint8_t*)buf[type], 0x1000, cpu);
}
else if(rdi_buf[i-1] == 'p'){
rdi_buf[i-1] = 'l';
memmove(rdi_buf+i+1, rdi_buf+i, 0x1000-i-1);
rdi_buf[i] = 'x';
buf[type] = (uint8_t*)env->regs[types[type]];
}
else {
read_virtual_memory((uint64_t)env->regs[types[type]], (uint8_t*)buf[type], 0x1000, cpu);
}
}
else{
buf[type] = (uint8_t*)env->regs[types[type]];
}
type++;
if(type > 4){
rdi_buf[i] = '\n';
rdi_buf[i+1] = '\x00';
break;
}
}
}
snprintf(printk_buf, 0x1000, (char*)rdi_buf, buf[0], buf[1], buf[2], buf[3], buf[4]);
if(printk_buf[0] == 0x1){
//printf("%s", rdi_buf+2);
//hprintf(printk_buf+2);
//printf("%s", printk_buf+2);
if(!strncmp(printk_buf+2, "---[ end Kernel panic", 21)){
return true;
}
}
else {
//printf("%s", rdi_buf);
//hprintf(printk_buf);
//printf("%s", printk_buf);
if(!strncmp(printk_buf, "---[ end Kernel panic", 21)){
return true;
}
}
return false;
}