GithubHelp home page GithubHelp logo

utoni / mingw-w64-dpp Goto Github PK

View Code? Open in Web Editor NEW
34.0 2.0 5.0 2.02 MB

"Mingw64 Driver Plus Plus": Mingw64, C++, DDK and (EA)STL made easy!

Makefile 0.16% C++ 80.29% C 12.32% CMake 0.29% HTML 6.49% CSS 0.02% Shell 0.36% Batchfile 0.02% BitBake 0.06%
cpp stl eastl mingw mingw64 windows driver ddk

mingw-w64-dpp's Introduction

Build Gitlab-CI Circle-CI

Mingw64 Driver Plus Plus

A Windows kernel driver C/C++ SDK using Mingw64.

It provides also some examples and a feature complete STL including your beloved containers.

You will need an modern Mingw64-GCC toolchain. Do not use any broken toolchains like the one shipped with debian-10. Mingw64 for debian-11 seems to work, but is not well tested. Mingw64 for debian-12 untested. Instead either use Zeranoe's build script with make -C [path-to-this-repo] -f Makefile.deps all (same as make -C [path-to-this-repo] deps) or use your own.

What?

  1. examples/dpp-template: plain and stupid ddk C example
  2. examples/dpp-template-cplusplus: same, but written in C++, including a very complex class and some MT
  3. examples/dpp-template-cplusplus-EASTL: C++ example w/ (EA)STL integration, basicially everything usable except for VEH and assertions.

examples/dpp-template-cplusplus-EASTL supports BUILD_NATIVE! You can build and run it on your native Linux either with the other examples e.g. make examples, build only native executables make -C examples DPP_ROOT="$(realpath .)" BUILD_NATIVE=1 in the top-level directory or directly build it from the examples directory with make DPP_ROOT="$(realpath ..)" BUILD_NATIVE=1.

Build and Test

Build all examples with a Mingw64 toolchain using Zeranoe's build script:

make -C [path-to-this-repo] -f Makefile.deps all # build toolchain, CRT, CRT++ and EASTL
make -C [path-to-this-repo] all # build examples

Build all examples with your own Mingw64 toolchain:

make all CC=path/to/bin/x86_64-w64-mingw32-gcc CXX=path/to/bin/x86_64-w64-mingw32-g++ DDK_INCLUDE_DIR=path/to/include/ddk

HowTo use it in your own project

At the moment only a GMake build system is supported. A minimal working Makefile for your own project could look alike:

ifndef DPP_ROOT
$(error DPP_ROOT is undefined)
endif

include $(DPP_ROOT)/Makefile.inc

DRIVER_NAME = Driver
DRIVER_OBJECTS = $(DRIVER_NAME).opp
DRIVER_TARGET = $(DRIVER_NAME).sys

%.opp: %.cpp
	$(call BUILD_CPP_OBJECT,$<,$@)

$(DRIVER_TARGET): $(DRIVER_OBJECTS)
	$(call LINK_CPP_KERNEL_TARGET,$(DRIVER_OBJECTS),$@)

Build it with: make Driver.sys DPP_ROOT=[path/to/this/repository]

It also possible to (self-)sign your driver and install your driver with:

install: $(DRIVER_TARGET)
    $(call INSTALL_EXEC_SIGN,$(DRIVER_TARGET))

You can also add the toolchain to your path and use it for other projects w/o any Makefile blueprint:

make -C [path-to-this-repo] -f Makefile.deps all
source [path-to-this-repo]/mingw-w64-sysroot/x86_64/activate.sh

Packaging

It is possible to create *.dpp archives ready to get shipped. To do this you need to call the PACKAGE macro. But before you should install public header files with the INSTALL_HEADERS macro.

See the Makefile of mingw-w64-ksocket for an example.

The CRT and CRT++

This project uses a very very rudimentary CRT for C and C++ projects. Please keep in mind that depending on what you want to do the CRT may lack features you are familiar with. Usually this will manifest in linker errors such as undefined references. Most of the time copy&pasting missing libc/libgcc functions from various online sources should be sufficient.

Remember: The CRT/CRT++ sets a driver unload function meaning that code .e.g.:

NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT * DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
    DriverObject->DriverUnload = MyDriverUnload;
}

must not used. Overwriting DriverObject->DriverUnload with your own function may BSOD. Instead the function DriverUnload will be called. Make sure that the symbol DriverUnload exists and has the usual ddk function signature: void DriverUnload(_In_ struct _DRIVER_OBJECT * DriverObject). This is required to make ctors/dtors work without calling additional functions in DriverEntry / DriverUnload.

Do not forget to disable C++ name mangeling if your driver source which contains the DriverEntry and DriverUnload symbols is compiled with g++:

extern "C" {
NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
    // ...
}
VOID DriverUnload(_In_ struct _DRIVER_OBJECT *DriverObject)
{
    // ...
}
}

Host EASTL/CRT/CRT++ Build

It is possible to build parts of the repository for your host distribution. To do that simply type:

make -C [path-to-this-repo] -f Makefile.deps -j1 all BUILD_NATIVE=1

The results should be visible in ./CRT and EASTL-native-build. If you ran make -C [path-to-this-repo] deps before, everything is already done including the native build.

You can use the Host Build in your Makefile based project with:

ifndef DPP_ROOT
$(error DPP_ROOT is undefined)
endif

ifndef BUILD_NATIVE
include $(DPP_ROOT)/Makefile.inc
else
include $(DPP_ROOT)/Makefile.native.inc
endif

# Driver
DRIVER_NAME = Driver
DRIVER_OBJECTS = $(DRIVER_NAME).opp
DRIVER_TARGET = $(DRIVER_NAME).sys
DRIVER_LIBS =
CFLAGS_$(DRIVER_NAME).opp =
LDFLAGS_$(DRIVER_NAME).sys =

# Userspace
USER_NAME = usa$(NAME_SUFFIX)
USER_OBJECTS = $(USER_NAME).opp
USER_TARGET = $(USER_NAME).exe
USER_LIBS =
CFLAGS_$(USER_NAME).opp =
LDFLAGS_$(USER_NAME).exe =

# specify additional CFLAGS for kernel/user targets
CUSTOM_CFLAGS = -I.

%.opp: %.cpp
	$(call BUILD_CPP_OBJECT,$<,$@)

$(DRIVER_TARGET): $(DRIVER_OBJECTS)
	$(call LINK_CPP_KERNEL_TARGET,$(DRIVER_OBJECTS),$@)

$(USER_TARGET): $(USER_OBJECTS)
	$(call LINK_CPP_USER_TARGET,$(USER_OBJECTS),$@)

A simple and stupid project example.

Driver Signing

Driver signing can be done in two ways. Using a native osslsigncode executable or sign it manually on your Windows platform. The first one is always done by calling the macro INSTALL_EXEC_SIGN from your own Makefile. The latter one has to be done manually on your target Windows machine by running:

  1. create_codesign_ca.bat in DESTDIR (Administrator permission required to import CA/CERTs to the Windows certificate storage
  2. *-sign-driver-on-windows.bat e.g. dpp-example-sign-driver-on-windows.bat (no Administrator permissions required)

Note: You still need to call the macro INSTALL_EXEC_SIGN from your own Makefile to create/install the batch files in DESTDIR.

Extending

You may reach a point where system functions, intrinsics or built-ins are required. For system functions that can be retrieved via MmGetSystemRoutineAddress, you may use CRT/gen_wrapper.sh to create wrapper modules. These modules retrieve the desired functions during run-time, but will be available during link-time. An example is ZwTraceControl, which gets exported by ntdll.dll. Eventually missing intrinsics/built-ins should be placed in CRT/kcrt.c.

Notes on SEH

There are some limitations regarding the use of MingW's SEH implementation in kernel mode. You can not use it as you might have been known it from MSVC or MingW.

Predefined statements __try, __catch, __finally, __try1, __catch1, etc. do not work!

You need to use something like:

#include <except.h>

int handler(_In_ EXCEPTION_POINTERS * ep)
{
    (void)ep;
    return EXCEPTION_EXECUTE_HANDLER;
}

// ...

__dpptry(handler, unique_identifier) {
    *(int *)0 = 0;
} __dppexcept(unique_identifier) {
    DbgPrint("%s\n", "Exception caught!");
} __dpptryend(unique_identifier);

SEH needs to be improved. Patches are welcome!

Known Issues

Unfortunately, eastl::to_string does not work. See CRT/eastl_compat.cpp for more details. Instead, #include <eastl_compat.hpp> and use ::to_string globals.

Thanks goes to:

  • Zeranoe for the Mingw64 build script
  • sidyhe for some copy paste ready CRT code
  • liupengs helped me to fix the ctor/dtor issue

and last but not least:

  • EA, bad company, good STL

mingw-w64-dpp's People

Contributors

tmm1 avatar utoni avatar zeranoe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

mingw-w64-dpp's Issues

Driver sign not working

Hello.

Thanks for great project!

I have tried to build self-signed driver from Your sample https://github.com/utoni/mingw-w64-driver . So I have added few lines into Makefile:

      install: $(DRIVER_TARGET)
            $(call INSTALL_EXEC_SIGN,$(DRIVER_TARGET))

Then run build with command make DPP_ROOT=../mingw-w64-dpp/ DESTDIR=bin install.

After that in bin directory files codesign-ca-cert.crt and driver.sys appeared.

I have installed certificate in system and tried to install driver with sc.exe [create|start]. On start it failed with signature error.

I have found issues mtrojnar/osslsigncode#86 and mtrojnar/osslsigncode#111 . So I believe that this should work.

Could You please provide some more details on the topic?

Thanks in advance!

Intronsics _disable and _enable not defined

Hello,

Using intrinsics "_disable" and "_enable" ( https://learn.microsoft.com/en-us/cpp/preprocessor/intrinsic?view=msvc-170 ) lead to errors:

~/driver-project/dpp/mingw-w64-sysroot/x86_64/lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld: src/main.o:main.c:(.text$main+0x19): undefined reference to `_disable'
~/driver-project/dpp/mingw-w64-sysroot/x86_64/lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld: src/main.o:main.c:(.text$main+0x52): undefined reference to `_enable'
collect2: error: ld returned 1 exit status
Makefile:20: recipe for target 'driver.sys' failed
make: *** [driver.sys] Error 1

I have tried with and without:

#pragma intrinsic(_enable,_disable)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.