├── image ├── sample.png ├── dependency.png ├── new_project.png ├── properties.png └── source_file.png ├── .gitmodules ├── cs_driver ├── cs_driver_mm.h ├── cs_driver.vcxproj.filters ├── cs_driver_test.cpp ├── cs_driver.inf ├── cs_driver.c ├── cs_driver_mm.c └── cs_driver.vcxproj ├── LICENSE ├── cs_driver.sln ├── .gitignore └── README.md /image/sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tandasat/cs_driver/HEAD/image/sample.png -------------------------------------------------------------------------------- /image/dependency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tandasat/cs_driver/HEAD/image/dependency.png -------------------------------------------------------------------------------- /image/new_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tandasat/cs_driver/HEAD/image/new_project.png -------------------------------------------------------------------------------- /image/properties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tandasat/cs_driver/HEAD/image/properties.png -------------------------------------------------------------------------------- /image/source_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tandasat/cs_driver/HEAD/image/source_file.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "capstone"] 2 | path = capstone 3 | url = https://github.com/tandasat/capstone.git 4 | -------------------------------------------------------------------------------- /cs_driver/cs_driver_mm.h: -------------------------------------------------------------------------------- 1 | #ifndef CAPSTONE_CS_DRIVER_MM_H_ 2 | #define CAPSTONE_CS_DRIVER_MM_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | /* 11 | Initializes Capstone dynamic memory management for Windows drivers 12 | 13 | @return: CS_ERR_OK on success, or other value on failure. 14 | Refer to cs_err enum for detailed error. 15 | 16 | NOTE: cs_driver_init() can be called at IRQL <= DISPATCH_LEVEL. 17 | */ 18 | cs_err CAPSTONE_API cs_driver_mm_init(); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif // CAPSTONE_CS_DRIVER_MM_H_ 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Satoshi Tanda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cs_driver/cs_driver.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /cs_driver/cs_driver_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../myinttypes.h" 3 | #include 4 | 5 | #pragma warning(push) 6 | #pragma warning(disable : 4005) // 'identifier' : macro redefinition 7 | #pragma warning(disable : 4007) // 'main': must be '__cdecl' 8 | 9 | // "Import" existing tests into this file. All code is encaptured into unique 10 | // namespace so that the same name does not conflict. Beware that those code 11 | // is going to be compiled as C++ source file and not C files because this file 12 | // is C++. 13 | 14 | namespace unnamed { 15 | #include "../tests/test.c" 16 | } // namespace unnamed 17 | 18 | namespace arm { 19 | #include "../tests/test_arm.c" 20 | } // namespace arm 21 | 22 | namespace arm64 { 23 | #include "../tests/test_arm64.c" 24 | } // namespace arm64 25 | 26 | namespace detail { 27 | #include "../tests/test_detail.c" 28 | } // namespace detail 29 | 30 | namespace iter { 31 | #include "../tests/test_iter.c" 32 | } // namespace iter 33 | 34 | namespace mips { 35 | #include "../tests/test_mips.c" 36 | } // namespace mips 37 | 38 | namespace ppc { 39 | #include "../tests/test_ppc.c" 40 | } // namespace ppc 41 | 42 | namespace skipdata { 43 | #include "../tests/test_skipdata.c" 44 | } // namespace skipdata 45 | 46 | namespace sparc { 47 | #include "../tests/test_sparc.c" 48 | } // namespace sparc 49 | 50 | namespace systemz { 51 | #include "../tests/test_systemz.c" 52 | } // namespace systemz 53 | 54 | namespace x86 { 55 | #include "../tests/test_x86.c" 56 | } // namespace x86 57 | 58 | namespace xcore { 59 | #include "../tests/test_xcore.c" 60 | } // namespace xcore 61 | 62 | #pragma warning(pop) 63 | 64 | // Exercises all existing regression tests 65 | EXTERN_C void cs_driver_regression_test() { 66 | KFLOATING_SAVE float_save; 67 | NTSTATUS status = KeSaveFloatingPointState(&float_save); 68 | NT_VERIFY(NT_SUCCESS(status)); 69 | 70 | unnamed::test(); 71 | arm::test(); 72 | arm64::test(); 73 | detail::test(); 74 | iter::test(); 75 | mips::test(); 76 | ppc::test(); 77 | skipdata::test(); 78 | sparc::test(); 79 | systemz::test(); 80 | x86::test(); 81 | xcore::test(); 82 | 83 | KeRestoreFloatingPointState(&float_save); 84 | } 85 | -------------------------------------------------------------------------------- /cs_driver/cs_driver.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; cs_driver.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=Sample ; TODO: edit Class 8 | ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=cs_driver.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | 16 | ; ================= Class section ===================== 17 | 18 | [ClassInstall32] 19 | Addreg=SampleClassReg 20 | 21 | [SampleClassReg] 22 | HKR,,,0,%ClassName% 23 | HKR,,Icon,,-5 24 | 25 | [SourceDisksNames] 26 | 1 = %DiskName%,,,"" 27 | 28 | [SourceDisksFiles] 29 | cs_driver.sys = 1,, 30 | 31 | ;***************************************** 32 | ; Install Section 33 | ;***************************************** 34 | 35 | [Manufacturer] 36 | %ManufacturerName%=Standard,NT$ARCH$ 37 | 38 | [Standard.NT$ARCH$] 39 | %cs_driver.DeviceDesc%=cs_driver_Device, Root\cs_driver ; TODO: edit hw-id 40 | 41 | [cs_driver_Device.NT] 42 | CopyFiles=Drivers_Dir 43 | 44 | [Drivers_Dir] 45 | cs_driver.sys 46 | 47 | ;-------------- Service installation 48 | [cs_driver_Device.NT.Services] 49 | AddService = cs_driver,%SPSVCINST_ASSOCSERVICE%, cs_driver_Service_Inst 50 | 51 | ; -------------- cs_driver driver install sections 52 | [cs_driver_Service_Inst] 53 | DisplayName = %cs_driver.SVCDESC% 54 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 55 | StartType = 3 ; SERVICE_DEMAND_START 56 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 57 | ServiceBinary = %12%\cs_driver.sys 58 | 59 | ; 60 | ;--- cs_driver_Device Coinstaller installation ------ 61 | ; 62 | 63 | [DestinationDirs] 64 | cs_driver_Device_CoInstaller_CopyFiles = 11 65 | 66 | [cs_driver_Device.NT.CoInstallers] 67 | AddReg=cs_driver_Device_CoInstaller_AddReg 68 | CopyFiles=cs_driver_Device_CoInstaller_CopyFiles 69 | 70 | [cs_driver_Device_CoInstaller_AddReg] 71 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 72 | 73 | [cs_driver_Device_CoInstaller_CopyFiles] 74 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 75 | 76 | [SourceDisksFiles] 77 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 78 | 79 | [cs_driver_Device.NT.Wdf] 80 | KmdfService = cs_driver, cs_driver_wdfsect 81 | [cs_driver_wdfsect] 82 | KmdfLibraryVersion = $KMDFVERSION$ 83 | 84 | [Strings] 85 | SPSVCINST_ASSOCSERVICE= 0x00000002 86 | ManufacturerName="" ;TODO: Replace with your manufacturer name 87 | ClassName="Samples" ; TODO: edit ClassName 88 | DiskName = "cs_driver Installation Disk" 89 | cs_driver.DeviceDesc = "cs_driver Device" 90 | cs_driver.SVCDESC = "cs_driver Service" 91 | -------------------------------------------------------------------------------- /cs_driver.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cs_driver", "cs_driver\cs_driver.vcxproj", "{942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {5B01D900-2359-44CA-9914-6B0C6AFB7BE7} = {5B01D900-2359-44CA-9914-6B0C6AFB7BE7} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "capstone_static", "capstone\msvc\capstone_static\capstone_static.vcxproj", "{5B01D900-2359-44CA-9914-6B0C6AFB7BE7}" 12 | EndProject 13 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F4FA38A0-1D9F-429D-B837-304D62290A2A}" 14 | ProjectSection(SolutionItems) = preProject 15 | README.md = README.md 16 | EndProjectSection 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|x64 = Debug|x64 21 | Debug|x86 = Debug|x86 22 | Release|x64 = Release|x64 23 | Release|x86 = Release|x86 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Debug|x64.ActiveCfg = Debug|x64 27 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Debug|x64.Build.0 = Debug|x64 28 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Debug|x64.Deploy.0 = Debug|x64 29 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Debug|x86.ActiveCfg = Debug|Win32 30 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Debug|x86.Build.0 = Debug|Win32 31 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Debug|x86.Deploy.0 = Debug|Win32 32 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Release|x64.ActiveCfg = Release|x64 33 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Release|x64.Build.0 = Release|x64 34 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Release|x64.Deploy.0 = Release|x64 35 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Release|x86.ActiveCfg = Release|Win32 36 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Release|x86.Build.0 = Release|Win32 37 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E}.Release|x86.Deploy.0 = Release|Win32 38 | {5B01D900-2359-44CA-9914-6B0C6AFB7BE7}.Debug|x64.ActiveCfg = Debug_WDK|x64 39 | {5B01D900-2359-44CA-9914-6B0C6AFB7BE7}.Debug|x64.Build.0 = Debug_WDK|x64 40 | {5B01D900-2359-44CA-9914-6B0C6AFB7BE7}.Debug|x86.ActiveCfg = Debug_WDK|Win32 41 | {5B01D900-2359-44CA-9914-6B0C6AFB7BE7}.Debug|x86.Build.0 = Debug_WDK|Win32 42 | {5B01D900-2359-44CA-9914-6B0C6AFB7BE7}.Release|x64.ActiveCfg = Release_WDK|x64 43 | {5B01D900-2359-44CA-9914-6B0C6AFB7BE7}.Release|x64.Build.0 = Release_WDK|x64 44 | {5B01D900-2359-44CA-9914-6B0C6AFB7BE7}.Release|x86.ActiveCfg = Release_WDK|Win32 45 | {5B01D900-2359-44CA-9914-6B0C6AFB7BE7}.Release|x86.Build.0 = Release_WDK|Win32 46 | EndGlobalSection 47 | GlobalSection(SolutionProperties) = preSolution 48 | HideSolutionNode = FALSE 49 | EndGlobalSection 50 | EndGlobal 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | *.VC.opendb 5 | *.VC.db 6 | 7 | # User-specific files 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Dd]ebug_WDK/ 20 | [Rr]elease/ 21 | [Rr]elease_WDK/ 22 | [Rr]eleases/ 23 | x64/ 24 | x86/ 25 | build/ 26 | bld/ 27 | [Bb]in/ 28 | [Oo]bj/ 29 | 30 | # Visual Studio 2015 cache/options directory 31 | .vs/ 32 | 33 | # MSTest test Results 34 | [Tt]est[Rr]esult*/ 35 | [Bb]uild[Ll]og.* 36 | 37 | # NUNIT 38 | *.VisualState.xml 39 | TestResult.xml 40 | 41 | # Build Results of an ATL Project 42 | [Dd]ebugPS/ 43 | [Rr]eleasePS/ 44 | dlldata.c 45 | 46 | # DNX 47 | project.lock.json 48 | artifacts/ 49 | 50 | *_i.c 51 | *_p.c 52 | *_i.h 53 | *.ilk 54 | *.meta 55 | *.obj 56 | *.pch 57 | *.pdb 58 | *.pgc 59 | *.pgd 60 | *.rsp 61 | *.sbr 62 | *.tlb 63 | *.tli 64 | *.tlh 65 | *.tmp 66 | *.tmp_proj 67 | *.log 68 | *.vspscc 69 | *.vssscc 70 | .builds 71 | *.pidb 72 | *.svclog 73 | *.scc 74 | 75 | # Chutzpah Test files 76 | _Chutzpah* 77 | 78 | # Visual C++ cache files 79 | ipch/ 80 | *.aps 81 | *.ncb 82 | *.opensdf 83 | *.sdf 84 | *.cachefile 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | 115 | # MightyMoose 116 | *.mm.* 117 | AutoTest.Net/ 118 | 119 | # Web workbench (sass) 120 | .sass-cache/ 121 | 122 | # Installshield output folder 123 | [Ee]xpress/ 124 | 125 | # DocProject is a documentation generator add-in 126 | DocProject/buildhelp/ 127 | DocProject/Help/*.HxT 128 | DocProject/Help/*.HxC 129 | DocProject/Help/*.hhc 130 | DocProject/Help/*.hhk 131 | DocProject/Help/*.hhp 132 | DocProject/Help/Html2 133 | DocProject/Help/html 134 | 135 | # Click-Once directory 136 | publish/ 137 | 138 | # Publish Web Output 139 | *.[Pp]ublish.xml 140 | *.azurePubxml 141 | ## TODO: Comment the next line if you want to checkin your 142 | ## web deploy settings but do note that will include unencrypted 143 | ## passwords 144 | #*.pubxml 145 | 146 | *.publishproj 147 | 148 | # NuGet Packages 149 | *.nupkg 150 | # The packages folder can be ignored because of Package Restore 151 | **/packages/* 152 | # except build/, which is used as an MSBuild target. 153 | !**/packages/build/ 154 | # Uncomment if necessary however generally it will be regenerated when needed 155 | #!**/packages/repositories.config 156 | 157 | # Windows Azure Build Output 158 | csx/ 159 | *.build.csdef 160 | 161 | # Windows Store app package directory 162 | AppPackages/ 163 | 164 | # Visual Studio cache files 165 | # files ending in .cache can be ignored 166 | *.[Cc]ache 167 | # but keep track of directories ending in .cache 168 | !*.[Cc]ache/ 169 | 170 | # Others 171 | ClientBin/ 172 | [Ss]tyle[Cc]op.* 173 | ~$* 174 | *~ 175 | *.dbmdl 176 | *.dbproj.schemaview 177 | *.pfx 178 | *.publishsettings 179 | node_modules/ 180 | orleans.codegen.cs 181 | 182 | # RIA/Silverlight projects 183 | Generated_Code/ 184 | 185 | # Backup & report files from converting an old project file 186 | # to a newer Visual Studio version. Backup files are not needed, 187 | # because we have git ;-) 188 | _UpgradeReport_Files/ 189 | Backup*/ 190 | UpgradeLog*.XML 191 | UpgradeLog*.htm 192 | 193 | # SQL Server files 194 | *.mdf 195 | *.ldf 196 | 197 | # Business Intelligence projects 198 | *.rdl.data 199 | *.bim.layout 200 | *.bim_*.settings 201 | 202 | # Microsoft Fakes 203 | FakesAssemblies/ 204 | 205 | # Node.js Tools for Visual Studio 206 | .ntvs_analysis.dat 207 | 208 | # Visual Studio 6 build log 209 | *.plg 210 | 211 | # Visual Studio 6 workspace options file 212 | *.opt 213 | 214 | # LightSwitch generated files 215 | GeneratedArtifacts/ 216 | _Pvt_Extensions/ 217 | ModelManifest.xml 218 | -------------------------------------------------------------------------------- /cs_driver/cs_driver.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cs_driver_mm.h" 3 | 4 | // 'conversion' : from function pointer 'type1' to data pointer 'type2' 5 | #pragma warning(disable : 4054) 6 | 7 | EXTERN_C int cs_snprintf(char *buffer, size_t size, const char *fmt, ...); 8 | EXTERN_C void cs_driver_regression_test(); 9 | 10 | DRIVER_INITIALIZE DriverEntry; 11 | static void cs_driver_tests(); 12 | static NTSTATUS cs_driver_hello(); 13 | static void cs_driver_vsnprintf_test(); 14 | 15 | 16 | // Driver entry point 17 | EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, 18 | PUNICODE_STRING RegistryPath) { 19 | printf("Entering DriverEntry()\n"); 20 | 21 | KdBreakPoint(); 22 | cs_driver_tests(); 23 | 24 | printf("Leaving DriverEntry()\n"); 25 | return STATUS_CANCELLED; 26 | } 27 | 28 | // Exercises all tests 29 | static void cs_driver_tests() { 30 | cs_driver_hello(); 31 | cs_driver_vsnprintf_test(); 32 | cs_driver_regression_test(); 33 | } 34 | 35 | // Hello, Capstone! 36 | static NTSTATUS cs_driver_hello() { 37 | csh handle; 38 | cs_insn *insn; 39 | size_t count; 40 | KFLOATING_SAVE float_save; 41 | NTSTATUS status = STATUS_UNSUCCESSFUL; 42 | 43 | // Any of Capstone APIs cannot be called at IRQL higher than DISPATCH_LEVEL 44 | // since our malloc implementation using ExAllocatePoolWithTag() is able to 45 | // allocate memory only up to the DISPATCH_LEVEL level. 46 | NT_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 47 | 48 | // Setup our own dynamic memory functions with cs_driver_init(). 49 | if (cs_driver_mm_init() != CS_ERR_OK) { 50 | // Failed to initialize our user-defined dynamic mem functions. 51 | // Quit is the only choice here :-( 52 | return STATUS_UNSUCCESSFUL; 53 | } 54 | 55 | // On a 32bit driver, KeSaveFloatingPointState() is required before using any 56 | // Capstone function because Capstone can access to the MMX/x87 registers and 57 | // 32bit Windows requires drivers to use KeSaveFloatingPointState() before and 58 | // KeRestoreFloatingPointState() after accesing to them. See "Using Floating 59 | // Point or MMX in a WDM Driver" on MSDN for more details. 60 | status = KeSaveFloatingPointState(&float_save); 61 | if (!NT_SUCCESS(status)) { 62 | return status; 63 | } 64 | 65 | if (cs_open(CS_ARCH_X86, (sizeof(void *) == 4) ? CS_MODE_32 : CS_MODE_64, 66 | &handle) != CS_ERR_OK) { 67 | goto exit; 68 | } 69 | 70 | count = cs_disasm(handle, (uint8_t *)&cs_driver_hello, 0x100, 71 | (uint64_t)&cs_driver_hello, 0, &insn); 72 | if (count > 0) { 73 | printf("cs_driver!cs_driver_hello:\n"); 74 | for (size_t j = 0; j < count; j++) { 75 | printf("0x%p\t%s\t\t%s\n", (void *)(uintptr_t)insn[j].address, 76 | insn[j].mnemonic, insn[j].op_str); 77 | } 78 | cs_free(insn, count); 79 | } 80 | cs_close(&handle); 81 | 82 | exit:; 83 | // Restores the nonvolatile floating-point context. 84 | KeRestoreFloatingPointState(&float_save); 85 | return status; 86 | } 87 | 88 | // Functional test for cs_driver_vsnprintf() 89 | static void cs_driver_vsnprintf_test() { 90 | char buf[10]; 91 | NT_VERIFY(cs_snprintf(buf, sizeof(buf), "%s", "") == 0 && 92 | strcmp(buf, "") == 0); 93 | NT_VERIFY(cs_snprintf(buf, sizeof(buf), "%s", "0") == 1 && 94 | strcmp(buf, "0") == 0); 95 | NT_VERIFY(cs_snprintf(buf, sizeof(buf), "%s", "012345678") == 9 && 96 | strcmp(buf, "012345678") == 0); 97 | NT_VERIFY(cs_snprintf(buf, sizeof(buf), "%s", "0123456789") == 10 && 98 | strcmp(buf, "012345678") == 0); 99 | NT_VERIFY(cs_snprintf(buf, sizeof(buf), "%s", "01234567890") == 11 && 100 | strcmp(buf, "012345678") == 0); 101 | NT_VERIFY(cs_snprintf(buf, sizeof(buf), "%s", "0123456789001234567890") == 102 | 22 && 103 | strcmp(buf, "012345678") == 0); 104 | NT_VERIFY(cs_snprintf(buf, sizeof(buf), "%s", NULL) == 6 && 105 | strcmp(buf, "(null)") == 0); 106 | } 107 | 108 | // printf() is required to exercise regression test etc. It can be omitted if 109 | // those are not used in the project. This functions mimics printf() but does 110 | // not return the same value as printf() would do. 111 | _Use_decl_annotations_ int __cdecl printf(const char *_Format, ...) { 112 | NTSTATUS status; 113 | va_list args; 114 | 115 | va_start(args, _Format); 116 | status = vDbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL, _Format, args); 117 | va_end(args); 118 | return NT_SUCCESS(status); 119 | } 120 | -------------------------------------------------------------------------------- /cs_driver/cs_driver_mm.c: -------------------------------------------------------------------------------- 1 | #include "cs_driver_mm.h" 2 | #include 3 | 4 | // A pool tag for memory allocation 5 | static const ULONG CS_DRIVER_POOL_TAG = 'rdsC'; 6 | 7 | 8 | // A structure to implement realloc() 9 | typedef struct _CS_DRIVER_MEMBLOCK 10 | { 11 | size_t size; // A number of bytes allocated 12 | char data[1]; // An address returned to a caller 13 | } CS_DRIVER_MEMBLOCK; 14 | C_ASSERT(sizeof(CS_DRIVER_MEMBLOCK) == sizeof(void *) * 2); 15 | 16 | 17 | // free() 18 | static void CAPSTONE_API csdrv_free(void *ptr) 19 | { 20 | if (ptr) 21 | { 22 | ExFreePoolWithTag(CONTAINING_RECORD(ptr, CS_DRIVER_MEMBLOCK, data), 23 | CS_DRIVER_POOL_TAG); 24 | } 25 | } 26 | 27 | // malloc() 28 | static void * CAPSTONE_API csdrv_malloc(size_t size) 29 | { 30 | // Disallow zero length allocation because they waste pool header space and, 31 | // in many cases, indicate a potential validation issue in the calling code. 32 | NT_ASSERT(size); 33 | 34 | CS_DRIVER_MEMBLOCK *block = (CS_DRIVER_MEMBLOCK *)ExAllocatePoolWithTag( 35 | NonPagedPoolNx, size + sizeof(CS_DRIVER_MEMBLOCK), CS_DRIVER_POOL_TAG); 36 | if (!block) 37 | { 38 | return NULL; 39 | } 40 | block->size = size; 41 | return block->data; 42 | } 43 | 44 | // calloc() 45 | static void * CAPSTONE_API csdrv_calloc(size_t n, size_t size) 46 | { 47 | size_t total = n * size; 48 | 49 | void *new_ptr = csdrv_malloc(total); 50 | if (!new_ptr) 51 | { 52 | return NULL; 53 | } 54 | 55 | return RtlFillMemory(new_ptr, total, 0); 56 | } 57 | 58 | // realloc() 59 | static void * CAPSTONE_API csdrv_realloc(void *ptr, size_t size) 60 | { 61 | void *new_ptr = NULL; 62 | size_t current_size = 0; 63 | size_t smaller_size = 0; 64 | 65 | if (!ptr) 66 | { 67 | return csdrv_malloc(size); 68 | } 69 | 70 | new_ptr = csdrv_malloc(size); 71 | if (!new_ptr) 72 | { 73 | return NULL; 74 | } 75 | 76 | current_size = CONTAINING_RECORD(ptr, CS_DRIVER_MEMBLOCK, data)->size; 77 | smaller_size = (current_size < size) ? current_size : size; 78 | RtlCopyMemory(new_ptr, ptr, smaller_size); 79 | csdrv_free(ptr); 80 | return new_ptr; 81 | } 82 | 83 | // vsnprintf(). _vsnprintf() is avaialable for drivers, but it differs from 84 | // vsnprintf() in a return value and when a null-terminater is set. 85 | // csdrv_vsnprintf() takes care of those differences. 86 | #pragma warning(push) 87 | #pragma warning(disable : 28719) // Banned API Usage : _vsnprintf is a Banned 88 | // API as listed in dontuse.h for security 89 | // purposes. 90 | static int CAPSTONE_API csdrv_vsnprintf(char *buffer, size_t count, 91 | const char *format, va_list argptr) 92 | { 93 | int result = _vsnprintf(buffer, count, format, argptr); 94 | 95 | // _vsnprintf() returns -1 when a string is truncated, and returns "count" 96 | // when an entire string is stored but without '\0' at the end of "buffer". 97 | // In both cases, null-terminater needs to be added manually. 98 | if (result == -1 || (size_t)result == count) 99 | { 100 | buffer[count - 1] = '\0'; 101 | } 102 | if (result == -1) 103 | { 104 | // In case when -1 is returned, the function has to get and return a number 105 | // of characters that would have been written. This attempts so by re-tring 106 | // the same conversion with temp buffer that is most likely big enough to 107 | // complete formatting and get a number of characters that would have been 108 | // written. 109 | char tmp[1024]; 110 | result = _vsnprintf(tmp, RTL_NUMBER_OF(tmp), format, argptr); 111 | NT_ASSERT(result != -1); 112 | } 113 | 114 | return result; 115 | } 116 | #pragma warning(pop) 117 | 118 | /* 119 | Initializes Capstone dynamic memory management for Windows drivers 120 | 121 | @return: CS_ERR_OK on success, or other value on failure. 122 | Refer to cs_err enum for detailed error. 123 | 124 | NOTE: cs_driver_init() can be called at IRQL <= DISPATCH_LEVEL. 125 | */ 126 | cs_err CAPSTONE_API cs_driver_mm_init() 127 | { 128 | KFLOATING_SAVE float_save; 129 | NTSTATUS status; 130 | cs_opt_mem setup; 131 | cs_err err; 132 | 133 | NT_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 134 | 135 | // Capstone API may use floating point. 136 | status = KeSaveFloatingPointState(&float_save); 137 | if (!NT_SUCCESS(status)) 138 | { 139 | return CS_ERR_MEM; 140 | } 141 | 142 | setup.malloc = csdrv_malloc; 143 | setup.calloc = csdrv_calloc; 144 | setup.realloc = csdrv_realloc; 145 | setup.free = csdrv_free; 146 | setup.vsnprintf = csdrv_vsnprintf; 147 | err = cs_option(0, CS_OPT_MEM, (size_t)&setup); 148 | 149 | KeRestoreFloatingPointState(&float_save); 150 | return err; 151 | } 152 | -------------------------------------------------------------------------------- /cs_driver/cs_driver.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | {942ABF0B-6B0D-49CE-A4EE-7C1C7414D60E} 26 | {497e31cb-056b-4f31-abb8-447fd55ee5a5} 27 | v4.5 28 | 12.0 29 | Debug 30 | Win32 31 | cs_driver 32 | 33 | 34 | 35 | Windows7 36 | true 37 | WindowsKernelModeDriver10.0 38 | Driver 39 | KMDF 40 | Desktop 41 | 42 | 43 | Windows7 44 | false 45 | WindowsKernelModeDriver10.0 46 | Driver 47 | KMDF 48 | Desktop 49 | 50 | 51 | Windows7 52 | true 53 | WindowsKernelModeDriver10.0 54 | Driver 55 | KMDF 56 | Desktop 57 | 58 | 59 | Windows7 60 | false 61 | WindowsKernelModeDriver10.0 62 | Driver 63 | KMDF 64 | Desktop 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | DbgengKernelDebugger 76 | 77 | 78 | DbgengKernelDebugger 79 | 80 | 81 | DbgengKernelDebugger 82 | 83 | 84 | DbgengKernelDebugger 85 | 86 | 87 | 88 | true 89 | trace.h 90 | true 91 | $(SolutionDir)capstone\include;$(IntDir);%(AdditionalIncludeDirectories) 92 | 93 | 94 | $(OutDir)..\$(ConfigurationName)_WDK\capstone.lib;ntstrsafe.lib;%(AdditionalDependencies) 95 | 96 | 97 | 98 | 99 | true 100 | trace.h 101 | true 102 | $(SolutionDir)capstone\include;$(IntDir);%(AdditionalIncludeDirectories) 103 | 104 | 105 | $(OutDir)..\$(ConfigurationName)_WDK\capstone.lib;ntstrsafe.lib;%(AdditionalDependencies) 106 | 107 | 108 | 109 | 110 | true 111 | trace.h 112 | true 113 | $(SolutionDir)capstone\include;$(IntDir);%(AdditionalIncludeDirectories) 114 | 115 | 116 | $(OutDir)..\$(ConfigurationName)_WDK\capstone.lib;ntstrsafe.lib;%(AdditionalDependencies) 117 | 118 | 119 | 120 | 121 | true 122 | trace.h 123 | true 124 | $(SolutionDir)capstone\include;$(IntDir);%(AdditionalIncludeDirectories) 125 | 126 | 127 | $(OutDir)..\$(ConfigurationName)_WDK\capstone.lib;ntstrsafe.lib;%(AdditionalDependencies) 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cs_driver 2 | cs_driver is a sample project for using Capstone from a driver in Visual Studio 3 | 2015. This project aims to provide a minimal, clean procedure to compile and link 4 | the Capstone disassembly framework in your Windows driver project. For more 5 | information about Capstone, see its project page. 6 | - http://www.capstone-engine.org/ 7 | 8 | # Good news :-) 9 | This project is completely merged to the master branch of Capstone. Capstone now 10 | supports make use of it from your drivers. Learn more with msvc/README on 11 | Capstone project page. 12 | - https://github.com/aquynh/capstone/tree/master/msvc 13 | 14 | 15 | This project is left only as a record, and no further work or support is planned. 16 | 17 | 18 | ## Sample Output 19 | ![sample](/image/sample.png) 20 | 21 | 22 | ## Motivation 23 | Capstone is a reliable, supported disassemler developed by an active community. 24 | It is designed for multi-platform support in first place, and supports usage by 25 | OS kernel code. In fact, one of Capstone documents refers to a sample project 26 | for learning how to embed Capstone into an Windows kernel driver. 27 | - https://github.com/aquynh/KernelProject 28 | 29 | However, this project lacks information about how to actually configure your 30 | driver project and compile Capstone. Also, it refers to a two-year-old branch 31 | and cannot be compiled with Visual Studio 2015 with described instructions. Not 32 | only that, the repository consists of 50000+, 1.3GB of files in order to 33 | demonstrate make use of C++ Standard Template Library and Boost Libraries from 34 | drivers while those libraries are neither relevant to Capstone nor always 35 | demanded. For those reasons, the sample project is not overly helpful for those 36 | who want to learn how to use Capstone in Windows drivers. 37 | 38 | cs_driver, on the other hand, explains how to configure your and Capstone project 39 | and includes only minimum amount of code with detailed comments for learning a 40 | procedure to apply Capstone to your project quickly. Also, cs_driver is able to 41 | run all existing Capstone test code so that a developer can confirm that Capstone 42 | on the kernel mode is properly functioning. 43 | 44 | 45 | ## How to use Capstone from your WDK project 46 | In general, what you need to embed Capstone to a driver are: capstone.lib 47 | complied from the modified source code (contents of modification are explained 48 | later), ntstrsafe.lib to resolve __fltused, and cs_driver.h and some runtime 49 | initialization and safe guard code explained in cs_driver.c. 50 | 51 | In order to make use of Capstone from a new driver project, follow the below steps. 52 | 53 | 1. Check out the cs_driver repository and open cs_driver.sln. 54 | 55 | $ git clone --recursive https://github.com/tandasat/cs_driver.git 56 | 57 | 2. Add a new project "Kernel Mode Driver, Empty (KMDF)" to the cs_driver solution 58 | ![new_project](/image/new_project.png) 59 | 60 | 3. Add a source file to the new project 61 | 62 | ![source_file](/image/source_file.png) 63 | 64 | 4. Open a project properties of the cs_driver project and set Configuration to 65 | "All Configurations" and Platform to "All Platforms" 66 | - C/C++ > General > Additional Include Directories 67 | - $(SolutionDir)capstone\include 68 | - Linker > Input > Additional Dependencies 69 | - $(OutDir)..\$(ConfigurationName)_WDK\capstone.lib;ntstrsafe.lib 70 | ![properties](/image/properties.png) 71 | 72 | 5. Set dependency as below from [Project] > [Project Dependencies] 73 | ![dependency](/image/dependency.png) 74 | 75 | 6. Add cs_driver_mm.h and cs_driver_mm.c to the project and include the header 76 | from the source file. It can be done by referencing existing one or creating 77 | a copy under the project 78 | 79 | 7. In source code, call cs_driver_mm_init() in order to setup dynamic memory 80 | management of Capstone first. Also, do not forget to call 81 | KeSaveFloatingPointState() before using any of Capstone APIs on a 32bit 82 | system. For more details, refer to comments in cs_driver.c 83 | 84 | After this, you are free to use Capstone API from a driver. 85 | 86 | Those steps are just example and not a hard-rule. Developpers are also free to 87 | have separate solutions for Capstone and your driver as long as the driver can 88 | link capstone.lib and run equivalent code to what cs_driver.h provides. 89 | 90 | 91 | ## How the cloned Capstone was modified for WDK projects 92 | **EDIT: Those changes are begin merged into Capstone.** 93 | 94 | As of time cs_driver was created, source code of Capstone needs to be modified 95 | in order to compile, link and run all tests as part of a driver successfully. 96 | This sections explains what changes were made and why as a reference. Beware 97 | that you not need apply those changes when Capstone in this repository is used. 98 | 99 | #### Added CAPSTONE_API to all Capstone APIs 100 | - https://github.com/tandasat/capstone/commit/760940fdceb50a09f1a8ebee5dc807b6039f144e 101 | - https://github.com/tandasat/capstone/commit/6dad56669b1e2fb2f09484adfb5c494285204d18 102 | 103 | This change is to specifie calling convention for Calstone APIs. 104 | 105 | The default setting of calling convention is different between the capstone_static 106 | project and a WDK project. capstone_static compiles code with __cdecl calling 107 | converntion, while a WDK project compiles code as __stdcall, leading to link or 108 | runtime errors 109 | 110 | #### Replacesd snprintf() with cs_snprintf() 111 | - https://github.com/tandasat/capstone/commit/aba6117c6c6723dc446797d2b889f4b989cd512a 112 | - https://github.com/tandasat/capstone/commit/6bf747e5a59a0f785117198cc04c93391decae43 113 | - https://github.com/tandasat/capstone/commit/760940fdceb50a09f1a8ebee5dc807b6039f144e 114 | 115 | This change is to avoid making use of snprintf(), which is not available for 116 | drivers. 117 | 118 | **This change could lead to a runtime issue when user-defined vsnprintf() does 119 | not return the same value as what genuine vsnprintf() does.** In order to 120 | assess this impact, a developer is able to use the cs_driver_vsnprintf_test() 121 | function to test if their vsnprintf() conforms behaviour of that of the C/C++ 122 | standard. 123 | 124 | #### Avoided compile errors with regard to string literals 125 | - https://github.com/tandasat/capstone/commit/6bf747e5a59a0f785117198cc04c93391decae43 126 | 127 | This change is to avoid that strings comprise of PRI* macros is being threated 128 | as string literals and cause compile errors when compiled as C++11 and later. 129 | Details of this issue is explained under the "String literals followed by macros" 130 | section in the "Breaking Changes in Visual C++ 2015" page on MSDN. 131 | - https://msdn.microsoft.com/en-us/library/bb531344.aspx#BK_compiler 132 | 133 | This change was made because cs_driver_test.cpp attemped to compile all test 134 | code as C++ code for ease of excersising all regression test. 135 | 136 | #### Added and made use of CS_OPT_NONE and CS_OPT_OFF 137 | - https://github.com/tandasat/capstone/commit/6bf747e5a59a0f785117198cc04c93391decae43 138 | - https://github.com/tandasat/capstone/commit/760940fdceb50a09f1a8ebee5dc807b6039f144e 139 | 140 | This change is to avoid compile errors with regard to conversion errors from 141 | integer to enum (cs_opt_type and cs_opt_value) when test_skipdata.c is compiled 142 | as C++ source as part of cs_driver_test.cpp. 143 | 144 | #### Renamed a variable "i" to "ins" to avoid a warning 145 | - https://github.com/tandasat/capstone/commit/6bf747e5a59a0f785117198cc04c93391decae43 146 | 147 | This change is to avoid compiler warning C4456 with regard to shadowed variables 148 | and required because warnings are treated as errors in a WDK project by default. 149 | 150 | #### Added *_WDK configurations in the capstone_static project 151 | - https://github.com/tandasat/capstone/commit/8ae679e0dee211a7ea0cbebb50a978e63414877a 152 | 153 | This change is to add new build configurations for drivers. 154 | 155 | First of all, the project file was upgraded for Visual Studio 2015. Then, *_WDK 156 | configurations were made from existing configurations and following changes were 157 | made to the *_WDK configurations: 158 | - C/C++ > General > Debug Information Format 159 | - OLD: Program Database for Edit And Continue (/ZI) 160 | - NEW: Program Database (/Zi) 161 | - C/C++ > Preprocessor > Preprocessor Definitions 162 | - NEW: Deleted CAPSTONE_USE_SYS_DYN_MEM 163 | - C/C++ > Code Generation > Basic Runtime Checks 164 | - OLD: Both (/RTC1, equiv. to /RTCsu) (/RTC1) 165 | - NEW: Default 166 | - C/C++ > Code Generation > Runtime Library 167 | - OLD: Multi-threaded Debug (/MTd) 168 | - NEW: (empty) 169 | - C/C++ > All Options > Additional Options 170 | - OLD: (empty) 171 | - NEW: /kernel 172 | 173 | #### Replaced stdint.h with myinttypes.h 174 | - https://github.com/tandasat/capstone/commit/f04254a87c5fed7abddc3aa607ec8bc7f67bfc6a 175 | 176 | This change is to avoid compile errors due to make use of stdint.h, which is not 177 | available for drivers. 178 | 179 | #### Added _KERNEL_MODE support 180 | - https://github.com/tandasat/capstone/commit/52959a1bb8eca4d9162396cb4ea3cdfbf31a2b98 181 | - https://github.com/tandasat/capstone/commit/743bf536e0c14b4934c7d92cd5c749eef1baf258 182 | 183 | This change is to let myinttype.h and platform.h use the non-stanadard 184 | definitions instead of the standard headers (stdint.h and stdbool.h), which are 185 | not available for drivers. 186 | 187 | Note that _KERNEL_MODE is defined when a program is compiled with the /kernel 188 | option as explained in the "/kernel (Create Kernel Mode Binary)" page on MSDN. 189 | - https://msdn.microsoft.com/en-us/library/jj620896.aspx?f=255&MSPPError=-2147217396 190 | 191 | 192 | ## Supported Platforms 193 | - x86 and x64 Windows 7, 8.1 and 10 194 | 195 | 196 | ## License 197 | This software is released under the MIT License, see LICENSE. 198 | --------------------------------------------------------------------------------