2

I'm trying to learn/test x86-64 privileged instructions & memory protection / management (which causes #GP exceptions in a user mode code.) At the moment I'm re-using a template device driver that I installed in a VM in a Win7 x64 client OS. After that I initiate remote kernel debugging into that VM via WinDbg, break into my driver and then modify the code I need on the fly by using x86-64 opcodes. I then run my tests, and break to see the result. This often also results in a BSOD and later rinse-and-repeat process.

As you can imagine my made up method is quite inconvenient.

So I was wondering if there's an easier way to do these tests?

c00000fd
  • 20,994
  • 29
  • 177
  • 400
  • 2
    BOCHS is an x86 PC emulator with a built-in debugger. You could build a legacy-BIOS boot sector that uses the instruction and boot it inside BOCHS. http://bochs.sourceforge.net/ – Peter Cordes Jun 02 '18 at 00:04
  • @PeterCordes: Wow, it got 2 of everything: 2 upvotes, 2 votes to close and you got 2 upvotes on your comment. :) Thanks for your suggestion. I guess I'll have to stick with my butchering-kernel-driver method. I found an old DOS image that I can use in the VM but then there's an issue of actually getting anything to run in it. (I don't think there's a modern compiler or debugger that runs on DOS.) As for your suggestion, I need to run these tests on the hardware itself. Don't wanna deal with emulators. – c00000fd Jun 02 '18 at 18:32
  • Ok fine, then use qemu-system with its GDB-stub; I think that might let you single-step the whole machine.. And I didn't say anything about DOS; I wouldn't recommend DOS at all. You'd probably want to switch to 32-bit protected mode or 64-bit long mode in a boot sector, depending on which privileged instruction. Or just try stuff in 16-bit real mode. – Peter Cordes Jun 02 '18 at 18:45
  • Oh, I can switch CPU modes with my own GDT and a `call gate` once I step into it with a debugger. I'll research that gdb stub. Thanks. – c00000fd Jun 02 '18 at 18:49
  • IDK if it would be easier to start with EFI, where your EFI application runs in 64-bit mode to start with, and doesn't have to fit in 512 bytes or else load more code itself. A legacy BIOS boot-sector is *very* portable, though. And yeah you make a GDT and do a `jmp far` to set CS. See https://wiki.osdev.org/ – Peter Cordes Jun 02 '18 at 18:57
  • Using an emulator or a VM may be better because it's easy to lock up or corrupt a machine when messing up with the privileged instructions. If you want to run on real hw, you can temper Windows' GDT to give user mode applications ring0 privileges (e.g. changing the DPL, creating a new descriptor, creating a call gate to a fixed address, etc). – Margaret Bloom Jun 03 '18 at 14:55
  • @MargaretBloom: Hah, that's a good idea I didn't think about. From just curiosity, have you tried it? And will Windows continue to run OK with the user mode code running with ring0 CPL? – c00000fd Jun 03 '18 at 17:56
  • @c00000fd In the WinXP times I injected some code in `hal.dll` to create a call gate and give access to ring0 to user mode program. I had to disable the interrupts when executing the code behind the call gate but it worked. Changing the DPL of the user mode's code segment is easy to do, it may be worth trying it directly on a VM. I suppose changing these things may mess up some of the Windows Internals. – Margaret Bloom Jun 03 '18 at 20:43
  • @MargaretBloom: Just curious why did you have to disable interrupts for that? – c00000fd Jun 04 '18 at 05:36
  • @c00000fd I didn't investigate at the time (It was a time where the so-called DDK was not free and I had a pay-per-use internet access) but with interrupts enabled an IRQ_NOT_LESS_OR_EQUAL bugcheck was being thrown. Curiously, this didn't happen on WinMe. – Margaret Bloom Jun 04 '18 at 07:56
  • Why don't you just write a small device driver that uses either inline assembly or takes the instruction you want to execute as a parameter? Then you can just load the driver in debug mode and call it through IOCTL. – Hadi Brais Jun 05 '18 at 20:45
  • @HadiBrais: That's what I'm doing now. I just thought there was an easier way (i.e. specialized environment) to do this. – c00000fd Jun 05 '18 at 20:59
  • But why are you using a debugger for that? You can automate that by passing the instruction as a parameter to the driver. The user-mode program can be set to run at startup in case of BSOD and pick up from where it left last time. – Hadi Brais Jun 05 '18 at 21:04
  • @HadiBrais: It's easier/faster to check the result w/debugger. For instance, if I'm resetting the GDT or IDT I can't expect the kernel to do much after that. When I'm done with my tests, it's pretty much lights-out for the OS. – c00000fd Jun 05 '18 at 21:55

0 Answers0