yrp604 / bochscpu

72 stars 8 forks source link

Simulate CPU with UIMP feature #4

Closed 1ndahous3 closed 2 years ago

1ndahous3 commented 2 years ago

During fuzzing a kernel driver via WTF fuzzer with bochscpu backend for one case I got #GP (--> nt!KiGeneralProtectionFault() ) on the instruction: fffff8062804a378 0f22e0 mov cr4,rax

Inside nt!KiFlushCurrentTbWorker():

image

I caught the reason in the debug build of bochs: check_CR4(): write of 0x00350e78 not supported (allowMask=0x3727ff) (https://sourceforge.net/p/bochs/code/HEAD/tree/trunk/bochs/cpu/crregs.cc#l1273)

Decoded: 001101110010011111111111 - allowed mask 001101010000111001111000 - new value

11 bit is important for now: // [11] UMIP: User Mode Instruction Prevention R/W (https://sourceforge.net/p/bochs/code/HEAD/tree/trunk/bochs/cpu/crregs.cc#l1172)

And this bit isn't set:

  if (is_cpu_extension_supported(BX_ISA_UMIP))
    allowMask |= BX_CR4_UMIP_MASK;

(https://sourceforge.net/p/bochs/code/HEAD/tree/trunk/bochs/cpu/crregs.cc#l1251)

The flag BX_ISA_UMIP is set (enable_cpu_extension(BX_ISA_UMIP);) for 3 CPU profiles:

Inside this project the CPU profile selection is simulated in the sim_get_param_enum() function, which uses PARAMS_ENUM with "cpu.model" key: https://github.com/yrp604/bochscpu/blob/20f197bbe43bde9d5054bd92f579c6cce95a60b4/src/sim.rs#L20-L54

According to this part, the hardcoded value of 24 always means "corei7_skylake_x", which does not support UMIP. I think it would be nice to sync with the actual cpudb.h and return the value 27 for the latest CPU profile (tigerlake): https://sourceforge.net/p/bochs/code/HEAD/tree/trunk/bochs/cpudb.h#l55

yrp604 commented 2 years ago

Thanks for the detailed writeup, updated the cpulist and switched the default to tigerlake. Change is tentative until @0vercl0k confirms it works in wtf https://github.com/0vercl0k/wtf/issues/122.

0vercl0k commented 2 years ago

I'm planning to try to ingest the changes tomorrow (17th of August) FWIW. One thing that's interesting is that according to your disassembly picture, NT turns it on if it isn't set w/o making sure the CPU supports it? Maybe it happens before?

One way I've dealt w/ issues like this one is to find the piece of code that checks if the CPU supports something or not (cpuid, etc.) and instrument the code myself to make it go one way or another.

Thanks @yrp604!

Cheers

0vercl0k commented 2 years ago

Okay I've tried it on both Linux / Windows and I haven't run into any issues, awesome.

Cheers