Trying to build and run VBoxSampleDevice

Discussions related to using the OSE version of VirtualBox.
SrBIOS
Posts: 18
Joined: 30. Aug 2021, 20:06
Primary OS: MS Windows other
VBox Version: OSE other
Guest OSses: DOS / Windows

Trying to build and run VBoxSampleDevice

Post by SrBIOS »

Hello,

I'm trying to learn how to build virtual devices in VirtualBox. I've done this in QEMU and Bochs, but this is a new learning experience (working with kernel mode drivers).

First, I'd like to use the official build (I have 6.1.18 running in Windows 10 - Version 10.0.19042.1165), but attach the virtual device.

I tried that, and the line <ExtraDataItem name="VBoxInternal/PDM/Devices/playground/Path" value="C:\Users\nnn\VirtualBox VMs\VBoxSampleDevice.dll"/> is added to the vbox file.

I test signed the dll, I have my PC in test signed mode, and have the cert in the trusted root / trusted publishers, and in personal. In personal, it shows the complete path and private key. The DLL is owned by system, too.

My hurdle now is VERR_CR_X509_CPV_NO_TRUSTED_PATHS .

00:00:03.996095 VMSetError: F:\tinderbox\win-6.1\src\VBox\VMM\VMMR3\PDMLdr.cpp(318) int __cdecl pdmR3LoadR3U(struct UVM *,const char *,const char *); rc=VERR_CR_X509_CPV_NO_TRUSTED_PATHS
00:00:03.996111 VMSetError: Unable to load R3 module C:\Users\nnn\VirtualBox VMs\VBoxSampleDevice.dll (playground): None of the 1 path(s) have a trust anchor.: \Device\HarddiskVolume3\Users\nnn\VirtualBox VMs\VBoxSampleDevice.dll
00:00:03.998128 ERROR [COM]: aRC=E_FAIL (0x80004005) aIID={872da645-4a9b-1727-bee2-5585105b9eed} aComponent={ConsoleWrap} aText={Unable to load R3 module C:\Users\nnn\VirtualBox VMs\VBoxSampleDevice.dll (playground): None of the 1 path(s) have a trust anchor.: \Device\HarddiskVolume3\Users\nnn\VirtualBox VMs\VBoxSampleDevice.dll (VERR_CR_X509_CPV_NO_TRUSTED_PATHS)}, preserve=false aResultDetail=-23021
00:00:03.998420 Console: Machine state changed to 'PoweredOff'
00:00:04.003385 Power up failed (vrc=VERR_CR_X509_CPV_NO_TRUSTED_PATHS, rc=E_FAIL (0X80004005))
00:00:04.504489 GUI: UIMachineViewNormal::resendSizeHint: Restoring guest size-hint for screen 0 to 800x600
00:00:04.504570 ERROR [COM]: aRC=E_ACCESSDENIED (0x80070005) aIID={4680b2de-8690-11e9-b83d-5719e53cf1de} aComponent={DisplayWrap} aText={The console is not powered up}, preserve=false aResultDetail=0
00:00:04.505046 GUI: Aborting startup due to power up progress issue detected...


I must be missing something. Can I not attach a custom device to the official build? Did I sign something wrong? Can I build the driver to only be Ring3 and not need signing?

I only have one dev PC, and I don't want to ruin my official VBox install (as I use VMs to test other projects), by registering my build of VBox.

Any hints / help would be greatly appreciated,
Thank you,
Ben
klaus
Oracle Corporation
Posts: 1115
Joined: 10. May 2007, 14:57

Re: Trying to build and run VBoxSampleDevice

Post by klaus »

It should be possible to build and sign code properly (with a certificate suitable for kernel mode signing, i.e. not some self-signed stuff), but since Microsoft recently changed the whole signing approach for kernel mode signing (effectively requiring a signature from Microsoft itself, using "attestation signing") I don't know if this has any chance of working. It wasn't tested in a while (I suspect a few years), because we haven't heard of anyone who did this kind of extension of VirtualBox.

VirtualBox uses a very consistent approach: both for kernel and userland code it expects using a certificate suitable for kernel mode signing.

The signature checking code in VirtualBox release builds cannot be disabled (otherwise the whole hardening effort would've been useless), so the only way to relax the rules would be building all of VirtualBox yourself with hardening disabled (and maybe test signing enabled which allows developing using a self-signed certificate).
SrBIOS
Posts: 18
Joined: 30. Aug 2021, 20:06
Primary OS: MS Windows other
VBox Version: OSE other
Guest OSses: DOS / Windows

Re: Trying to build and run VBoxSampleDevice

Post by SrBIOS »

Hello klaus,

When I say self signed, I mean the method described in the VirtualBox wiki, Windows build instructions. Are these instructions no longer good under recent Windows 10? Would earlier Win10 builds work? Maybe go back to Win 7?

I'm not trying to bypass anything (well, except when testing), as getting a code signing cert to deploy my code isn't unreasonable. However, if I need the really $$$ cert, or if Microsoft is just making it really difficult, I might be stuck.

I'd like to look at expanding the COM port limit, with a virtual 8-COM port device, based on other real hardware in the wild. I have equipment, with real hardware, from the last century (ISA / PCI), which needs to continue running well into this century. I have lots of other hardware, too, I'd like to virtualize.

Thank you for your time,
Ben
klaus
Oracle Corporation
Posts: 1115
Joined: 10. May 2007, 14:57

Re: Trying to build and run VBoxSampleDevice

Post by klaus »

Self signing works (otherwise our devs wouldn't be able to make changes), but only if you do this for the entire build.

A VirtualBox build from Oracle is always hardened, and I guess you noticed in the instructions you pointed to there is a line disabling hardening. Which is vital to get a self-signed build going, and it must be applied to all of VirtualBox. You can't "convince" a hardened build to accept a self-signed driver.
SrBIOS
Posts: 18
Joined: 30. Aug 2021, 20:06
Primary OS: MS Windows other
VBox Version: OSE other
Guest OSses: DOS / Windows

Re: Trying to build and run VBoxSampleDevice

Post by SrBIOS »

Hello klaus,

Ok, I get it now. Official build (or any hardened build) won't run test signed code.
VBOX_WITHOUT_HARDENING=1
Disable Windows hardening. Useful for testing. Do not use this setting for production builds! Without hardening the binaries are not signed and VirtualBox.exe can be started straight away from the out\...\bin directory (kmk packing + installation not required).
Please note that it's still necessary to enablg code signing to be able to start VMs as Windows refuses to load unsigned kernel drivers.
When I first compiled the code, I did try "VBOX_WITHOUT_HARDENING=1", just to see if I was even in the ballpark. That code failed to run due to not being signed at all... Expected. So, I commented that out, sorted out all the signing stuff, and I made it this far.

So, if I put "VBOX_WITHOUT_HARDENING=1" back in, and run the VirtualBox I build, won't the other part of that description block me from testing?
Please note that it's still necessary to enablg code signing to be able to start VMs

Thank you again for your time and help on this,
Ben
klaus
Oracle Corporation
Posts: 1115
Joined: 10. May 2007, 14:57

Re: Trying to build and run VBoxSampleDevice

Post by klaus »

Disabling hardening is one step you need to do for being able to run test signed code, and setting up test signing is the other. It's what the description of the first step is reminding.

Did you run the self-built VirtualBox or do you still mix it with running a build from virtualbox.org? Usually the best approach is to uninstall the official package, because then there can't be confusion (which can originate in the COM component registration, running the official build instead of the local one).

What the build instructions don't state too clearly is that building can be done as a normal (non-admin) user. Just comregister.com and loadall.cmd need to be run by an admin. After that you should be able to run the executables as a normal user.

You could also install the result of your own build, but that's usually not worth the effort (and possibly another way to cause confusion because it puts another set of binaries in the Program Files directory) during development work. It is possible to run everything straight from the build directory (as long as the build isn't hardened).

Oh, and before I forget: unless you really know what you're doing I highly recommend loading only "release" drivers (which is default for an OSE build, KBUILD_TYPE), i.e. using out\win.amd64\release\bin\loadall.cmd. Don't use drivers from ...\debug unless you're happy to have your system running into a BSOD in unpredictable situations. You can mix and match release drivers with a debug build of the rest of VirtualBox if you want to get additional logging/assertions and so on in the userland parts.
SrBIOS
Posts: 18
Joined: 30. Aug 2021, 20:06
Primary OS: MS Windows other
VBox Version: OSE other
Guest OSses: DOS / Windows

Re: Trying to build and run VBoxSampleDevice

Post by SrBIOS »

Hello klaus,

I'm sorry for the delay in replying. I've been working on this all morning. I took your advise, and mixed it with the forum topic "Building VirtualBox OSE 5.0.0 on Windows 7 (x86)" I found last night.

I was trying to mix official release, and my release, but abandoned that when I read your last post.

I was able to get my hands on a fresh Win10 box, and copy all my compiled code over to it to run. I then realized I needed to build OpenSSL / cURL / QT, and build them to be signed. I'm still working on QT, but OpenSSL and cURL went ok.

I turned off hardening, and I was able to run headless (I have no display, but the logs show everything went ok). The logs show OK hardened, too.. I need to build QT to get a display (I think).

...
00:00:00.424845 Extradata overrides:
00:00:00.424854 VBoxInternal/PDM/Devices/playground/Path="C:\Ben\bin\VBoxSampleDevice.dll"
00:00:00.425077 ************************* CFGM dump *************************
...
00:00:00.425383 [/PDM/Devices/] (level 2)
00:00:00.425383
00:00:00.425383 [/PDM/Devices/playground/] (level 3)
00:00:00.425384 Path <string> = "C:\Ben\bin\VBoxSampleDevice.dll" (cb=32)
00:00:00.425384
...
00:00:03.294957 VMMDev: Guest Log: BIOS: Boot : bseqnr=3, bootseq=0002
00:00:03.295807 VMMDev: Guest Log: BIOS: Booting from Hard Disk...
00:00:03.295905 PIIX3 ATA: Ctl#0: RESET, DevSel=0 AIOIf=0 CmdIf0=0xc4 (-1 usec ago) CmdIf1=0x00 (-1 usec ago)
00:00:03.295905 PIIX3 ATA: Ctl#0: finished processing RESET


So, I may be ok. I really appreciate your help and holding my hand and telling me things will be ok ; ) . Let me build QT, and see where I can go from there. Once I can do that, I'll try to add an IO port to the device, and just flip simple bits on port 0x300, or something.

Oh, a quick question, since we are talking about building. Is there a way to release in-use files on the folder after running VBox? Most of the .exe files stay in use, and I need to reboot between builds. The service is stopped, so I don't know what locks up. That is just a minor annoyance. Building takes longer than the test PC rebooting..

Thank you again very much for your time and help,
Ben
fth0
Volunteer
Posts: 5668
Joined: 14. Feb 2019, 03:06
Primary OS: Mac OS X other
VBox Version: PUEL
Guest OSses: Linux, Windows 10, ...
Location: Germany

Re: Trying to build and run VBoxSampleDevice

Post by fth0 »

SrBIOS wrote:I need to build QT to get a display (I think).
If you want VirtualBox to display the typical window containing the VM's screen, then yes. Otherwise, if you can remote into the guest OS (e.g. SSH, RDP, VNC) ...
SrBIOS
Posts: 18
Joined: 30. Aug 2021, 20:06
Primary OS: MS Windows other
VBox Version: OSE other
Guest OSses: DOS / Windows

Re: Trying to build and run VBoxSampleDevice

Post by SrBIOS »

Hello,

I'd like to post an update. (I tried the RDP method, but it never opens the socket. Maybe something else is broken on my first build, too)

Building QT was quite the learning curve, to say the very least. I found it beneficial to just delete the whole directory between compiles, as the jom / nmake clean left lots of trash, and makefiles would not auto generate after changes, and took forever to run. It was slightly faster to just nuke the directory, and unzip fresh. It took a few days to get a good (I think) compile of QT. I also added a line to the qmake program to always call the signtool after it makes a DLL (it has builtin support already, but it was a sig file). So that was nice, and VERY helpful!

I even switched to a VM running Win7x64 (the official VirtualBox is AWESOME, btw, thank you!) and VS2010 (I followed the QT recomended procedure for updates, too), DirectX SDK, WinSDK 7.1 / DDK 7600.16385.1, just to make sure I had a really clean install, and to make sure Win10 wasn't causing something on older SDKs.

SSL, cURL, and SDL took a few compiles to figure out what I was doing, too...

VirtualBox took a few passes, too, which usually led back to recompiling the previous...

However, I was able to compile VirtualBox, and get it to run a DOS VM in the GUI!

So, now I have the sample (VBoxSampleDevice) linked in, but something isn't right.

In the VBox file, I have <ExtraDataItem name="VBoxInternal/PDM/Devices/sample/Path" value="C:\Ben\bin\VBoxSampleDevice.dll"/>

And I have it logging through VBoxDevicesRegister, but I never see it call (log in) devSampleConstruct. I use the same LogRel(("Something\n")); in each function, so I assume that should work.

I even added a few more hooks into the structure, to see if that would help.

static const PDMDEVREG g_DeviceSample =
{
/* .u32Version = */ PDM_DEVREG_VERSION,
/* .uReserved0 = */ 0,
/* .szName = */ "sample",
/* .fFlags = */ PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_NEW_STYLE,
/* .fClass = */ PDM_DEVREG_CLASS_MISC,
/* .cMaxInstances = */ 1,
/* .uSharedVersion = */ 42,
/* .cbInstanceShared = */ sizeof(VBOXSAMPLEDEVICE),
/* .cbInstanceCC = */ 0,
/* .cbInstanceRC = */ 0,
/* .cMaxPciDevices = */ 0,
/* .cMaxMsixVectors = */ 0,
/* .pszDescription = */ "VBox Sample Device.",
#if defined(IN_RING3)
/* .pszRCMod = */ "",
/* .pszR0Mod = */ "",
/* .pfnConstruct = */ devSampleConstruct,
/* .pfnDestruct = */ devSampleDestruct,
/* .pfnRelocate = */ NULL,
/* .pfnMemSetup = */ NULL,
/* .pfnPowerOn = */ NULL,
/* .pfnReset = */ sampleR3Reset,
/* .pfnSuspend = */ NULL,
/* .pfnResume = */ NULL,
/* .pfnAttach = */ sampleR3Attach,
/* .pfnDetach = */ sampleR3Detach,


In the log, I have these lines...
00:00:00.925466 [/PDM/Devices/sample/] (level 3)
00:00:00.925466 Path <string> = "C:\Ben\bin\VBoxSampleDevice.dll" (cb=32)


I'm trying to compare to serial and playground, but I'm just not seeing what I need to do. Any hints would be greatly appreciated.

Thanks again for everyone's time and help,
Ben
SrBIOS
Posts: 18
Joined: 30. Aug 2021, 20:06
Primary OS: MS Windows other
VBox Version: OSE other
Guest OSses: DOS / Windows

Re: Trying to build and run VBoxSampleDevice

Post by SrBIOS »

Ah ha, I think I figured it out..

I need to add some setting, with an instance #..

VBoxManage setextradata DOS VBoxInternal/Devices/sample/0/Config/Whatever1 11

I commented out the check for config settings, and I never set any, other than the path. I think I need a setting, tied to an instance #, to make an instance. Sneaky!

I can write to IO port 0x300, invert the data, and read it back! Magic!

Now to intercept memory, try some IRQ stuff, and take over the world!

Thank you klaus and fth0!

--Ben
Attachments
VBoxSampleDevice.cpp
Totally NOT a good device...
(9.63 KiB) Downloaded 59 times
javispedro
Posts: 58
Joined: 29. Jan 2022, 15:31
Primary OS: openSUSE
VBox Version: OSE other
Guest OSses: Old & New Windows, Linux

Re: Trying to build and run VBoxSampleDevice

Post by javispedro »

klaus wrote:It should be possible to build and sign code properly (with a certificate suitable for kernel mode signing, i.e. not some self-signed stuff), but since Microsoft recently changed the whole signing approach for kernel mode signing (effectively requiring a signature from Microsoft itself, using "attestation signing") I don't know if this has any chance of working. It wasn't tested in a while (I suspect a few years), because we haven't heard of anyone who did this kind of extension of VirtualBox.

VirtualBox uses a very consistent approach: both for kernel and userland code it expects using a certificate suitable for kernel mode signing.
I have also hit the kernel code signing requeriment :(

Starting from the ExtPack samples I was able to create a pack containing a very simple PDM for a MPU-401 UART-only simulator (for MIDI out) and another for an Adlib/OPL2/OPL3 card.

It works well enough on Linux hosts, but it just can't be loaded under Windows due to "Not valid kernel code signature" on the ExtPack's MainVMModule .dll. , despite the lack of R0 code.

I guess this makes sense -- after all, the MainVMModule is being loaded into every VMM VBox process (likewise for the PDM R3 .dlls), and it may be used to attack R0 even if by itself it does not contain any R0 code.
However, it severely limits the usefulness of ExtPacks and PDMs.
Getting a kernel codesign certificate is already pretty hard; getting a kernel signature on a random user-mode .dll probably impossible, for an individual.
Not even test mode signing is allowed by the ExtPack signature validator in upstream VBox -- it just whitelists MS or MS cross-signed root certificates, ignoring the machine's certificate stores.

Any chance to relax this in the future -- without compromising R0 hardening, which I guess is a MS requirement?
scottgus1
Site Moderator
Posts: 20965
Joined: 30. Dec 2009, 20:14
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: Trying to build and run VBoxSampleDevice

Post by scottgus1 »

@javispedro please note what Klaus said in his post right after the part you quoted:
klaus wrote:The signature checking code in VirtualBox release builds cannot be disabled (otherwise the whole hardening effort would've been useless), so the only way to relax the rules would be building all of VirtualBox yourself with hardening disabled (and maybe test signing enabled which allows developing using a self-signed certificate).
And Klaus' post thereafter:
klaus wrote:Self signing works (otherwise our devs wouldn't be able to make changes), but only if you do this for the entire build.

A VirtualBox build from Oracle is always hardened, and I guess you noticed in the instructions you pointed to there is a line disabling hardening. Which is vital to get a self-signed build going, and it must be applied to all of VirtualBox. You can't "convince" a hardened build to accept a self-signed driver.
javispedro
Posts: 58
Joined: 29. Jan 2022, 15:31
Primary OS: openSUSE
VBox Version: OSE other
Guest OSses: Old & New Windows, Linux

Re: Trying to build and run VBoxSampleDevice

Post by javispedro »

Sorry -- this is why I was saying the usefulness of ExtPacks and PDMs is significantly reduced.
If one is forced to create a new VirtualBox build for a specific ExtPack/PDM, then it is probably easier to just introduce your new devices/changes into the VirtualBox source itself and rebuild, rather than making them pluggable modules. Not much point to have separate ExtPacks if each can only be loaded by their corresponding ExtPack-specific VBox build. :)

I can guess anyway that the MS requirements for signing VBoxDrv.sys are the reason it is impossible to relax VBox's kernel-mode signature checking, even for user-space/R3 only components. Just asking in case there was some other approach I missed.
klaus
Oracle Corporation
Posts: 1115
Joined: 10. May 2007, 14:57

Re: Trying to build and run VBoxSampleDevice

Post by klaus »

Will have a chat with our experts in the code signing/extpack area. If someone installs (which implies having admin access) a 3rd party extpack then that's from my perspective a way to express trust, i.e. the expectation that the functionality is not harmful.

Code in VM processes is sensitive, but this isn't meant to keep all 3rd party code out.
SrBIOS
Posts: 18
Joined: 30. Aug 2021, 20:06
Primary OS: MS Windows other
VBox Version: OSE other
Guest OSses: DOS / Windows

Re: Trying to build and run VBoxSampleDevice

Post by SrBIOS »

@javispedro / @klaus,

I had an idea, probably a really bad one, but it was something I did on boch's VM, when I was playing with it...

I had a lightweight shim "driver" where I could pass in the IO and MEM ranges, and a named pipe name. The driver would grab the ranges, and then send them over a connected named pipe, to an external application, where they would then be handled.

I originally did this for VXD stuff for the DOS box in Win2K and XP, where I would capture the IO calls, and then pipe the IO to external hardware, running on another PC, over network... Then I moved it to boch's. I've though about doing this for VirtualBox, but I just haven't had the time to play around (I lost some steam after trying to play with the vga adaptor code. This stuff is hard!).

So, in summary, build a device where the port ranges are passed in. During run, the port accesses are relayed out over named pipe. The external app does its thing super fast, and relays the response back over the same pipe. The reply then get back to the VM. That driver should then be signable. I don't know how the Microsoft signing testing goes, and they might have opinions about that..

The external app could further relay the IO to real hardware, or some emulated hardware. It wouldn't get to interact with the VM state, which is probably dangerous for pausing or saving the state of the VM, but anyone playing in this realm probably knows those kinds of risks. I'm sure those VM calls could be abstracted and relayed over the pipe, too, to get the desired effect. I'll leave that as a task / nightmare for the reader.

--Ben
Post Reply