Home x64 Inline Assembly in Windows Driver Kit
Post
Cancel

x64 Inline Assembly in Windows Driver Kit

As my testing always interferes with running assembly directly in kernel-level and unfortunately Microsoft no longer supports x64 inline assembly through their compilers and as I always have struggle creating a simple inline assembly project so I decided to create a post to describe how to create a Windows Driver Kit project with Inline assembly to run kernel code directly in a kernel driver.

This terms only applies to x64 Windows Kernel Driver, you can use _asm and asm directly in your code in x86 drivers and user-mode codes, Linux also supports x64 Inline assembly in their kernel modules.

Let’s get down to business.

First of all, you should have Windows WDK support in your visual studio, just follow the steps here, then after downloading Windows Driver Kit and Windows SDK then you can create a WDK Project in your visual studio like this :

Create Project

So I created a project named MyDriver after that you should add some files to your project. As you might know, you should create a .asm file beside your .c (code) and .h (header) files thus I created two files named (source.cpp)

add cpp

and the other file is source.asm.

Add Assembly file

I made a simple assembly function (Masm) along with a simple driver entry function, you can add these files to your project. For example the following lines for source.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PUBLIC MainAsm
.code _text

MainAsm PROC PUBLIC
push rax

; do stuffs here

pop rax
ret
MainAsm ENDP

MainAsm2 PROC PUBLIC
int 3
ret
MainAsm2 ENDP 

END

There are some important notes here, 

  • Your function should ends with ret, if not it never comes back from your function and as long as you are in the kernel, every error lead to a BSOD.
  • The other important note is you are responsible for the calling convention used in your driver (for passing arguments or clearing the stack).
  • The default calling convention in Windows x64 driver is fastcall so in most situations, all the parameters placed in the registers and you are not forced to clear anything before ret.

The other file is driver entry (Source.cpp), you can use something like :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <ntddk.h>
#include <wdf.h>

extern void inline MainAsm(void);
extern void inline MainAsm2(void);

VOID Unload(IN WDFDRIVER Driver)
{}

NTSTATUS MyDriverEntry(_In_ PDRIVER_OBJECT     DriverObject,
	_In_ PUNICODE_STRING    RegistryPath)
{

	// NTSTATUS variable to record success or failure
	NTSTATUS status = STATUS_SUCCESS;

	// Allocate the driver configuration object
	WDF_DRIVER_CONFIG config;

	WDF_DRIVER_CONFIG_INIT(
		&config,
		WDF_NO_EVENT_CALLBACK // This is a non-pnp driver.
	);

	config.EvtDriverUnload = Unload;
	MainAsm();

	return status;
}

Please note that I defined MainAsm and MainAsm2 from the previous assembly file as function name so that I can use it directly in my DriverEntry or etc.

Make sure to change the architecture to x64.

Change arch to x64

That’s it, build your project and you can use tools like OSR Driver Loader from osronline.com to load your driver.

Almost in all current Windows versions (<=Window 7) you should disable Driver Signature Enforcement, a protection for Windows to prevent non-verified drivers or rootkits to go in ring 0.

Update :

If you see some errors like this in your building process,

Error

Then make sure to add your driver entry in properties -> Linker -> All Options -> search for the entry point.

 Add entry

That should solve the problem.

I also added the source of this project on my GitHub, take a look at :

[https://github.com/SinaKarvandi/x64-Driver-Inline-Assembly/]

This post is licensed under CC BY 4.0 by the author.

Inside Windows Page Frame Number (PFN) – Part 2

Hypervisor From Scratch - Part 1: Basic Concepts & Configure Testing Environment

Comments powered by Disqus.