Run the Simulation
Run the system with the command below. Remember that the simulated system will be much slower than the virtualized system, especially as we will run with VMP disabled.
./simics ./run.simics
Then, in the Simics command line:
run
The system will begin booting. The boot process may take a significant amount of time and the system may reboot. Wait until the system runs all the way through boot. Wait until after you are automatically logged into the system and the Simics agent command window is open. This is a good time to make another coffee!
At this point, if the mouse cursor is visible on the guest, move it to the taskbar.
Then, After being logged in, press control+c on the Simics command line to pause
execution. The board.mb.gpu.vga
screen should turn greyscale like below.
Then, run:
board.disk0.hd_image.save-diff-file filename = "windows-11.diff.craff"
This will save a diff between the current image state and our initial state, which will allow us to skip the long process of Windows driver reinitialization.
Next, we will add a line to run.simics
to load the diff file from the saved diff. This
will speed up subsequent boots of the system significantly.
board.disk0.hd_image.add-diff-file filename = "windows-11.diff.craff"
Then, we will save a graphical breakpoint which will allow us to wait in the boot process until login is complete and the system is logged in and ready to run Agent commands.
In the Simics cli, run:
board.console.con.status
This will display graphical console information like:
Status of board.console.con [class graphcon]
============================================
Mouse:
Absolute positioning : True
Absolute pointer device : board.tablet.usb_tablet
Grab:
Mouse button : right
Modifier : shift
VNC:
Port : none
UNIX socket : none
Listening : False
Connections : 0
Screen:
Size width x height : 1024x600
Refresh rate (Hz, real time) : 50
Note the screen width and height. We will not capture the entire screen, only the very top left -- enough to conclude the system is booted but not enough to capture any time data.
To determine the size of screenshot we need, we'll save the screen to a PNG with:
board.console.con.screenshot filename = screenshot.png
Then, we can crop it on the command line with ImageMagick (dnf -y install ImageMagick
)
and examine the result:
convert screenshot.png -crop 80x80+0+0 cropped.png
Then, check the screenshot in your favorite viewer (a web browser works conveniently for this), e.g.:
firefox cropped.png
In this case, we want to see the desktop and the CMD window that tells us the Simics agent is running. Importantly, we do not want to see the time printed by either the Simics agent at startup, or the time on the taskbar (or anything else that could change from run to run).
With our graphical breakpoint size decided, we can save our boot breakpoint:
board.console.con.save-break-xy breakpoint-boot 0 0 80 80
This will save a graphical capture of the graphical console containing the top left of the displayed screen (enough to capture the booted desktop and CMD prompt window, and exclude the time in the taskbar and CMD prompt).
We will then resume the simulation by running (in the Simics CLI):
continue
Allow the simulation to run for a few seconds to tick the clock, then pause it again by entering Ctrl+C.
Check that the breakpoint is valid by running:
board.console.con.gfx-break-match breakpoint-boot
You should see:
TRUE
Connect to Agent
Next, we'll create an agent manager in the Simics CLI:
start-agent-manager
You should see:
'agent_manager' is created and enabled.
Then we'll run:
agent_manager.connect-to-agent
After which you should see:
matic0:job 0 (connect-to)
[matic0 info] connected to DESKTOP-QNP1C9S0
Now we can run commands on the guest from the Simics command line. We want run our fuzz driver program.
matic0.run "C:\\Users\\user\\fuzzer\\fuzzer.exe"
When the fuzz driver runs, we'll get a blue screen:
This is because we just submitted a buffer of size 4096 (our configured maximum size) and overflowed the stack of the driver process, corrupting it. This means all is working correctly and we can move on to fuzzing the driver. Note that when we start up the fuzzer, it will not immediately cause the same blue screen because it will start with a random corpus of small inputs.