├── .gitignore ├── README.md ├── resources ├── hiding_file.gif ├── infinityhook_log.gif └── perf.png └── src ├── infinityhook.sln ├── kinfinityhook ├── entry.cpp ├── entry.h ├── helpers.h ├── kinfinityhook.inf ├── kinfinityhook.vcxproj ├── kinfinityhook.vcxproj.filters ├── stdafx.cpp └── stdafx.h └── libinfinityhook ├── hde ├── hde64.cpp ├── hde64.h ├── pstdint.h └── table64.h ├── img.cpp ├── img.h ├── infinityhook.cpp ├── infinityhook.h ├── libinfinityhook.inf ├── libinfinityhook.vcxproj ├── libinfinityhook.vcxproj.filters ├── mm.cpp ├── mm.h ├── ntint.h ├── stdafx.cpp └── stdafx.h /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | 33 | # Visual Studio 2015/2017 cache/options directory 34 | .vs/ 35 | # Uncomment if you have tasks that create the project's static files in wwwroot 36 | #wwwroot/ 37 | 38 | # Visual Studio 2017 auto generated files 39 | Generated\ Files/ 40 | 41 | # MSTest test Results 42 | [Tt]est[Rr]esult*/ 43 | [Bb]uild[Ll]og.* 44 | 45 | # NUnit 46 | *.VisualState.xml 47 | TestResult.xml 48 | nunit-*.xml 49 | 50 | # Build Results of an ATL Project 51 | [Dd]ebugPS/ 52 | [Rr]eleasePS/ 53 | dlldata.c 54 | 55 | # Benchmark Results 56 | BenchmarkDotNet.Artifacts/ 57 | 58 | # .NET Core 59 | project.lock.json 60 | project.fragment.lock.json 61 | artifacts/ 62 | 63 | # StyleCop 64 | StyleCopReport.xml 65 | 66 | # Files built by Visual Studio 67 | *_i.c 68 | *_p.c 69 | *_h.h 70 | *.ilk 71 | *.meta 72 | *.obj 73 | *.iobj 74 | *.pch 75 | *.pdb 76 | *.ipdb 77 | *.pgc 78 | *.pgd 79 | *.rsp 80 | *.sbr 81 | *.tlb 82 | *.tli 83 | *.tlh 84 | *.tmp 85 | *.tmp_proj 86 | *_wpftmp.csproj 87 | *.log 88 | *.vspscc 89 | *.vssscc 90 | .builds 91 | *.pidb 92 | *.svclog 93 | *.scc 94 | 95 | # Chutzpah Test files 96 | _Chutzpah* 97 | 98 | # Visual C++ cache files 99 | ipch/ 100 | *.aps 101 | *.ncb 102 | *.opendb 103 | *.opensdf 104 | *.sdf 105 | *.cachefile 106 | *.VC.db 107 | *.VC.VC.opendb 108 | 109 | # Visual Studio profiler 110 | *.psess 111 | *.vsp 112 | *.vspx 113 | *.sap 114 | 115 | # Visual Studio Trace Files 116 | *.e2e 117 | 118 | # TFS 2012 Local Workspace 119 | $tf/ 120 | 121 | # Guidance Automation Toolkit 122 | *.gpState 123 | 124 | # ReSharper is a .NET coding add-in 125 | _ReSharper*/ 126 | *.[Rr]e[Ss]harper 127 | *.DotSettings.user 128 | 129 | # JustCode is a .NET coding add-in 130 | .JustCode 131 | 132 | # TeamCity is a build add-in 133 | _TeamCity* 134 | 135 | # DotCover is a Code Coverage Tool 136 | *.dotCover 137 | 138 | # AxoCover is a Code Coverage Tool 139 | .axoCover/* 140 | !.axoCover/settings.json 141 | 142 | # Visual Studio code coverage results 143 | *.coverage 144 | *.coveragexml 145 | 146 | # NCrunch 147 | _NCrunch_* 148 | .*crunch*.local.xml 149 | nCrunchTemp_* 150 | 151 | # MightyMoose 152 | *.mm.* 153 | AutoTest.Net/ 154 | 155 | # Web workbench (sass) 156 | .sass-cache/ 157 | 158 | # Installshield output folder 159 | [Ee]xpress/ 160 | 161 | # DocProject is a documentation generator add-in 162 | DocProject/buildhelp/ 163 | DocProject/Help/*.HxT 164 | DocProject/Help/*.HxC 165 | DocProject/Help/*.hhc 166 | DocProject/Help/*.hhk 167 | DocProject/Help/*.hhp 168 | DocProject/Help/Html2 169 | DocProject/Help/html 170 | 171 | # Click-Once directory 172 | publish/ 173 | 174 | # Publish Web Output 175 | *.[Pp]ublish.xml 176 | *.azurePubxml 177 | # Note: Comment the next line if you want to checkin your web deploy settings, 178 | # but database connection strings (with potential passwords) will be unencrypted 179 | *.pubxml 180 | *.publishproj 181 | 182 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 183 | # checkin your Azure Web App publish settings, but sensitive information contained 184 | # in these scripts will be unencrypted 185 | PublishScripts/ 186 | 187 | # NuGet Packages 188 | *.nupkg 189 | # NuGet Symbol Packages 190 | *.snupkg 191 | # The packages folder can be ignored because of Package Restore 192 | **/[Pp]ackages/* 193 | # except build/, which is used as an MSBuild target. 194 | !**/[Pp]ackages/build/ 195 | # Uncomment if necessary however generally it will be regenerated when needed 196 | #!**/[Pp]ackages/repositories.config 197 | # NuGet v3's project.json files produces more ignorable files 198 | *.nuget.props 199 | *.nuget.targets 200 | 201 | # Microsoft Azure Build Output 202 | csx/ 203 | *.build.csdef 204 | 205 | # Microsoft Azure Emulator 206 | ecf/ 207 | rcf/ 208 | 209 | # Windows Store app package directories and files 210 | AppPackages/ 211 | BundleArtifacts/ 212 | Package.StoreAssociation.xml 213 | _pkginfo.txt 214 | *.appx 215 | *.appxbundle 216 | *.appxupload 217 | 218 | # Visual Studio cache files 219 | # files ending in .cache can be ignored 220 | *.[Cc]ache 221 | # but keep track of directories ending in .cache 222 | !?*.[Cc]ache/ 223 | 224 | # Others 225 | ClientBin/ 226 | ~$* 227 | *~ 228 | *.dbmdl 229 | *.dbproj.schemaview 230 | *.jfm 231 | *.pfx 232 | *.publishsettings 233 | orleans.codegen.cs 234 | 235 | # Including strong name files can present a security risk 236 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 237 | #*.snk 238 | 239 | # Since there are multiple workflows, uncomment next line to ignore bower_components 240 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 241 | #bower_components/ 242 | 243 | # RIA/Silverlight projects 244 | Generated_Code/ 245 | 246 | # Backup & report files from converting an old project file 247 | # to a newer Visual Studio version. Backup files are not needed, 248 | # because we have git ;-) 249 | _UpgradeReport_Files/ 250 | Backup*/ 251 | UpgradeLog*.XML 252 | UpgradeLog*.htm 253 | ServiceFabricBackup/ 254 | *.rptproj.bak 255 | 256 | # SQL Server files 257 | *.mdf 258 | *.ldf 259 | *.ndf 260 | 261 | # Business Intelligence projects 262 | *.rdl.data 263 | *.bim.layout 264 | *.bim_*.settings 265 | *.rptproj.rsuser 266 | *- [Bb]ackup.rdl 267 | *- [Bb]ackup ([0-9]).rdl 268 | *- [Bb]ackup ([0-9][0-9]).rdl 269 | 270 | # Microsoft Fakes 271 | FakesAssemblies/ 272 | 273 | # GhostDoc plugin setting file 274 | *.GhostDoc.xml 275 | 276 | # Node.js Tools for Visual Studio 277 | .ntvs_analysis.dat 278 | node_modules/ 279 | 280 | # Visual Studio 6 build log 281 | *.plg 282 | 283 | # Visual Studio 6 workspace options file 284 | *.opt 285 | 286 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 287 | *.vbw 288 | 289 | # Visual Studio LightSwitch build output 290 | **/*.HTMLClient/GeneratedArtifacts 291 | **/*.DesktopClient/GeneratedArtifacts 292 | **/*.DesktopClient/ModelManifest.xml 293 | **/*.Server/GeneratedArtifacts 294 | **/*.Server/ModelManifest.xml 295 | _Pvt_Extensions 296 | 297 | # Paket dependency manager 298 | .paket/paket.exe 299 | paket-files/ 300 | 301 | # FAKE - F# Make 302 | .fake/ 303 | 304 | # CodeRush personal settings 305 | .cr/personal 306 | 307 | # Python Tools for Visual Studio (PTVS) 308 | __pycache__/ 309 | *.pyc 310 | 311 | # Cake - Uncomment if you are using it 312 | # tools/** 313 | # !tools/packages.config 314 | 315 | # Tabs Studio 316 | *.tss 317 | 318 | # Telerik's JustMock configuration file 319 | *.jmconfig 320 | 321 | # BizTalk build output 322 | *.btp.cs 323 | *.btm.cs 324 | *.odx.cs 325 | *.xsd.cs 326 | 327 | # OpenCover UI analysis results 328 | OpenCover/ 329 | 330 | # Azure Stream Analytics local run output 331 | ASALocalRun/ 332 | 333 | # MSBuild Binary and Structured Log 334 | *.binlog 335 | 336 | # NVidia Nsight GPU debugger configuration file 337 | *.nvuser 338 | 339 | # MFractors (Xamarin productivity tool) working folder 340 | .mfractor/ 341 | 342 | # Local History for Visual Studio 343 | .localhistory/ 344 | 345 | # BeatPulse healthcheck temp database 346 | healthchecksdb 347 | 348 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 349 | MigrationBackup/ 350 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Hook system calls, context switches, page faults, DPCs and more. InfinityHook works along side Patchguard and VBS/Hyperguard to subtly hook various kernel events. InfinityHook is incredibly portable and stealthy, it works in all versions of Windows 7 to the latest versions of Windows 10. 2 | 3 | InfinityHook stands to be one of the best tools in the rootkit arsenal over the last decade. 4 | 5 | 6 | # InfinityHook 7 | 8 | ![Hiding file example](/resources/hiding_file.gif) 9 | 10 | ## Usage 11 | The sample in this repository is a kernel driver that will hook system calls for you. It is extremely easy to use and requires you to call a single API. Please read below for usage instructions. We leave it upon the reader to decipher the implementation details and create hooks for other events like context switches, page faults, and DPCs. The comments embedded in the source files can help you toward this task. 12 | 13 | To use InfinityHook, simply reference the **libinfinityhook** library in your kernel driver and include `infinityhook.h`: 14 | 15 | Call `IfhInitialize`. You will need to pass a function pointer to a user-defined routine: 16 | ```C++ 17 | NTSTATUS IfhInitialize(_In_ INFINITYHOOKCALLBACK InfinityHookCallback) 18 | ``` 19 | 20 | Your callback should be of this type: 21 | ```C++ 22 | typedef void (__fastcall* INFINITYHOOKCALLBACK)(_In_ unsigned int SystemCallIndex, _Inout_ void** SystemCallFunction); 23 | ``` 24 | 25 | Your `InfinityHookCallback` is invoked before the system executes the actual system call. The first argument passed to your callback handler is the system call index, and the second is a function pointer to the system call that is about to be invoked. You may choose to overwrite this function pointer, and the system will branch to the routine of your choosing instead. This allows you to receive all of its arguments. Ideally, you would save off the original routine pointed to by `SystemCallFunction`, so your hook can invoke the original at some point allowing you to monitor/filter the data. 26 | 27 | ## How does InfinityHook actually work? 28 | To understand InfinityHook, a little background in ETW (Event Tracing for Windows) is helpful. ETW is a construct within the Windows kernel for logging and consuming a rather enormous amount of possible events. The three main components of this are controllers, providers, and consumers. A controller typically creates and defines a trace session. A trace session consists of a name, an identifier GUID, flags about how the kernel should serialize and prepare the data for consumers, and information about what providers are enabled for that session. A controller can also manage and modify existing built-in trace sessions. The main interface for a controller to do all of the aforementioned work is through the `NtTraceControl` API. 29 | 30 | A provider gives event data to logger sessions. It's typically through the `NtTraceEvent` API or the kernel equivalent, `EtwWrite`. Based on how the session is setup by the controller, a consumer, which is previously aware of the event data, either consumes the data in real time, a file, or perhaps occasionally from a circular buffer. 31 | 32 | To understand more on ETW internals, please read: https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing 33 | 34 | When a session is created, it has the opportunity to collect events from `SystemTraceProvider`, instead of collecting events from registered providers. A list of these events fired by `SystemTraceProvider` can be found here: https://docs.microsoft.com/en-us/windows/win32/etw/event-trace-properties 35 | 36 | It should be of note that this is not the complete list. There are plenty of undocumented ones ;). 37 | 38 | You'll probably notice that the list of items in `EnableFlags` is the same that InfinityHook allows you to hook. This is because each active logger session is put into an array of `WMI_LOGGER_CONTEXT` structures. They look like this: 39 | 40 | ``` 41 | 0: kd> dt nt!_WMI_LOGGER_CONTEXT 42 | +0x000 LoggerId : Uint4B 43 | +0x004 BufferSize : Uint4B 44 | +0x008 MaximumEventSize : Uint4B 45 | +0x00c LoggerMode : Uint4B 46 | +0x010 AcceptNewEvents : Int4B 47 | +0x014 EventMarker : [2] Uint4B 48 | +0x01c ErrorMarker : Uint4B 49 | +0x020 SizeMask : Uint4B 50 | +0x028 GetCpuClock : Ptr64 int64 51 | +0x030 LoggerThread : Ptr64 _ETHREAD 52 | +0x038 LoggerStatus : Int4B 53 | +0x03c FailureReason : Uint4B 54 | +0x040 BufferQueue : _ETW_BUFFER_QUEUE 55 | +0x050 OverflowQueue : _ETW_BUFFER_QUEUE 56 | +0x060 GlobalList : _LIST_ENTRY 57 | +0x070 DebugIdTrackingList : _LIST_ENTRY 58 | +0x080 DecodeControlList : Ptr64 _ETW_DECODE_CONTROL_ENTRY 59 | +0x088 DecodeControlCount : Uint4B 60 | +0x090 BatchedBufferList : Ptr64 _WMI_BUFFER_HEADER 61 | +0x090 CurrentBuffer : _EX_FAST_REF 62 | +0x098 LoggerName : _UNICODE_STRING 63 | +0x0a8 LogFileName : _UNICODE_STRING 64 | +0x0b8 LogFilePattern : _UNICODE_STRING 65 | +0x0c8 NewLogFileName : _UNICODE_STRING 66 | +0x0d8 ClockType : Uint4B 67 | +0x0dc LastFlushedBuffer : Uint4B 68 | +0x0e0 FlushTimer : Uint4B 69 | +0x0e4 FlushThreshold : Uint4B 70 | +0x0e8 ByteOffset : _LARGE_INTEGER 71 | +0x0f0 MinimumBuffers : Uint4B 72 | +0x0f4 BuffersAvailable : Int4B 73 | +0x0f8 NumberOfBuffers : Int4B 74 | +0x0fc MaximumBuffers : Uint4B 75 | +0x100 EventsLost : Uint4B 76 | +0x104 PeakBuffersCount : Int4B 77 | +0x108 BuffersWritten : Uint4B 78 | +0x10c LogBuffersLost : Uint4B 79 | +0x110 RealTimeBuffersDelivered : Uint4B 80 | +0x114 RealTimeBuffersLost : Uint4B 81 | +0x118 SequencePtr : Ptr64 Int4B 82 | +0x120 LocalSequence : Uint4B 83 | +0x124 InstanceGuid : _GUID 84 | +0x134 MaximumFileSize : Uint4B 85 | +0x138 FileCounter : Int4B 86 | +0x13c PoolType : _POOL_TYPE 87 | +0x140 ReferenceTime : _ETW_REF_CLOCK 88 | +0x150 CollectionOn : Int4B 89 | +0x154 ProviderInfoSize : Uint4B 90 | +0x158 Consumers : _LIST_ENTRY 91 | +0x168 NumConsumers : Uint4B 92 | +0x170 TransitionConsumer : Ptr64 _ETW_REALTIME_CONSUMER 93 | +0x178 RealtimeLogfileHandle : Ptr64 Void 94 | +0x180 RealtimeLogfileName : _UNICODE_STRING 95 | +0x190 RealtimeWriteOffset : _LARGE_INTEGER 96 | +0x198 RealtimeReadOffset : _LARGE_INTEGER 97 | +0x1a0 RealtimeLogfileSize : _LARGE_INTEGER 98 | +0x1a8 RealtimeLogfileUsage : Uint8B 99 | +0x1b0 RealtimeMaximumFileSize : Uint8B 100 | +0x1b8 RealtimeBuffersSaved : Uint4B 101 | +0x1c0 RealtimeReferenceTime : _ETW_REF_CLOCK 102 | +0x1d0 NewRTEventsLost : _ETW_RT_EVENT_LOSS 103 | +0x1d8 LoggerEvent : _KEVENT 104 | +0x1f0 FlushEvent : _KEVENT 105 | +0x208 FlushTimeOutTimer : _KTIMER 106 | +0x248 LoggerDpc : _KDPC 107 | +0x288 LoggerMutex : _KMUTANT 108 | +0x2c0 LoggerLock : _EX_PUSH_LOCK 109 | +0x2c8 BufferListSpinLock : Uint8B 110 | +0x2c8 BufferListPushLock : _EX_PUSH_LOCK 111 | +0x2d0 ClientSecurityContext : _SECURITY_CLIENT_CONTEXT 112 | +0x318 TokenAccessInformation : Ptr64 _TOKEN_ACCESS_INFORMATION 113 | +0x320 SecurityDescriptor : _EX_FAST_REF 114 | +0x328 StartTime : _LARGE_INTEGER 115 | +0x330 LogFileHandle : Ptr64 Void 116 | +0x338 BufferSequenceNumber : Int8B 117 | +0x340 Flags : Uint4B 118 | +0x340 Persistent : Pos 0, 1 Bit 119 | +0x340 AutoLogger : Pos 1, 1 Bit 120 | +0x340 FsReady : Pos 2, 1 Bit 121 | +0x340 RealTime : Pos 3, 1 Bit 122 | +0x340 Wow : Pos 4, 1 Bit 123 | +0x340 KernelTrace : Pos 5, 1 Bit 124 | +0x340 NoMoreEnable : Pos 6, 1 Bit 125 | +0x340 StackTracing : Pos 7, 1 Bit 126 | +0x340 ErrorLogged : Pos 8, 1 Bit 127 | +0x340 RealtimeLoggerContextFreed : Pos 9, 1 Bit 128 | +0x340 PebsTracing : Pos 10, 1 Bit 129 | +0x340 PmcCounters : Pos 11, 1 Bit 130 | +0x340 PageAlignBuffers : Pos 12, 1 Bit 131 | +0x340 StackLookasideListAllocated : Pos 13, 1 Bit 132 | +0x340 SecurityTrace : Pos 14, 1 Bit 133 | +0x340 LastBranchTracing : Pos 15, 1 Bit 134 | +0x340 SystemLoggerIndex : Pos 16, 8 Bits 135 | +0x340 StackCaching : Pos 24, 1 Bit 136 | +0x340 ProviderTracking : Pos 25, 1 Bit 137 | +0x340 ProcessorTrace : Pos 26, 1 Bit 138 | +0x340 QpcDeltaTracking : Pos 27, 1 Bit 139 | +0x340 SpareFlags2 : Pos 28, 4 Bits 140 | +0x344 RequestFlag : Uint4B 141 | +0x344 DbgRequestNewFile : Pos 0, 1 Bit 142 | +0x344 DbgRequestUpdateFile : Pos 1, 1 Bit 143 | +0x344 DbgRequestFlush : Pos 2, 1 Bit 144 | +0x344 DbgRequestDisableRealtime : Pos 3, 1 Bit 145 | +0x344 DbgRequestDisconnectConsumer : Pos 4, 1 Bit 146 | +0x344 DbgRequestConnectConsumer : Pos 5, 1 Bit 147 | +0x344 DbgRequestNotifyConsumer : Pos 6, 1 Bit 148 | +0x344 DbgRequestUpdateHeader : Pos 7, 1 Bit 149 | +0x344 DbgRequestDeferredFlush : Pos 8, 1 Bit 150 | +0x344 DbgRequestDeferredFlushTimer : Pos 9, 1 Bit 151 | +0x344 DbgRequestFlushTimer : Pos 10, 1 Bit 152 | +0x344 DbgRequestUpdateDebugger : Pos 11, 1 Bit 153 | +0x344 DbgSpareRequestFlags : Pos 12, 20 Bits 154 | +0x350 StackTraceBlock : _ETW_STACK_TRACE_BLOCK 155 | +0x3d0 HookIdMap : _RTL_BITMAP 156 | +0x3e0 StackCache : Ptr64 _ETW_STACK_CACHE 157 | +0x3e8 PmcData : Ptr64 _ETW_PMC_SUPPORT 158 | +0x3f0 LbrData : Ptr64 _ETW_LBR_SUPPORT 159 | +0x3f8 IptData : Ptr64 _ETW_IPT_SUPPORT 160 | +0x400 BinaryTrackingList : _LIST_ENTRY 161 | +0x410 ScratchArray : Ptr64 Ptr64 _WMI_BUFFER_HEADER 162 | +0x418 DisallowedGuids : _DISALLOWED_GUIDS 163 | +0x428 RelativeTimerDueTime : Int8B 164 | +0x430 PeriodicCaptureStateGuids : _PERIODIC_CAPTURE_STATE_GUIDS 165 | +0x440 PeriodicCaptureStateTimer : Ptr64 _EX_TIMER 166 | +0x448 PeriodicCaptureStateTimerState : _ETW_PERIODIC_TIMER_STATE 167 | +0x450 SoftRestartContext : Ptr64 _ETW_SOFT_RESTART_CONTEXT 168 | +0x458 SiloState : Ptr64 _ETW_SILODRIVERSTATE 169 | +0x460 CompressionWorkItem : _WORK_QUEUE_ITEM 170 | +0x480 CompressionWorkItemState : Int4B 171 | +0x488 CompressionLock : _EX_PUSH_LOCK 172 | +0x490 CompressionTarget : Ptr64 _WMI_BUFFER_HEADER 173 | +0x498 CompressionWorkspace : Ptr64 Void 174 | +0x4a0 CompressionOn : Int4B 175 | +0x4a4 CompressionRatioGuess : Uint4B 176 | +0x4a8 PartialBufferCompressionLevel : Uint4B 177 | +0x4ac CompressionResumptionMode : ETW_COMPRESSION_RESUMPTION_MODE 178 | +0x4b0 PlaceholderList : _SINGLE_LIST_ENTRY 179 | +0x4b8 CompressionDpc : _KDPC 180 | +0x4f8 LastBufferSwitchTime : _LARGE_INTEGER 181 | +0x500 BufferWriteDuration : _LARGE_INTEGER 182 | +0x508 BufferCompressDuration : _LARGE_INTEGER 183 | +0x510 ReferenceQpcDelta : Int8B 184 | +0x518 CallbackContext : Ptr64 _ETW_EVENT_CALLBACK_CONTEXT 185 | ``` 186 | 187 | 188 | Although not exported, this array is easily resolvable because a pointer to it exists right after `EtwpDebuggerData`, which interestingly enough can be signature scanned for Windows 7, 8, 8.1, and all the existing versions of Windows 10, using just a 5 byte signature: `0x2c, 0x08, 0x04, 0x38, 0x0c`. 189 | 190 | At `+0x28` in the `_WMI_LOGGER_CONTEXT` structure, you can see a member called `GetCpuClock`. This is a function pointer that can be one of three values based on how the session was configured: `EtwGetCycleCount`, `EtwpGetSystemTime`, or `PpmQueryTime`. We simply overwrite this function pointer with a custom routine, but this is only half the battle. 191 | 192 | First, we choose to hijack the circular kernel context logger session because it's always running by default. If not, we turn it on, and we configure it to log syscalls only, in a circular memory buffer. 193 | 194 | After this, we walk up the stack to locate magic values, in order to filter out the fact that this is not a syscall exit being logged. We grab `SystemCallNumber` saved into the current `_KTHREAD` from logic in `KiSystemCall64`. The real magic here occurs because prior to `KiSystemCall64` invoking `PerfInfoLogSyscallEntry`, it saves the resolved system call target pointer on the stack. We locate this pointer for you and, if you so choose, you are able to overwrite it in your handler. 195 | 196 | ![PerfInfoLogSyscallEntry](/resources/perf.png) 197 | 198 | ![Logging syscalls](/resources/infinityhook_log.gif) 199 | 200 | The sample code provided is for system calls only, and as mentioned above, it's up to the reader to implement it for other events. This sample was also only quickly whipped up and tested for 1903 and 1803. The stack walk function may need to be tweaked for earlier Windows 10 builds and 7. 201 | -------------------------------------------------------------------------------- /resources/hiding_file.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fIappy/InfinityHook/864a0eabc44e7cd8581be499bf88857e6fd28bfb/resources/hiding_file.gif -------------------------------------------------------------------------------- /resources/infinityhook_log.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fIappy/InfinityHook/864a0eabc44e7cd8581be499bf88857e6fd28bfb/resources/infinityhook_log.gif -------------------------------------------------------------------------------- /resources/perf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fIappy/InfinityHook/864a0eabc44e7cd8581be499bf88857e6fd28bfb/resources/perf.png -------------------------------------------------------------------------------- /src/infinityhook.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29102.190 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kinfinityhook", "kinfinityhook\kinfinityhook.vcxproj", "{71A0ED4D-0B55-4A92-B020-9021C86BEDA0}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libinfinityhook", "libinfinityhook\libinfinityhook.vcxproj", "{B9079C4E-D613-48C4-A649-9146B29CA9E7}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {71A0ED4D-0B55-4A92-B020-9021C86BEDA0}.Debug|x64.ActiveCfg = Debug|x64 17 | {71A0ED4D-0B55-4A92-B020-9021C86BEDA0}.Debug|x64.Build.0 = Debug|x64 18 | {71A0ED4D-0B55-4A92-B020-9021C86BEDA0}.Debug|x64.Deploy.0 = Debug|x64 19 | {71A0ED4D-0B55-4A92-B020-9021C86BEDA0}.Release|x64.ActiveCfg = Release|x64 20 | {71A0ED4D-0B55-4A92-B020-9021C86BEDA0}.Release|x64.Build.0 = Release|x64 21 | {71A0ED4D-0B55-4A92-B020-9021C86BEDA0}.Release|x64.Deploy.0 = Release|x64 22 | {B9079C4E-D613-48C4-A649-9146B29CA9E7}.Debug|x64.ActiveCfg = Debug|x64 23 | {B9079C4E-D613-48C4-A649-9146B29CA9E7}.Debug|x64.Build.0 = Debug|x64 24 | {B9079C4E-D613-48C4-A649-9146B29CA9E7}.Debug|x64.Deploy.0 = Debug|x64 25 | {B9079C4E-D613-48C4-A649-9146B29CA9E7}.Release|x64.ActiveCfg = Release|x64 26 | {B9079C4E-D613-48C4-A649-9146B29CA9E7}.Release|x64.Build.0 = Release|x64 27 | {B9079C4E-D613-48C4-A649-9146B29CA9E7}.Release|x64.Deploy.0 = Release|x64 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | GlobalSection(ExtensibilityGlobals) = postSolution 33 | SolutionGuid = {DD83D104-603B-4CE2-9025-2C4963CCFDC1} 34 | EndGlobalSection 35 | EndGlobal 36 | -------------------------------------------------------------------------------- /src/kinfinityhook/entry.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * entry.cpp 4 | * 5 | * Abstract: 6 | * Sample driver that implements infinity hook to detour 7 | * system calls. 8 | * 9 | * Authors: 10 | * Nick Peterson | http://everdox.net/ 11 | * 12 | * Special thanks to Nemanja (Nemi) Mulasmajic 13 | * for his help with the POC. 14 | * 15 | */ 16 | 17 | #include "stdafx.h" 18 | #include "entry.h" 19 | #include "infinityhook.h" 20 | 21 | static wchar_t IfhMagicFileName[] = L"ifh--"; 22 | 23 | static UNICODE_STRING StringNtCreateFile = RTL_CONSTANT_STRING(L"NtCreateFile"); 24 | static NtCreateFile_t OriginalNtCreateFile = NULL; 25 | 26 | /* 27 | * The entry point of the driver. Initializes infinity hook and 28 | * sets up the driver's unload routine so that it can be gracefully 29 | * turned off. 30 | */ 31 | extern "C" NTSTATUS DriverEntry( 32 | _In_ PDRIVER_OBJECT DriverObject, 33 | _In_ PUNICODE_STRING RegistryPath) 34 | { 35 | UNREFERENCED_PARAMETER(RegistryPath); 36 | 37 | // 38 | // Figure out when we built this last for debugging purposes. 39 | // 40 | kprintf("[+] infinityhook: Loaded.\n"); 41 | 42 | // 43 | // Let the driver be unloaded gracefully. This also turns off 44 | // infinity hook. 45 | // 46 | DriverObject->DriverUnload = DriverUnload; 47 | 48 | // 49 | // Demo detouring of nt!NtCreateFile. 50 | // 51 | OriginalNtCreateFile = (NtCreateFile_t)MmGetSystemRoutineAddress(&StringNtCreateFile); 52 | if (!OriginalNtCreateFile) 53 | { 54 | kprintf("[-] infinityhook: Failed to locate export: %wZ.\n", StringNtCreateFile); 55 | return STATUS_ENTRYPOINT_NOT_FOUND; 56 | } 57 | 58 | // 59 | // Initialize infinity hook. Each system call will be redirected 60 | // to our syscall stub. 61 | // 62 | NTSTATUS Status = IfhInitialize(SyscallStub); 63 | if (!NT_SUCCESS(Status)) 64 | { 65 | kprintf("[-] infinityhook: Failed to initialize with status: 0x%lx.\n", Status); 66 | } 67 | 68 | return Status; 69 | } 70 | 71 | /* 72 | * Turns off infinity hook. 73 | */ 74 | void DriverUnload( 75 | _In_ PDRIVER_OBJECT DriverObject) 76 | { 77 | UNREFERENCED_PARAMETER(DriverObject); 78 | 79 | // 80 | // Unload infinity hook gracefully. 81 | // 82 | IfhRelease(); 83 | 84 | kprintf("\n[!] infinityhook: Unloading... BYE!\n"); 85 | } 86 | 87 | /* 88 | * For each usermode syscall, this stub will be invoked. 89 | */ 90 | void __fastcall SyscallStub( 91 | _In_ unsigned int SystemCallIndex, 92 | _Inout_ void** SystemCallFunction) 93 | { 94 | // 95 | // Enabling this message gives you VERY verbose logging... and slows 96 | // down the system. Use it only for debugging. 97 | // 98 | 99 | #if 0 100 | kprintf("[+] infinityhook: SYSCALL %lu: 0x%p [stack: 0x%p].\n", SystemCallIndex, *SystemCallFunction, SystemCallFunction); 101 | #endif 102 | 103 | UNREFERENCED_PARAMETER(SystemCallIndex); 104 | 105 | // 106 | // In our demo, we care only about nt!NtCreateFile calls. 107 | // 108 | if (*SystemCallFunction == OriginalNtCreateFile) 109 | { 110 | // 111 | // We can overwrite the return address on the stack to our detoured 112 | // NtCreateFile. 113 | // 114 | *SystemCallFunction = DetourNtCreateFile; 115 | } 116 | } 117 | 118 | /* 119 | * This function is invoked instead of nt!NtCreateFile. It will 120 | * attempt to filter a file by the "magic" file name. 121 | */ 122 | NTSTATUS DetourNtCreateFile( 123 | _Out_ PHANDLE FileHandle, 124 | _In_ ACCESS_MASK DesiredAccess, 125 | _In_ POBJECT_ATTRIBUTES ObjectAttributes, 126 | _Out_ PIO_STATUS_BLOCK IoStatusBlock, 127 | _In_opt_ PLARGE_INTEGER AllocationSize, 128 | _In_ ULONG FileAttributes, 129 | _In_ ULONG ShareAccess, 130 | _In_ ULONG CreateDisposition, 131 | _In_ ULONG CreateOptions, 132 | _In_reads_bytes_opt_(EaLength) PVOID EaBuffer, 133 | _In_ ULONG EaLength) 134 | { 135 | // 136 | // We're going to filter for our "magic" file name. 137 | // 138 | if (ObjectAttributes && 139 | ObjectAttributes->ObjectName && 140 | ObjectAttributes->ObjectName->Buffer) 141 | { 142 | // 143 | // Unicode strings aren't guaranteed to be NULL terminated so 144 | // we allocate a copy that is. 145 | // 146 | PWCHAR ObjectName = (PWCHAR)ExAllocatePool(NonPagedPool, ObjectAttributes->ObjectName->Length + sizeof(wchar_t)); 147 | if (ObjectName) 148 | { 149 | memset(ObjectName, 0, ObjectAttributes->ObjectName->Length + sizeof(wchar_t)); 150 | memcpy(ObjectName, ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length); 151 | 152 | // 153 | // Does it contain our special file name? 154 | // 155 | if (wcsstr(ObjectName, IfhMagicFileName)) 156 | { 157 | kprintf("[+] infinityhook: Denying access to file: %wZ.\n", ObjectAttributes->ObjectName); 158 | 159 | ExFreePool(ObjectName); 160 | 161 | // 162 | // The demo denies access to said file. 163 | // 164 | return STATUS_ACCESS_DENIED; 165 | } 166 | 167 | ExFreePool(ObjectName); 168 | } 169 | } 170 | 171 | // 172 | // We're uninterested, call the original. 173 | // 174 | return OriginalNtCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength); 175 | } 176 | -------------------------------------------------------------------------------- /src/kinfinityhook/entry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * entry.h 4 | * 5 | * Abstract: 6 | * Sample driver that implements infinity hook to detour 7 | * system calls. 8 | * 9 | * Authors: 10 | * Nick Peterson | http://everdox.net/ 11 | * 12 | * Special thanks to Nemanja (Nemi) Mulasmajic 13 | * for his help with the POC. 14 | * 15 | */ 16 | 17 | #pragma once 18 | 19 | /// 20 | /// Structures and typedefs. 21 | /// 22 | 23 | typedef NTSTATUS(*NtCreateFile_t)( 24 | _Out_ PHANDLE FileHandle, 25 | _In_ ACCESS_MASK DesiredAccess, 26 | _In_ POBJECT_ATTRIBUTES ObjectAttributes, 27 | _Out_ PIO_STATUS_BLOCK IoStatusBlock, 28 | _In_opt_ PLARGE_INTEGER AllocationSize, 29 | _In_ ULONG FileAttributes, 30 | _In_ ULONG ShareAccess, 31 | _In_ ULONG CreateDisposition, 32 | _In_ ULONG CreateOptions, 33 | _In_reads_bytes_opt_(EaLength) PVOID EaBuffer, 34 | _In_ ULONG EaLength); 35 | 36 | /// 37 | /// Forward declarations. 38 | /// 39 | 40 | extern "C" DRIVER_INITIALIZE DriverEntry; 41 | 42 | void DriverUnload( 43 | _In_ PDRIVER_OBJECT DriverObject); 44 | 45 | void __fastcall SyscallStub( 46 | _In_ unsigned int SystemCallIndex, 47 | _Inout_ void** SystemCallFunction); 48 | 49 | NTSTATUS DetourNtCreateFile( 50 | _Out_ PHANDLE FileHandle, 51 | _In_ ACCESS_MASK DesiredAccess, 52 | _In_ POBJECT_ATTRIBUTES ObjectAttributes, 53 | _Out_ PIO_STATUS_BLOCK IoStatusBlock, 54 | _In_opt_ PLARGE_INTEGER AllocationSize, 55 | _In_ ULONG FileAttributes, 56 | _In_ ULONG ShareAccess, 57 | _In_ ULONG CreateDisposition, 58 | _In_ ULONG CreateOptions, 59 | _In_reads_bytes_opt_(EaLength) PVOID EaBuffer, 60 | _In_ ULONG EaLength); 61 | -------------------------------------------------------------------------------- /src/kinfinityhook/helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define kprintf(...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, __VA_ARGS__) -------------------------------------------------------------------------------- /src/kinfinityhook/kinfinityhook.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; kinfinityhook.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} 9 | Provider=%ManufacturerName% 10 | DriverVer= 11 | CatalogFile=kinfinityhook.cat 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | 16 | 17 | [SourceDisksNames] 18 | 1 = %DiskName%,,,"" 19 | 20 | [SourceDisksFiles] 21 | 22 | 23 | [Manufacturer] 24 | %ManufacturerName%=Standard,NT$ARCH$ 25 | 26 | [Standard.NT$ARCH$] 27 | 28 | 29 | [Strings] 30 | ManufacturerName="" ;TODO: Replace with your manufacturer name 31 | ClassName="" 32 | DiskName="kinfinityhook Source Disk" 33 | -------------------------------------------------------------------------------- /src/kinfinityhook/kinfinityhook.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {71A0ED4D-0B55-4A92-B020-9021C86BEDA0} 15 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 16 | v4.5 17 | 12.0 18 | Debug 19 | Win32 20 | kinfinityhook 21 | kinfinityhook 22 | 23 | 24 | 25 | Windows7 26 | true 27 | WindowsKernelModeDriver10.0 28 | Driver 29 | WDM 30 | false 31 | 32 | 33 | Windows7 34 | false 35 | WindowsKernelModeDriver10.0 36 | Driver 37 | WDM 38 | false 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | DbgengKernelDebugger 50 | false 51 | $(SolutionDir)libinfinityhook;$(IncludePath) 52 | 53 | 54 | DbgengKernelDebugger 55 | false 56 | $(SolutionDir)libinfinityhook;$(IncludePath) 57 | 58 | 59 | 60 | MultiThreadedDebug 61 | Use 62 | EnableAllWarnings 63 | false 64 | 65 | 66 | 4711;5045;28751;4748;%(DisableSpecificWarnings) 67 | 68 | 69 | 70 | 71 | MultiThreaded 72 | Use 73 | EnableAllWarnings 74 | false 75 | 76 | 77 | 4711;5045;28751;4603;4627;4986;4987;4996;%(DisableSpecificWarnings) 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | Create 90 | Create 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | {b9079c4e-d613-48c4-a649-9146b29ca9e7} 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /src/kinfinityhook/kinfinityhook.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 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/kinfinityhook/stdafx.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * stdafx.cpp 4 | * 5 | * Abstract: 6 | * Precompiled header. 7 | * 8 | * Authors: 9 | * Nick Peterson | http://everdox.net/ 10 | * 11 | * Special thanks to Nemanja (Nemi) Mulasmajic 12 | * for his help with the POC. 13 | * 14 | */ 15 | 16 | #include "stdafx.h" -------------------------------------------------------------------------------- /src/kinfinityhook/stdafx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * stdafx.h 4 | * 5 | * Abstract: 6 | * Precompiled header. 7 | * 8 | * Authors: 9 | * Nick Peterson | http://everdox.net/ 10 | * 11 | * Special thanks to Nemanja (Nemi) Mulasmajic 12 | * for his help with the POC. 13 | * 14 | */ 15 | 16 | #pragma once 17 | 18 | /// 19 | /// Includes. 20 | /// 21 | 22 | #pragma warning(push, 0) 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "ntint.h" 29 | #pragma warning(pop) 30 | 31 | #include "helpers.h" -------------------------------------------------------------------------------- /src/libinfinityhook/hde/hde64.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #include "stdafx.h" 9 | 10 | #if defined(_M_X64) || defined(__x86_64__) 11 | #pragma warning(push, 0) 12 | #pragma warning(disable: 4701 4706 26451) 13 | 14 | #include "hde64.h" 15 | #include "table64.h" 16 | 17 | unsigned int hde64_disasm(const void *code, hde64s *hs) 18 | { 19 | uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; 20 | uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; 21 | uint8_t op64 = 0; 22 | 23 | // Avoid using memset to reduce the footprint. 24 | memset(hs, 0, sizeof(hde64s)); 25 | 26 | for (x = 16; x; x--) 27 | switch (c = *p++) { 28 | case 0xf3: 29 | hs->p_rep = c; 30 | pref |= PRE_F3; 31 | break; 32 | case 0xf2: 33 | hs->p_rep = c; 34 | pref |= PRE_F2; 35 | break; 36 | case 0xf0: 37 | hs->p_lock = c; 38 | pref |= PRE_LOCK; 39 | break; 40 | case 0x26: case 0x2e: case 0x36: 41 | case 0x3e: case 0x64: case 0x65: 42 | hs->p_seg = c; 43 | pref |= PRE_SEG; 44 | break; 45 | case 0x66: 46 | hs->p_66 = c; 47 | pref |= PRE_66; 48 | break; 49 | case 0x67: 50 | hs->p_67 = c; 51 | pref |= PRE_67; 52 | break; 53 | default: 54 | goto pref_done; 55 | } 56 | pref_done: 57 | 58 | hs->flags = (uint32_t)pref << 23; 59 | 60 | if (!pref) 61 | pref |= PRE_NONE; 62 | 63 | if ((c & 0xf0) == 0x40) { 64 | hs->flags |= F_PREFIX_REX; 65 | if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) 66 | op64++; 67 | hs->rex_r = (c & 7) >> 2; 68 | hs->rex_x = (c & 3) >> 1; 69 | hs->rex_b = c & 1; 70 | if (((c = *p++) & 0xf0) == 0x40) { 71 | opcode = c; 72 | goto error_opcode; 73 | } 74 | } 75 | 76 | if ((hs->opcode = c) == 0x0f) { 77 | hs->opcode2 = c = *p++; 78 | ht += DELTA_OPCODES; 79 | } else if (c >= 0xa0 && c <= 0xa3) { 80 | op64++; 81 | if (pref & PRE_67) 82 | pref |= PRE_66; 83 | else 84 | pref &= ~PRE_66; 85 | } 86 | 87 | opcode = c; 88 | cflags = ht[ht[opcode / 4] + (opcode % 4)]; 89 | 90 | if (cflags == C_ERROR) { 91 | error_opcode: 92 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 93 | cflags = 0; 94 | if ((opcode & -3) == 0x24) 95 | cflags++; 96 | } 97 | 98 | x = 0; 99 | if (cflags & C_GROUP) { 100 | uint16_t t; 101 | t = *(uint16_t *)(ht + (cflags & 0x7f)); 102 | cflags = (uint8_t)t; 103 | x = (uint8_t)(t >> 8); 104 | } 105 | 106 | if (hs->opcode2) { 107 | ht = hde64_table + DELTA_PREFIXES; 108 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref) 109 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 110 | } 111 | 112 | if (cflags & C_MODRM) { 113 | hs->flags |= F_MODRM; 114 | hs->modrm = c = *p++; 115 | hs->modrm_mod = m_mod = c >> 6; 116 | hs->modrm_rm = m_rm = c & 7; 117 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3; 118 | 119 | if (x && ((x << m_reg) & 0x80)) 120 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 121 | 122 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { 123 | uint8_t t = opcode - 0xd9; 124 | if (m_mod == 3) { 125 | ht = hde64_table + DELTA_FPU_MODRM + t*8; 126 | t = ht[m_reg] << m_rm; 127 | } else { 128 | ht = hde64_table + DELTA_FPU_REG; 129 | t = ht[t] << m_reg; 130 | } 131 | if (t & 0x80) 132 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 133 | } 134 | 135 | if (pref & PRE_LOCK) { 136 | if (m_mod == 3) { 137 | hs->flags |= F_ERROR | F_ERROR_LOCK; 138 | } else { 139 | uint8_t *table_end, op = opcode; 140 | if (hs->opcode2) { 141 | ht = hde64_table + DELTA_OP2_LOCK_OK; 142 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; 143 | } else { 144 | ht = hde64_table + DELTA_OP_LOCK_OK; 145 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; 146 | op &= -2; 147 | } 148 | for (; ht != table_end; ht++) 149 | if (*ht++ == op) { 150 | if (!((*ht << m_reg) & 0x80)) 151 | goto no_lock_error; 152 | else 153 | break; 154 | } 155 | hs->flags |= F_ERROR | F_ERROR_LOCK; 156 | no_lock_error: 157 | ; 158 | } 159 | } 160 | 161 | if (hs->opcode2) { 162 | switch (opcode) { 163 | case 0x20: case 0x22: 164 | m_mod = 3; 165 | if (m_reg > 4 || m_reg == 1) 166 | goto error_operand; 167 | else 168 | goto no_error_operand; 169 | case 0x21: case 0x23: 170 | m_mod = 3; 171 | if (m_reg == 4 || m_reg == 5) 172 | goto error_operand; 173 | else 174 | goto no_error_operand; 175 | } 176 | } else { 177 | switch (opcode) { 178 | case 0x8c: 179 | if (m_reg > 5) 180 | goto error_operand; 181 | else 182 | goto no_error_operand; 183 | case 0x8e: 184 | if (m_reg == 1 || m_reg > 5) 185 | goto error_operand; 186 | else 187 | goto no_error_operand; 188 | } 189 | } 190 | 191 | if (m_mod == 3) { 192 | uint8_t *table_end; 193 | if (hs->opcode2) { 194 | ht = hde64_table + DELTA_OP2_ONLY_MEM; 195 | table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; 196 | } else { 197 | ht = hde64_table + DELTA_OP_ONLY_MEM; 198 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; 199 | } 200 | for (; ht != table_end; ht += 2) 201 | if (*ht++ == opcode) { 202 | if (*ht++ & pref && !((*ht << m_reg) & 0x80)) 203 | goto error_operand; 204 | else 205 | break; 206 | } 207 | goto no_error_operand; 208 | } else if (hs->opcode2) { 209 | switch (opcode) { 210 | case 0x50: case 0xd7: case 0xf7: 211 | if (pref & (PRE_NONE | PRE_66)) 212 | goto error_operand; 213 | break; 214 | case 0xd6: 215 | if (pref & (PRE_F2 | PRE_F3)) 216 | goto error_operand; 217 | break; 218 | case 0xc5: 219 | goto error_operand; 220 | } 221 | goto no_error_operand; 222 | } else 223 | goto no_error_operand; 224 | 225 | error_operand: 226 | hs->flags |= F_ERROR | F_ERROR_OPERAND; 227 | no_error_operand: 228 | 229 | c = *p++; 230 | if (m_reg <= 1) { 231 | if (opcode == 0xf6) 232 | cflags |= C_IMM8; 233 | else if (opcode == 0xf7) 234 | cflags |= C_IMM_P66; 235 | } 236 | 237 | switch (m_mod) { 238 | case 0: 239 | if (pref & PRE_67) { 240 | if (m_rm == 6) 241 | disp_size = 2; 242 | } else 243 | if (m_rm == 5) 244 | disp_size = 4; 245 | break; 246 | case 1: 247 | disp_size = 1; 248 | break; 249 | case 2: 250 | disp_size = 2; 251 | if (!(pref & PRE_67)) 252 | disp_size <<= 1; 253 | } 254 | 255 | if (m_mod != 3 && m_rm == 4) { 256 | hs->flags |= F_SIB; 257 | p++; 258 | hs->sib = c; 259 | hs->sib_scale = c >> 6; 260 | hs->sib_index = (c & 0x3f) >> 3; 261 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) 262 | disp_size = 4; 263 | } 264 | 265 | p--; 266 | switch (disp_size) { 267 | case 1: 268 | hs->flags |= F_DISP8; 269 | hs->disp.disp8 = *p; 270 | break; 271 | case 2: 272 | hs->flags |= F_DISP16; 273 | hs->disp.disp16 = *(uint16_t *)p; 274 | break; 275 | case 4: 276 | hs->flags |= F_DISP32; 277 | hs->disp.disp32 = *(uint32_t *)p; 278 | } 279 | p += disp_size; 280 | } else if (pref & PRE_LOCK) 281 | hs->flags |= F_ERROR | F_ERROR_LOCK; 282 | 283 | if (cflags & C_IMM_P66) { 284 | if (cflags & C_REL32) { 285 | if (pref & PRE_66) { 286 | hs->flags |= F_IMM16 | F_RELATIVE; 287 | hs->imm.imm16 = *(uint16_t *)p; 288 | p += 2; 289 | goto disasm_done; 290 | } 291 | goto rel32_ok; 292 | } 293 | if (op64) { 294 | hs->flags |= F_IMM64; 295 | hs->imm.imm64 = *(uint64_t *)p; 296 | p += 8; 297 | } else if (!(pref & PRE_66)) { 298 | hs->flags |= F_IMM32; 299 | hs->imm.imm32 = *(uint32_t *)p; 300 | p += 4; 301 | } else 302 | goto imm16_ok; 303 | } 304 | 305 | 306 | if (cflags & C_IMM16) { 307 | imm16_ok: 308 | hs->flags |= F_IMM16; 309 | hs->imm.imm16 = *(uint16_t *)p; 310 | p += 2; 311 | } 312 | if (cflags & C_IMM8) { 313 | hs->flags |= F_IMM8; 314 | hs->imm.imm8 = *p++; 315 | } 316 | 317 | if (cflags & C_REL32) { 318 | rel32_ok: 319 | hs->flags |= F_IMM32 | F_RELATIVE; 320 | hs->imm.imm32 = *(uint32_t *)p; 321 | p += 4; 322 | } else if (cflags & C_REL8) { 323 | hs->flags |= F_IMM8 | F_RELATIVE; 324 | hs->imm.imm8 = *p++; 325 | } 326 | 327 | disasm_done: 328 | 329 | if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { 330 | hs->flags |= F_ERROR | F_ERROR_LENGTH; 331 | hs->len = 15; 332 | } 333 | 334 | return (unsigned int)hs->len; 335 | } 336 | 337 | #pragma warning(pop) 338 | #endif // defined(_M_X64) || defined(__x86_64__) 339 | -------------------------------------------------------------------------------- /src/libinfinityhook/hde/hde64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | * hde64.h: C/C++ header file 7 | * 8 | */ 9 | 10 | #ifndef _HDE64_H_ 11 | #define _HDE64_H_ 12 | 13 | /* stdint.h - C99 standard header 14 | * http://en.wikipedia.org/wiki/stdint.h 15 | * 16 | * if your compiler doesn't contain "stdint.h" header (for 17 | * example, Microsoft Visual C++), you can download file: 18 | * http://www.azillionmonkeys.com/qed/pstdint.h 19 | * and change next line to: 20 | * #include "pstdint.h" 21 | */ 22 | #include "pstdint.h" 23 | 24 | #define F_MODRM 0x00000001 25 | #define F_SIB 0x00000002 26 | #define F_IMM8 0x00000004 27 | #define F_IMM16 0x00000008 28 | #define F_IMM32 0x00000010 29 | #define F_IMM64 0x00000020 30 | #define F_DISP8 0x00000040 31 | #define F_DISP16 0x00000080 32 | #define F_DISP32 0x00000100 33 | #define F_RELATIVE 0x00000200 34 | #define F_ERROR 0x00001000 35 | #define F_ERROR_OPCODE 0x00002000 36 | #define F_ERROR_LENGTH 0x00004000 37 | #define F_ERROR_LOCK 0x00008000 38 | #define F_ERROR_OPERAND 0x00010000 39 | #define F_PREFIX_REPNZ 0x01000000 40 | #define F_PREFIX_REPX 0x02000000 41 | #define F_PREFIX_REP 0x03000000 42 | #define F_PREFIX_66 0x04000000 43 | #define F_PREFIX_67 0x08000000 44 | #define F_PREFIX_LOCK 0x10000000 45 | #define F_PREFIX_SEG 0x20000000 46 | #define F_PREFIX_REX 0x40000000 47 | #define F_PREFIX_ANY 0x7f000000 48 | 49 | #define PREFIX_SEGMENT_CS 0x2e 50 | #define PREFIX_SEGMENT_SS 0x36 51 | #define PREFIX_SEGMENT_DS 0x3e 52 | #define PREFIX_SEGMENT_ES 0x26 53 | #define PREFIX_SEGMENT_FS 0x64 54 | #define PREFIX_SEGMENT_GS 0x65 55 | #define PREFIX_LOCK 0xf0 56 | #define PREFIX_REPNZ 0xf2 57 | #define PREFIX_REPX 0xf3 58 | #define PREFIX_OPERAND_SIZE 0x66 59 | #define PREFIX_ADDRESS_SIZE 0x67 60 | 61 | #pragma pack(push,1) 62 | 63 | typedef struct { 64 | uint8_t len; 65 | uint8_t p_rep; 66 | uint8_t p_lock; 67 | uint8_t p_seg; 68 | uint8_t p_66; 69 | uint8_t p_67; 70 | uint8_t rex; 71 | uint8_t rex_w; 72 | uint8_t rex_r; 73 | uint8_t rex_x; 74 | uint8_t rex_b; 75 | uint8_t opcode; 76 | uint8_t opcode2; 77 | uint8_t modrm; 78 | uint8_t modrm_mod; 79 | uint8_t modrm_reg; 80 | uint8_t modrm_rm; 81 | uint8_t sib; 82 | uint8_t sib_scale; 83 | uint8_t sib_index; 84 | uint8_t sib_base; 85 | union { 86 | uint8_t imm8; 87 | uint16_t imm16; 88 | uint32_t imm32; 89 | uint64_t imm64; 90 | } imm; 91 | union { 92 | uint8_t disp8; 93 | uint16_t disp16; 94 | uint32_t disp32; 95 | } disp; 96 | uint32_t flags; 97 | } hde64s; 98 | 99 | #pragma pack(pop) 100 | 101 | #ifdef __cplusplus 102 | extern "C" { 103 | #endif 104 | 105 | /* __cdecl */ 106 | unsigned int hde64_disasm(const void *code, hde64s *hs); 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | 112 | #endif /* _HDE64_H_ */ 113 | -------------------------------------------------------------------------------- /src/libinfinityhook/hde/pstdint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #pragma once 28 | 29 | // Integer types for HDE. 30 | typedef INT8 int8_t; 31 | typedef INT16 int16_t; 32 | typedef INT32 int32_t; 33 | typedef INT64 int64_t; 34 | typedef UINT8 uint8_t; 35 | typedef UINT16 uint16_t; 36 | typedef UINT32 uint32_t; 37 | typedef UINT64 uint64_t; 38 | -------------------------------------------------------------------------------- /src/libinfinityhook/hde/table64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #define C_NONE 0x00 9 | #define C_MODRM 0x01 10 | #define C_IMM8 0x02 11 | #define C_IMM16 0x04 12 | #define C_IMM_P66 0x10 13 | #define C_REL8 0x20 14 | #define C_REL32 0x40 15 | #define C_GROUP 0x80 16 | #define C_ERROR 0xff 17 | 18 | #define PRE_ANY 0x00 19 | #define PRE_NONE 0x01 20 | #define PRE_F2 0x02 21 | #define PRE_F3 0x04 22 | #define PRE_66 0x08 23 | #define PRE_67 0x10 24 | #define PRE_LOCK 0x20 25 | #define PRE_SEG 0x40 26 | #define PRE_ALL 0xff 27 | 28 | #define DELTA_OPCODES 0x4a 29 | #define DELTA_FPU_REG 0xfd 30 | #define DELTA_FPU_MODRM 0x104 31 | #define DELTA_PREFIXES 0x13c 32 | #define DELTA_OP_LOCK_OK 0x1ae 33 | #define DELTA_OP2_LOCK_OK 0x1c6 34 | #define DELTA_OP_ONLY_MEM 0x1d8 35 | #define DELTA_OP2_ONLY_MEM 0x1e7 36 | 37 | unsigned char hde64_table[] = { 38 | 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5, 39 | 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1, 40 | 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea, 41 | 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0, 42 | 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab, 43 | 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92, 44 | 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90, 45 | 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b, 46 | 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b, 47 | 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc, 48 | 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20, 49 | 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff, 50 | 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00, 51 | 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01, 52 | 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10, 53 | 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00, 54 | 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00, 55 | 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00, 56 | 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00, 57 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, 58 | 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00, 59 | 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40, 60 | 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43, 61 | 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, 62 | 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40, 63 | 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06, 64 | 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07, 65 | 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, 66 | 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10, 67 | 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00, 68 | 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb, 69 | 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff, 70 | 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09, 71 | 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff, 72 | 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08, 73 | 0x00,0xf0,0x02,0x00 74 | }; 75 | -------------------------------------------------------------------------------- /src/libinfinityhook/img.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * img.cpp 4 | * 5 | * Abstract: 6 | * Helper routines for extracting useful information from the PE 7 | * file specification. 8 | * 9 | * Authors: 10 | * Nick Peterson | http://everdox.net/ 11 | * 12 | * Special thanks to Nemanja (Nemi) Mulasmajic 13 | * for his help with the POC. 14 | * 15 | */ 16 | 17 | #include "stdafx.h" 18 | #include "img.h" 19 | #include "hde/hde64.h" 20 | 21 | #define OPCODE_JMP_NEAR 0xE9 22 | 23 | /* 24 | * Returns the base address and size of the specified image. 25 | */ 26 | PVOID ImgGetBaseAddress( 27 | _In_opt_ const char* ImageName, 28 | _Out_opt_ PULONG SizeOfImage) 29 | { 30 | if (SizeOfImage) 31 | { 32 | *SizeOfImage = 0; 33 | } 34 | 35 | PVOID Buffer = NULL; 36 | ULONG SizeOfBuffer = 0; 37 | do 38 | { 39 | // 40 | // Get the list of all kernel drivers that are loaded. 41 | // 42 | ULONG ReturnLength = 0; 43 | NTSTATUS Status = ZwQuerySystemInformation(SystemModuleInformation, Buffer, SizeOfBuffer, &ReturnLength); 44 | if (NT_SUCCESS(Status)) 45 | { 46 | break; 47 | } 48 | else if (Status == STATUS_INFO_LENGTH_MISMATCH || Status == STATUS_BUFFER_TOO_SMALL) 49 | { 50 | // 51 | // Need a bigger buffer. 52 | // 53 | 54 | SizeOfBuffer = ReturnLength; 55 | 56 | if (Buffer) 57 | { 58 | ExFreePool(Buffer); 59 | Buffer = NULL; 60 | } 61 | 62 | Buffer = ExAllocatePool(NonPagedPool, SizeOfBuffer); 63 | if (!Buffer) 64 | { 65 | break; 66 | } 67 | } 68 | else 69 | { 70 | break; 71 | } 72 | } while (TRUE); 73 | 74 | if (!Buffer) 75 | { 76 | return NULL; 77 | } 78 | 79 | // 80 | // Find the one we're looking for... 81 | // 82 | PRTL_PROCESS_MODULES SystemModules = (PRTL_PROCESS_MODULES)Buffer; 83 | for (ULONG i = 0; i < SystemModules->NumberOfModules; ++i) 84 | { 85 | PRTL_PROCESS_MODULE_INFORMATION ModuleInformation = &SystemModules->Modules[i]; 86 | 87 | // 88 | // If you don't supply an image name, you'll get the first 89 | // loaded driver which should be ntoskrnl. 90 | // 91 | if (!ImageName || !_stricmp(ImageName, (const char*)& ModuleInformation->FullPathName[ModuleInformation->OffsetToFileName])) 92 | { 93 | if (SizeOfImage) 94 | { 95 | *SizeOfImage = ModuleInformation->ImageSize; 96 | } 97 | 98 | PVOID ImageBase = ModuleInformation->ImageBase; 99 | 100 | // 101 | // Free the buffer. Thanks to @tandasat for catching my 102 | // silly mistake. 103 | // 104 | ExFreePool(Buffer); 105 | 106 | return ImageBase; 107 | } 108 | } 109 | 110 | ExFreePool(Buffer); 111 | 112 | return NULL; 113 | } 114 | 115 | /* 116 | * Retrieves the start of a PE section and its size within an 117 | * image. 118 | */ 119 | PVOID ImgGetImageSection( 120 | _In_ PVOID ImageBase, 121 | _In_ const char* SectionName, 122 | _Out_opt_ PULONG SizeOfSection) 123 | { 124 | // 125 | // Get the IMAGE_NT_HEADERS. 126 | // 127 | PIMAGE_NT_HEADERS64 NtHeaders = RtlImageNtHeader(ImageBase); 128 | if (!NtHeaders) 129 | { 130 | return NULL; 131 | } 132 | 133 | // 134 | // Walk the PE sections, looking for our target section. 135 | // 136 | PIMAGE_SECTION_HEADER SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); 137 | for (USHORT i = 0; i < NtHeaders->FileHeader.NumberOfSections; ++i, ++SectionHeader) 138 | { 139 | if (!_strnicmp((const char*)SectionHeader->Name, SectionName, IMAGE_SIZEOF_SHORT_NAME)) 140 | { 141 | if (SizeOfSection) 142 | { 143 | *SizeOfSection = SectionHeader->SizeOfRawData; 144 | } 145 | 146 | return (PVOID)((uintptr_t)ImageBase + SectionHeader->VirtualAddress); 147 | } 148 | } 149 | 150 | return NULL; 151 | } 152 | 153 | /* 154 | * Retrieves the address of the non-KVA shadow system call entry. 155 | */ 156 | PVOID ImgGetSyscallEntry() 157 | { 158 | // 159 | // Get the base address of the kernel. 160 | // 161 | PVOID NtBaseAddress = ImgGetBaseAddress(NULL, NULL); 162 | if (!NtBaseAddress) 163 | { 164 | return NULL; 165 | } 166 | 167 | // 168 | // Get the LSTAR MSR. This should be KiSystemCall64 if KVA shadowing 169 | // is not enabled. 170 | // 171 | PVOID SyscallEntry = (PVOID)__readmsr(IA32_LSTAR_MSR); 172 | 173 | // 174 | // Get the PE section for KVASCODE. If one doesn't exit, KVA 175 | // shadowing doesn't exist. This can be queried using 176 | // NtQuerySystemInformation alternatively. 177 | // 178 | ULONG SizeOfSection; 179 | PVOID SectionBase = ImgGetImageSection(NtBaseAddress, "KVASCODE", &SizeOfSection); 180 | if (!SectionBase) 181 | { 182 | return SyscallEntry; 183 | } 184 | 185 | // 186 | // Is the value within this KVA shadow region? If not, we're done. 187 | // 188 | if (!(SyscallEntry >= SectionBase && SyscallEntry < (PVOID)((uintptr_t)SectionBase + SizeOfSection))) 189 | { 190 | return SyscallEntry; 191 | } 192 | 193 | // 194 | // This is KiSystemCall64Shadow. 195 | // 196 | hde64s HDE; 197 | for (PCHAR KiSystemServiceUser = (PCHAR)SyscallEntry; /* */; KiSystemServiceUser += HDE.len) 198 | { 199 | // 200 | // Disassemble every instruction till the first near jmp (E9). 201 | // 202 | if (!hde64_disasm(KiSystemServiceUser, &HDE)) 203 | { 204 | break; 205 | } 206 | 207 | if (HDE.opcode != OPCODE_JMP_NEAR) 208 | { 209 | continue; 210 | } 211 | 212 | // 213 | // Ignore jmps within the KVA shadow region. 214 | // 215 | PVOID PossibleSyscallEntry = (PVOID)((intptr_t)KiSystemServiceUser + (int)HDE.len + (int)HDE.imm.imm32); 216 | if (PossibleSyscallEntry >= SectionBase && PossibleSyscallEntry < (PVOID)((uintptr_t)SectionBase + SizeOfSection)) 217 | { 218 | continue; 219 | } 220 | 221 | // 222 | // Found KiSystemServiceUser. 223 | // 224 | SyscallEntry = PossibleSyscallEntry; 225 | break; 226 | } 227 | 228 | return SyscallEntry; 229 | } 230 | -------------------------------------------------------------------------------- /src/libinfinityhook/img.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * img.h 4 | * 5 | * Abstract: 6 | * Helper routines for extracting useful information from the PE 7 | * file specification. 8 | * 9 | * Authors: 10 | * Nick Peterson | http://everdox.net/ 11 | * 12 | * Special thanks to Nemanja (Nemi) Mulasmajic 13 | * for his help with the POC. 14 | * 15 | */ 16 | 17 | #pragma once 18 | 19 | /// 20 | /// Forward declarations. 21 | /// 22 | 23 | PVOID ImgGetBaseAddress( 24 | _In_opt_ const char* ImageName, 25 | _Out_opt_ PULONG SizeOfImage); 26 | 27 | PVOID ImgGetImageSection( 28 | _In_ PVOID ImageBase, 29 | _In_ const char* SectionName, 30 | _Out_opt_ PULONG SizeOfSection); 31 | 32 | PVOID ImgGetSyscallEntry(); -------------------------------------------------------------------------------- /src/libinfinityhook/infinityhook.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * infinityhook.cpp 4 | * 5 | * Abstract: 6 | * The implementation details of infinity hook. 7 | * 8 | * Authors: 9 | * Nick Peterson | http://everdox.net/ 10 | * 11 | * Special thanks to Nemanja (Nemi) Mulasmajic 12 | * for his help with the POC. 13 | * 14 | */ 15 | 16 | #include "stdafx.h" 17 | #include "infinityhook.h" 18 | #include "img.h" 19 | #include "mm.h" 20 | 21 | // 22 | // Used internally for IfhpModifyTraceSettings. 23 | // 24 | enum CKCL_TRACE_OPERATION 25 | { 26 | CKCL_TRACE_START, 27 | CKCL_TRACE_SYSCALL, 28 | CKCL_TRACE_END 29 | }; 30 | 31 | // 32 | // To enable/disable tracing on the circular kernel context logger. 33 | // 34 | typedef struct _CKCL_TRACE_PROPERIES: EVENT_TRACE_PROPERTIES 35 | { 36 | ULONG64 Unknown[3]; 37 | UNICODE_STRING ProviderName; 38 | } CKCL_TRACE_PROPERTIES, *PCKCL_TRACE_PROPERTIES; 39 | 40 | static BOOLEAN IfhpResolveSymbols(); 41 | 42 | static NTSTATUS IfhpModifyTraceSettings( 43 | _In_ CKCL_TRACE_OPERATION Operation); 44 | 45 | static ULONG64 IfhpInternalGetCpuClock(); 46 | 47 | // 48 | // Works from Windows 7+. You can backport this to Vista if you 49 | // include an OS check and add the Vista appropriate signature. 50 | // 51 | UCHAR EtwpDebuggerDataPattern[] = 52 | { 53 | 0x2c, 54 | 0x08, 55 | 0x04, 56 | 0x38, 57 | 0x0c 58 | }; 59 | 60 | // 61 | // _WMI_LOGGER_CONTEXT.GetCpuClock. 62 | // 63 | #define OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK 0x28 64 | 65 | // 66 | // _KPCR.Prcb.RspBase. 67 | // 68 | #define OFFSET_KPCR_RSP_BASE 0x1A8 69 | 70 | // 71 | // _KPCR.Prcb.CurrentThread. 72 | // 73 | #define OFFSET_KPCR_CURRENT_THREAD 0x188 74 | 75 | // 76 | // _KTHREAD.SystemCallNumber. 77 | // 78 | #define OFFSET_KTHREAD_SYSTEM_CALL_NUMBER 0x80 79 | 80 | // 81 | // EtwpDebuggerData silos. 82 | // 83 | #define OFFSET_ETW_DEBUGGER_DATA_SILO 0x10 84 | 85 | // 86 | // The index of the circular kernel context logger. 87 | // 88 | #define INDEX_CKCL_LOGGER 2 89 | 90 | // 91 | // Magic values on the stack. We use this to filter out system call 92 | // exit events. 93 | // 94 | #define INFINITYHOOK_MAGIC_1 ((ULONG)0x501802) 95 | #define INFINITYHOOK_MAGIC_2 ((USHORT)0xF33) 96 | 97 | static bool IfhpInitialized = false; 98 | static INFINITYHOOKCALLBACK IfhpCallback = NULL; 99 | 100 | static const void* EtwpDebuggerData = NULL; 101 | static PVOID CkclWmiLoggerContext = NULL; 102 | static PVOID SystemCallEntryPage = NULL; 103 | 104 | /* 105 | * Initialize infinity hook: executes your user defined callback on 106 | * each syscall. You can extend this functionality to do other things 107 | * like trap on page faults, context switches, and more... This demo 108 | * only does syscalls. 109 | */ 110 | NTSTATUS IfhInitialize(_In_ 111 | INFINITYHOOKCALLBACK InfinityHookCallback) 112 | { 113 | if (IfhpInitialized) 114 | { 115 | return STATUS_ACCESS_DENIED; 116 | } 117 | 118 | // 119 | // Let's assume CKCL session is already started (which is the 120 | // default scenario) and try to update it for system calls only. 121 | // 122 | NTSTATUS Status = IfhpModifyTraceSettings(CKCL_TRACE_SYSCALL); 123 | if (!NT_SUCCESS(Status)) 124 | { 125 | // 126 | // Failed... let's try to turn it on. 127 | // 128 | Status = IfhpModifyTraceSettings(CKCL_TRACE_START); 129 | 130 | // 131 | // Failed again... We exit here, but it's possible to setup 132 | // a custom logger instead and use SystemTraceProvider instead 133 | // of hijacking the circular kernel context logger. 134 | // 135 | if (!NT_SUCCESS(Status)) 136 | { 137 | return Status; 138 | } 139 | 140 | Status = IfhpModifyTraceSettings(CKCL_TRACE_SYSCALL); 141 | if (!NT_SUCCESS(Status)) 142 | { 143 | return Status; 144 | } 145 | } 146 | 147 | // 148 | // We need to resolve certain unexported symbols. 149 | // 150 | if (!IfhpResolveSymbols()) 151 | { 152 | return STATUS_ENTRYPOINT_NOT_FOUND; 153 | } 154 | 155 | IfhpCallback = InfinityHookCallback; 156 | 157 | // 158 | // CkclWmiLoggerContext is a WMI_LOGGER_CONTEXT structure: 159 | // 160 | /* 161 | 0: kd> dt nt!_WMI_LOGGER_CONTEXT 162 | +0x000 LoggerId : Uint4B 163 | +0x004 BufferSize : Uint4B 164 | +0x008 MaximumEventSize : Uint4B 165 | +0x00c LoggerMode : Uint4B 166 | +0x010 AcceptNewEvents : Int4B 167 | +0x014 EventMarker : [2] Uint4B 168 | +0x01c ErrorMarker : Uint4B 169 | +0x020 SizeMask : Uint4B 170 | +0x028 GetCpuClock : Ptr64 int64 171 | +0x030 LoggerThread : Ptr64 _ETHREAD 172 | +0x038 LoggerStatus : Int4B 173 | +0x03c FailureReason : Uint4B 174 | +0x040 BufferQueue : _ETW_BUFFER_QUEUE 175 | +0x050 OverflowQueue : _ETW_BUFFER_QUEUE 176 | +0x060 GlobalList : _LIST_ENTRY 177 | +0x070 DebugIdTrackingList : _LIST_ENTRY 178 | +0x080 DecodeControlList : Ptr64 _ETW_DECODE_CONTROL_ENTRY 179 | +0x088 DecodeControlCount : Uint4B 180 | +0x090 BatchedBufferList : Ptr64 _WMI_BUFFER_HEADER 181 | +0x090 CurrentBuffer : _EX_FAST_REF 182 | +0x098 LoggerName : _UNICODE_STRING 183 | +0x0a8 LogFileName : _UNICODE_STRING 184 | +0x0b8 LogFilePattern : _UNICODE_STRING 185 | +0x0c8 NewLogFileName : _UNICODE_STRING 186 | +0x0d8 ClockType : Uint4B 187 | +0x0dc LastFlushedBuffer : Uint4B 188 | +0x0e0 FlushTimer : Uint4B 189 | +0x0e4 FlushThreshold : Uint4B 190 | +0x0e8 ByteOffset : _LARGE_INTEGER 191 | +0x0f0 MinimumBuffers : Uint4B 192 | +0x0f4 BuffersAvailable : Int4B 193 | +0x0f8 NumberOfBuffers : Int4B 194 | +0x0fc MaximumBuffers : Uint4B 195 | +0x100 EventsLost : Uint4B 196 | +0x104 PeakBuffersCount : Int4B 197 | +0x108 BuffersWritten : Uint4B 198 | +0x10c LogBuffersLost : Uint4B 199 | +0x110 RealTimeBuffersDelivered : Uint4B 200 | +0x114 RealTimeBuffersLost : Uint4B 201 | +0x118 SequencePtr : Ptr64 Int4B 202 | +0x120 LocalSequence : Uint4B 203 | +0x124 InstanceGuid : _GUID 204 | +0x134 MaximumFileSize : Uint4B 205 | +0x138 FileCounter : Int4B 206 | +0x13c PoolType : _POOL_TYPE 207 | +0x140 ReferenceTime : _ETW_REF_CLOCK 208 | +0x150 CollectionOn : Int4B 209 | +0x154 ProviderInfoSize : Uint4B 210 | +0x158 Consumers : _LIST_ENTRY 211 | +0x168 NumConsumers : Uint4B 212 | +0x170 TransitionConsumer : Ptr64 _ETW_REALTIME_CONSUMER 213 | +0x178 RealtimeLogfileHandle : Ptr64 Void 214 | +0x180 RealtimeLogfileName : _UNICODE_STRING 215 | +0x190 RealtimeWriteOffset : _LARGE_INTEGER 216 | +0x198 RealtimeReadOffset : _LARGE_INTEGER 217 | +0x1a0 RealtimeLogfileSize : _LARGE_INTEGER 218 | +0x1a8 RealtimeLogfileUsage : Uint8B 219 | +0x1b0 RealtimeMaximumFileSize : Uint8B 220 | +0x1b8 RealtimeBuffersSaved : Uint4B 221 | +0x1c0 RealtimeReferenceTime : _ETW_REF_CLOCK 222 | +0x1d0 NewRTEventsLost : _ETW_RT_EVENT_LOSS 223 | +0x1d8 LoggerEvent : _KEVENT 224 | +0x1f0 FlushEvent : _KEVENT 225 | +0x208 FlushTimeOutTimer : _KTIMER 226 | +0x248 LoggerDpc : _KDPC 227 | +0x288 LoggerMutex : _KMUTANT 228 | +0x2c0 LoggerLock : _EX_PUSH_LOCK 229 | +0x2c8 BufferListSpinLock : Uint8B 230 | +0x2c8 BufferListPushLock : _EX_PUSH_LOCK 231 | +0x2d0 ClientSecurityContext : _SECURITY_CLIENT_CONTEXT 232 | +0x318 TokenAccessInformation : Ptr64 _TOKEN_ACCESS_INFORMATION 233 | +0x320 SecurityDescriptor : _EX_FAST_REF 234 | +0x328 StartTime : _LARGE_INTEGER 235 | +0x330 LogFileHandle : Ptr64 Void 236 | +0x338 BufferSequenceNumber : Int8B 237 | +0x340 Flags : Uint4B 238 | +0x340 Persistent : Pos 0, 1 Bit 239 | +0x340 AutoLogger : Pos 1, 1 Bit 240 | +0x340 FsReady : Pos 2, 1 Bit 241 | +0x340 RealTime : Pos 3, 1 Bit 242 | +0x340 Wow : Pos 4, 1 Bit 243 | +0x340 KernelTrace : Pos 5, 1 Bit 244 | +0x340 NoMoreEnable : Pos 6, 1 Bit 245 | +0x340 StackTracing : Pos 7, 1 Bit 246 | +0x340 ErrorLogged : Pos 8, 1 Bit 247 | +0x340 RealtimeLoggerContextFreed : Pos 9, 1 Bit 248 | +0x340 PebsTracing : Pos 10, 1 Bit 249 | +0x340 PmcCounters : Pos 11, 1 Bit 250 | +0x340 PageAlignBuffers : Pos 12, 1 Bit 251 | +0x340 StackLookasideListAllocated : Pos 13, 1 Bit 252 | +0x340 SecurityTrace : Pos 14, 1 Bit 253 | +0x340 LastBranchTracing : Pos 15, 1 Bit 254 | +0x340 SystemLoggerIndex : Pos 16, 8 Bits 255 | +0x340 StackCaching : Pos 24, 1 Bit 256 | +0x340 ProviderTracking : Pos 25, 1 Bit 257 | +0x340 ProcessorTrace : Pos 26, 1 Bit 258 | +0x340 QpcDeltaTracking : Pos 27, 1 Bit 259 | +0x340 MarkerBufferSaved : Pos 28, 1 Bit 260 | +0x340 SpareFlags2 : Pos 29, 3 Bits 261 | +0x344 RequestFlag : Uint4B 262 | +0x344 DbgRequestNewFile : Pos 0, 1 Bit 263 | +0x344 DbgRequestUpdateFile : Pos 1, 1 Bit 264 | +0x344 DbgRequestFlush : Pos 2, 1 Bit 265 | +0x344 DbgRequestDisableRealtime : Pos 3, 1 Bit 266 | +0x344 DbgRequestDisconnectConsumer : Pos 4, 1 Bit 267 | +0x344 DbgRequestConnectConsumer : Pos 5, 1 Bit 268 | +0x344 DbgRequestNotifyConsumer : Pos 6, 1 Bit 269 | +0x344 DbgRequestUpdateHeader : Pos 7, 1 Bit 270 | +0x344 DbgRequestDeferredFlush : Pos 8, 1 Bit 271 | +0x344 DbgRequestDeferredFlushTimer : Pos 9, 1 Bit 272 | +0x344 DbgRequestFlushTimer : Pos 10, 1 Bit 273 | +0x344 DbgRequestUpdateDebugger : Pos 11, 1 Bit 274 | +0x344 DbgSpareRequestFlags : Pos 12, 20 Bits 275 | +0x350 StackTraceBlock : _ETW_STACK_TRACE_BLOCK 276 | +0x3d0 HookIdMap : _RTL_BITMAP 277 | +0x3e0 StackCache : Ptr64 _ETW_STACK_CACHE 278 | +0x3e8 PmcData : Ptr64 _ETW_PMC_SUPPORT 279 | +0x3f0 LbrData : Ptr64 _ETW_LBR_SUPPORT 280 | +0x3f8 IptData : Ptr64 _ETW_IPT_SUPPORT 281 | +0x400 BinaryTrackingList : _LIST_ENTRY 282 | +0x410 ScratchArray : Ptr64 Ptr64 _WMI_BUFFER_HEADER 283 | +0x418 DisallowedGuids : _DISALLOWED_GUIDS 284 | +0x428 RelativeTimerDueTime : Int8B 285 | +0x430 PeriodicCaptureStateGuids : _PERIODIC_CAPTURE_STATE_GUIDS 286 | +0x440 PeriodicCaptureStateTimer : Ptr64 _EX_TIMER 287 | +0x448 PeriodicCaptureStateTimerState : _ETW_PERIODIC_TIMER_STATE 288 | +0x450 SoftRestartContext : Ptr64 _ETW_SOFT_RESTART_CONTEXT 289 | +0x458 SiloState : Ptr64 _ETW_SILODRIVERSTATE 290 | +0x460 CompressionWorkItem : _WORK_QUEUE_ITEM 291 | +0x480 CompressionWorkItemState : Int4B 292 | +0x488 CompressionLock : _EX_PUSH_LOCK 293 | +0x490 CompressionTarget : Ptr64 _WMI_BUFFER_HEADER 294 | +0x498 CompressionWorkspace : Ptr64 Void 295 | +0x4a0 CompressionOn : Int4B 296 | +0x4a4 CompressionRatioGuess : Uint4B 297 | +0x4a8 PartialBufferCompressionLevel : Uint4B 298 | +0x4ac CompressionResumptionMode : ETW_COMPRESSION_RESUMPTION_MODE 299 | +0x4b0 PlaceholderList : _SINGLE_LIST_ENTRY 300 | +0x4b8 CompressionDpc : _KDPC 301 | +0x4f8 LastBufferSwitchTime : _LARGE_INTEGER 302 | +0x500 BufferWriteDuration : _LARGE_INTEGER 303 | +0x508 BufferCompressDuration : _LARGE_INTEGER 304 | +0x510 ReferenceQpcDelta : Int8B 305 | +0x518 CallbackContext : Ptr64 _ETW_EVENT_CALLBACK_CONTEXT 306 | +0x520 LastDroppedTime : Ptr64 _LARGE_INTEGER 307 | +0x528 FlushingLastDroppedTime : Ptr64 _LARGE_INTEGER 308 | +0x530 FlushingSequenceNumber : Int8B 309 | */ 310 | 311 | // 312 | // We care about overwriting the GetCpuClock (+0x28) pointer in 313 | // this structure. 314 | // 315 | PVOID* AddressOfEtwpGetCycleCount = (PVOID*)((uintptr_t)CkclWmiLoggerContext + OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK); 316 | 317 | // 318 | // Replace this function pointer with our own. Each time syscall 319 | // is logged by ETW, it will invoke our new timing function. 320 | // 321 | *AddressOfEtwpGetCycleCount = IfhpInternalGetCpuClock; 322 | 323 | IfhpInitialized = true; 324 | 325 | return STATUS_SUCCESS; 326 | } 327 | 328 | /* 329 | * Disables and then re-enables the circular kernel context logger, 330 | * clearing the system of the infinity hook pointer override. 331 | */ 332 | void IfhRelease() 333 | { 334 | if (!IfhpInitialized) 335 | { 336 | return; 337 | } 338 | 339 | if (NT_SUCCESS(IfhpModifyTraceSettings(CKCL_TRACE_END))) 340 | { 341 | IfhpModifyTraceSettings(CKCL_TRACE_START); 342 | } 343 | 344 | IfhpInitialized = false; 345 | } 346 | 347 | /* 348 | * Resolves necessary unexported symbols. 349 | */ 350 | static BOOLEAN IfhpResolveSymbols() 351 | { 352 | // 353 | // We need to resolve nt!EtwpDebuggerData to get the current ETW 354 | // sessions WMI_LOGGER_CONTEXTS, find the CKCL, and overwrite its 355 | // GetCpuClock function pointer. 356 | // 357 | PVOID NtBaseAddress = NULL; 358 | ULONG SizeOfNt = 0; 359 | NtBaseAddress = ImgGetBaseAddress(NULL, &SizeOfNt); 360 | if (!NtBaseAddress) 361 | { 362 | return FALSE; 363 | } 364 | 365 | ULONG SizeOfSection; 366 | PVOID SectionBase = ImgGetImageSection(NtBaseAddress, ".data", &SizeOfSection); 367 | if (!SectionBase) 368 | { 369 | return FALSE; 370 | } 371 | 372 | // 373 | // Look for the EtwpDebuggerData global using the signature. This 374 | // should be the same for Windows 7+. 375 | // 376 | EtwpDebuggerData = MmSearchMemory(SectionBase, SizeOfSection, EtwpDebuggerDataPattern, RTL_NUMBER_OF(EtwpDebuggerDataPattern)); 377 | if (!EtwpDebuggerData) 378 | { 379 | // 380 | // Check inside of .rdata too... this is true for Windows 7. 381 | // Thanks to @ivanpos2015 for reporting. 382 | // 383 | SectionBase = ImgGetImageSection(NtBaseAddress, ".rdata", &SizeOfSection); 384 | if (!SectionBase) 385 | { 386 | return FALSE; 387 | } 388 | 389 | EtwpDebuggerData = MmSearchMemory(SectionBase, SizeOfSection, EtwpDebuggerDataPattern, RTL_NUMBER_OF(EtwpDebuggerDataPattern)); 390 | if (!EtwpDebuggerData) 391 | { 392 | return FALSE; 393 | } 394 | } 395 | 396 | // 397 | // This is offset by 2 bytes due to where the signature starts. 398 | // 399 | EtwpDebuggerData = (PVOID)((uintptr_t)EtwpDebuggerData - 2); 400 | 401 | // 402 | // Get the silos of EtwpDebuggerData. 403 | // 404 | PVOID* EtwpDebuggerDataSilo = *(PVOID**)((uintptr_t)EtwpDebuggerData + OFFSET_ETW_DEBUGGER_DATA_SILO); 405 | 406 | // 407 | // Pull out the circular kernel context logger. 408 | // 409 | CkclWmiLoggerContext = EtwpDebuggerDataSilo[INDEX_CKCL_LOGGER]; 410 | 411 | // 412 | // Grab the system call entry value. 413 | // 414 | SystemCallEntryPage = PAGE_ALIGN(ImgGetSyscallEntry()); 415 | if (!SystemCallEntryPage) 416 | { 417 | return FALSE; 418 | } 419 | 420 | return TRUE; 421 | } 422 | 423 | /* 424 | * Modify the trace settings for the circular kernel context logger. 425 | */ 426 | static NTSTATUS IfhpModifyTraceSettings( 427 | _In_ CKCL_TRACE_OPERATION Operation) 428 | { 429 | PCKCL_TRACE_PROPERTIES Property = (PCKCL_TRACE_PROPERTIES)ExAllocatePool(NonPagedPool, PAGE_SIZE); 430 | if (!Property) 431 | { 432 | return STATUS_MEMORY_NOT_ALLOCATED; 433 | } 434 | 435 | memset(Property, 0, PAGE_SIZE); 436 | 437 | Property->Wnode.BufferSize = PAGE_SIZE; 438 | Property->Wnode.Flags = WNODE_FLAG_TRACED_GUID; 439 | Property->ProviderName = RTL_CONSTANT_STRING(L"Circular Kernel Context Logger"); 440 | Property->Wnode.Guid = CkclSessionGuid; 441 | Property->Wnode.ClientContext = 1; 442 | Property->BufferSize = sizeof(ULONG); 443 | Property->MinimumBuffers = Property->MaximumBuffers = 2; 444 | Property->LogFileMode = EVENT_TRACE_BUFFERING_MODE; 445 | 446 | NTSTATUS Status = STATUS_ACCESS_DENIED; 447 | ULONG ReturnLength = 0; 448 | 449 | // 450 | // Might be wise to actually hook ZwTraceControl so folks don't 451 | // disable your infinity hook ;). 452 | // 453 | switch (Operation) 454 | { 455 | case CKCL_TRACE_START: 456 | { 457 | Status = ZwTraceControl(EtwpStartTrace, Property, PAGE_SIZE, Property, PAGE_SIZE, &ReturnLength); 458 | break; 459 | } 460 | case CKCL_TRACE_END: 461 | { 462 | Status = ZwTraceControl(EtwpStopTrace, Property, PAGE_SIZE, Property, PAGE_SIZE, &ReturnLength); 463 | break; 464 | } 465 | case CKCL_TRACE_SYSCALL: 466 | { 467 | // 468 | // Add more flags here to trap on more events! 469 | // 470 | Property->EnableFlags = EVENT_TRACE_FLAG_SYSTEMCALL; 471 | 472 | Status = ZwTraceControl(EtwpUpdateTrace, Property, PAGE_SIZE, Property, PAGE_SIZE, &ReturnLength); 473 | break; 474 | } 475 | } 476 | 477 | ExFreePool(Property); 478 | 479 | return Status; 480 | } 481 | 482 | /* 483 | * We replaced the GetCpuClock pointer to this one here which 484 | * implements stack walking logic. We use this to determine whether 485 | * a syscall occurred. It also provides you a way to alter the 486 | * address on the stack to redirect execution to your detoured 487 | * function. 488 | * 489 | */ 490 | static ULONG64 IfhpInternalGetCpuClock() 491 | { 492 | if (ExGetPreviousMode() == KernelMode) 493 | { 494 | return __rdtsc(); 495 | } 496 | 497 | // 498 | // Extract the system call index (if you so desire). 499 | // 500 | PKTHREAD CurrentThread = (PKTHREAD)__readgsqword(OFFSET_KPCR_CURRENT_THREAD); 501 | unsigned int SystemCallIndex = *(unsigned int*)((uintptr_t)CurrentThread + OFFSET_KTHREAD_SYSTEM_CALL_NUMBER); 502 | 503 | PVOID* StackMax = (PVOID*)__readgsqword(OFFSET_KPCR_RSP_BASE); 504 | PVOID* StackFrame = (PVOID*)_AddressOfReturnAddress(); 505 | 506 | // 507 | // First walk backwards on the stack to find the 2 magic values. 508 | // 509 | for (PVOID* StackCurrent = StackMax; 510 | StackCurrent > StackFrame; 511 | --StackCurrent) 512 | { 513 | // 514 | // This is intentionally being read as 4-byte magic on an 8 515 | // byte aligned boundary. 516 | // 517 | PULONG AsUlong = (PULONG)StackCurrent; 518 | if (*AsUlong != INFINITYHOOK_MAGIC_1) 519 | { 520 | continue; 521 | } 522 | 523 | // 524 | // If the first magic is set, check for the second magic. 525 | // 526 | --StackCurrent; 527 | 528 | PUSHORT AsShort = (PUSHORT)StackCurrent; 529 | if (*AsShort != INFINITYHOOK_MAGIC_2) 530 | { 531 | continue; 532 | } 533 | 534 | // 535 | // Now we reverse the direction of the stack walk. 536 | // 537 | for (; 538 | StackCurrent < StackMax; 539 | ++StackCurrent) 540 | { 541 | PULONGLONG AsUlonglong = (PULONGLONG)StackCurrent; 542 | 543 | if (!(PAGE_ALIGN(*AsUlonglong) >= SystemCallEntryPage && 544 | PAGE_ALIGN(*AsUlonglong) < (PVOID)((uintptr_t)SystemCallEntryPage + (PAGE_SIZE * 2)))) 545 | { 546 | continue; 547 | } 548 | 549 | // 550 | // If you want to "hook" this function, replace this stack memory 551 | // with a pointer to your own function. 552 | // 553 | void** SystemCallFunction = &StackCurrent[9]; 554 | 555 | if (IfhpCallback) 556 | { 557 | IfhpCallback(SystemCallIndex, SystemCallFunction); 558 | } 559 | 560 | break; 561 | } 562 | 563 | break; 564 | } 565 | 566 | return __rdtsc(); 567 | } -------------------------------------------------------------------------------- /src/libinfinityhook/infinityhook.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * infinityhook.h 4 | * 5 | * Abstract: 6 | * The interface to the infinity hook library. 7 | * 8 | * Authors: 9 | * Nick Peterson | http://everdox.net/ 10 | * 11 | * Special thanks to Nemanja (Nemi) Mulasmajic 12 | * for his help with the POC. 13 | * 14 | */ 15 | 16 | #pragma once 17 | 18 | /// 19 | /// Structures and typedefs. 20 | /// 21 | 22 | typedef void (__fastcall* INFINITYHOOKCALLBACK)(_In_ unsigned int SystemCallIndex, _Inout_ void** SystemCallFunction); 23 | 24 | /// 25 | /// Forward declarations. 26 | /// 27 | 28 | NTSTATUS IfhInitialize( 29 | _In_ INFINITYHOOKCALLBACK InfinityHookCallback); 30 | 31 | void IfhRelease(); -------------------------------------------------------------------------------- /src/libinfinityhook/libinfinityhook.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; libinfinityhook.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} 9 | Provider=%ManufacturerName% 10 | DriverVer= 11 | CatalogFile=libinfinityhook.cat 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | 16 | 17 | [SourceDisksNames] 18 | 1 = %DiskName%,,,"" 19 | 20 | [SourceDisksFiles] 21 | 22 | 23 | [Manufacturer] 24 | %ManufacturerName%=Standard,NT$ARCH$ 25 | 26 | [Standard.NT$ARCH$] 27 | 28 | 29 | [Strings] 30 | ManufacturerName="" ;TODO: Replace with your manufacturer name 31 | ClassName="" 32 | DiskName="libinfinityhook Source Disk" 33 | -------------------------------------------------------------------------------- /src/libinfinityhook/libinfinityhook.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 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {B9079C4E-D613-48C4-A649-9146B29CA9E7} 39 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | libinfinityhook 45 | $(LatestTargetPlatformVersion) 46 | 47 | 48 | 49 | Windows10 50 | true 51 | WindowsKernelModeDriver10.0 52 | Driver 53 | WDM 54 | 55 | 56 | Windows10 57 | false 58 | WindowsKernelModeDriver10.0 59 | Driver 60 | WDM 61 | 62 | 63 | Windows10 64 | true 65 | WindowsKernelModeDriver10.0 66 | StaticLibrary 67 | WDM 68 | false 69 | 70 | 71 | Windows10 72 | false 73 | WindowsKernelModeDriver10.0 74 | StaticLibrary 75 | WDM 76 | false 77 | 78 | 79 | Windows10 80 | true 81 | WindowsKernelModeDriver10.0 82 | Driver 83 | WDM 84 | 85 | 86 | Windows10 87 | false 88 | WindowsKernelModeDriver10.0 89 | Driver 90 | WDM 91 | 92 | 93 | Windows10 94 | true 95 | WindowsKernelModeDriver10.0 96 | Driver 97 | WDM 98 | 99 | 100 | Windows10 101 | false 102 | WindowsKernelModeDriver10.0 103 | Driver 104 | WDM 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | DbgengKernelDebugger 116 | 117 | 118 | DbgengKernelDebugger 119 | 120 | 121 | DbgengKernelDebugger 122 | ..\..\..\..\Program Files (x86)\Windows Kits\10\CodeAnalysis\DriverMinimumRules.ruleset 123 | false 124 | $(ProjectDir);$(IncludePath) 125 | 126 | 127 | DbgengKernelDebugger 128 | ..\..\..\..\Program Files (x86)\Windows Kits\10\CodeAnalysis\DriverMinimumRules.ruleset 129 | false 130 | $(ProjectDir);$(IncludePath) 131 | 132 | 133 | DbgengKernelDebugger 134 | 135 | 136 | DbgengKernelDebugger 137 | 138 | 139 | DbgengKernelDebugger 140 | 141 | 142 | DbgengKernelDebugger 143 | 144 | 145 | 146 | Use 147 | EnableAllWarnings 148 | false 149 | 4711;5045;28751;4748;%(DisableSpecificWarnings) 150 | 151 | 152 | 153 | 154 | Use 155 | EnableAllWarnings 156 | false 157 | 4711;5045;28751;4603;4627;4986;4987;4996;%(DisableSpecificWarnings) 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | Create 173 | Create 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /src/libinfinityhook/libinfinityhook.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 | {135166da-524d-40b2-8d85-e7740d73f30a} 22 | 23 | 24 | {aebdf6d9-f46e-4c1f-a4bc-046066ba113a} 25 | 26 | 27 | 28 | 29 | Driver Files 30 | 31 | 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files\hde 47 | 48 | 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files\hde 67 | 68 | 69 | Header Files\hde 70 | 71 | 72 | Header Files\hde 73 | 74 | 75 | -------------------------------------------------------------------------------- /src/libinfinityhook/mm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * mm.cpp 4 | * 5 | * Abstract: 6 | * Generic memory manipulation routines. 7 | * 8 | * Authors: 9 | * Nick Peterson | http://everdox.net/ 10 | * 11 | * Special thanks to Nemanja (Nemi) Mulasmajic 12 | * for his help with the POC. 13 | * 14 | */ 15 | 16 | #include "stdafx.h" 17 | #include "mm.h" 18 | 19 | /* 20 | * Search a memory buffer for the input signature. 21 | */ 22 | const void* MmSearchMemory( 23 | _In_ const void* Buffer, 24 | _In_ size_t SizeOfBuffer, 25 | _In_ const void* Signature, 26 | _In_ size_t SizeOfSignature) 27 | { 28 | // 29 | // Sanity check... 30 | // 31 | if (SizeOfSignature > SizeOfBuffer) 32 | { 33 | return NULL; 34 | } 35 | 36 | PCHAR Memory = (PCHAR)Buffer; 37 | 38 | // 39 | // The +1 is necessary or there will be an off-by-one error. 40 | // Thanks to @milabs for reporting. 41 | // 42 | for (size_t i = 0; i < ((SizeOfBuffer - SizeOfSignature) + 1); ++i) 43 | { 44 | if (!memcmp(&Memory[i], Signature, SizeOfSignature)) 45 | { 46 | return &Memory[i]; 47 | } 48 | } 49 | 50 | return NULL; 51 | } -------------------------------------------------------------------------------- /src/libinfinityhook/mm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * mm.h 4 | * 5 | * Abstract: 6 | * Generic memory manipulation routines. 7 | * 8 | * Authors: 9 | * Nick Peterson | http://everdox.net/ 10 | * 11 | * Special thanks to Nemanja (Nemi) Mulasmajic 12 | * for his help with the POC. 13 | * 14 | */ 15 | 16 | #pragma once 17 | 18 | /// 19 | /// Forward declarations. 20 | /// 21 | 22 | const void* MmSearchMemory( 23 | _In_ const void* Buffer, 24 | _In_ size_t SizeOfBuffer, 25 | _In_ const void* Signature, 26 | _In_ size_t SizeOfSignature); -------------------------------------------------------------------------------- /src/libinfinityhook/ntint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * ntint.h 4 | * 5 | * Abstract: 6 | * Header file that defines Windows-specific types and structures. An 7 | * extension of Windows.h. 8 | * 9 | * Authors: 10 | * Nick Peterson | http://everdox.net/ 11 | * 12 | * Special thanks to Nemanja (Nemi) Mulasmajic 13 | * for his help with the POC. 14 | * 15 | */ 16 | 17 | #pragma once 18 | 19 | #define EtwpStartTrace 1 20 | #define EtwpStopTrace 2 21 | #define EtwpQueryTrace 3 22 | #define EtwpUpdateTrace 4 23 | #define EtwpFlushTrace 5 24 | 25 | #define WNODE_FLAG_TRACED_GUID 0x00020000 // denotes a trace 26 | #define EVENT_TRACE_BUFFERING_MODE 0x00000400 // Buffering mode only 27 | #define EVENT_TRACE_FLAG_SYSTEMCALL 0x00000080 // system calls 28 | 29 | #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 30 | #define IMAGE_SIZEOF_SHORT_NAME 8 31 | 32 | #define IA32_LSTAR_MSR 0xC0000082 33 | 34 | #define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ 35 | ((ULONG_PTR)(ntheader) + \ 36 | FIELD_OFFSET( IMAGE_NT_HEADERS64, OptionalHeader ) + \ 37 | ((ntheader))->FileHeader.SizeOfOptionalHeader \ 38 | )) 39 | 40 | typedef enum _SYSTEM_INFORMATION_CLASS 41 | { 42 | SystemBasicInformation, // q: SYSTEM_BASIC_INFORMATION 43 | SystemProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION 44 | SystemPerformanceInformation, // q: SYSTEM_PERFORMANCE_INFORMATION 45 | SystemTimeOfDayInformation, // q: SYSTEM_TIMEOFDAY_INFORMATION 46 | SystemPathInformation, // not implemented 47 | SystemProcessInformation, // q: SYSTEM_PROCESS_INFORMATION 48 | SystemCallCountInformation, // q: SYSTEM_CALL_COUNT_INFORMATION 49 | SystemDeviceInformation, // q: SYSTEM_DEVICE_INFORMATION 50 | SystemProcessorPerformanceInformation, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION 51 | SystemFlagsInformation, // q: SYSTEM_FLAGS_INFORMATION 52 | SystemCallTimeInformation, // not implemented // SYSTEM_CALL_TIME_INFORMATION // 10 53 | SystemModuleInformation, // q: RTL_PROCESS_MODULES 54 | SystemLocksInformation, // q: RTL_PROCESS_LOCKS 55 | SystemStackTraceInformation, // q: RTL_PROCESS_BACKTRACES 56 | SystemPagedPoolInformation, // not implemented 57 | SystemNonPagedPoolInformation, // not implemented 58 | SystemHandleInformation, // q: SYSTEM_HANDLE_INFORMATION 59 | SystemObjectInformation, // q: SYSTEM_OBJECTTYPE_INFORMATION mixed with SYSTEM_OBJECT_INFORMATION 60 | SystemPageFileInformation, // q: SYSTEM_PAGEFILE_INFORMATION 61 | SystemVdmInstemulInformation, // q 62 | SystemVdmBopInformation, // not implemented // 20 63 | SystemFileCacheInformation, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemCache) 64 | SystemPoolTagInformation, // q: SYSTEM_POOLTAG_INFORMATION 65 | SystemInterruptInformation, // q: SYSTEM_INTERRUPT_INFORMATION 66 | SystemDpcBehaviorInformation, // q: SYSTEM_DPC_BEHAVIOR_INFORMATION; s: SYSTEM_DPC_BEHAVIOR_INFORMATION (requires SeLoadDriverPrivilege) 67 | SystemFullMemoryInformation, // not implemented 68 | SystemLoadGdiDriverInformation, // s (kernel-mode only) 69 | SystemUnloadGdiDriverInformation, // s (kernel-mode only) 70 | SystemTimeAdjustmentInformation, // q: SYSTEM_QUERY_TIME_ADJUST_INFORMATION; s: SYSTEM_SET_TIME_ADJUST_INFORMATION (requires SeSystemtimePrivilege) 71 | SystemSummaryMemoryInformation, // not implemented 72 | SystemMirrorMemoryInformation, // s (requires license value "Kernel-MemoryMirroringSupported") (requires SeShutdownPrivilege) // 30 73 | SystemPerformanceTraceInformation, // q; s: (type depends on EVENT_TRACE_INFORMATION_CLASS) 74 | SystemObsolete0, // not implemented 75 | SystemExceptionInformation, // q: SYSTEM_EXCEPTION_INFORMATION 76 | SystemCrashDumpStateInformation, // s (requires SeDebugPrivilege) 77 | SystemKernelDebuggerInformation, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION 78 | SystemContextSwitchInformation, // q: SYSTEM_CONTEXT_SWITCH_INFORMATION 79 | SystemRegistryQuotaInformation, // q: SYSTEM_REGISTRY_QUOTA_INFORMATION; s (requires SeIncreaseQuotaPrivilege) 80 | SystemExtendServiceTableInformation, // s (requires SeLoadDriverPrivilege) // loads win32k only 81 | SystemPrioritySeperation, // s (requires SeTcbPrivilege) 82 | SystemVerifierAddDriverInformation, // s (requires SeDebugPrivilege) // 40 83 | SystemVerifierRemoveDriverInformation, // s (requires SeDebugPrivilege) 84 | SystemProcessorIdleInformation, // q: SYSTEM_PROCESSOR_IDLE_INFORMATION 85 | SystemLegacyDriverInformation, // q: SYSTEM_LEGACY_DRIVER_INFORMATION 86 | SystemCurrentTimeZoneInformation, // q; s: RTL_TIME_ZONE_INFORMATION 87 | SystemLookasideInformation, // q: SYSTEM_LOOKASIDE_INFORMATION 88 | SystemTimeSlipNotification, // s (requires SeSystemtimePrivilege) 89 | SystemSessionCreate, // not implemented 90 | SystemSessionDetach, // not implemented 91 | SystemSessionInformation, // not implemented (SYSTEM_SESSION_INFORMATION) 92 | SystemRangeStartInformation, // q: SYSTEM_RANGE_START_INFORMATION // 50 93 | SystemVerifierInformation, // q: SYSTEM_VERIFIER_INFORMATION; s (requires SeDebugPrivilege) 94 | SystemVerifierThunkExtend, // s (kernel-mode only) 95 | SystemSessionProcessInformation, // q: SYSTEM_SESSION_PROCESS_INFORMATION 96 | SystemLoadGdiDriverInSystemSpace, // s (kernel-mode only) (same as SystemLoadGdiDriverInformation) 97 | SystemNumaProcessorMap, // q 98 | SystemPrefetcherInformation, // q: PREFETCHER_INFORMATION; s: PREFETCHER_INFORMATION // PfSnQueryPrefetcherInformation 99 | SystemExtendedProcessInformation, // q: SYSTEM_PROCESS_INFORMATION 100 | SystemRecommendedSharedDataAlignment, // q 101 | SystemComPlusPackage, // q; s 102 | SystemNumaAvailableMemory, // 60 103 | SystemProcessorPowerInformation, // q: SYSTEM_PROCESSOR_POWER_INFORMATION 104 | SystemEmulationBasicInformation, 105 | SystemEmulationProcessorInformation, 106 | SystemExtendedHandleInformation, // q: SYSTEM_HANDLE_INFORMATION_EX 107 | SystemLostDelayedWriteInformation, // q: ULONG 108 | SystemBigPoolInformation, // q: SYSTEM_BIGPOOL_INFORMATION 109 | SystemSessionPoolTagInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION 110 | SystemSessionMappedViewInformation, // q: SYSTEM_SESSION_MAPPED_VIEW_INFORMATION 111 | SystemHotpatchInformation, // q; s: SYSTEM_HOTPATCH_CODE_INFORMATION 112 | SystemObjectSecurityMode, // q: ULONG // 70 113 | SystemWatchdogTimerHandler, // s (kernel-mode only) 114 | SystemWatchdogTimerInformation, // q (kernel-mode only); s (kernel-mode only) 115 | SystemLogicalProcessorInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION 116 | SystemWow64SharedInformationObsolete, // not implemented 117 | SystemRegisterFirmwareTableInformationHandler, // s (kernel-mode only) 118 | SystemFirmwareTableInformation, // SYSTEM_FIRMWARE_TABLE_INFORMATION 119 | SystemModuleInformationEx, // q: RTL_PROCESS_MODULE_INFORMATION_EX 120 | SystemVerifierTriageInformation, // not implemented 121 | SystemSuperfetchInformation, // q; s: SUPERFETCH_INFORMATION // PfQuerySuperfetchInformation 122 | SystemMemoryListInformation, // q: SYSTEM_MEMORY_LIST_INFORMATION; s: SYSTEM_MEMORY_LIST_COMMAND (requires SeProfileSingleProcessPrivilege) // 80 123 | SystemFileCacheInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (same as SystemFileCacheInformation) 124 | SystemThreadPriorityClientIdInformation, // s: SYSTEM_THREAD_CID_PRIORITY_INFORMATION (requires SeIncreaseBasePriorityPrivilege) 125 | SystemProcessorIdleCycleTimeInformation, // q: SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION[] 126 | SystemVerifierCancellationInformation, // not implemented // name:wow64:whNT32QuerySystemVerifierCancellationInformation 127 | SystemProcessorPowerInformationEx, // not implemented 128 | SystemRefTraceInformation, // q; s: SYSTEM_REF_TRACE_INFORMATION // ObQueryRefTraceInformation 129 | SystemSpecialPoolInformation, // q; s (requires SeDebugPrivilege) // MmSpecialPoolTag, then MmSpecialPoolCatchOverruns != 0 130 | SystemProcessIdInformation, // q: SYSTEM_PROCESS_ID_INFORMATION 131 | SystemErrorPortInformation, // s (requires SeTcbPrivilege) 132 | SystemBootEnvironmentInformation, // q: SYSTEM_BOOT_ENVIRONMENT_INFORMATION // 90 133 | SystemHypervisorInformation, // q; s (kernel-mode only) 134 | SystemVerifierInformationEx, // q; s: SYSTEM_VERIFIER_INFORMATION_EX 135 | SystemTimeZoneInformation, // s (requires SeTimeZonePrivilege) 136 | SystemImageFileExecutionOptionsInformation, // s: SYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION (requires SeTcbPrivilege) 137 | SystemCoverageInformation, // q; s // name:wow64:whNT32QuerySystemCoverageInformation; ExpCovQueryInformation 138 | SystemPrefetchPatchInformation, // not implemented 139 | SystemVerifierFaultsInformation, // s (requires SeDebugPrivilege) 140 | SystemSystemPartitionInformation, // q: SYSTEM_SYSTEM_PARTITION_INFORMATION 141 | SystemSystemDiskInformation, // q: SYSTEM_SYSTEM_DISK_INFORMATION 142 | SystemProcessorPerformanceDistribution, // q: SYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION // 100 143 | SystemNumaProximityNodeInformation, 144 | SystemDynamicTimeZoneInformation, // q; s (requires SeTimeZonePrivilege) 145 | SystemCodeIntegrityInformation, // q: SYSTEM_CODEINTEGRITY_INFORMATION // SeCodeIntegrityQueryInformation 146 | SystemProcessorMicrocodeUpdateInformation, // s 147 | SystemProcessorBrandString, // q // HaliQuerySystemInformation -> HalpGetProcessorBrandString, info class 23 148 | SystemVirtualAddressInformation, // q: SYSTEM_VA_LIST_INFORMATION[]; s: SYSTEM_VA_LIST_INFORMATION[] (requires SeIncreaseQuotaPrivilege) // MmQuerySystemVaInformation 149 | SystemLogicalProcessorAndGroupInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX // since WIN7 // KeQueryLogicalProcessorRelationship 150 | SystemProcessorCycleTimeInformation, // q: SYSTEM_PROCESSOR_CYCLE_TIME_INFORMATION[] 151 | SystemStoreInformation, // q; s: SYSTEM_STORE_INFORMATION // SmQueryStoreInformation 152 | SystemRegistryAppendString, // s: SYSTEM_REGISTRY_APPEND_STRING_PARAMETERS // 110 153 | SystemAitSamplingValue, // s: ULONG (requires SeProfileSingleProcessPrivilege) 154 | SystemVhdBootInformation, // q: SYSTEM_VHD_BOOT_INFORMATION 155 | SystemCpuQuotaInformation, // q; s // PsQueryCpuQuotaInformation 156 | SystemNativeBasicInformation, // not implemented 157 | SystemSpare1, // not implemented 158 | SystemLowPriorityIoInformation, // q: SYSTEM_LOW_PRIORITY_IO_INFORMATION 159 | SystemTpmBootEntropyInformation, // q: TPM_BOOT_ENTROPY_NT_RESULT // ExQueryTpmBootEntropyInformation 160 | SystemVerifierCountersInformation, // q: SYSTEM_VERIFIER_COUNTERS_INFORMATION 161 | SystemPagedPoolInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypePagedPool) 162 | SystemSystemPtesInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemPtes) // 120 163 | SystemNodeDistanceInformation, 164 | SystemAcpiAuditInformation, // q: SYSTEM_ACPI_AUDIT_INFORMATION // HaliQuerySystemInformation -> HalpAuditQueryResults, info class 26 165 | SystemBasicPerformanceInformation, // q: SYSTEM_BASIC_PERFORMANCE_INFORMATION // name:wow64:whNtQuerySystemInformation_SystemBasicPerformanceInformation 166 | SystemQueryPerformanceCounterInformation, // q: SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION // since WIN7 SP1 167 | SystemSessionBigPoolInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION // since WIN8 168 | SystemBootGraphicsInformation, // q; s: SYSTEM_BOOT_GRAPHICS_INFORMATION (kernel-mode only) 169 | SystemScrubPhysicalMemoryInformation, // q; s: MEMORY_SCRUB_INFORMATION 170 | SystemBadPageInformation, 171 | SystemProcessorProfileControlArea, // q; s: SYSTEM_PROCESSOR_PROFILE_CONTROL_AREA 172 | SystemCombinePhysicalMemoryInformation, // s: MEMORY_COMBINE_INFORMATION, MEMORY_COMBINE_INFORMATION_EX, MEMORY_COMBINE_INFORMATION_EX2 // 130 173 | SystemEntropyInterruptTimingCallback, 174 | SystemConsoleInformation, // q: SYSTEM_CONSOLE_INFORMATION 175 | SystemPlatformBinaryInformation, // q: SYSTEM_PLATFORM_BINARY_INFORMATION 176 | SystemThrottleNotificationInformation, 177 | SystemHypervisorProcessorCountInformation, // q: SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION 178 | SystemDeviceDataInformation, // q: SYSTEM_DEVICE_DATA_INFORMATION 179 | SystemDeviceDataEnumerationInformation, 180 | SystemMemoryTopologyInformation, // q: SYSTEM_MEMORY_TOPOLOGY_INFORMATION 181 | SystemMemoryChannelInformation, // q: SYSTEM_MEMORY_CHANNEL_INFORMATION 182 | SystemBootLogoInformation, // q: SYSTEM_BOOT_LOGO_INFORMATION // 140 183 | SystemProcessorPerformanceInformationEx, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_EX // since WINBLUE 184 | SystemSpare0, 185 | SystemSecureBootPolicyInformation, // q: SYSTEM_SECUREBOOT_POLICY_INFORMATION 186 | SystemPageFileInformationEx, // q: SYSTEM_PAGEFILE_INFORMATION_EX 187 | SystemSecureBootInformation, // q: SYSTEM_SECUREBOOT_INFORMATION 188 | SystemEntropyInterruptTimingRawInformation, 189 | SystemPortableWorkspaceEfiLauncherInformation, // q: SYSTEM_PORTABLE_WORKSPACE_EFI_LAUNCHER_INFORMATION 190 | SystemFullProcessInformation, // q: SYSTEM_PROCESS_INFORMATION with SYSTEM_PROCESS_INFORMATION_EXTENSION (requires admin) 191 | SystemKernelDebuggerInformationEx, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX 192 | SystemBootMetadataInformation, // 150 193 | SystemSoftRebootInformation, // q: ULONG 194 | SystemElamCertificateInformation, // s: SYSTEM_ELAM_CERTIFICATE_INFORMATION 195 | SystemOfflineDumpConfigInformation, 196 | SystemProcessorFeaturesInformation, // q: SYSTEM_PROCESSOR_FEATURES_INFORMATION 197 | SystemRegistryReconciliationInformation, 198 | SystemEdidInformation, 199 | SystemManufacturingInformation, // q: SYSTEM_MANUFACTURING_INFORMATION // since THRESHOLD 200 | SystemEnergyEstimationConfigInformation, // q: SYSTEM_ENERGY_ESTIMATION_CONFIG_INFORMATION 201 | SystemHypervisorDetailInformation, // q: SYSTEM_HYPERVISOR_DETAIL_INFORMATION 202 | SystemProcessorCycleStatsInformation, // q: SYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION // 160 203 | SystemVmGenerationCountInformation, 204 | SystemTrustedPlatformModuleInformation, // q: SYSTEM_TPM_INFORMATION 205 | SystemKernelDebuggerFlags, // SYSTEM_KERNEL_DEBUGGER_FLAGS 206 | SystemCodeIntegrityPolicyInformation, // q: SYSTEM_CODEINTEGRITYPOLICY_INFORMATION 207 | SystemIsolatedUserModeInformation, // q: SYSTEM_ISOLATED_USER_MODE_INFORMATION 208 | SystemHardwareSecurityTestInterfaceResultsInformation, 209 | SystemSingleModuleInformation, // q: SYSTEM_SINGLE_MODULE_INFORMATION 210 | SystemAllowedCpuSetsInformation, 211 | SystemVsmProtectionInformation, // q: SYSTEM_VSM_PROTECTION_INFORMATION (previously SystemDmaProtectionInformation) 212 | SystemInterruptCpuSetsInformation, // q: SYSTEM_INTERRUPT_CPU_SET_INFORMATION // 170 213 | SystemSecureBootPolicyFullInformation, // q: SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION 214 | SystemCodeIntegrityPolicyFullInformation, 215 | SystemAffinitizedInterruptProcessorInformation, 216 | SystemRootSiloInformation, // q: SYSTEM_ROOT_SILO_INFORMATION 217 | SystemCpuSetInformation, // q: SYSTEM_CPU_SET_INFORMATION // since THRESHOLD2 218 | SystemCpuSetTagInformation, // q: SYSTEM_CPU_SET_TAG_INFORMATION 219 | SystemWin32WerStartCallout, 220 | SystemSecureKernelProfileInformation, // q: SYSTEM_SECURE_KERNEL_HYPERGUARD_PROFILE_INFORMATION 221 | SystemCodeIntegrityPlatformManifestInformation, // q: SYSTEM_SECUREBOOT_PLATFORM_MANIFEST_INFORMATION // since REDSTONE 222 | SystemInterruptSteeringInformation, // 180 223 | SystemSupportedProcessorArchitectures, 224 | SystemMemoryUsageInformation, // q: SYSTEM_MEMORY_USAGE_INFORMATION 225 | SystemCodeIntegrityCertificateInformation, // q: SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION 226 | SystemPhysicalMemoryInformation, // q: SYSTEM_PHYSICAL_MEMORY_INFORMATION // since REDSTONE2 227 | SystemControlFlowTransition, 228 | SystemKernelDebuggingAllowed, // s: ULONG 229 | SystemActivityModerationExeState, // SYSTEM_ACTIVITY_MODERATION_EXE_STATE 230 | SystemActivityModerationUserSettings, // SYSTEM_ACTIVITY_MODERATION_USER_SETTINGS 231 | SystemCodeIntegrityPoliciesFullInformation, 232 | SystemCodeIntegrityUnlockInformation, // SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION // 190 233 | SystemIntegrityQuotaInformation, 234 | SystemFlushInformation, // q: SYSTEM_FLUSH_INFORMATION 235 | SystemProcessorIdleMaskInformation, // q: ULONG_PTR // since REDSTONE3 236 | SystemSecureDumpEncryptionInformation, 237 | SystemWriteConstraintInformation, // SYSTEM_WRITE_CONSTRAINT_INFORMATION 238 | SystemKernelVaShadowInformation, // SYSTEM_KERNEL_VA_SHADOW_INFORMATION 239 | SystemHypervisorSharedPageInformation, // SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION // since REDSTONE4 240 | SystemFirmwareBootPerformanceInformation, 241 | SystemCodeIntegrityVerificationInformation, // SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION 242 | SystemFirmwarePartitionInformation, // SYSTEM_FIRMWARE_PARTITION_INFORMATION // 200 243 | SystemSpeculationControlInformation, // SYSTEM_SPECULATION_CONTROL_INFORMATION // (CVE-2017-5715) REDSTONE3 and above. 244 | SystemDmaGuardPolicyInformation, // SYSTEM_DMA_GUARD_POLICY_INFORMATION 245 | SystemEnclaveLaunchControlInformation, // SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION 246 | SystemWorkloadAllowedCpuSetsInformation, // SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION // since REDSTONE5 247 | SystemCodeIntegrityUnlockModeInformation, 248 | SystemLeapSecondInformation, // SYSTEM_LEAP_SECOND_INFORMATION 249 | SystemFlags2Information, // q: SYSTEM_FLAGS_INFORMATION 250 | SystemSecurityModelInformation, // SYSTEM_SECURITY_MODEL_INFORMATION // since 19H1 251 | SystemCodeIntegritySyntheticCacheInformation, 252 | MaxSystemInfoClass 253 | } SYSTEM_INFORMATION_CLASS; 254 | 255 | typedef struct _RTL_PROCESS_MODULE_INFORMATION 256 | { 257 | HANDLE Section; 258 | PVOID MappedBase; 259 | PVOID ImageBase; 260 | ULONG ImageSize; 261 | ULONG Flags; 262 | USHORT LoadOrderIndex; 263 | USHORT InitOrderIndex; 264 | USHORT LoadCount; 265 | USHORT OffsetToFileName; 266 | UCHAR FullPathName[256]; 267 | } RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION; 268 | 269 | typedef struct _RTL_PROCESS_MODULES 270 | { 271 | ULONG NumberOfModules; 272 | RTL_PROCESS_MODULE_INFORMATION Modules[1]; 273 | } RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES; 274 | 275 | typedef struct _IMAGE_DATA_DIRECTORY { 276 | ULONG VirtualAddress; 277 | ULONG Size; 278 | } IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY; 279 | 280 | typedef struct _IMAGE_SECTION_HEADER { 281 | UCHAR Name[IMAGE_SIZEOF_SHORT_NAME]; 282 | union { 283 | ULONG PhysicalAddress; 284 | ULONG VirtualSize; 285 | } Misc; 286 | ULONG VirtualAddress; 287 | ULONG SizeOfRawData; 288 | ULONG PointerToRawData; 289 | ULONG PointerToRelocations; 290 | ULONG PointerToLinenumbers; 291 | USHORT NumberOfRelocations; 292 | USHORT NumberOfLinenumbers; 293 | ULONG Characteristics; 294 | } IMAGE_SECTION_HEADER, * PIMAGE_SECTION_HEADER; 295 | 296 | typedef struct _IMAGE_OPTIONAL_HEADER64 { 297 | USHORT Magic; 298 | UCHAR MajorLinkerVersion; 299 | UCHAR MinorLinkerVersion; 300 | ULONG SizeOfCode; 301 | ULONG SizeOfInitializedData; 302 | ULONG SizeOfUninitializedData; 303 | ULONG AddressOfEntryPoint; 304 | ULONG BaseOfCode; 305 | ULONGLONG ImageBase; 306 | ULONG SectionAlignment; 307 | ULONG FileAlignment; 308 | USHORT MajorOperatingSystemVersion; 309 | USHORT MinorOperatingSystemVersion; 310 | USHORT MajorImageVersion; 311 | USHORT MinorImageVersion; 312 | USHORT MajorSubsystemVersion; 313 | USHORT MinorSubsystemVersion; 314 | ULONG Win32VersionValue; 315 | ULONG SizeOfImage; 316 | ULONG SizeOfHeaders; 317 | ULONG CheckSum; 318 | USHORT Subsystem; 319 | USHORT DllCharacteristics; 320 | ULONGLONG SizeOfStackReserve; 321 | ULONGLONG SizeOfStackCommit; 322 | ULONGLONG SizeOfHeapReserve; 323 | ULONGLONG SizeOfHeapCommit; 324 | ULONG LoaderFlags; 325 | ULONG NumberOfRvaAndSizes; 326 | IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; 327 | } IMAGE_OPTIONAL_HEADER64, * PIMAGE_OPTIONAL_HEADER64; 328 | 329 | typedef struct _IMAGE_FILE_HEADER { 330 | USHORT Machine; 331 | USHORT NumberOfSections; 332 | ULONG TimeDateStamp; 333 | ULONG PointerToSymbolTable; 334 | ULONG NumberOfSymbols; 335 | USHORT SizeOfOptionalHeader; 336 | USHORT Characteristics; 337 | } IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER; 338 | 339 | typedef struct _IMAGE_NT_HEADERS64 { 340 | ULONG Signature; 341 | IMAGE_FILE_HEADER FileHeader; 342 | IMAGE_OPTIONAL_HEADER64 OptionalHeader; 343 | } IMAGE_NT_HEADERS64, * PIMAGE_NT_HEADERS64; 344 | 345 | typedef struct _WNODE_HEADER 346 | { 347 | ULONG BufferSize; // Size of entire buffer inclusive of this ULONG 348 | ULONG ProviderId; // Provider Id of driver returning this buffer 349 | union 350 | { 351 | ULONG64 HistoricalContext; // Logger use 352 | struct 353 | { 354 | ULONG Version; // Reserved 355 | ULONG Linkage; // Linkage field reserved for WMI 356 | } DUMMYSTRUCTNAME; 357 | } DUMMYUNIONNAME; 358 | 359 | union 360 | { 361 | ULONG CountLost; // Reserved 362 | HANDLE KernelHandle; // Kernel handle for data block 363 | LARGE_INTEGER TimeStamp; // Timestamp as returned in units of 100ns 364 | // since 1/1/1601 365 | } DUMMYUNIONNAME2; 366 | GUID Guid; // Guid for data block returned with results 367 | ULONG ClientContext; 368 | ULONG Flags; // Flags, see below 369 | } WNODE_HEADER, *PWNODE_HEADER; 370 | 371 | typedef struct _EVENT_TRACE_PROPERTIES { 372 | WNODE_HEADER Wnode; 373 | ULONG BufferSize; 374 | ULONG MinimumBuffers; 375 | ULONG MaximumBuffers; 376 | ULONG MaximumFileSize; 377 | ULONG LogFileMode; 378 | ULONG FlushTimer; 379 | ULONG EnableFlags; 380 | LONG AgeLimit; 381 | ULONG NumberOfBuffers; 382 | ULONG FreeBuffers; 383 | ULONG EventsLost; 384 | ULONG BuffersWritten; 385 | ULONG LogBuffersLost; 386 | ULONG RealTimeBuffersLost; 387 | HANDLE LoggerThreadId; 388 | ULONG LogFileNameOffset; 389 | ULONG LoggerNameOffset; 390 | } EVENT_TRACE_PROPERTIES, *PEVENT_TRACE_PROPERTIES; 391 | 392 | /* 54dea73a-ed1f-42a4-af713e63d056f174 */ 393 | const GUID CkclSessionGuid = { 0x54dea73a, 0xed1f, 0x42a4, { 0xaf, 0x71, 0x3e, 0x63, 0xd0, 0x56, 0xf1, 0x74 } }; 394 | 395 | EXTERN_C 396 | NTSYSCALLAPI 397 | NTSTATUS 398 | NTAPI 399 | ZwTraceControl ( 400 | _In_ ULONG FunctionCode, 401 | _In_reads_bytes_opt_(InBufferLen) PVOID InBuffer, 402 | _In_ ULONG InBufferLen, 403 | _Out_writes_bytes_opt_(OutBufferLen) PVOID OutBuffer, 404 | _In_ ULONG OutBufferLen, 405 | _Out_ PULONG ReturnLength 406 | ); 407 | 408 | EXTERN_C 409 | NTSYSCALLAPI 410 | NTSTATUS 411 | NTAPI 412 | ZwQuerySystemInformation ( 413 | _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, 414 | _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation, 415 | _In_ ULONG SystemInformationLength, 416 | _Out_opt_ PULONG ReturnLength 417 | ); 418 | 419 | EXTERN_C 420 | NTSYSAPI 421 | PIMAGE_NT_HEADERS 422 | NTAPI 423 | RtlImageNtHeader ( 424 | _In_ PVOID ModuleAddress 425 | ); 426 | -------------------------------------------------------------------------------- /src/libinfinityhook/stdafx.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * stdafx.cpp 4 | * 5 | * Abstract: 6 | * Precompiled header. 7 | * 8 | * Authors: 9 | * Nick Peterson | http://everdox.net/ 10 | * 11 | * Special thanks to Nemanja (Nemi) Mulasmajic 12 | * for his help with the POC. 13 | * 14 | */ 15 | 16 | #include "stdafx.h" -------------------------------------------------------------------------------- /src/libinfinityhook/stdafx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module Name: 3 | * stdafx.h 4 | * 5 | * Abstract: 6 | * Precompiled header. 7 | * 8 | * Authors: 9 | * Nick Peterson | http://everdox.net/ 10 | * 11 | * Special thanks to Nemanja (Nemi) Mulasmajic 12 | * for his help with the POC. 13 | * 14 | */ 15 | 16 | #pragma once 17 | 18 | /// 19 | /// Includes. 20 | /// 21 | 22 | #pragma warning(push, 0) 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "ntint.h" 30 | #pragma warning(pop) --------------------------------------------------------------------------------