├── .gitattributes ├── .gitignore ├── Documents ├── Hivelist.gif ├── SwishDbgExt.pdf ├── Windbg_Template.WEW └── windbg_template.reg ├── LICENSE ├── README.md ├── SwishDbgExt.sln └── SwishDbgExt ├── Azure.cpp ├── Azure.h ├── CNdiskd ├── CAdapters.cpp ├── CAdapters.h ├── CMinidriver.cpp ├── CMinidriver.h ├── CNdiskd.cpp ├── CNdiskd.h ├── COpenblock.cpp ├── COpenblock.h ├── CProtocols.cpp ├── CProtocols.h ├── CReport.cpp ├── CReport.h ├── utils.cpp └── utils.h ├── Checks ├── Codecave.cpp └── Codecave.h ├── Common.cpp ├── Common.h ├── Credentials.cpp ├── Credentials.h ├── DbgHelpEx.cpp ├── DbgHelpEx.h ├── Drivers.cpp ├── Drivers.h ├── EngExpCppEx.h ├── EngExtCppEx.cpp ├── Lxss.cpp ├── Lxss.h ├── Md5.cpp ├── Md5.h ├── Network.cpp ├── Network.h ├── NtDef.h ├── Objects.cpp ├── Objects.h ├── Output.cpp ├── Output.h ├── Process.cpp ├── Process.h ├── Registry.cpp ├── Registry.h ├── Security.cpp ├── Security.h ├── Storage.cpp ├── Storage.h ├── SwishDbgExt.cpp ├── SwishDbgExt.def ├── SwishDbgExt.h ├── SwishDbgExt.rc ├── SwishDbgExt.vcxproj ├── SwishDbgExt.vcxproj.filters ├── System.cpp ├── System.h ├── UntypedData.cpp ├── UntypedData.h ├── Version.rc ├── Version.txt ├── VirusTotal.cpp ├── VirusTotal.h ├── Yara.cpp ├── Yara.h ├── engextcpp.cpp ├── engextcpp.hpp ├── packages.config ├── resource.h ├── stdafx.cpp ├── stdafx.h └── targetver.h /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | BundleArtifacts/ 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | [Ss]tyle[Cc]op.* 182 | ~$* 183 | *~ 184 | *.dbmdl 185 | *.dbproj.schemaview 186 | *.pfx 187 | *.publishsettings 188 | node_modules/ 189 | orleans.codegen.cs 190 | 191 | # RIA/Silverlight projects 192 | Generated_Code/ 193 | 194 | # Backup & report files from converting an old project file 195 | # to a newer Visual Studio version. Backup files are not needed, 196 | # because we have git ;-) 197 | _UpgradeReport_Files/ 198 | Backup*/ 199 | UpgradeLog*.XML 200 | UpgradeLog*.htm 201 | 202 | # SQL Server files 203 | *.mdf 204 | *.ldf 205 | 206 | # Business Intelligence projects 207 | *.rdl.data 208 | *.bim.layout 209 | *.bim_*.settings 210 | 211 | # Microsoft Fakes 212 | FakesAssemblies/ 213 | 214 | # GhostDoc plugin setting file 215 | *.GhostDoc.xml 216 | 217 | # Node.js Tools for Visual Studio 218 | .ntvs_analysis.dat 219 | 220 | # Visual Studio 6 build log 221 | *.plg 222 | 223 | # Visual Studio 6 workspace options file 224 | *.opt 225 | 226 | # Visual Studio LightSwitch build output 227 | **/*.HTMLClient/GeneratedArtifacts 228 | **/*.DesktopClient/GeneratedArtifacts 229 | **/*.DesktopClient/ModelManifest.xml 230 | **/*.Server/GeneratedArtifacts 231 | **/*.Server/ModelManifest.xml 232 | _Pvt_Extensions 233 | 234 | # LightSwitch generated files 235 | GeneratedArtifacts/ 236 | ModelManifest.xml 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | 241 | # FAKE - F# Make 242 | .fake/ 243 | -------------------------------------------------------------------------------- /Documents/Hivelist.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MagnetForensics/SwishDbgExt/bd3b324967bfcd0994abf9f45708982b3ebc9516/Documents/Hivelist.gif -------------------------------------------------------------------------------- /Documents/SwishDbgExt.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MagnetForensics/SwishDbgExt/bd3b324967bfcd0994abf9f45708982b3ebc9516/Documents/SwishDbgExt.pdf -------------------------------------------------------------------------------- /Documents/Windbg_Template.WEW: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MagnetForensics/SwishDbgExt/bd3b324967bfcd0994abf9f45708982b3ebc9516/Documents/Windbg_Template.WEW -------------------------------------------------------------------------------- /Documents/windbg_template.reg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MagnetForensics/SwishDbgExt/bd3b324967bfcd0994abf9f45708982b3ebc9516/Documents/windbg_template.reg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #SwishDbgExt 2 | =========== 3 | 4 | SwishDbgExt is a Microsoft WinDbg debugging extension that expands the set of available commands by Microsoft WinDbg, but also fixes and improves existing commands. 5 | This extension has been developed by Matt Suiche (@msuiche) – feel free to reach out on support@comae.io ask for more features, offer to contribute and/or report bugs. 6 | 7 | SwishDbgExt aims at making life easier for kernel developers, troubleshooters and security experts with a series of debugging, incident response and memory forensics commands. 8 | Because SwishDbgExt is a WinDbg debugging extension, it means it can be used on local or remote kernel debugging session, live sessions generated by Microsoft LiveKd, but also on Microsoft crash dumps generated to a Blue Screen of Death or hybrid utilities such as Comae DumpIt. 9 | 10 | ## 2016 Contest 11 | More information on https://blog.comae.io/comae-2016-contest-swishdbgext-features-3c9a63c62209#.tnt1b9usx 12 | 13 | ## Installation 14 | You can either copy the WinDbg extension in the corresponding (x86 or x64) WinDbg folder or load it manually using the !load command such as below. Please note you can’t have spaces or quotes in the full path to the target dll to be loaded. 15 | `!load X:\FullPath\SwishDbgExt.dll` 16 | 17 | ###Example: 18 | ``` 19 | kd> !load E:\projects\labs\SwishDbgExt\bin\x64\SwishDbgExt.dll; 20 | SwishDbgExt v0.7.0 (Nov 2 2016) - Incident Response & Digital Forensics Debugging Extension 21 | SwishDbgExt Copyright (C) 2016 Comae Technologies FZE - http://www.comae.io 22 | SwishDbgExt Copyright (C) 2014-2016 Matthieu Suiche (@msuiche) 23 | 24 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 25 | This is free software, and you are welcome to redistribute it 26 | under certain conditions; type `show c' for details. 27 | ``` 28 | 29 | If you wish to update your WinDbg template with a more DML-friendly template, you can directly import windbg_template.reg file joined to the package. 30 | 31 | ## TODO 32 | - [ ] Define structures 33 | - [ ] Define Commands 34 | - [ ] Announce feature contest. 35 | 36 | ## Commands 37 | ### !SwishDbgExt.help 38 | Displays information on available extension commands. 39 | 40 | This command will give you the list of all commands if you specify no argument, will give you the list of parameters for an existing command if specified as an argument. 41 | 42 | ### !ms_callbacks 43 | Display callback functions 44 | 45 | ### !ms_checkcodecave 46 | Look for used code cave 47 | 48 | ### !ms_consoles 49 | Display console command's history 50 | 51 | ### !ms_credentials 52 | Display user's credentials (based on gentilwiki's mimikatz) 53 | ### !ms_drivers 54 | Display list of drivers. 55 | !ms_drivers will go ahead and display a list of drivers that are currently loaded. 56 | In this example, here’s a few of the drivers loaded at the time of the crash in this kernel-dump: 57 | With this command, we can also view in-depth IRP information regarding a driver: 58 | In the above image we can see the driver-specific I/O stack location within e1cexpress.sys’ IRP. Here we can see function codes such as IRP_MJ_CREATE which opens the target device object, indicating that it is present and available for I/O operations. 59 | 60 | ### !ms_dump 61 | Dump memory space on disk 62 | 63 | ### !ms_exqueue 64 | Display Ex queued workers. 65 | 66 | `!exqueue` doesn’t work properly on Windows 8, so a working version needed to be implemented. Just like the original command this one dispaly the working threads queue. 67 | 68 | ### !ms_fixit 69 | Reset segmentation in WinDbg (Fix "16.kd>") 70 | 71 | ### !ms_gdt 72 | Display GDT. 73 | 74 | !ms_gdt displays the Global Descriptor Table. Note on x64 that every selector is flat (0x0000000000000000 to 0xFFFFFFFFFFFFFFFF). This command can be extra helpful to check for any suspected hooking of the GDT, as attempting to do so on x64 will call a bug check. This is because x64 forbids hooking of the GDT. 75 | 76 | ### !ms_hivelist 77 | Display list of registry hives. 78 | 79 | `ms_hivelist` displays a list of registry hives. 80 | We can look directly into a hive (\Registry\Machine\Software for example) to see its subkeys, values, etc: 81 | 82 | ![Alt text](Documents/Hivelist.gif?raw=true "Hive List") 83 | 84 | ### !ms_idt 85 | Display IDT. 86 | 87 | `!ms_idt` displays the Interrupt descriptor table. Very much like the GDT, if the IDT is hooked on an x64 system, it will call a bug check. This is due to the fact that Microsoft implemented (programmatically) a prevention of hooking the IDT with a kernel-mode driver that would normally intercept calls to the IDT and then add in its own processing. This is why in the above image, there is ‘No’ as far as the eye can see. 88 | 89 | ### !ms_malscore 90 | Analyze a memory space and returns a Malware Score Index (MSI) - (based on Frank Boldewin's work) 91 | 92 | ### !ms_mbr 93 | Scan Master Boot Record (MBR) 94 | 95 | ### !ms_netstat 96 | Display network information (sockets, connections, ...) 97 | 98 | ### !ms_object 99 | Display list of object 100 | 101 | ### !ms_process 102 | Display list of processes. 103 | `!ms_process` is an improved version of `!process` and `!dml_proc`.. 104 | One of the nice thing as you can notice below is the usage of DML (Debugger Markup Language) with the commands. All the underline commands are in fact links to commands. 105 | As an example below, you can see the output of /vads /scan, to scan VAD (Virtual Address Descriptors). You can notice that one column gives the “Malware Score Index” which can be useful to detect shellcodes or heap-spray. 106 | In the screenshot below, you can see an abnormally high score in several VADs – due to usage of heap spray. Just by clicking on the score it will run the scanning algorithm. 107 | The scanning algorithm is based on Frank Boldewin’s OfficeMalScanner utility. 108 | And returns you information about where the shellcode is: 109 | `/scan` option can also be used on exported functions to know if the EAT (Export Address Table) has been patched or if the prolog of the function modified. 110 | 111 | Similar tests are available for the SSDT (`!ms_ssdt`). 112 | 113 | ### !ms_readkcb 114 | Read key control block 115 | 116 | ### !ms_readknode 117 | Read key node. 118 | `!reg` WinDbg command has been a frustration for a long time, due to some bugs. This is why SwishDbgExt, has its own registry explorer functions to try to make access to registry data as simple as possible. 119 | 120 | ### !ms_readkvalue 121 | Read key value 122 | 123 | ### !ms_scanndishook 124 | Scan and display suspicious NDIS hooks 125 | 126 | ### !ms_services 127 | Display list of services 128 | 129 | ### !ms_ssdt 130 | Display service descriptor table (SDT) functions. 131 | `!ms_ssdt` displays the System Service Dispatch Table. This command is extremely helpful in the investigation of suspected rootkit hooks through what is known as Direct Kernel Object Manipulation (DKOM). If you see a low level routine here that is hooked (such as nt!NtEnumerateKey), this can aid you in your analysis regarding a possible rootkit infection. 132 | 133 | ### !ms_store 134 | Display information related to the Store Manager (ReadyBoost). 135 | 136 | The present command allows to list the current ReadyBoost (requires USB 3.0) cache used by the Operating System, but also to display the logs of the memory pages managed by the store manager. 137 | Parameter: /cache 138 | 139 | ### !ms_timers 140 | Display list of KTIMER. 141 | 142 | !ms_timers displays the KTIMER structure, which is an opaque structure that represents and contains various timer objects. This command can be helpful to figure out what drivers created what timer objects, what drivers called what routines, etc. 143 | 144 | ### !ms_vacbs 145 | Display list of cached VACBs 146 | 147 | ### !ms_verbose 148 | Turn verbose mode on/off 149 | 150 | ### !ms_lxss 151 | The following is based on the research published by Alex Ionescu and available here: https://github.com/ionescu007/lxss/ 152 | 153 | This feature is available on Windows 10+ O.S. as an optional feature installable via the following PowerShell command: 154 | ``` 155 | Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux 156 | ``` 157 | 158 | You can read more about the Windows Subsystem for Linux at the following links: 159 | - https://blogs.msdn.microsoft.com/wsl/2016/04/22/windows-subsystem-for-linux-overview/ 160 | - https://channel9.msdn.com/Blogs/Seth-Juarez/Windows-Subsystem-for-Linux-Architectural-Overview 161 | - https://msdn.microsoft.com/en-us/commandline/wsl/install_guide 162 | 163 | ``` 164 | Windows Subsystem for Linux Overview. 165 | Instance 0xFFFFE704EEB8F010 166 | GUID: {E29032FD-35D3-4C53-AB68-6BCEBDA7176F} 167 | State: (1) [STARTED] 168 | Creation Flags: 00000001 169 | GlobalData: 0xFFFFF802ED4138A0 170 | Root Handle: 80000834 171 | Temp Handle: 80000838 172 | Job Handle: 8000083c 173 | Token: 80000818 174 | Event Handle: 800008bc 175 | 176 | Map Paths (0): 0xFFFFE704EF437920 177 | VFS Context: 0xFFFFE704EEFC4710 178 | Memory Flags: 0x2 179 | 180 | Last PID: 35 181 | Thread Groups: 3 182 | Session 0xFFFFE704EDB79EC0 183 | Instance: 0xFFFFE704EEB8F010 184 | Console inode: 0x0 185 | Foreground PID: -1 186 | Process Group 0xFFFFE704EDB79AE0 187 | Instance: 0xFFFFE704EEB8F010 188 | Session: 0xFFFFE704EDB79EC0 189 | Thread Group 0xFFFFE704EF4F8000 190 | Binary Path: /init 191 | Thread(s): 1 192 | Owner Process Group: 0xFFFFE704EDB79AE0 193 | Flags: 0x00000000 194 | Main Thread: 0xFFFFE704EF5CC010 195 | Arguments (006 bytes): 0x00007FFFC081D6E0 196 | Process 0xFFFFE704EF2F1D70 197 | Instance: 0xFFFFE704EEB8F010 198 | NT Process Object: 0xFFFFAE05E84EF800 199 | NT Process Handle: 0xFFFFFFFF80000F58 200 | VDSO Address: 0x00007FFFC0849000 201 | Stack Address: 0x00007FFFC001E000 202 | Session 0xFFFFE704EF5DB830 203 | Instance: 0xFFFFE704EEB8F010 204 | Console inode: 0xFFFFE704EF32D7A0 205 | Foreground PID: 2 206 | Process Group 0xFFFFE704EF5EF970 207 | Instance: 0xFFFFE704EEB8F010 208 | Session: 0xFFFFE704EF5DB830 209 | Thread Group 0xFFFFE704EF5EE000 210 | Binary Path: /bin/bash 211 | Thread(s): 1 212 | Owner Process Group: 0xFFFFE704EF5EF970 213 | Flags: 0x0000000C 214 | Main Thread: 0xFFFFE704EF5F8010 215 | Arguments (010 bytes): 0x00007FFFDF34E418 216 | Process 0xFFFFE704EDEF6EC0 217 | Instance: 0xFFFFE704EEB8F010 218 | NT Process Object: 0xFFFFAE05E84E6800 219 | NT Process Handle: 0xFFFFFFFF80000D9C 220 | VDSO Address: 0x00007FFFDF883000 221 | Stack Address: 0x00007FFFDEB4F000 222 | Session 0xFFFFE704EF0A8ED0 223 | Instance: 0xFFFFE704EEB8F010 224 | Console inode: 0xFFFFE704EF06B9C0 225 | Foreground PID: 19 226 | Process Group 0xFFFFE704F059CBC0 227 | Instance: 0xFFFFE704EEB8F010 228 | Session: 0xFFFFE704EF0A8ED0 229 | Thread Group 0xFFFFE704EDE51000 230 | Binary Path: /bin/bash 231 | Thread(s): 1 232 | Owner Process Group: 0xFFFFE704F059CBC0 233 | Flags: 0x0000000C 234 | Main Thread: 0xFFFFE704EDC78090 235 | Arguments (010 bytes): 0x00007FFFF78CFB78 236 | Process 0xFFFFE704F06389B0 237 | Instance: 0xFFFFE704EEB8F010 238 | NT Process Object: 0xFFFFAE05E618D800 239 | NT Process Handle: 0xFFFFFFFF80001650 240 | VDSO Address: 0x00007FFFF7C99000 241 | Stack Address: 0x00007FFFF70D0000 242 | ``` 243 | 244 | ### !ms_yarascan 245 | 246 | Scan a process memory with yara rules. 247 | 248 | Scan a process memory. 249 | ``` 250 | !ms_yarascan /pid 0x228 /yarafile /yarafile C:\Rules.yar 251 | ``` 252 | 253 | Scan all processes memory. 254 | ``` 255 | !for_each_process "r? @$t0 = (nt!_EPROCESS *) @#Process; .process /r /p @$t0; !ms_yarascan /pid @@C++(@$t0->UniqueProcessId) /yarafile C:\\Rules.yar" 256 | ``` 257 | 258 | ## Classes 259 | ### PEFile 260 | `MsPEImageFile` contains the basic common information used by Windows binaries (PE) and has been derivated into three different classes: 261 | 262 | - MsProcessObject 263 | - MsDllObject 264 | - MsDriverObject 265 | -------------------------------------------------------------------------------- /SwishDbgExt.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SwishDbgExt", "SwishDbgExt\SwishDbgExt.vcxproj", "{3DEADBA0-BE78-43B7-A17A-027F185957E6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3DEADBA0-BE78-43B7-A17A-027F185957E6}.Debug|x64.ActiveCfg = Debug|x64 17 | {3DEADBA0-BE78-43B7-A17A-027F185957E6}.Debug|x64.Build.0 = Debug|x64 18 | {3DEADBA0-BE78-43B7-A17A-027F185957E6}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3DEADBA0-BE78-43B7-A17A-027F185957E6}.Debug|x86.Build.0 = Debug|Win32 20 | {3DEADBA0-BE78-43B7-A17A-027F185957E6}.Debug|x86.Deploy.0 = Debug|Win32 21 | {3DEADBA0-BE78-43B7-A17A-027F185957E6}.Release|x64.ActiveCfg = Release|x64 22 | {3DEADBA0-BE78-43B7-A17A-027F185957E6}.Release|x64.Build.0 = Release|x64 23 | {3DEADBA0-BE78-43B7-A17A-027F185957E6}.Release|x86.ActiveCfg = Release|Win32 24 | {3DEADBA0-BE78-43B7-A17A-027F185957E6}.Release|x86.Build.0 = Release|Win32 25 | {3DEADBA0-BE78-43B7-A17A-027F185957E6}.Release|x86.Deploy.0 = Release|Win32 26 | EndGlobalSection 27 | GlobalSection(SolutionProperties) = preSolution 28 | HideSolutionNode = FALSE 29 | EndGlobalSection 30 | EndGlobal 31 | -------------------------------------------------------------------------------- /SwishDbgExt/Azure.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Azure.cpp 23 | 24 | Abstract: 25 | 26 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | // 39 | // HYPERV functions from MoonSols LiveCloudKd 40 | // 41 | 42 | #include "stdafx.h" -------------------------------------------------------------------------------- /SwishDbgExt/Azure.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Azure.h 23 | 24 | Abstract: 25 | 26 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 27 | 28 | 29 | Environment: 30 | 31 | - User mode 32 | 33 | Revision History: 34 | 35 | - Matthieu Suiche 36 | 37 | --*/ -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/CAdapters.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #include "stdafx.h" 21 | #include "CNdiskd.h" 22 | 23 | // CAdapters constructor 24 | CAdapters::CAdapters() 25 | { 26 | // Initialize handler function address 27 | m_ptrPacketIndicateHandler = 0; 28 | m_ptrSendCompleteHandler = 0; 29 | m_ptrResetCompleteHandler = 0; 30 | m_ptrStatusHandler = 0; 31 | m_ptrStatusCompleteHandler = 0; 32 | m_ptrWanSendCompleteHandler = 0; 33 | m_ptrWanRcvHandler = 0; 34 | m_ptrWanRcvCompleteHandler = 0; 35 | m_ptrSendNetBufferListsCompleteHandler = 0; 36 | // Initialize NDIS start and end address 37 | m_ndisStartAddr = 0; 38 | m_ndisEndAddr = 0; 39 | // Initialize minidriver start and end address 40 | m_minidrvStartAddr = 0; 41 | m_minidrvEndAddr = 0; 42 | // Initialize heap to store protocol's information 43 | m_adaptername = (PWSTR)malloc(MAX_ADAPTER_NAME*sizeof(WCHAR)); 44 | 45 | } 46 | 47 | // CAdapters destructor 48 | CAdapters::~CAdapters() 49 | { 50 | // Cleanup 51 | free(m_adaptername); 52 | 53 | } 54 | 55 | VOID WINAPI CAdapters::SetAdapterName(PWSTR AdatperName) 56 | { 57 | StringCchCopyW(m_adaptername, MAX_ADAPTER_NAME, AdatperName); 58 | } 59 | 60 | PWSTR WINAPI CAdapters::GetAdapterName() 61 | { 62 | return m_adaptername; 63 | } 64 | 65 | BOOL WINAPI CAdapters::IsNdisFuncHandlerHooked(ULONG64 PtrHandler) 66 | { 67 | BOOL boolIsHooked = (PtrHandler < m_ndisStartAddr) && (PtrHandler > m_ndisEndAddr); 68 | 69 | if (boolIsHooked) 70 | return true; 71 | else 72 | return false; 73 | } 74 | 75 | std::map* WINAPI CAdapters::GetFunctionHandlers(std::map *PtrHandlers) 76 | { 77 | PtrHandlers->insert(std::make_pair("PacketIndicateHandler", m_ptrPacketIndicateHandler)); 78 | PtrHandlers->insert(std::make_pair("ResetCompleteHandler", m_ptrResetCompleteHandler)); 79 | PtrHandlers->insert(std::make_pair("WanRcvHandler", m_ptrWanRcvHandler)); 80 | PtrHandlers->insert(std::make_pair("WanRcvCompleteHandler", m_ptrWanRcvCompleteHandler)); 81 | PtrHandlers->insert(std::make_pair("WanSendCompleteHandler", m_ptrWanSendCompleteHandler)); 82 | PtrHandlers->insert(std::make_pair("SendCompleteHandler", m_ptrSendCompleteHandler)); 83 | PtrHandlers->insert(std::make_pair("SendNetBufferListsCompleteHandler", m_ptrSendNetBufferListsCompleteHandler)); 84 | PtrHandlers->insert(std::make_pair("StatusCompleteHandler", m_ptrStatusCompleteHandler)); 85 | PtrHandlers->insert(std::make_pair("StatusHandler", m_ptrStatusHandler)); 86 | 87 | return PtrHandlers; 88 | } -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/CAdapters.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | #ifndef _CADAPTERS_H_ 20 | #define _CADAPTERS_H_ 21 | 22 | #define MAX_ADAPTER_NAME 500 23 | 24 | class CAdapters 25 | { 26 | public: 27 | CAdapters(); 28 | ~CAdapters(); 29 | BOOL WINAPI IsNdisFuncHandlerHooked(ULONG64); 30 | VOID WINAPI SetAdapterName(PWSTR); 31 | PWSTR WINAPI GetAdapterName(); 32 | std::map* WINAPI GetFunctionHandlers(std::map*); 33 | ULONG64 m_ndisStartAddr; 34 | ULONG64 m_ndisEndAddr; 35 | ULONG64 m_minidrvStartAddr; 36 | ULONG64 m_minidrvEndAddr; 37 | // Only partial handler functions that are known to be targeted on NDIS library 38 | ULONG64 m_ptrPacketIndicateHandler; 39 | ULONG64 m_ptrSendCompleteHandler; 40 | ULONG64 m_ptrResetCompleteHandler; 41 | ULONG64 m_ptrStatusHandler; 42 | ULONG64 m_ptrStatusCompleteHandler; 43 | ULONG64 m_ptrWanSendCompleteHandler; 44 | ULONG64 m_ptrWanRcvHandler; 45 | ULONG64 m_ptrWanRcvCompleteHandler; 46 | ULONG64 m_ptrSendNetBufferListsCompleteHandler; 47 | private: 48 | PWSTR m_adaptername; 49 | }; 50 | 51 | #endif // _CADAPTERS_H_ -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/CMinidriver.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #include "stdafx.h" 21 | #include "CNdiskd.h" 22 | 23 | // CMinidriver constructor 24 | CMinidriver::CMinidriver(ULONG64 MinidriverAddr) 25 | { 26 | // Initialize minidriver ptr 27 | m_minidrvaddr = MinidriverAddr; 28 | 29 | // Initialize handler function address 30 | m_ptrCheckForHangHandler = 0; 31 | m_ptrDisableInterruptHandler = 0; 32 | m_ptrEnableInterruptHandler = 0; 33 | m_ptrHaltHandler = 0; 34 | m_ptrHandleInterruptHandler = 0; 35 | m_ptrInitializeHandler = 0; 36 | m_ptrIsrHandler = 0; 37 | m_ptrQueryInformationHandler = 0; 38 | m_ptrReconfigureHandler = 0; 39 | m_ptrResetHandler = 0; 40 | m_ptrSendHandler = 0; 41 | m_ptrWanSendHandler = 0; 42 | m_ptrSetInformationHandler = 0; 43 | m_ptrTransferDataHandler = 0; 44 | m_ptrWanTransferDataHandler = 0; 45 | m_ptrReturnPacketHandler = 0; 46 | m_ptrSendPacketsHandler = 0; 47 | m_ptrAllocateCompleteHandler = 0; 48 | m_ptrCancelSendPacketsHandler = 0; 49 | m_ptrPnpEventNotifyHandler = 0; 50 | m_ptrAdapterShutdownHandler = 0; 51 | 52 | // Initialize mini-driver start and end address 53 | m_drvstartaddr = 0; 54 | m_drvendaddr = 0; 55 | 56 | // Initialize heap to store minidriver's name 57 | m_drivername = (PWSTR)malloc(MAX_MINIDRV_NAME*sizeof(WCHAR)); 58 | 59 | } 60 | 61 | // CMinidriver destructor 62 | CMinidriver::~CMinidriver() 63 | { 64 | free(m_drivername); 65 | } 66 | 67 | PWSTR WINAPI CMinidriver::GetMDriverName() 68 | { 69 | ExtRemoteTyped miniDrv("(ndis!_NDIS_M_DRIVER_BLOCK*)@$extin", m_minidrvaddr); 70 | 71 | // NDIS6.X 72 | if (utils::IsVistaOrAbove()) 73 | { 74 | WCHAR wDriverName[MAX_MINIDRV_NAME*sizeof(WCHAR)] = { 0 }; 75 | ExtRemoteTyped minidrvName("(nt!_UNICODE_STRING*)@$extin", miniDrv.Field("ServiceName").m_Offset); 76 | utils::getUnicodeString(minidrvName, wDriverName, MAX_MINIDRV_NAME*sizeof(WCHAR)); 77 | 78 | // ServiceName field might be empty 79 | // Get minidriver name from DriverObject->DriverName 80 | if (wcslen(wDriverName) == 0) 81 | { 82 | 83 | ULONG64 ptrMiniDrvObject = miniDrv.Field("DriverObject").GetPtr(); 84 | ExtRemoteTyped miniDrvObject("(nt!_DRIVER_OBJECT*)@$extin", ptrMiniDrvObject); 85 | 86 | // Get minidriver name (eg: "\Driver\NdisWan") 87 | ExtRemoteTyped minidrvName2("(nt!_UNICODE_STRING*)@$extin", miniDrvObject.Field("DriverName").m_Offset); 88 | utils::getUnicodeString(minidrvName2, wDriverName, MAX_MINIDRV_NAME*sizeof(WCHAR)); 89 | } 90 | 91 | // Get minidriver name 92 | PWSTR drvName = wcsrchr(wDriverName, L'\\'); 93 | 94 | if (drvName != NULL) 95 | { 96 | StringCchCopyW(m_drivername, MAX_MINIDRV_NAME, drvName + 1); 97 | } 98 | else 99 | { 100 | StringCchCopyW(m_drivername, MAX_MINIDRV_NAME, wDriverName); 101 | } 102 | } 103 | // NDIS5.X 104 | else 105 | { 106 | ExtRemoteTyped minidrvInfo("(ndis!_NDIS_WRAPPER_HANDLE*)@$extin", miniDrv.Field("NdisDriverInfo").GetPtr()); 107 | ExtRemoteTyped minidrvName("(nt!_UNICODE_STRING*)@$extin", minidrvInfo.Field("ServiceRegPath").m_Offset); 108 | 109 | // Get service registry path 110 | WCHAR wRegPath[MAX_MINIDRV_NAME*sizeof(WCHAR)] = { 0 }; 111 | utils::getUnicodeString(minidrvName, wRegPath, MAX_MINIDRV_NAME*sizeof(WCHAR)); 112 | 113 | // Get minidriver name 114 | PWSTR drvName = wcsrchr(wRegPath, L'\\'); 115 | 116 | if (drvName != NULL) 117 | { 118 | StringCchCopyW(m_drivername, MAX_MINIDRV_NAME, drvName + 1); 119 | } 120 | else 121 | { 122 | StringCchCopyW(m_drivername, MAX_MINIDRV_NAME, wRegPath); 123 | } 124 | 125 | } 126 | 127 | return m_drivername; 128 | } 129 | 130 | BOOL WINAPI CMinidriver::IsHandlerHooked(ULONG64 PtrHandler) 131 | { 132 | BOOL boolIsHooked = (PtrHandler < m_drvstartaddr) && (m_drvendaddr > PtrHandler); 133 | 134 | if (boolIsHooked) 135 | return true; 136 | else 137 | return false; 138 | } 139 | 140 | ULONG64 WINAPI CMinidriver::GetDriverStartAddr() 141 | { 142 | ExtRemoteTyped miniDrv("(ndis!_NDIS_M_DRIVER_BLOCK*)@$extin", m_minidrvaddr); 143 | BOOLEAN Is64Bit = (g_Ext->m_Control->IsPointer64Bit() == S_OK) ? TRUE : FALSE; 144 | ExtRemoteTyped drvObj; 145 | 146 | // NDIS6.X 147 | if (utils::IsVistaOrAbove()) 148 | { 149 | drvObj = ExtRemoteTyped("(nt!_DRIVER_OBJECT*)@$extin", miniDrv.Field("DriverObject").GetPtr()); 150 | } 151 | // NDIS5.X 152 | else 153 | { 154 | ExtRemoteTyped minidrvInfo("(ndis!_NDIS_WRAPPER_HANDLE*)@$extin", miniDrv.Field("NdisDriverInfo").GetPtr()); 155 | drvObj = ExtRemoteTyped("(nt!_DRIVER_OBJECT*)@$extin", minidrvInfo.Field("DriverObject").GetPtr()); 156 | } 157 | 158 | m_drvstartaddr = Is64Bit ? drvObj.Field("DriverStart").GetUlong64() : drvObj.Field("DriverStart").GetUlong(); 159 | return m_drvstartaddr; 160 | } 161 | 162 | ULONG64 WINAPI CMinidriver::GetDriverEndAddr() 163 | { 164 | return (m_drvendaddr = utils::getModuleSize(m_drvstartaddr) + m_drvstartaddr); 165 | } 166 | 167 | std::map* WINAPI CMinidriver::GetFunctionHandlers(std::map *PtrHandlers) 168 | { 169 | PtrHandlers->insert(std::make_pair("CheckForHangHandler", m_ptrCheckForHangHandler)); 170 | PtrHandlers->insert(std::make_pair("DisableInterruptHandler", m_ptrDisableInterruptHandler)); 171 | PtrHandlers->insert(std::make_pair("EnableInterruptHandler", m_ptrEnableInterruptHandler)); 172 | PtrHandlers->insert(std::make_pair("HaltHandler", m_ptrHaltHandler)); 173 | PtrHandlers->insert(std::make_pair("HandleInterruptHandler", m_ptrHandleInterruptHandler)); 174 | PtrHandlers->insert(std::make_pair("InitializeHandler", m_ptrInitializeHandler)); 175 | PtrHandlers->insert(std::make_pair("ISRHandler", m_ptrIsrHandler)); 176 | PtrHandlers->insert(std::make_pair("QueryInformationHandler", m_ptrQueryInformationHandler)); 177 | PtrHandlers->insert(std::make_pair("ReconfigureHandler", m_ptrReconfigureHandler)); 178 | PtrHandlers->insert(std::make_pair("ResetHandler", m_ptrResetHandler)); 179 | PtrHandlers->insert(std::make_pair("SendHandler", m_ptrSendHandler)); 180 | PtrHandlers->insert(std::make_pair("WanSendHandler", m_ptrWanSendHandler)); 181 | PtrHandlers->insert(std::make_pair("SetInformationHandler", m_ptrSetInformationHandler)); 182 | PtrHandlers->insert(std::make_pair("TransferDataHandler", m_ptrTransferDataHandler)); 183 | PtrHandlers->insert(std::make_pair("WanTransferDataHandler", m_ptrWanTransferDataHandler)); 184 | PtrHandlers->insert(std::make_pair("ReturnPacketHandler", m_ptrReturnPacketHandler)); 185 | PtrHandlers->insert(std::make_pair("SendPacketsHandler", m_ptrSendPacketsHandler)); 186 | PtrHandlers->insert(std::make_pair("AllocateCompleteHandler", m_ptrAllocateCompleteHandler)); 187 | PtrHandlers->insert(std::make_pair("CancelSendPacketsHandler", m_ptrCancelSendPacketsHandler)); 188 | PtrHandlers->insert(std::make_pair("PnpEventNotifyHandler", m_ptrPnpEventNotifyHandler)); 189 | PtrHandlers->insert(std::make_pair("AdapterShutdownHandler", m_ptrAdapterShutdownHandler)); 190 | 191 | return PtrHandlers; 192 | } -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/CMinidriver.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #ifndef _CMINIDRIVER_H_ 21 | #define _CMINIDRIVER_H_ 22 | 23 | #define MAX_MINIDRV_NAME 100 24 | 25 | class CMinidriver 26 | { 27 | public: 28 | CMinidriver(ULONG64); 29 | ~CMinidriver(); 30 | BOOL WINAPI IsHandlerHooked(ULONG64); 31 | PWSTR WINAPI GetMDriverName(); 32 | ULONG64 WINAPI GetDriverStartAddr(); 33 | ULONG64 WINAPI GetDriverEndAddr(); 34 | std::map* WINAPI GetFunctionHandlers(std::map*); 35 | ULONG64 m_minidrvaddr; 36 | 37 | // Only partial handler functions that are known to be targeted on Minidriver 38 | ULONG64 m_ptrCheckForHangHandler; 39 | ULONG64 m_ptrDisableInterruptHandler; 40 | ULONG64 m_ptrEnableInterruptHandler; 41 | ULONG64 m_ptrHaltHandler; 42 | ULONG64 m_ptrHandleInterruptHandler; 43 | ULONG64 m_ptrInitializeHandler; 44 | ULONG64 m_ptrIsrHandler; 45 | ULONG64 m_ptrQueryInformationHandler; 46 | ULONG64 m_ptrReconfigureHandler; 47 | ULONG64 m_ptrResetHandler; 48 | ULONG64 m_ptrSendHandler; 49 | ULONG64 m_ptrWanSendHandler; 50 | ULONG64 m_ptrSetInformationHandler; 51 | ULONG64 m_ptrTransferDataHandler; 52 | ULONG64 m_ptrWanTransferDataHandler; 53 | ULONG64 m_ptrReturnPacketHandler; 54 | ULONG64 m_ptrSendPacketsHandler; 55 | ULONG64 m_ptrAllocateCompleteHandler; 56 | ULONG64 m_ptrCancelSendPacketsHandler; 57 | ULONG64 m_ptrPnpEventNotifyHandler; 58 | ULONG64 m_ptrAdapterShutdownHandler; 59 | private: 60 | PWSTR m_drivername; 61 | ULONG64 m_drvstartaddr; 62 | ULONG64 m_drvendaddr; 63 | }; 64 | 65 | #endif // _CMINIDRIVER_H_ -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/CNdiskd.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #ifndef _CNDISKD_H_ 21 | #define _CNDISKD_H_ 22 | 23 | #ifdef _DEBUG 24 | #define DBG 1 25 | #else 26 | #define DBG 0 27 | #endif 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #define KDEXT_64BIT 39 | #include "CProtocols.h" 40 | #include "CAdapters.h" 41 | #include "COpenblock.h" 42 | #include "CMinidriver.h" 43 | #include "CReport.h" 44 | #include "utils.h" 45 | 46 | #define SIGN_EXTEND(_x_) (ULONG64)(LONG)(_x_) 47 | #define NDIS_NAME "ndis" 48 | #define NDIS_DRV_NAME "ndis.sys" 49 | 50 | class CNdiskd 51 | { 52 | public: 53 | CNdiskd(); 54 | ~CNdiskd(); 55 | BOOL WINAPI IsNdisHook(ULONG64); 56 | BOOL WINAPI HeuristicHookCheck(ULONG64, int&); 57 | CHAR* WINAPI GetHookType(int); 58 | ULONG64 m_ndisBaseAddress; 59 | ULONG64 m_ndisEndAddress; 60 | ULONG m_ndiskdChecked; 61 | PWSTR m_ndiskdBuildDate; 62 | PWSTR m_ndiskdBuildTime; 63 | PWSTR m_ndiskdBuiltBy; 64 | std::list* WINAPI GetProtocolList(std::list *protocolList); 65 | std::list* WINAPI GetAdapterList(std::list *adapterList); 66 | std::list* WINAPI GetOpenblockList(std::list *openblockList); 67 | std::list* WINAPI GetMDriverList(std::list *mDrvList); 68 | private: 69 | BOOL WINAPI IsWhitelistedNdisModule(CHAR*); 70 | }; 71 | 72 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/COpenblock.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #include "stdafx.h" 21 | #include "CNdiskd.h" 22 | 23 | 24 | // COpenblock constructor 25 | COpenblock::COpenblock(ULONG64 OpenBlockAddr) 26 | { 27 | // Initialize binder address 28 | m_binderAddress = OpenBlockAddr; 29 | 30 | // Initialize NDIS module start and end address 31 | m_ndisStartAddr = 0; 32 | m_ndisEndAddr = 0; 33 | 34 | // Initialize the bounding protocol module start and end address 35 | m_bindProtocolHandlerStartAddr = 0; 36 | m_bindProtocolHandlerEndAddr = 0; 37 | 38 | // Initialize the bounding adapter module start and end address 39 | m_bindAdapterHandlerStartAddr = 0; 40 | m_bindAdapterHandlerEndAddr = 0; 41 | 42 | // Initialize handler function address 43 | m_ptrSendHandler = 0; 44 | m_ptrSendCompleteHandler = 0; 45 | m_ptrSendPacketsHandler = 0; 46 | m_ptrReceiveHandler = 0; 47 | m_ptrReceiveCompleteHandler = 0; 48 | m_ptrResetCompleteHandler = 0; 49 | m_ptrStatusHandler = 0; 50 | m_ptrStatusCompleteHandler = 0; 51 | m_ptrWanReceiveHandler = 0; 52 | m_ptrRequestCompleteHandler = 0; 53 | m_ptrReceivePacketHandler = 0; 54 | m_ptrWanSendHandler = 0; 55 | m_ptrReceiveNetBufferLists = 0; 56 | 57 | // Initialize heap to store protocol's information 58 | m_bindingname = (PWSTR)malloc(MAX_BINDING_NAME*sizeof(WCHAR)); 59 | m_protocolname = (PWSTR)malloc(MAX_PROTOCOL_NAME*sizeof(WCHAR)); 60 | m_adaptername = (PWSTR)malloc(MAX_ADAPTER_NAME*sizeof(WCHAR)); 61 | } 62 | 63 | // COpenblock destructor 64 | COpenblock::~COpenblock() 65 | { 66 | // Cleanup 67 | free(m_bindingname); 68 | free(m_protocolname); 69 | free(m_adaptername); 70 | 71 | } 72 | 73 | BOOL WINAPI COpenblock::IsHandlerHooked(ULONG64 PtrHandler) 74 | { 75 | // If the binder's handler not belong to/within: 76 | // - Miniport (eg: NDIS) address range 77 | // - Protocol (eg: NDISWAN or PSCHED [XP]) address range 78 | /* 79 | **** NDIS6.X **** 80 | kd> !ndiskd.mopen 81 | 82 | Open fffffa800271d8d0 83 | Miniport: fffffa800210a1a0 - Intel(R) PRO/1000 MT Network Connection 84 | Protocol: fffffa800198d3b0 - TCPIP 85 | 86 | kd> dt _ndis_open_block SendHandler WanSendHandler ReceiveHandler ReceivePacketHandler fffffa800271d8d0 87 | ndis!_NDIS_OPEN_BLOCK 88 | +0x060 SendHandler : 0xfffff880`01589cd0 int ndis!ndisMSend+0 89 | +0x060 WanSendHandler : 0xfffff880`01589cd0 int ndis!ndisMSend+0 90 | +0x080 ReceiveHandler : (null) 91 | +0x0a0 ReceivePacketHandler : (null) 92 | 93 | **** NDIS5.X **** 94 | kd> !ndiskd.mopen 95 | 96 | Open 81a681c0 97 | Miniport: 8185c378 - VMware Accelerated AMD PCNet Adapter 98 | Protocol: 81a0a220 - PSCHED 99 | 100 | Open 81a80160 101 | Miniport: 81a07130 - WAN Miniport (L2TP) 102 | Protocol: 81a60008 - NDISWAN 103 | 104 | kd> dt _ndis_open_block SendHandler WanSendHandler ReceiveHandler ReceivePacketHandler 81a681c0 105 | NDIS!_NDIS_OPEN_BLOCK 106 | +0x030 SendHandler : 0xf96f687b int NDIS!ndisMSendX+0 107 | +0x030 WanSendHandler : 0xf96f687b int NDIS!ndisMSendX+0 108 | +0x040 ReceiveHandler : 0xf95dc3bc int psched!ClReceiveIndication+0 109 | +0x050 ReceivePacketHandler : 0xf95dc1c8 int psched!ClReceivePacket+0 110 | kd> dt _ndis_open_block SendHandler WanSendHandler ReceiveHandler ReceivePacketHandler 81a80160 111 | NDIS!_NDIS_OPEN_BLOCK 112 | +0x030 SendHandler : 0xf96f687b int NDIS!ndisMSendX+0 113 | +0x030 WanSendHandler : 0xf96f687b int NDIS!ndisMSendX+0 114 | +0x040 ReceiveHandler : 0xf95f0d4b int ndiswan!ProtoWanReceiveIndication+0 115 | +0x050 ReceivePacketHandler : (null) 116 | 117 | */ 118 | BOOL boolIsValid = ((PtrHandler >= m_ndisStartAddr) && (PtrHandler <= m_ndisEndAddr)) || \ 119 | ((PtrHandler >= m_bindProtocolHandlerStartAddr) && (PtrHandler <= m_bindProtocolHandlerEndAddr)) || \ 120 | ((PtrHandler >= m_bindAdapterHandlerStartAddr) && (PtrHandler <= m_bindAdapterHandlerEndAddr)); 121 | 122 | if (!boolIsValid) 123 | return true; 124 | else 125 | return false; 126 | } 127 | 128 | ULONG64 WINAPI COpenblock::GetMiniDriverStartAddr() 129 | { 130 | ExtRemoteTyped openBlock("(ndis!_NDIS_OPEN_BLOCK*)@$extin", m_binderAddress); 131 | BOOLEAN Is64Bit = (g_Ext->m_Control->IsPointer64Bit() == S_OK) ? TRUE : FALSE; 132 | ExtRemoteTyped miniportBlock, devObj, drvObj; 133 | 134 | miniportBlock = ExtRemoteTyped("(ndis!_NDIS_MINIPORT_BLOCK*)@$extin", openBlock.Field("MiniportHandle").GetPtr()); 135 | devObj = ExtRemoteTyped("(nt!_DEVICE_OBJECT*)@$extin", miniportBlock.Field("DeviceObject").GetPtr()); 136 | drvObj = ExtRemoteTyped("(nt!_DRIVER_OBJECT*)@$extin", devObj.Field("DriverObject").GetPtr()); 137 | 138 | 139 | m_bindAdapterHandlerStartAddr = Is64Bit ? drvObj.Field("DriverStart").GetUlong64() : drvObj.Field("DriverStart").GetUlong(); 140 | return m_bindAdapterHandlerStartAddr; 141 | } 142 | 143 | ULONG64 WINAPI COpenblock::GetMiniDriverEndAddr() 144 | { 145 | return (m_bindAdapterHandlerEndAddr = utils::getModuleSize(m_bindAdapterHandlerStartAddr) + m_bindAdapterHandlerStartAddr); 146 | } 147 | 148 | VOID WINAPI COpenblock::SetBinderName(PWSTR AdatperName) 149 | { 150 | StringCchCopyW(m_bindingname, MAX_BINDING_NAME, AdatperName); 151 | } 152 | 153 | PWSTR WINAPI COpenblock::GetBinderName() 154 | { 155 | return m_bindingname; 156 | } 157 | 158 | PWSTR WINAPI COpenblock::GetProtocolName() 159 | { 160 | ExtRemoteTyped openBlock("(ndis!_NDIS_OPEN_BLOCK*)@$extin", m_binderAddress); 161 | ExtRemoteTyped protBlock("(ndis!_NDIS_PROTOCOL_BLOCK*)@$extin", openBlock.Field("ProtocolHandle").GetPtr()); 162 | ExtRemoteTyped protName("(nt!_UNICODE_STRING*)@$extin", utils::getNdisFieldData(openBlock.Field("ProtocolHandle").GetPtr(), protBlock, "Name")); 163 | // Get protocol name in m_protocolName 164 | utils::getUnicodeString(protName, m_protocolname, MAX_PROTOCOL_NAME*sizeof(WCHAR)); 165 | 166 | return m_protocolname; 167 | } 168 | 169 | PWSTR WINAPI COpenblock::GetAdpaterName() 170 | { 171 | ExtRemoteTyped openBlock("(ndis!_NDIS_OPEN_BLOCK*)@$extin", m_binderAddress); 172 | ExtRemoteTyped miniBlock("(ndis!_NDIS_MINIPORT_BLOCK*)@$extin", openBlock.Field("MiniportHandle").GetPtr()); 173 | ExtRemoteTyped adapterName("(nt!_UNICODE_STRING*)@$extin", miniBlock.Field("pAdapterInstanceName").GetPtr()); 174 | // Get adapter name in m_adaptername 175 | utils::getUnicodeString(adapterName, m_adaptername, MAX_ADAPTER_NAME*sizeof(WCHAR)); 176 | 177 | return m_adaptername; 178 | } 179 | 180 | std::map* WINAPI COpenblock::GetFunctionHandlers(std::map *PtrHandlers) 181 | { 182 | PtrHandlers->insert(std::make_pair("SendHandler", m_ptrSendHandler)); 183 | PtrHandlers->insert(std::make_pair("SendCompleteHandler", m_ptrSendCompleteHandler)); 184 | PtrHandlers->insert(std::make_pair("ResetCompleteHandler", m_ptrResetCompleteHandler)); 185 | PtrHandlers->insert(std::make_pair("SendPacketsHandler", m_ptrSendPacketsHandler)); 186 | PtrHandlers->insert(std::make_pair("ReceiveHandler", m_ptrReceiveHandler)); 187 | PtrHandlers->insert(std::make_pair("ReceiveCompleteHandler", m_ptrReceiveCompleteHandler)); 188 | PtrHandlers->insert(std::make_pair("WanReceiveHandler", m_ptrWanReceiveHandler)); 189 | PtrHandlers->insert(std::make_pair("RequestCompleteHandler", m_ptrRequestCompleteHandler)); 190 | PtrHandlers->insert(std::make_pair("ReceivePacketHandler", m_ptrReceivePacketHandler)); 191 | PtrHandlers->insert(std::make_pair("StatusCompleteHandler", m_ptrStatusCompleteHandler)); 192 | PtrHandlers->insert(std::make_pair("StatusHandler", m_ptrStatusHandler)); 193 | PtrHandlers->insert(std::make_pair("WanSendHandler", m_ptrWanSendHandler)); 194 | PtrHandlers->insert(std::make_pair("ReceiveNetBufferLists", m_ptrReceiveNetBufferLists)); 195 | 196 | return PtrHandlers; 197 | } -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/COpenblock.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #ifndef _COPENBLOCKS_H_ 21 | #define _COPENBLOCKS_H_ 22 | 23 | #define MAX_PROTOCOL_NAME 100 24 | #define MAX_ADAPTER_NAME 500 25 | #define MAX_BINDING_NAME 1000 26 | 27 | class COpenblock 28 | { 29 | public: 30 | COpenblock(ULONG64); 31 | ~COpenblock(); 32 | BOOL WINAPI IsHandlerHooked(ULONG64); 33 | ULONG64 WINAPI GetMiniDriverStartAddr(); 34 | ULONG64 WINAPI GetMiniDriverEndAddr(); 35 | VOID WINAPI SetBinderName(PWSTR); 36 | PWSTR WINAPI GetBinderName(); 37 | PWSTR WINAPI GetProtocolName(); 38 | PWSTR WINAPI GetAdpaterName(); 39 | std::map* WINAPI GetFunctionHandlers(std::map*); 40 | ULONG64 m_binderAddress; 41 | // Will be used in IsHandlerHooked 42 | ULONG64 m_ndisStartAddr; 43 | ULONG64 m_ndisEndAddr; 44 | ULONG64 m_bindProtocolHandlerStartAddr; 45 | ULONG64 m_bindProtocolHandlerEndAddr; 46 | ULONG64 m_bindAdapterHandlerStartAddr; 47 | ULONG64 m_bindAdapterHandlerEndAddr; 48 | // Only partial handler functions that are known to be targeted on NDIS library 49 | ULONG64 m_ptrSendHandler; 50 | ULONG64 m_ptrSendCompleteHandler; 51 | ULONG64 m_ptrSendPacketsHandler; 52 | ULONG64 m_ptrReceiveHandler; 53 | ULONG64 m_ptrReceiveCompleteHandler; 54 | ULONG64 m_ptrWanReceiveHandler; 55 | ULONG64 m_ptrRequestCompleteHandler; 56 | ULONG64 m_ptrResetCompleteHandler; 57 | ULONG64 m_ptrReceivePacketHandler; 58 | ULONG64 m_ptrStatusHandler; 59 | ULONG64 m_ptrStatusCompleteHandler; 60 | ULONG64 m_ptrWanSendHandler; 61 | // Available on NDIS6.x 62 | ULONG64 m_ptrReceiveNetBufferLists; 63 | private: 64 | PWSTR m_bindingname; 65 | PWSTR m_protocolname; 66 | PWSTR m_adaptername; 67 | }; 68 | 69 | #endif // _COPENBLOCKS_H_ -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/CProtocols.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #include "stdafx.h" 21 | #include "CNdiskd.h" 22 | 23 | // CProtocols constructor 24 | CProtocols::CProtocols() 25 | { 26 | m_majorversion = 0; 27 | m_minorversion = 0; 28 | m_protocolStartAddr = 0; 29 | m_protocolEndAddr = 0; 30 | m_ptrReceiveHandler = 0; 31 | m_ptrReceivePacketHandler = 0; 32 | m_ptrReceiveCompleteHandler = 0; 33 | m_ptrWanReceiveHandler = 0; 34 | m_ptrResetCompleteHandler = 0; 35 | m_ptrWanTransferDataCompleteHandler = 0; 36 | m_ptrTransferDataCompleteHandler = 0; 37 | m_ptrWanSendCompleteHandler = 0; 38 | m_ptrSendCompleteHandler = 0; 39 | m_ptrCloseAdapterCompleteHandler = 0; 40 | m_ptrOpenAdapterCompleteHandler = 0; 41 | m_ptrSendNetBufferListsCompleteHandler = 0; 42 | m_ptrReceiveNetBufferListsHandler = 0; 43 | m_ptrStatusCompleteHandler = 0; 44 | m_ptrStatusHandler = 0; 45 | m_ptrStatusHandlerEx = 0; 46 | m_ptrRequestCompleteHandler = 0; 47 | // Initialize heap to store protocol's information 48 | m_protocolname = (PWSTR)malloc(MAX_PROTOCOL_NAME*sizeof(WCHAR)); 49 | m_ModuleName = (PSTR)malloc(MAX_MODULE_NAME); 50 | } 51 | 52 | // CProtocols destructor 53 | CProtocols::~CProtocols() 54 | { 55 | // Cleanup 56 | free(m_protocolname); 57 | free(m_ModuleName); 58 | } 59 | 60 | VOID WINAPI CProtocols::SetProtocolName(PWSTR ProtocolName) 61 | { 62 | StringCchCopyW(m_protocolname, MAX_PROTOCOL_NAME, ProtocolName); 63 | } 64 | 65 | PWSTR WINAPI CProtocols::GetProtocolName() 66 | { 67 | return m_protocolname; 68 | } 69 | 70 | VOID WINAPI CProtocols::SetPtrHandler(ULONG64 Handler) 71 | { 72 | UNREFERENCED_PARAMETER(Handler); 73 | } 74 | 75 | BOOL WINAPI CProtocols::IsProtocolFuncHandlerHooked(ULONG64 PtrHandler) 76 | { 77 | BOOL boolIsHooked = (PtrHandler < m_protocolStartAddr) && (PtrHandler > m_protocolEndAddr); 78 | 79 | if (boolIsHooked) 80 | return true; 81 | else 82 | return false; 83 | } 84 | 85 | std::map* WINAPI CProtocols::GetFunctionHandlers(std::map *PtrHandlers) 86 | { 87 | PtrHandlers->insert(std::make_pair("ReceiveHandler", m_ptrReceiveHandler)); 88 | PtrHandlers->insert(std::make_pair("ReceivePacketHandler", m_ptrReceivePacketHandler)); 89 | PtrHandlers->insert(std::make_pair("ReceiveCompleteHandler", m_ptrReceiveCompleteHandler)); 90 | PtrHandlers->insert(std::make_pair("WanReceiveHandler", m_ptrWanReceiveHandler)); 91 | PtrHandlers->insert(std::make_pair("ResetCompleteHandler", m_ptrResetCompleteHandler)); 92 | PtrHandlers->insert(std::make_pair("WanTransferDataCompleteHandler", m_ptrWanTransferDataCompleteHandler)); 93 | PtrHandlers->insert(std::make_pair("TransferDataCompleteHandler", m_ptrTransferDataCompleteHandler)); 94 | PtrHandlers->insert(std::make_pair("WanSendCompleteHandler", m_ptrWanSendCompleteHandler)); 95 | PtrHandlers->insert(std::make_pair("SendCompleteHandler", m_ptrSendCompleteHandler)); 96 | PtrHandlers->insert(std::make_pair("CloseAdapterCompleteHandler", m_ptrCloseAdapterCompleteHandler)); 97 | PtrHandlers->insert(std::make_pair("OpenAdapterCompleteHandler", m_ptrOpenAdapterCompleteHandler)); 98 | PtrHandlers->insert(std::make_pair("SendNetBufferListsCompleteHandler", m_ptrSendNetBufferListsCompleteHandler)); 99 | PtrHandlers->insert(std::make_pair("ReceiveNetBufferListsHandler", m_ptrReceiveNetBufferListsHandler)); 100 | PtrHandlers->insert(std::make_pair("StatusCompleteHandler", m_ptrStatusCompleteHandler)); 101 | PtrHandlers->insert(std::make_pair("StatusHandler", m_ptrStatusHandler)); 102 | PtrHandlers->insert(std::make_pair("StatusHandlerEx", m_ptrStatusHandlerEx)); 103 | PtrHandlers->insert(std::make_pair("RequestCompleteHandler", m_ptrRequestCompleteHandler)); 104 | 105 | return PtrHandlers; 106 | } -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/CProtocols.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #ifndef _CPROTOCOLS_H_ 21 | #define _CPROTOCOLS_H_ 22 | 23 | #define MAX_PROTOCOL_NAME 100 24 | #define MAX_MODULE_NAME 256 25 | 26 | class CProtocols 27 | { 28 | public: 29 | CProtocols(); 30 | ~CProtocols(); 31 | BOOL WINAPI IsProtocolFuncHandlerHooked(ULONG64); 32 | VOID WINAPI SetProtocolName(PWSTR); 33 | PWSTR WINAPI GetProtocolName(); 34 | VOID WINAPI SetPtrHandler(ULONG64); 35 | ULONG64 WINAPI GetPtrHandler(); 36 | std::map* WINAPI GetFunctionHandlers(std::map*); 37 | UCHAR m_majorversion; 38 | UCHAR m_minorversion; 39 | ULONG64 m_protocolStartAddr; 40 | ULONG64 m_protocolEndAddr; 41 | PSTR m_ModuleName; 42 | // Only partial handler functions that are known to be targeted 43 | ULONG64 m_ptrReceiveHandler; 44 | ULONG64 m_ptrReceivePacketHandler; 45 | ULONG64 m_ptrReceiveCompleteHandler; 46 | ULONG64 m_ptrWanReceiveHandler; 47 | ULONG64 m_ptrResetCompleteHandler; 48 | ULONG64 m_ptrWanTransferDataCompleteHandler; 49 | ULONG64 m_ptrTransferDataCompleteHandler; 50 | ULONG64 m_ptrWanSendCompleteHandler; 51 | ULONG64 m_ptrSendCompleteHandler; 52 | ULONG64 m_ptrCloseAdapterCompleteHandler; 53 | ULONG64 m_ptrOpenAdapterCompleteHandler; 54 | ULONG64 m_ptrSendNetBufferListsCompleteHandler; 55 | ULONG64 m_ptrReceiveNetBufferListsHandler; 56 | ULONG64 m_ptrStatusCompleteHandler; 57 | ULONG64 m_ptrStatusHandler; 58 | ULONG64 m_ptrStatusHandlerEx; 59 | ULONG64 m_ptrRequestCompleteHandler; 60 | 61 | private: 62 | PWSTR m_protocolname; 63 | }; 64 | 65 | #endif // _CPROTOCOLS_H_ -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/CReport.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #include "stdafx.h" 21 | #include "CNdiskd.h" 22 | 23 | CReport::CReport(ExtCheckedPointer gExt) : m_gExt(gExt) 24 | { 25 | // Constructor 26 | } 27 | 28 | ////////////////////////////////////////////////////////////////////////// 29 | // Output hooks report in using Debugger Markup Language 30 | // @Param: None 31 | // @Return: None 32 | ////////////////////////////////////////////////////////////////////////// 33 | VOID WINAPI CReport::ReportHooks(PCSTR Format, ...) 34 | { 35 | 36 | CHAR Buffer[1024] = { 0 }; 37 | va_list Args; 38 | 39 | va_start(Args, Format); 40 | 41 | vsnprintf_s(Buffer, _countof(Buffer), _TRUNCATE, Format, Args); 42 | 43 | m_gExt->Dml(Buffer); 44 | 45 | va_end(Args); 46 | } 47 | -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/CReport.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #ifndef _CREPORT_H_ 21 | #define _CREPORT_H_ 22 | #pragma once 23 | #include "../engextcpp.hpp" 24 | 25 | class CReport 26 | { 27 | public: 28 | CReport(ExtCheckedPointer); 29 | ~CReport(); 30 | VOID WINAPI ReportHooks(PCSTR, ...); 31 | private: 32 | ExtCheckedPointer m_gExt; 33 | }; 34 | #endif // _CREPORT_H_ -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/utils.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | 20 | #include "stdafx.h" 21 | #include 22 | #include "..\SwishDbgExt.h" // DbgPrint macro 23 | #include "CNdiskd.h" 24 | 25 | #define SIGN_EXTEND(_x_) (ULONG64)(LONG)(_x_) 26 | 27 | ////////////////////////////////////////////////////////////////////////// 28 | // Documented structure definitions 29 | ////////////////////////////////////////////////////////////////////////// 30 | typedef struct _UNICODE_STRING { 31 | USHORT Length; 32 | USHORT MaximumLength; 33 | PWSTR Buffer; 34 | } UNICODE_STRING, *PUNICODE_STRING; 35 | 36 | namespace utils { 37 | 38 | BOOL IsVistaOrAbove() 39 | { 40 | BOOL bIsWindowsVistaOrLater = false; 41 | ULONG PlatformId, Win32Major, Win32Minor; 42 | HRESULT hres; 43 | 44 | hres = g_Ext->m_Control4->GetSystemVersionValues(&PlatformId, &Win32Major, &Win32Minor, NULL, NULL); 45 | 46 | if ( FAILED( hres ) ) 47 | g_Ext->ThrowRemote(hres, "IDebugControl4::GetSystemVersionValues" ); 48 | 49 | bIsWindowsVistaOrLater = Win32Major == 6; 50 | 51 | if (bIsWindowsVistaOrLater) 52 | return true; 53 | else 54 | return false; 55 | } 56 | 57 | ULONG64 findModuleBase(PCSTR moduleName) 58 | { 59 | HRESULT hres; 60 | ULONG64 base; 61 | 62 | hres = g_Ext->m_Symbols->GetModuleByModuleName(moduleName, 0, NULL, &base); 63 | 64 | if ( FAILED( hres ) ) 65 | g_Ext->ThrowRemote(hres, "IDebugSymbol::GetModuleByModuleName"); 66 | 67 | return base; 68 | } 69 | 70 | ULONG64 findModuleBase(PWSTR moduleName) 71 | { 72 | HRESULT hres; 73 | ULONG64 base; 74 | 75 | hres = g_Ext->m_Symbols3->GetModuleByModuleNameWide(moduleName, 0, NULL, &base); 76 | 77 | if ( FAILED( hres ) ) 78 | g_Ext->ThrowRemote(hres, "IDebugSymbol3::GetModuleByModuleName"); 79 | 80 | return base; 81 | } 82 | 83 | ULONG64 findModuleBase(ULONG64 offset) 84 | { 85 | HRESULT hres; 86 | ULONG64 base; 87 | ULONG moduleIndex; 88 | 89 | // 32-bit 90 | if (g_Ext->IsMachine32(g_Ext->m_ActualMachine)) 91 | hres = g_Ext->m_Symbols->GetModuleByOffset(SIGN_EXTEND(offset), 0, &moduleIndex, &base); 92 | // 64-bit 93 | else 94 | hres = g_Ext->m_Symbols->GetModuleByOffset(offset, 0, &moduleIndex, &base); 95 | 96 | if ( FAILED( hres ) ) 97 | g_Ext->ThrowRemote(hres, "IDebugSymbol::GetModuleByOffset. Try reloading symbols (.reload /f)"); 98 | 99 | return base; 100 | } 101 | 102 | ULONG64 getNdisFieldData(ULONG64 Base, ExtRemoteTyped TypedObj, PSTR FieldName) 103 | { 104 | CHAR NewFieldName[100] = {0}; 105 | ULONG64 Address; 106 | 107 | // Is object type NDIS_PROTOCOL_BLOCK? 108 | if (strstr(TypedObj.GetTypeName(), "_NDIS_PROTOCOL_BLOCK") != NULL) 109 | { 110 | // Ndis6x does not have ProtocolCharaterisitics 111 | if (utils::IsVistaOrAbove()) 112 | { 113 | StringCchCopyA(NewFieldName, _countof(NewFieldName), FieldName); 114 | } 115 | // Ndis5x has a union structure ProtocolCharaterisitics 116 | else 117 | { 118 | if(strcmp(FieldName, "MajorNdisVersion") == 0 || 119 | strcmp(FieldName, "MinorNdisVersion") == 0 || 120 | strcmp(FieldName, "Name") == 0 || 121 | strcmp(FieldName, "Filler") == 0 || 122 | strcmp(FieldName, "Reserved") == 0 || 123 | strcmp(FieldName, "Flags") == 0 || 124 | strstr(FieldName, "Handler") != NULL) 125 | { 126 | StringCchCopyA(NewFieldName, _countof(NewFieldName), "ProtocolCharacteristics."); 127 | StringCchCatA(NewFieldName, _countof(NewFieldName), FieldName); 128 | } 129 | else 130 | { 131 | StringCchCopyA(NewFieldName, _countof(NewFieldName), FieldName); 132 | } 133 | } 134 | } 135 | else 136 | { 137 | StringCchCopyA(NewFieldName, _countof(NewFieldName), FieldName); 138 | } 139 | 140 | if (Base > 0) 141 | { 142 | Address = Base + TypedObj.GetFieldOffset(NewFieldName); 143 | return Address; 144 | } 145 | else 146 | { 147 | switch(TypedObj.Field(NewFieldName).GetTypeSize()) 148 | { 149 | case 8: 150 | return TypedObj.Field(NewFieldName).GetLong64(); 151 | case 4: 152 | return TypedObj.Field(NewFieldName).GetLong(); 153 | case 2: 154 | return TypedObj.Field(NewFieldName).GetUshort(); 155 | case 1: 156 | return TypedObj.Field(NewFieldName).GetUchar(); 157 | default: 158 | return TypedObj.Field(NewFieldName).GetBoolean(); 159 | } 160 | } 161 | } 162 | 163 | ULONG64 getPointerFromAddress(ULONG64 Address, PULONG cbBytesRead) 164 | { 165 | ULONG Status; 166 | ULONG64 Result; 167 | 168 | Result = 0; 169 | if (g_Ext->IsMachine32(g_Ext->m_ActualMachine)) 170 | { 171 | // SIGN_EXTEND: To mitigate ReadVirtual: xxxxxxxx not properly sign extended warning 172 | Status = ReadMemory(SIGN_EXTEND(Address), &Result, 4, cbBytesRead); 173 | } 174 | else 175 | { 176 | Status = ReadMemory(Address, &Result, 8, cbBytesRead); 177 | } 178 | 179 | if (Status == FALSE) 180 | { 181 | g_Ext->m_Control->Output(DEBUG_OUTPUT_ERROR, "Failed to read pointer from 0x%I64x.\n", Address); 182 | } 183 | 184 | return Result; 185 | } 186 | 187 | ULONG getUlongFromAddress(ULONG64 Address, PULONG cbBytesRead) 188 | { 189 | ULONG Status; 190 | ULONG Result; 191 | 192 | Result = 0; 193 | *cbBytesRead = 0; 194 | Status = ReadMemory(Address, &Result, sizeof(ULONG), cbBytesRead); 195 | 196 | if(Status == FALSE) 197 | { 198 | g_Ext->m_Control->Output(DEBUG_OUTPUT_ERROR, "Failed to read value from 0x%I64x.", Address); 199 | } 200 | else if(*cbBytesRead != sizeof(ULONG)) 201 | { 202 | g_Ext->m_Control->Output(DEBUG_OUTPUT_ERROR, "Something wrong when reading value from 0x%I64x.", Address); 203 | } 204 | 205 | return Result; 206 | } 207 | 208 | namespace { 209 | 210 | ULONG getModuleSizeImpl( ULONG64 baseOffset ) 211 | { 212 | HRESULT hres; 213 | DEBUG_MODULE_PARAMETERS moduleParam = { 0 }; 214 | 215 | hres = g_Ext->m_Symbols->GetModuleParameters(1, &baseOffset, 0, &moduleParam); 216 | if ( FAILED( hres ) ) 217 | g_Ext->ThrowRemote(hres, "IDebugSymbol::GetModuleParameters"); 218 | 219 | return moduleParam.Size; 220 | } 221 | } 222 | 223 | ULONG getModuleSize( ULONG64 baseOffset ) 224 | { 225 | // 32-bit 226 | if (g_Ext->IsMachine32(g_Ext->m_ActualMachine)) 227 | return getModuleSizeImpl( SIGN_EXTEND(baseOffset) ); 228 | // 64-bit 229 | else 230 | return getModuleSizeImpl( baseOffset ); 231 | } 232 | 233 | PSTR getNameByOffset(ULONG64 addr, PSTR symbolName) 234 | { 235 | HRESULT hres; 236 | ULONG64 displace = 0; 237 | 238 | RtlZeroMemory(symbolName, sizeof(symbolName)); 239 | 240 | // 32-bit 241 | if (g_Ext->IsMachine32(g_Ext->m_ActualMachine)) 242 | hres = g_Ext->m_Symbols->GetNameByOffset(SIGN_EXTEND(addr), symbolName, sizeof(symbolName), NULL, &displace); 243 | // 64-bit 244 | else 245 | hres = g_Ext->m_Symbols->GetNameByOffset(addr, symbolName, sizeof(symbolName), NULL, &displace); 246 | 247 | if ( FAILED( hres ) ) 248 | { 249 | //g_Ext->ThrowRemote(hres, "IDebugSymbol::GetNameByOffset failed at 0x%I64x.", addr); 250 | return NULL; 251 | } 252 | 253 | return symbolName; 254 | } 255 | 256 | PSTR getModuleNameByOffset(ULONG64 addr, PSTR moduleName) 257 | { 258 | HRESULT hres; 259 | ULONG moduleIndex; 260 | ULONG64 moduleBase; 261 | 262 | RtlZeroMemory(moduleName, sizeof(moduleName)); 263 | 264 | // 32-bit 265 | if (g_Ext->IsMachine32(g_Ext->m_ActualMachine)) 266 | hres = g_Ext->m_Symbols->GetModuleByOffset(SIGN_EXTEND(addr), 0, &moduleIndex, &moduleBase); 267 | // 64-bit 268 | else 269 | hres = g_Ext->m_Symbols->GetModuleByOffset(addr, 0, &moduleIndex, &moduleBase); 270 | 271 | if ( FAILED( hres ) ) 272 | { 273 | //g_Ext->ThrowRemote(hres, "IDebugSymbol::GetModuleByOffset failed at 0x%I64x.", addr); 274 | return NULL; 275 | } 276 | 277 | hres = g_Ext->m_Symbols2->GetModuleNameString(DEBUG_MODNAME_LOADED_IMAGE, moduleIndex, moduleBase, moduleName, sizeof(moduleName), NULL); 278 | 279 | if ( FAILED( hres ) ) 280 | { 281 | //g_Ext->ThrowRemote(hres, "IDebugSymbol::GetNameByOffset failed" ); 282 | return NULL; 283 | } 284 | 285 | return moduleName; 286 | } 287 | 288 | PWSTR getUnicodeString( 289 | IN ExtRemoteTyped TypedObject, 290 | OUT PWSTR Buffer, 291 | IN ULONG MaxChars) 292 | { 293 | UNICODE_STRING SavedUnicodeString = {0}; 294 | 295 | RtlZeroMemory(Buffer, MaxChars); 296 | 297 | SavedUnicodeString.Length = TypedObject.Field("Length").GetUshort(); 298 | SavedUnicodeString.MaximumLength = TypedObject.Field("MaximumLength").GetUshort(); 299 | SavedUnicodeString.Buffer = (PWCH)TypedObject.Field("Buffer").GetPtr(); 300 | 301 | if (SavedUnicodeString.Buffer && SavedUnicodeString.Length) 302 | { 303 | ExtRemoteData usData((ULONG64)SavedUnicodeString.Buffer, SavedUnicodeString.Length); 304 | 305 | if (SavedUnicodeString.Length > MaxChars) 306 | { 307 | g_Ext->ThrowRemote(HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW), 308 | "String at %p overflows buffer, need 0x%x chars", 309 | TypedObject.m_Offset, SavedUnicodeString.Length); 310 | } 311 | 312 | #if VVERBOSE_MODE 313 | ULONG64 ptrBuffer = (ULONG64)SavedUnicodeString.Buffer; 314 | DbgPrint("DEBUG: %s:%d:%s Get string from %#I64x with length %d to %#p\n", __FILE__, __LINE__, __FUNCTION__, ptrBuffer, SavedUnicodeString.Length, Buffer); 315 | #endif 316 | usData.GetString(Buffer, SavedUnicodeString.Length, SavedUnicodeString.MaximumLength, false, NULL); 317 | } 318 | 319 | // Some string is not NULL terminated 320 | Buffer[SavedUnicodeString.MaximumLength/sizeof(WCHAR)] = '\0'; 321 | return Buffer; 322 | } 323 | 324 | 325 | } -------------------------------------------------------------------------------- /SwishDbgExt/CNdiskd/utils.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | A NDIS hook scan extension to existing Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 wLcY (@x9090) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | --*/ 19 | #pragma once 20 | #include "../engextcpp.hpp" 21 | 22 | namespace utils { 23 | 24 | ULONG64 findModuleBase(PCSTR); 25 | ULONG64 findModuleBase(PWSTR); 26 | ULONG64 findModuleBase(ULONG64); 27 | ULONG64 getNdisFieldData(ULONG64, ExtRemoteTyped, PSTR); 28 | ULONG64 getPointerFromAddress(ULONG64, PULONG); 29 | ULONG getUlongFromAddress(ULONG64, PULONG); 30 | ULONG getModuleSize(ULONG64); 31 | BOOL IsVistaOrAbove(); 32 | PSTR getNameByOffset(ULONG64, PSTR); 33 | PSTR getModuleNameByOffset(ULONG64, PSTR); 34 | PWSTR getUnicodeString(ExtRemoteTyped, PWSTR, ULONG); 35 | 36 | } -------------------------------------------------------------------------------- /SwishDbgExt/Checks/Codecave.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | Comae Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2016 Comae Technologies FZE. 5 | Copyright (C) 2016 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Codecave.cpp 23 | 24 | Abstract: 25 | 26 | - https ://breakingmalware.com/injection-techniques/atombombing-brand-new-code-injection-for-windows/ 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche (m) 35 | 36 | --*/ 37 | 38 | #include "stdafx.h" 39 | #include "../SwishDbgExt.h" 40 | 41 | #define VERBOSE FALSE 42 | 43 | ULONG 44 | HasUsedCodeCave( 45 | ULONG64 ImageBase, 46 | vector *Sections, 47 | MsPEImageFile::PCACHED_SECTION_INFO SectionHeader, 48 | PULONG Score 49 | ) 50 | { 51 | ULONG Result = FALSE; 52 | PUCHAR Buffer = NULL; 53 | ULONG CorruptionScore = 0; 54 | 55 | ULONG CodeCaveVirtualOffset = SectionHeader->VaBase + min(SectionHeader->VaSize, SectionHeader->RawSize); 56 | 57 | ULONG DeadSpace = TRUE; 58 | for each (MsPEImageFile::CACHED_SECTION_INFO current in *Sections) { 59 | if (current.VaBase == CodeCaveVirtualOffset) { 60 | 61 | if (g_Verbose) g_Ext->Dml("[%s!%S!%d] '%s' ends right before '%s' .\n", __FILE__, __FUNCTIONW__, __LINE__, SectionHeader->Name, current.Name); 62 | DeadSpace = FALSE; 63 | goto CleanUp; 64 | } 65 | } 66 | 67 | ULONG BytesLeft = PAGE_SIZE - (CodeCaveVirtualOffset & (PAGE_SIZE - 1)); 68 | if (!BytesLeft) goto CleanUp; 69 | 70 | Buffer = (LPBYTE)malloc(BytesLeft); 71 | if (Buffer == NULL) goto CleanUp; 72 | 73 | ULONG64 TargetVa = SIGN_EXTEND(ImageBase + CodeCaveVirtualOffset); 74 | 75 | if (ExtRemoteTypedEx::ReadVirtual(TargetVa, Buffer, BytesLeft, NULL) != S_OK) { 76 | goto CleanUp; 77 | } 78 | 79 | // 80 | // Simple check, to know if the code space null or did someone wrote something into it ? 81 | // 82 | for (ULONG i = 0; i < min(BytesLeft, 0x10); i += 1) { 83 | if ((Buffer[i] != '\xff') && (Buffer[i] != '\0')) { 84 | CorruptionScore += 1; 85 | } 86 | } 87 | 88 | if (CorruptionScore) { 89 | if (g_Verbose) { 90 | g_Ext->Dml(" 0x%llx + 0x%x + 0x%x = 0x%llx\n", ImageBase, SectionHeader->VaBase, SectionHeader->RawSize, ImageBase + SectionHeader->VaBase + SectionHeader->RawSize); 91 | g_Ext->Dml(" Data[0] = 0x%02X, Data[1] = 0x%02X, Data[2] = 0x%02X, Data[3] = 0x%02X, \n", Buffer[0], Buffer[1], Buffer[2], Buffer[3]); 92 | g_Ext->Execute("u 0x%I64X", TargetVa); 93 | } 94 | 95 | Result = CodeCaveVirtualOffset; 96 | goto CleanUp; 97 | } 98 | 99 | CleanUp: 100 | *Score = CorruptionScore; 101 | if (Buffer) free(Buffer); 102 | 103 | return Result; 104 | } -------------------------------------------------------------------------------- /SwishDbgExt/Checks/Codecave.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Comae Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2016 Comae Technologies FZE. 5 | Copyright (C) 2016 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Codecave.h 23 | 24 | Abstract: 25 | 26 | - https ://breakingmalware.com/injection-techniques/atombombing-brand-new-code-injection-for-windows/ 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche (m) 35 | 36 | --*/ 37 | 38 | #ifndef __CODECAVE_H__ 39 | #define __CODECAVE_H__ 40 | 41 | ULONG 42 | HasUsedCodeCave( 43 | ULONG64 ImageBase, 44 | vector *Sections, 45 | MsPEImageFile::PCACHED_SECTION_INFO SectionHeader, 46 | PULONG Score 47 | ); 48 | 49 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Common.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2016 Comae Technologies FZE 6 | Copyright (C) 2014-2016 Matthieu Suiche (@msuiche) 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | 21 | Module Name: 22 | 23 | - Common.cpp 24 | 25 | Abstract: 26 | 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | #include "stdafx.h" 39 | #include "SwishDbgExt.h" 40 | 41 | PSTR 42 | GetISO8601Date( 43 | _Out_writes_(Length) PSTR Buffer, 44 | _In_ ULONG Length, 45 | _In_ PFILETIME FileTime 46 | ) 47 | { 48 | SYSTEMTIME SystemTime; 49 | 50 | Buffer[0] = '\0'; 51 | 52 | if ((FileTime->dwHighDateTime || FileTime->dwLowDateTime) && FileTimeToSystemTime(FileTime, &SystemTime)) { 53 | 54 | StringCchPrintfA(Buffer, 55 | Length, 56 | "%i-%02i-%02iT%02i:%02i:%02i.%03iZ", 57 | SystemTime.wYear, 58 | SystemTime.wMonth, 59 | SystemTime.wDay, 60 | SystemTime.wHour, 61 | SystemTime.wMinute, 62 | SystemTime.wSecond, 63 | SystemTime.wMilliseconds); 64 | } 65 | 66 | return Buffer; 67 | } 68 | 69 | ULONGLONG 70 | GetTimeStamp( 71 | VOID 72 | ) 73 | { 74 | FILETIME ft = {0}; 75 | LARGE_INTEGER li = {0}; 76 | 77 | GetSystemTimeAsFileTime(&ft); 78 | 79 | li.HighPart = ft.dwHighDateTime; 80 | li.LowPart = ft.dwLowDateTime; 81 | 82 | return li.QuadPart; 83 | } 84 | 85 | PSTR 86 | GetArchitectureType( 87 | VOID 88 | ) 89 | { 90 | switch (g_Ext->m_ActualMachine) { 91 | 92 | case IMAGE_FILE_MACHINE_I386: return "x86"; 93 | case IMAGE_FILE_MACHINE_AMD64: return "x64"; 94 | default: return "Unknown"; 95 | } 96 | } 97 | 98 | PSTR 99 | GetDumpType( 100 | _In_ ULONG Class, 101 | _In_ ULONG Qualifier 102 | ) 103 | { 104 | if (Class == DEBUG_CLASS_KERNEL) { 105 | 106 | switch (Qualifier) { 107 | 108 | case DEBUG_KERNEL_CONNECTION: return "Kernel Connection"; 109 | case DEBUG_KERNEL_LOCAL: return "Kernel Local"; 110 | case DEBUG_KERNEL_EXDI_DRIVER: return "Kernel EXDI Driver"; 111 | case DEBUG_KERNEL_SMALL_DUMP: return "Kernel Small Dump"; 112 | case DEBUG_KERNEL_DUMP: return "Kernel Dump"; 113 | case DEBUG_KERNEL_FULL_DUMP: return "Kernel Full Dump"; 114 | default: return ""; 115 | } 116 | } 117 | 118 | return ""; 119 | } 120 | 121 | PSTR 122 | GetTargetName( 123 | _Out_writes_(Length) PSTR Buffer, 124 | _In_ ULONG Length 125 | ) 126 | { 127 | ULONG64 Address; 128 | WCHAR UnicodeString[MAX_PATH]; 129 | 130 | if ((g_Ext->m_Symbols->GetOffsetByName("srv!SrvComputerName", &Address) == S_OK)) { 131 | 132 | ExtRemoteTypedEx::GetUnicodeStringEx(Address, UnicodeString, sizeof(UnicodeString)); 133 | 134 | StringCchPrintf(Buffer, Length, "%S", UnicodeString); 135 | } 136 | 137 | return Buffer; 138 | } 139 | 140 | PSTR 141 | GetIpAddressString( 142 | _Out_writes_(Length) PSTR Buffer, 143 | _In_ ULONG Length, 144 | _In_ PBYTE Address, 145 | _In_ ULONG SizeOfAddress 146 | ) 147 | { 148 | Buffer[0] = '\0'; 149 | 150 | if (SizeOfAddress == sizeof(IN_ADDR)) { 151 | 152 | StringCchPrintf(Buffer, 153 | Length, 154 | "%d.%d.%d.%d", 155 | Address[0], 156 | Address[1], 157 | Address[2], 158 | Address[3]); 159 | } 160 | else { 161 | 162 | StringCchPrintf(Buffer, 163 | Length, 164 | "%x:%x:%x:%x:%x:%x:%x:%x", 165 | _byteswap_ushort(((PUSHORT)Address)[0]), 166 | _byteswap_ushort(((PUSHORT)Address)[1]), 167 | _byteswap_ushort(((PUSHORT)Address)[2]), 168 | _byteswap_ushort(((PUSHORT)Address)[3]), 169 | _byteswap_ushort(((PUSHORT)Address)[4]), 170 | _byteswap_ushort(((PUSHORT)Address)[5]), 171 | _byteswap_ushort(((PUSHORT)Address)[6]), 172 | _byteswap_ushort(((PUSHORT)Address)[7])); 173 | } 174 | 175 | return Buffer; 176 | } 177 | 178 | PSTR 179 | GetGuidString( 180 | _Out_writes_(Length) PSTR Buffer, 181 | _In_ ULONG Length, 182 | _In_ GUID *Guid 183 | ) 184 | { 185 | Buffer[0] = '\0'; 186 | 187 | StringCchPrintfA(Buffer, 188 | Length, 189 | "%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX", 190 | Guid->Data1, 191 | Guid->Data2, 192 | Guid->Data3, 193 | Guid->Data4[0], 194 | Guid->Data4[1], 195 | Guid->Data4[2], 196 | Guid->Data4[3], 197 | Guid->Data4[4], 198 | Guid->Data4[5], 199 | Guid->Data4[6], 200 | Guid->Data4[7]); 201 | 202 | return Buffer; 203 | } 204 | 205 | PSTR 206 | GetHashString( 207 | _Out_writes_(Length) PSTR Buffer, 208 | _In_ ULONG Length, 209 | _In_ PBYTE Hash, 210 | _In_ ULONG HashLength 211 | ) 212 | { 213 | Buffer[0] = '\0'; 214 | 215 | CryptBinaryToStringA(Hash, HashLength, CRYPT_STRING_HEXRAW | CRYPT_STRING_NOCRLF, Buffer, &Length); 216 | 217 | return Buffer; 218 | } 219 | 220 | _Check_return_ 221 | BOOL 222 | GetFileSize( 223 | _In_ PTSTR FileName, 224 | _Out_ PLARGE_INTEGER FileSize 225 | ) 226 | { 227 | BOOL IsOk = FALSE; 228 | HANDLE hFile; 229 | OFSTRUCT of; 230 | 231 | hFile = (HANDLE)(ULONG_PTR)OpenFile(FileName, &of, OF_READ); 232 | 233 | if (hFile) { 234 | 235 | if (GetFileSizeEx(hFile, FileSize)) { 236 | 237 | IsOk = TRUE; 238 | } 239 | 240 | CloseHandle(hFile); 241 | } 242 | 243 | return IsOk; 244 | } 245 | 246 | _Check_return_ 247 | BOOL 248 | GetFileHash( 249 | _Out_writes_(Length) PTSTR Buffer, 250 | _In_ ULONG Length, 251 | _In_ PTSTR FileName, 252 | _In_ DWORD ProviderType, 253 | _In_ ALG_ID AlgId 254 | ) 255 | { 256 | HCRYPTPROV hCryptProvider; 257 | HCRYPTHASH hHash; 258 | LARGE_INTEGER FileSize; 259 | LONGLONG TotalNumberOfBytesRead = 0; 260 | FILE *File; 261 | PBYTE Data; 262 | PBYTE Hash; 263 | DWORD HashLength; 264 | DWORD NumberOfBytesRead; 265 | BOOL Status = FALSE; 266 | 267 | Buffer[0] = '\0'; 268 | 269 | if (0 == _tfopen_s(&File, FileName, "rb")) { 270 | 271 | if (GetFileSize(FileName, &FileSize)) { 272 | 273 | Data = (PBYTE)calloc(BUFFER_SIZE, sizeof(BYTE)); 274 | 275 | if (Data) { 276 | 277 | if (CryptAcquireContext(&hCryptProvider, NULL, NULL, ProviderType, CRYPT_VERIFYCONTEXT)) { 278 | 279 | if (CryptCreateHash(hCryptProvider, AlgId, NULL, 0, &hHash)) { 280 | 281 | while ((NumberOfBytesRead = (DWORD)fread(Data, sizeof(BYTE), BUFFER_SIZE, File)) != 0) { 282 | 283 | TotalNumberOfBytesRead += NumberOfBytesRead; 284 | 285 | if (!CryptHashData(hHash, (PBYTE)Data, NumberOfBytesRead, 0)) { 286 | 287 | break; 288 | } 289 | } 290 | 291 | if (TotalNumberOfBytesRead == FileSize.QuadPart) { 292 | 293 | if (CryptGetHashParam(hHash, HP_HASHVAL, NULL, &HashLength, 0)) { 294 | 295 | Hash = (PBYTE)calloc(HashLength, sizeof(BYTE)); 296 | 297 | if (Hash) { 298 | 299 | if (CryptGetHashParam(hHash, HP_HASHVAL, Hash, &HashLength, 0)) { 300 | 301 | if (CryptBinaryToString(Hash, HashLength, CRYPT_STRING_HEXRAW | CRYPT_STRING_NOCRLF, Buffer, &Length)) { 302 | 303 | Status = TRUE; 304 | } 305 | } 306 | 307 | free(Hash); 308 | } 309 | } 310 | } 311 | 312 | CryptDestroyHash(hHash); 313 | } 314 | 315 | CryptReleaseContext(hCryptProvider, 0); 316 | } 317 | 318 | free(Data); 319 | } 320 | } 321 | 322 | fclose(File); 323 | } 324 | 325 | return Status; 326 | } 327 | -------------------------------------------------------------------------------- /SwishDbgExt/Common.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2016 Comae Technologies FZE 6 | Copyright (C) 2014-2016 Matthieu Suiche (@msuiche) 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | 21 | Module Name: 22 | 23 | - Common.h 24 | 25 | Abstract: 26 | 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | 39 | #pragma once 40 | 41 | 42 | #define BUFFER_SIZE 64 * 1024 43 | 44 | #define MD5_HASH_LENGTH 16 45 | #define SHA256_HASH_LENGTH 32 46 | 47 | 48 | PSTR 49 | GetISO8601Date( 50 | _Out_writes_(Length) PSTR Buffer, 51 | _In_ ULONG Length, 52 | _In_ PFILETIME FileTime 53 | ); 54 | 55 | ULONGLONG 56 | GetTimeStamp( 57 | VOID 58 | ); 59 | 60 | PSTR 61 | GetArchitectureType( 62 | VOID 63 | ); 64 | 65 | PSTR 66 | GetDumpType( 67 | _In_ ULONG Class, 68 | _In_ ULONG Qualifier 69 | ); 70 | 71 | PSTR 72 | GetTargetName( 73 | _Out_writes_(Length) PSTR Buffer, 74 | _In_ ULONG Length 75 | ); 76 | 77 | PSTR 78 | GetIpAddressString( 79 | _Out_writes_(Length) PSTR Buffer, 80 | _In_ ULONG Length, 81 | _In_ PBYTE Address, 82 | _In_ ULONG SizeOfAddress 83 | ); 84 | 85 | PSTR 86 | GetGuidString( 87 | _Out_writes_(Length) PSTR Buffer, 88 | _In_ ULONG Length, 89 | _In_ GUID *Guid 90 | ); 91 | 92 | PSTR 93 | GetHashString( 94 | _Out_writes_(Length) PSTR Buffer, 95 | _In_ ULONG Length, 96 | _In_ PBYTE Hash, 97 | _In_ ULONG HashLength 98 | ); 99 | 100 | _Check_return_ 101 | BOOL 102 | GetFileSize( 103 | _In_ PTSTR FileName, 104 | _Out_ PLARGE_INTEGER FileSize 105 | ); 106 | 107 | _Check_return_ 108 | BOOL 109 | GetFileHash( 110 | _Out_writes_(Length) PTSTR Buffer, 111 | _In_ ULONG Length, 112 | _In_ PTSTR FileName, 113 | _In_ DWORD ProviderType, 114 | _In_ ALG_ID AlgId 115 | ); 116 | -------------------------------------------------------------------------------- /SwishDbgExt/DbgHelpEx.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - DbgHelpEx.h 23 | 24 | Abstract: 25 | 26 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 27 | 28 | 29 | Environment: 30 | 31 | - User mode 32 | 33 | Revision History: 34 | 35 | - Matthieu Suiche 36 | 37 | --*/ 38 | 39 | #include "SwishDbgExt.h" 40 | 41 | #ifndef __DBGHELPEX_H__ 42 | #define __DBGHELPEX_H__ 43 | 44 | #define CV_SIGNATURE_RSDS 'SDSR' 45 | 46 | typedef struct _CV_INFO_PDB70 47 | { 48 | DWORD Signature; 49 | GUID Guid; // unique identifier 50 | DWORD Age; // an always-incrementing value 51 | CHAR PdbFileName[1]; // zero terminated string with the name of the PDB file 52 | } CV_INFO_PDB70, *PCV_INFO_PDB70; 53 | 54 | class MsDllObject; 55 | 56 | class MsPEImageFile { 57 | public: 58 | typedef enum _IMAGE_TYPE { 59 | ImageInvalidType = 0, 60 | ImageProcessType = 1, 61 | ImageDllType = 2, 62 | ImageModuleType = 3 63 | } IMAGE_TYPE, *PIMAGE_TYPE; 64 | 65 | typedef struct _IMAGE_DATA { 66 | PIMAGE_DOS_HEADER Image; 67 | PIMAGE_NT_HEADERS32 NtHeader32; 68 | PIMAGE_NT_HEADERS64 NtHeader64; 69 | PIMAGE_DATA_DIRECTORY DataDirectory; 70 | PIMAGE_SECTION_HEADER Sections; 71 | 72 | ULONG NumberOfSections; 73 | 74 | BOOLEAN Initialized; 75 | } IMAGE_DATA, *PIMAGE_DATA; 76 | 77 | typedef struct _CACHED_SECTION_INFO { 78 | ULONG Index; 79 | 80 | CHAR Name[9]; 81 | 82 | ULONG VaBase; 83 | ULONG VaSize; 84 | CHAR VaMd5Hash[16]; 85 | 86 | ULONG RawBase; 87 | ULONG RawSize; 88 | CHAR RawMd5Hash[16]; 89 | 90 | BOOLEAN IsExecutable; 91 | ULONG32 Characteristics; 92 | } CACHED_SECTION_INFO, *PCACHED_SECTION_INFO; 93 | 94 | typedef struct _PDB_INFO { 95 | GUID Guid; 96 | ULONG Age; 97 | CHAR PdbName[MAX_PATH]; 98 | } PDB_INFO, *PPDB_INFO; 99 | 100 | typedef struct _LANGANDCODEPAGE { 101 | WORD wLanguage; 102 | WORD wCodePage; 103 | } LANGANDCODEPAGE, *PLANGANDCODEPAGE; 104 | 105 | typedef struct _FILE_VERSION { 106 | WCHAR ProductVersion[256]; 107 | WCHAR FileVersion[256]; 108 | WCHAR CompanyName[256]; 109 | WCHAR FileDescription[256]; 110 | } FILE_VERSION, *PFILE_VERSION; 111 | 112 | typedef struct _ADDRESS_INFO { 113 | ULONG64 Address; 114 | HOOK_TYPE HookType; 115 | BOOL IsTablePatched; 116 | } ADDRESS_INFO, *PADDRESS_INFO; 117 | 118 | typedef struct _IMPORT_INFO { 119 | ADDRESS_INFO AddressInfo; 120 | CHAR Name[MAX_PATH]; 121 | } IMPORT_INFO, *PIMPORT_INFO; 122 | 123 | typedef struct _IMPORT_DESCRIPTOR { 124 | vector m_Imports; 125 | CHAR DllName[MAX_PATH]; 126 | } IMPORT_DESCRIPTOR, *PIMPORT_DESCRIPTOR; 127 | 128 | typedef struct _EXPORT_INFO { 129 | ADDRESS_INFO AddressInfo; 130 | ULONG Index; 131 | ULONG Ordinal; 132 | CHAR Name[128]; 133 | } EXPORT_INFO, *PEXPORT_INFO; 134 | 135 | ULONG64 m_ImageBase; 136 | ULONG m_ImageSize; 137 | 138 | BOOL m_IsPagedOut; 139 | BOOL m_IsSigned; 140 | 141 | vector m_CcSections; 142 | FILE_VERSION m_FileVersion; 143 | IMAGE_DATA m_Image; 144 | PDB_INFO m_PdbInfo; 145 | 146 | ULONG64 m_ObjectPtr; 147 | ULONG m_NumberOfHookedAPIs; 148 | 149 | // 150 | // Imports 151 | // 152 | 153 | vector m_ImportDescriptors; 154 | ULONG m_NumberOfImportedFunctions; 155 | 156 | // 157 | // Exports 158 | // 159 | 160 | vector m_Exports; 161 | ULONG m_NumberOfExportedFunctions; 162 | 163 | VOID GetAddressInfo( 164 | _In_ ULONG64 Address, 165 | _Inout_ PADDRESS_INFO AddressInfo 166 | ); 167 | 168 | PVOID 169 | RtlGetRessourceData( 170 | _In_ ULONG Name, 171 | _In_ ULONG Type 172 | ); 173 | 174 | BOOLEAN 175 | RtlGetImports( 176 | vector &DllList 177 | ); 178 | 179 | BOOLEAN 180 | RtlGetExports( 181 | VOID 182 | ); 183 | 184 | BOOLEAN 185 | InitImage( 186 | VOID 187 | ); 188 | 189 | BOOLEAN 190 | RtlGetSections( 191 | VOID 192 | ); 193 | 194 | BOOLEAN 195 | RtlGetFileVersion( 196 | VOID 197 | ); 198 | 199 | BOOLEAN 200 | RtlGetPdbInfo( 201 | VOID 202 | ); 203 | 204 | BOOLEAN 205 | GetInfoFull( 206 | VOID 207 | ); 208 | 209 | BOOL 210 | IsAddressValid( 211 | _In_ ULONG_PTR Address 212 | ); 213 | 214 | void Free(void); 215 | 216 | protected: 217 | void Clear(void) 218 | { 219 | Free(); 220 | 221 | m_Image.Initialized = FALSE; 222 | m_ImageSize = 0; 223 | m_ImageBase = 0ULL; 224 | } 225 | }; 226 | 227 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Drivers.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Ob.cpp 23 | 24 | Abstract: 25 | 26 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | --*/ 36 | 37 | #include "stdafx.h" 38 | #include "SwishDbgExt.h" 39 | 40 | VOID 41 | MsDriverObject::Set( 42 | ) 43 | /*++ 44 | 45 | Routine Description: 46 | 47 | Description. 48 | 49 | Arguments: 50 | 51 | - 52 | 53 | Return Value: 54 | 55 | None. 56 | 57 | --*/ 58 | { 59 | ULONG64 MajorFunction[_countof(mm_DriverInfo.MajorFunction)]; 60 | 61 | try { 62 | 63 | m_ObjectPtr = m_TypedObject.GetPtr(); 64 | 65 | mm_DriverInfo.DeviceObject = m_TypedObject.Field("DeviceObject").GetPtr(); 66 | mm_DriverInfo.DriverStart = m_TypedObject.Field("DriverStart").GetPtr(); 67 | mm_DriverInfo.DriverSize = m_TypedObject.Field("DriverSize").GetUlong(); 68 | mm_DriverInfo.DriverSection = m_TypedObject.Field("DriverSection").GetPtr(); 69 | mm_DriverInfo.DriverExtension = m_TypedObject.Field("DriverExtension").GetPtr(); 70 | mm_DriverInfo.DriverInit = m_TypedObject.Field("DriverInit").GetPtr(); 71 | mm_DriverInfo.DriverStartIo = m_TypedObject.Field("DriverStartIo").GetPtr(); 72 | mm_DriverInfo.DriverUnload = m_TypedObject.Field("DriverUnload").GetPtr(); 73 | 74 | ExtRemoteTypedEx::GetUnicodeString(m_TypedObject.Field("DriverName"), (PWSTR)&mm_DriverInfo.DriverName, sizeof(mm_DriverInfo.DriverName)); 75 | 76 | if (mm_DriverInfo.DriverSection) { 77 | 78 | ExtRemoteTyped LdrData("(nt!_LDR_DATA_TABLE_ENTRY *)@$extin", mm_DriverInfo.DriverSection); 79 | 80 | ExtRemoteTypedEx::GetUnicodeString(LdrData.Field("FullDllName"), (PWSTR)&mm_DriverInfo.FullDllName, sizeof(mm_DriverInfo.FullDllName)); 81 | ExtRemoteTypedEx::GetUnicodeString(LdrData.Field("BaseDllName"), (PWSTR)&mm_DriverInfo.DllName, sizeof(mm_DriverInfo.DllName)); 82 | 83 | m_ImageBase = LdrData.Field("DllBase").GetPtr(); 84 | m_ImageSize = LdrData.Field("SizeOfImage").GetUlong(); 85 | } 86 | 87 | if (m_TypedObject.Field("FastIoDispatch").GetPtr()) { 88 | 89 | ExtRemoteTyped FastIoDispatch = m_TypedObject.Field("FastIoDispatch"); 90 | 91 | GetAddressInfo(FastIoDispatch.Field("FastIoCheckIfPossible").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoCheckIfPossible); 92 | GetAddressInfo(FastIoDispatch.Field("FastIoRead").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoRead); 93 | GetAddressInfo(FastIoDispatch.Field("FastIoWrite").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoWrite); 94 | GetAddressInfo(FastIoDispatch.Field("FastIoQueryBasicInfo").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoQueryBasicInfo); 95 | GetAddressInfo(FastIoDispatch.Field("FastIoQueryStandardInfo").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoQueryStandardInfo); 96 | GetAddressInfo(FastIoDispatch.Field("FastIoLock").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoLock); 97 | GetAddressInfo(FastIoDispatch.Field("FastIoUnlockSingle").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoUnlockSingle); 98 | GetAddressInfo(FastIoDispatch.Field("FastIoUnlockAll").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoUnlockAll); 99 | GetAddressInfo(FastIoDispatch.Field("FastIoUnlockAllByKey").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoUnlockAllByKey); 100 | GetAddressInfo(FastIoDispatch.Field("FastIoDeviceControl").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoDeviceControl); 101 | GetAddressInfo(FastIoDispatch.Field("AcquireFileForNtCreateSection").GetPtr(), &mm_DriverInfo.FastIoDispatch.AcquireFileForNtCreateSection); 102 | GetAddressInfo(FastIoDispatch.Field("ReleaseFileForNtCreateSection").GetPtr(), &mm_DriverInfo.FastIoDispatch.ReleaseFileForNtCreateSection); 103 | GetAddressInfo(FastIoDispatch.Field("FastIoDetachDevice").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoDetachDevice); 104 | GetAddressInfo(FastIoDispatch.Field("FastIoQueryNetworkOpenInfo").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoQueryNetworkOpenInfo); 105 | GetAddressInfo(FastIoDispatch.Field("AcquireForModWrite").GetPtr(), &mm_DriverInfo.FastIoDispatch.AcquireForModWrite); 106 | GetAddressInfo(FastIoDispatch.Field("MdlRead").GetPtr(), &mm_DriverInfo.FastIoDispatch.MdlRead); 107 | GetAddressInfo(FastIoDispatch.Field("MdlReadComplete").GetPtr(), &mm_DriverInfo.FastIoDispatch.MdlReadComplete); 108 | GetAddressInfo(FastIoDispatch.Field("PrepareMdlWrite").GetPtr(), &mm_DriverInfo.FastIoDispatch.PrepareMdlWrite); 109 | GetAddressInfo(FastIoDispatch.Field("MdlWriteComplete").GetPtr(), &mm_DriverInfo.FastIoDispatch.MdlWriteComplete); 110 | GetAddressInfo(FastIoDispatch.Field("FastIoReadCompressed").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoReadCompressed); 111 | GetAddressInfo(FastIoDispatch.Field("FastIoWriteCompressed").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoWriteCompressed); 112 | GetAddressInfo(FastIoDispatch.Field("MdlReadCompleteCompressed").GetPtr(), &mm_DriverInfo.FastIoDispatch.MdlReadCompleteCompressed); 113 | GetAddressInfo(FastIoDispatch.Field("MdlWriteCompleteCompressed").GetPtr(), &mm_DriverInfo.FastIoDispatch.MdlWriteCompleteCompressed); 114 | GetAddressInfo(FastIoDispatch.Field("FastIoQueryOpen").GetPtr(), &mm_DriverInfo.FastIoDispatch.FastIoQueryOpen); 115 | GetAddressInfo(FastIoDispatch.Field("ReleaseForModWrite").GetPtr(), &mm_DriverInfo.FastIoDispatch.ReleaseForModWrite); 116 | GetAddressInfo(FastIoDispatch.Field("AcquireForCcFlush").GetPtr(), &mm_DriverInfo.FastIoDispatch.AcquireForCcFlush); 117 | GetAddressInfo(FastIoDispatch.Field("ReleaseForCcFlush").GetPtr(), &mm_DriverInfo.FastIoDispatch.ReleaseForCcFlush); 118 | } 119 | 120 | ReadPointersVirtual(_countof(MajorFunction), m_TypedObject.Field("MajorFunction").GetPointerTo().GetPtr(), MajorFunction); 121 | 122 | for (ULONG i = 0; i < _countof(mm_DriverInfo.MajorFunction); i++) { 123 | 124 | GetAddressInfo(MajorFunction[i], &mm_DriverInfo.MajorFunction[i]); 125 | } 126 | } 127 | catch (...) { 128 | 129 | } 130 | } 131 | 132 | MsDriverObject::~MsDriverObject( 133 | ) 134 | /*++ 135 | 136 | Routine Description: 137 | 138 | Description. 139 | 140 | Arguments: 141 | 142 | - 143 | 144 | Return Value: 145 | 146 | None. 147 | 148 | --*/ 149 | { 150 | Clear(); 151 | /* 152 | if (m_Image) 153 | { 154 | // free(m_Image); 155 | // m_Image = NULL; 156 | // http://stackoverflow.com/questions/9331561/why-does-my-classs-destructor-get-called-when-i-add-instances-to-a-vector 157 | // http://stackoverflow.com/questions/15277606/c-vector-of-objects-and-excessive-calls-to-destructor 158 | 159 | Clear(); 160 | } 161 | */ 162 | } 163 | 164 | 165 | vector 166 | GetDrivers( 167 | ) 168 | /*++ 169 | 170 | Routine Description: 171 | 172 | Description. 173 | 174 | Arguments: 175 | 176 | - 177 | 178 | Return Value: 179 | 180 | vector. 181 | 182 | --*/ 183 | { 184 | vector DriverObjects = ObOpenObjectDirectory(ObGetDriverObject()); 185 | vector Drivers; 186 | vector DllList; 187 | vector Nodes; 188 | ULONG64 Head = ExtNtOsInformation::GetKernelLoadedModuleListHead(); 189 | 190 | if (IsValid(Head)) { 191 | 192 | try { 193 | 194 | ModuleIterator Dlls(Head); 195 | 196 | for (Dlls.First(); !Dlls.IsDone(); Dlls.Next()) { 197 | 198 | MsDllObject DllObject = Dlls.Current(); 199 | 200 | if (find(Nodes.rbegin(), Nodes.rend(), DllObject.m_ImageBase) != Nodes.rend()) { 201 | 202 | break; 203 | } 204 | 205 | Nodes.push_back(DllObject.m_ImageBase); 206 | 207 | DllList.push_back(DllObject); 208 | } 209 | } 210 | catch (...) { 211 | 212 | } 213 | } 214 | 215 | for each (HANDLE_OBJECT DriverObject in DriverObjects) { 216 | 217 | MsDriverObject Driver(DriverObject.ObjectPtr); 218 | 219 | Driver.GetInfoFull(); 220 | Driver.RtlGetExports(); 221 | Driver.RtlGetImports(DllList); 222 | 223 | Drivers.push_back(Driver); 224 | } 225 | 226 | DriverObjects = ObOpenObjectDirectory(ObGetFileSystemObject()); 227 | 228 | for each (HANDLE_OBJECT DriverObject in DriverObjects) { 229 | 230 | if (0 == wcscmp(DriverObject.Type, L"Driver")) { 231 | 232 | MsDriverObject Driver(DriverObject.ObjectPtr); 233 | 234 | Driver.GetInfoFull(); 235 | Driver.RtlGetExports(); 236 | Driver.RtlGetImports(DllList); 237 | 238 | Drivers.push_back(Driver); 239 | } 240 | } 241 | 242 | return Drivers; 243 | } 244 | -------------------------------------------------------------------------------- /SwishDbgExt/Drivers.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Driver.h 23 | 24 | Abstract: 25 | 26 | - ExtRemoteData Pointer(GetExpression("'htsxxxxx!gRingBuffer"), m_PtrSize); // <<< works just fine 27 | 28 | 29 | 30 | Environment: 31 | 32 | - User mode 33 | 34 | Revision History: 35 | 36 | - Matthieu Suiche 37 | 38 | --*/ 39 | 40 | #ifndef __DRIVERS_H__ 41 | #define __DRIVERS_H__ 42 | 43 | class MsDriverObject : public MsPEImageFile { 44 | public: 45 | typedef struct _FAST_IO_DISPATCH 46 | { 47 | ADDRESS_INFO FastIoCheckIfPossible; 48 | ADDRESS_INFO FastIoRead; 49 | ADDRESS_INFO FastIoWrite; 50 | ADDRESS_INFO FastIoQueryBasicInfo; 51 | ADDRESS_INFO FastIoQueryStandardInfo; 52 | ADDRESS_INFO FastIoLock; 53 | ADDRESS_INFO FastIoUnlockSingle; 54 | ADDRESS_INFO FastIoUnlockAll; 55 | ADDRESS_INFO FastIoUnlockAllByKey; 56 | ADDRESS_INFO FastIoDeviceControl; 57 | ADDRESS_INFO AcquireFileForNtCreateSection; 58 | ADDRESS_INFO ReleaseFileForNtCreateSection; 59 | ADDRESS_INFO FastIoDetachDevice; 60 | ADDRESS_INFO FastIoQueryNetworkOpenInfo; 61 | ADDRESS_INFO AcquireForModWrite; 62 | ADDRESS_INFO MdlRead; 63 | ADDRESS_INFO MdlReadComplete; 64 | ADDRESS_INFO PrepareMdlWrite; 65 | ADDRESS_INFO MdlWriteComplete; 66 | ADDRESS_INFO FastIoReadCompressed; 67 | ADDRESS_INFO FastIoWriteCompressed; 68 | ADDRESS_INFO MdlReadCompleteCompressed; 69 | ADDRESS_INFO MdlWriteCompleteCompressed; 70 | ADDRESS_INFO FastIoQueryOpen; 71 | ADDRESS_INFO ReleaseForModWrite; 72 | ADDRESS_INFO AcquireForCcFlush; 73 | ADDRESS_INFO ReleaseForCcFlush; 74 | } FAST_IO_DISPATCH, *PFAST_IO_DISPATCH; 75 | 76 | typedef struct _DRIVER_INFO { 77 | IMAGE_TYPE ImageType; // Always in first position. 78 | 79 | ULONG64 DeviceObject; 80 | ULONG64 DriverStart; 81 | ULONG DriverSize; 82 | ULONG64 DriverSection; 83 | ULONG64 DriverExtension; 84 | 85 | WCHAR DriverName[MAX_PATH]; 86 | 87 | FAST_IO_DISPATCH FastIoDispatch; 88 | ULONG64 DriverInit; 89 | ULONG64 DriverStartIo; 90 | ULONG64 DriverUnload; 91 | 92 | ADDRESS_INFO MajorFunction[28]; 93 | 94 | ULONG64 LoadTime; 95 | WCHAR DllName[MAX_PATH + 1]; 96 | WCHAR FullDllName[MAX_PATH + 1]; 97 | 98 | } DRIVER_INFO, *PDRIVER_INFO; 99 | 100 | MsDriverObject() 101 | { 102 | Clear(); 103 | } 104 | 105 | MsDriverObject(ULONG64 Object) 106 | { 107 | Clear(); 108 | 109 | m_TypedObject = ExtRemoteTyped("(nt!_DRIVER_OBJECT *)@$extin", Object); 110 | Set(); 111 | } 112 | 113 | MsDriverObject(ExtRemoteTyped Object) 114 | { 115 | Clear(); 116 | m_TypedObject = Object; 117 | Set(); 118 | } 119 | ~MsDriverObject(); 120 | 121 | VOID Set(); 122 | 123 | BOOLEAN Init(VOID); 124 | 125 | DRIVER_INFO mm_DriverInfo; 126 | 127 | ExtRemoteTyped m_TypedObject; 128 | }; 129 | 130 | vector 131 | GetDrivers( 132 | ); 133 | 134 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/EngExpCppEx.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - EngExtCppEx.h 23 | 24 | Abstract: 25 | 26 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 27 | 28 | 29 | Environment: 30 | 31 | - User mode 32 | 33 | Revision History: 34 | 35 | - Matthieu Suiche 36 | 37 | --*/ 38 | 39 | 40 | typedef enum _HOOK_TYPE { 41 | NoHook = 0, 42 | JmpHook = 1, 43 | CallHook = 2, 44 | MovEaxEdxCallPtrHook = 3, 45 | NtSyscallHook = MovEaxEdxCallPtrHook, 46 | PushRetHook = 4, 47 | JmpDwordPtrHook = 5, 48 | CallDwordPtrHook = 6 49 | } HOOK_TYPE; 50 | 51 | BOOLEAN 52 | IsValid( 53 | ULONG64 Pointer 54 | ); 55 | 56 | PSTR 57 | GetNameByOffset( 58 | _In_ ULONG64 Offset, 59 | _Out_writes_(Length) PSTR Buffer, 60 | _In_ ULONG Length 61 | ); 62 | 63 | HOOK_TYPE 64 | GetPointerHookType( 65 | _In_ ULONG64 Pointer 66 | ); 67 | 68 | ULONG64 69 | GetFastRefPointer( 70 | ULONG64 Pointer 71 | ); 72 | 73 | ULONG 74 | ReadPointersVirtual( 75 | ULONG PointerCount, 76 | ULONG64 Pointer, 77 | PULONG64 OutPtrTable 78 | ); 79 | 80 | class ExtRemoteTypedEx 81 | { 82 | public: 83 | typedef struct _UNICODE_STRING { 84 | USHORT Length; 85 | USHORT MaxLength; 86 | ULONG64 Buffer; 87 | } UNICODE_STRING, *PUNICODE_STRING; 88 | 89 | static LPWSTR GetUnicodeString( 90 | ExtRemoteTyped TypedObject, 91 | _Out_writes_opt_(BufferChars) PWSTR Buffer, 92 | _In_ ULONG MaxChars 93 | ); 94 | 95 | static LPWSTR 96 | ExtRemoteTypedEx::GetUnicodeString2( 97 | ExtRemoteTyped TypedObject 98 | ); 99 | 100 | static LPWSTR 101 | GetUnicodeStringEx( 102 | ULONG64 UntypedObject, 103 | _Out_writes_opt_(BufferChars) PWSTR Buffer, 104 | _In_ ULONG MaxChars 105 | ); 106 | 107 | static LPWSTR ExtRemoteTypedEx::GetString( 108 | ULONG64 Address, 109 | _Out_writes_opt_(BufferChars) LPWSTR Buffer, 110 | _In_ ULONG MaxChars 111 | ); 112 | 113 | static ULONG64 GetPointer( 114 | ULONG64 Address 115 | ); 116 | 117 | static ULONG GetPointerSize( 118 | ); 119 | 120 | static HRESULT ReadVirtual( 121 | ULONG64 BaseAddress, 122 | PVOID Buffer, 123 | ULONG BufferSize, 124 | _Out_ PULONG OutBytesRead 125 | ); 126 | 127 | static 128 | HRESULT 129 | ReadImageMemory( 130 | _In_ ULONG64 BaseAddress, 131 | _Out_writes_(BufferSize) PVOID Buffer, 132 | _In_ ULONG BufferSize, 133 | _Out_opt_ PULONG OutBytesRead 134 | ); 135 | 136 | private: 137 | }; -------------------------------------------------------------------------------- /SwishDbgExt/Lxss.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2017 Comae Technologies 5 | Copyright (C) 2017 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Lxss.h 23 | 24 | Abstract: 25 | 26 | - 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | #ifndef __LXSS_H__ 39 | #define __LXSS_H__ 40 | 41 | VOID 42 | GetLX( 43 | VOID 44 | ); 45 | 46 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Md5.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Md5.c 23 | 24 | Abstract: 25 | 26 | - 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | #include "stdafx.h" 39 | #include "SwishDbgExt.h" 40 | 41 | 42 | /* F, G and H are basic MD5 functions: selection, majority, parity */ 43 | #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 44 | #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 45 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 46 | #define I(x, y, z) ((y) ^ ((x) | (~z))) 47 | 48 | /* ROTATE_LEFT rotates x left n bits */ 49 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 50 | 51 | /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ 52 | /* Rotation is separate from addition to prevent recomputation */ 53 | #define FF(a, b, c, d, x, s, ac) \ 54 | {(a) += F ((b), (c), (d)) + (x) + (UINT32)(ac); \ 55 | (a) = ROTATE_LEFT ((a), (s)); \ 56 | (a) += (b); \ 57 | } 58 | #define GG(a, b, c, d, x, s, ac) \ 59 | {(a) += G ((b), (c), (d)) + (x) + (UINT32)(ac); \ 60 | (a) = ROTATE_LEFT ((a), (s)); \ 61 | (a) += (b); \ 62 | } 63 | #define HH(a, b, c, d, x, s, ac) \ 64 | {(a) += H ((b), (c), (d)) + (x) + (UINT32)(ac); \ 65 | (a) = ROTATE_LEFT ((a), (s)); \ 66 | (a) += (b); \ 67 | } 68 | #define II(a, b, c, d, x, s, ac) \ 69 | {(a) += I ((b), (c), (d)) + (x) + (UINT32)(ac); \ 70 | (a) = ROTATE_LEFT ((a), (s)); \ 71 | (a) += (b); \ 72 | } 73 | 74 | /* 75 | ********************************************************************** 76 | ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** 77 | ** ** 78 | ** License to copy and use this software is granted provided that ** 79 | ** it is identified as the "RSA Data Security, Inc. MD5 Message ** 80 | ** Digest Algorithm" In all material mentionIng or referencIng this ** 81 | ** software or this function. ** 82 | ** ** 83 | ** License is also granted to make and use derivative works ** 84 | ** provided that such works are identified as "derived from the RSA ** 85 | ** Data Security, Inc. MD5 Message Digest Algorithm" In all ** 86 | ** material mentionIng or referencIng the derived work. ** 87 | ** ** 88 | ** RSA Data Security, Inc. makes no representations concernIng ** 89 | ** either the merchantability of this software or the suitability ** 90 | ** of this software for any particular purpose. It is provided "as ** 91 | ** is" without express or implied warranty of any kInd. ** 92 | ** ** 93 | ** These notices must be retaIned In any copies of any part of this ** 94 | ** documentation and/or software. ** 95 | ********************************************************************** 96 | */ 97 | 98 | UCHAR PADDING[64] = { 99 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 100 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 102 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 103 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 104 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 105 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 106 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 107 | }; 108 | 109 | /* Basic MD5 step. Transform Buffer based on In. 110 | */ 111 | VOID 112 | Transform( 113 | _Inout_ ULONG *Buffer, 114 | _Inout_ ULONG *In 115 | ) 116 | /*++ 117 | 118 | Routine Description: 119 | 120 | Description. 121 | 122 | Arguments: 123 | 124 | Buffer - 125 | In - 126 | 127 | Return Value: 128 | 129 | VOID. 130 | 131 | --*/ 132 | { 133 | ULONG a = Buffer[0], b = Buffer[1], c = Buffer[2], d = Buffer[3]; 134 | 135 | /* Round 1 */ 136 | #define S11 7 137 | #define S12 12 138 | #define S13 17 139 | #define S14 22 140 | FF ( a, b, c, d, In[ 0], S11, 3614090360); /* 1 */ 141 | FF ( d, a, b, c, In[ 1], S12, 3905402710); /* 2 */ 142 | FF ( c, d, a, b, In[ 2], S13, 606105819); /* 3 */ 143 | FF ( b, c, d, a, In[ 3], S14, 3250441966); /* 4 */ 144 | FF ( a, b, c, d, In[ 4], S11, 4118548399); /* 5 */ 145 | FF ( d, a, b, c, In[ 5], S12, 1200080426); /* 6 */ 146 | FF ( c, d, a, b, In[ 6], S13, 2821735955); /* 7 */ 147 | FF ( b, c, d, a, In[ 7], S14, 4249261313); /* 8 */ 148 | FF ( a, b, c, d, In[ 8], S11, 1770035416); /* 9 */ 149 | FF ( d, a, b, c, In[ 9], S12, 2336552879); /* 10 */ 150 | FF ( c, d, a, b, In[10], S13, 4294925233); /* 11 */ 151 | FF ( b, c, d, a, In[11], S14, 2304563134); /* 12 */ 152 | FF ( a, b, c, d, In[12], S11, 1804603682); /* 13 */ 153 | FF ( d, a, b, c, In[13], S12, 4254626195); /* 14 */ 154 | FF ( c, d, a, b, In[14], S13, 2792965006); /* 15 */ 155 | FF ( b, c, d, a, In[15], S14, 1236535329); /* 16 */ 156 | 157 | /* Round 2 */ 158 | #define S21 5 159 | #define S22 9 160 | #define S23 14 161 | #define S24 20 162 | GG ( a, b, c, d, In[ 1], S21, 4129170786); /* 17 */ 163 | GG ( d, a, b, c, In[ 6], S22, 3225465664); /* 18 */ 164 | GG ( c, d, a, b, In[11], S23, 643717713); /* 19 */ 165 | GG ( b, c, d, a, In[ 0], S24, 3921069994); /* 20 */ 166 | GG ( a, b, c, d, In[ 5], S21, 3593408605); /* 21 */ 167 | GG ( d, a, b, c, In[10], S22, 38016083); /* 22 */ 168 | GG ( c, d, a, b, In[15], S23, 3634488961); /* 23 */ 169 | GG ( b, c, d, a, In[ 4], S24, 3889429448); /* 24 */ 170 | GG ( a, b, c, d, In[ 9], S21, 568446438); /* 25 */ 171 | GG ( d, a, b, c, In[14], S22, 3275163606); /* 26 */ 172 | GG ( c, d, a, b, In[ 3], S23, 4107603335); /* 27 */ 173 | GG ( b, c, d, a, In[ 8], S24, 1163531501); /* 28 */ 174 | GG ( a, b, c, d, In[13], S21, 2850285829); /* 29 */ 175 | GG ( d, a, b, c, In[ 2], S22, 4243563512); /* 30 */ 176 | GG ( c, d, a, b, In[ 7], S23, 1735328473); /* 31 */ 177 | GG ( b, c, d, a, In[12], S24, 2368359562); /* 32 */ 178 | 179 | /* Round 3 */ 180 | #define S31 4 181 | #define S32 11 182 | #define S33 16 183 | #define S34 23 184 | HH ( a, b, c, d, In[ 5], S31, 4294588738); /* 33 */ 185 | HH ( d, a, b, c, In[ 8], S32, 2272392833); /* 34 */ 186 | HH ( c, d, a, b, In[11], S33, 1839030562); /* 35 */ 187 | HH ( b, c, d, a, In[14], S34, 4259657740); /* 36 */ 188 | HH ( a, b, c, d, In[ 1], S31, 2763975236); /* 37 */ 189 | HH ( d, a, b, c, In[ 4], S32, 1272893353); /* 38 */ 190 | HH ( c, d, a, b, In[ 7], S33, 4139469664); /* 39 */ 191 | HH ( b, c, d, a, In[10], S34, 3200236656); /* 40 */ 192 | HH ( a, b, c, d, In[13], S31, 681279174); /* 41 */ 193 | HH ( d, a, b, c, In[ 0], S32, 3936430074); /* 42 */ 194 | HH ( c, d, a, b, In[ 3], S33, 3572445317); /* 43 */ 195 | HH ( b, c, d, a, In[ 6], S34, 76029189); /* 44 */ 196 | HH ( a, b, c, d, In[ 9], S31, 3654602809); /* 45 */ 197 | HH ( d, a, b, c, In[12], S32, 3873151461); /* 46 */ 198 | HH ( c, d, a, b, In[15], S33, 530742520); /* 47 */ 199 | HH ( b, c, d, a, In[ 2], S34, 3299628645); /* 48 */ 200 | 201 | /* Round 4 */ 202 | #define S41 6 203 | #define S42 10 204 | #define S43 15 205 | #define S44 21 206 | II ( a, b, c, d, In[ 0], S41, 4096336452); /* 49 */ 207 | II ( d, a, b, c, In[ 7], S42, 1126891415); /* 50 */ 208 | II ( c, d, a, b, In[14], S43, 2878612391); /* 51 */ 209 | II ( b, c, d, a, In[ 5], S44, 4237533241); /* 52 */ 210 | II ( a, b, c, d, In[12], S41, 1700485571); /* 53 */ 211 | II ( d, a, b, c, In[ 3], S42, 2399980690); /* 54 */ 212 | II ( c, d, a, b, In[10], S43, 4293915773); /* 55 */ 213 | II ( b, c, d, a, In[ 1], S44, 2240044497); /* 56 */ 214 | II ( a, b, c, d, In[ 8], S41, 1873313359); /* 57 */ 215 | II ( d, a, b, c, In[15], S42, 4264355552); /* 58 */ 216 | II ( c, d, a, b, In[ 6], S43, 2734768916); /* 59 */ 217 | II ( b, c, d, a, In[13], S44, 1309151649); /* 60 */ 218 | II ( a, b, c, d, In[ 4], S41, 4149444226); /* 61 */ 219 | II ( d, a, b, c, In[11], S42, 3174756917); /* 62 */ 220 | II ( c, d, a, b, In[ 2], S43, 718787259); /* 63 */ 221 | II ( b, c, d, a, In[ 9], S44, 3951481745); /* 64 */ 222 | 223 | Buffer[0] += a; 224 | Buffer[1] += b; 225 | Buffer[2] += c; 226 | Buffer[3] += d; 227 | } 228 | 229 | VOID 230 | MD5Init( 231 | _Inout_ PMD5_CONTEXT Md5Context 232 | ) 233 | /*++ 234 | 235 | Routine Description: 236 | 237 | Description. 238 | 239 | Arguments: 240 | 241 | Md5Context - 242 | 243 | Return Value: 244 | 245 | VOID. 246 | 247 | --*/ 248 | { 249 | Md5Context->i[0] = Md5Context->i[1] = (UINT32)0; 250 | 251 | /* Load magic Initialization constants. 252 | */ 253 | Md5Context->Buffer[0] = (UINT32)0x67452301; 254 | Md5Context->Buffer[1] = (UINT32)0xefcdab89; 255 | Md5Context->Buffer[2] = (UINT32)0x98badcfe; 256 | Md5Context->Buffer[3] = (UINT32)0x10325476; 257 | } 258 | 259 | VOID 260 | MD5Update( 261 | _Inout_ PMD5_CONTEXT Md5Context, 262 | _In_ PUCHAR InBuf, 263 | _In_ ULONG InLen 264 | ) 265 | /*++ 266 | 267 | Routine Description: 268 | 269 | Description. 270 | 271 | Arguments: 272 | 273 | Md5Context - 274 | InBuf - 275 | InLen - 276 | 277 | Return Value: 278 | 279 | ULONG64. 280 | 281 | --*/ 282 | { 283 | ULONG In[16]; 284 | int Mdi; 285 | ULONG i, ii; 286 | 287 | /* compute number of bytes mod 64 */ 288 | Mdi = (int)((Md5Context->i[0] >> 3) & 0x3F); 289 | 290 | /* update number of bits */ 291 | if ((Md5Context->i[0] + ((ULONG)InLen << 3)) < Md5Context->i[0]) 292 | Md5Context->i[1]++; 293 | Md5Context->i[0] += ((ULONG)InLen << 3); 294 | Md5Context->i[1] += ((ULONG)InLen >> 29); 295 | 296 | while (InLen--) 297 | { 298 | /* add new character to Bufferfer, Increment Mdi */ 299 | Md5Context->In[Mdi++] = *InBuf++; 300 | 301 | /* transform if necessary */ 302 | if (Mdi == 0x40) 303 | { 304 | for (i = 0, ii = 0; i < 16; i++, ii += 4) 305 | In[i] = (((ULONG)Md5Context->In[ii+3]) << 24) | 306 | (((ULONG)Md5Context->In[ii+2]) << 16) | 307 | (((ULONG)Md5Context->In[ii+1]) << 8) | 308 | ((ULONG)Md5Context->In[ii]); 309 | Transform (Md5Context->Buffer, In); 310 | Mdi = 0; 311 | } 312 | } 313 | } 314 | 315 | VOID 316 | MD5Final( 317 | _Inout_ MD5_CONTEXT *Md5Context 318 | ) 319 | /*++ 320 | 321 | Routine Description: 322 | 323 | Description. 324 | 325 | Arguments: 326 | 327 | Md5Context - 328 | 329 | Return Value: 330 | 331 | VOID. 332 | 333 | --*/ 334 | { 335 | ULONG In[16]; 336 | int Mdi; 337 | ULONG i, ii; 338 | ULONG PadLen; 339 | 340 | /* save number of bits */ 341 | In[14] = Md5Context->i[0]; 342 | In[15] = Md5Context->i[1]; 343 | 344 | /* compute number of bytes mod 64 */ 345 | Mdi = (int)((Md5Context->i[0] >> 3) & 0x3F); 346 | 347 | /* pad out to 56 mod 64 */ 348 | PadLen = (Mdi < 56) ? (56 - Mdi) : (120 - Mdi); 349 | MD5Update (Md5Context, PADDING, PadLen); 350 | 351 | /* append length In bits and transform */ 352 | for (i = 0, ii = 0; i < 14; i++, ii += 4) 353 | In[i] = (((ULONG)Md5Context->In[ii+3]) << 24) | 354 | (((ULONG)Md5Context->In[ii+2]) << 16) | 355 | (((ULONG)Md5Context->In[ii+1]) << 8) | 356 | ((ULONG)Md5Context->In[ii]); 357 | Transform (Md5Context->Buffer, In); 358 | 359 | /* store Bufferfer In Digest */ 360 | for (i = 0, ii = 0; i < 4; i++, ii += 4) 361 | { 362 | Md5Context->Digest[ii] = (UCHAR)(Md5Context->Buffer[i] & 0xFF); 363 | Md5Context->Digest[ii+1] = 364 | (UCHAR)((Md5Context->Buffer[i] >> 8) & 0xFF); 365 | Md5Context->Digest[ii+2] = 366 | (UCHAR)((Md5Context->Buffer[i] >> 16) & 0xFF); 367 | Md5Context->Digest[ii+3] = 368 | (UCHAR)((Md5Context->Buffer[i] >> 24) & 0xFF); 369 | } 370 | } -------------------------------------------------------------------------------- /SwishDbgExt/Md5.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Md5.h 23 | 24 | Abstract: 25 | 26 | - ExtRemoteData Pointer(GetExpression("'htsxxxxx!gRingBuffer"), m_PtrSize); // <<< works just fine 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | 39 | #ifndef __MD5_H__ 40 | #define __MD5_H__ 41 | 42 | // 43 | // Data structure for MD5 (Message Digest) computation 44 | // 45 | typedef struct _MD5_CONTEXT { 46 | ULONG i[2]; /* number of _bits_ handled mod 2^64 */ 47 | ULONG Buffer[4]; /* scratch Bufferfer */ 48 | UCHAR In[64]; /* Input Bufferfer */ 49 | UCHAR Digest[16]; /* actual Digest after MD5FInal call */ 50 | } MD5_CONTEXT, *PMD5_CONTEXT; 51 | 52 | void 53 | MD5Init( 54 | MD5_CONTEXT *Md5Context 55 | ); 56 | 57 | void 58 | MD5Update( 59 | MD5_CONTEXT *Md5Context, 60 | unsigned char *InBuf, 61 | unsigned long InLen 62 | ); 63 | 64 | void 65 | MD5Final( 66 | MD5_CONTEXT *Md5Context 67 | ); 68 | 69 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Network.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Network.cpp 23 | 24 | - SMB 25 | 26 | Abstract: 27 | 28 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 29 | 30 | 31 | Environment: 32 | 33 | - User mode 34 | 35 | Revision History: 36 | 37 | - Matthieu Suiche 38 | 39 | --*/ 40 | 41 | // 42 | // TCPIP 43 | // SMB 44 | // NETBIOS 45 | // 46 | 47 | #include "stdafx.h" 48 | #include "SwishDbgExt.h" 49 | 50 | PSTR 51 | GetProtocolType( 52 | _In_ ULONG Type 53 | ) 54 | /*++ 55 | 56 | Routine Description: 57 | 58 | Description. 59 | 60 | Arguments: 61 | 62 | Type - 63 | 64 | Return Value: 65 | 66 | PSTR. 67 | 68 | --*/ 69 | { 70 | switch (Type) 71 | { 72 | case PROTOCOL_AH: 73 | return "AH"; 74 | break; 75 | case PROTOCOL_ESP: 76 | return "ESP"; 77 | break; 78 | case PROTOCOL_COMP: 79 | return "COMP"; 80 | break; 81 | case PROTOCOL_TCP: 82 | return "TCP"; 83 | break; 84 | case PROTOCOL_UDP: 85 | return "UDP"; 86 | break; 87 | case PROTOCOL_RSVP: 88 | return "RSVP"; 89 | break; 90 | case PROTOCOL_ICMP: 91 | return "ICMP"; 92 | break; 93 | } 94 | 95 | return "UKNWN"; 96 | } 97 | 98 | LPSTR 99 | GetTcbState( 100 | _In_ ULONG State 101 | ) 102 | /*++ 103 | 104 | Routine Description: 105 | 106 | Description. 107 | 108 | Arguments: 109 | 110 | State - 111 | 112 | Return Value: 113 | 114 | LPSTR. 115 | 116 | --*/ 117 | { 118 | LPSTR TcbState[] = { 119 | "CLOSED", 120 | "LISTEN", 121 | "SYN SENT", 122 | "SYN RCVD", 123 | "ESTABLISHED", 124 | "FIN WAIT1", 125 | "FIN WAIT2", 126 | "CLOSE WAIT", 127 | "CLOSING", 128 | "LACK ACK", 129 | "TIME WAIT", 130 | NULL 131 | }; 132 | 133 | if (State >= TcbMaximumState) return "UN"; 134 | 135 | return TcbState[State]; 136 | } 137 | 138 | vector 139 | GetSockets( 140 | ) 141 | /*++ 142 | 143 | Routine Description: 144 | 145 | Description. 146 | 147 | Arguments: 148 | 149 | - 150 | 151 | Return Value: 152 | 153 | vector. 154 | 155 | --*/ 156 | { 157 | ULONG64 TableAddr; 158 | ULONG64 TableCountAddr; 159 | 160 | PULONG64 Table = NULL; 161 | ULONG TableCount; 162 | 163 | vector NetworkEntries; 164 | vector Nodes; 165 | 166 | ULONG ProcessorType; 167 | ULONG PlateformId, Major, Minor, ServicePackNumber; 168 | 169 | if (g_Ext->m_Control->GetActualProcessorType(&ProcessorType) != S_OK) goto CleanUp; 170 | if (g_Ext->m_Control->GetSystemVersion(&PlateformId, &Major, &Minor, NULL, NULL, NULL, &ServicePackNumber, NULL, NULL, NULL) != S_OK) goto CleanUp; 171 | 172 | // g_Ext->Dml("Major: %d, Minor: %d, ProcessorType = %x\n", Major, Minor, ProcessorType); 173 | 174 | if ((Minor < 6000) && (ProcessorType == IMAGE_FILE_MACHINE_I386)) 175 | { 176 | if (g_Ext->m_Symbols->GetOffsetByName("tcpip!AddrObjTable", &TableAddr) != S_OK) goto CleanUp; 177 | if (g_Ext->m_Symbols->GetOffsetByName("tcpip!AddrObjTableSize", &TableCountAddr) != S_OK) goto CleanUp; 178 | 179 | if (ReadPointersVirtual(1, TableAddr, &TableAddr) != S_OK) goto CleanUp; 180 | if (g_Ext->m_Data->ReadVirtual(TableCountAddr, &TableCount, sizeof(ULONG), NULL) != S_OK) goto CleanUp; 181 | 182 | Table = (PULONG64)malloc(TableCount * sizeof(ULONG64)); 183 | if (ReadPointersVirtual(TableCount, TableAddr, Table) != S_OK) goto CleanUp; 184 | 185 | for (UINT i = 0; i < TableCount; i += 1) 186 | { 187 | Network::OBJECT_ENTRY_X86 ObjectEntry = { 0 }; 188 | 189 | NETWORK_ENTRY NetworkEntry = { 0 }; 190 | 191 | if (Table[i] == 0) continue; 192 | 193 | if (g_Ext->m_Data->ReadVirtual(Table[i], &ObjectEntry, sizeof(Network::OBJECT_ENTRY_X86), NULL) != S_OK) goto CleanUp; 194 | 195 | NetworkEntry.ObjectPtr = Table[i]; 196 | NetworkEntry.CreationTime = ObjectEntry.CreationTime; 197 | 198 | NetworkEntry.ProcessId = ObjectEntry.ProcessId; 199 | NetworkEntry.Protocol = ObjectEntry.Protocol; 200 | 201 | NetworkEntry.Local.Port = (ObjectEntry.Port[1] << 8) | ObjectEntry.Port[0]; 202 | NetworkEntry.Local.IPv4_Addr[3] = ObjectEntry.LocalAddress[3]; 203 | NetworkEntry.Local.IPv4_Addr[2] = ObjectEntry.LocalAddress[2]; 204 | NetworkEntry.Local.IPv4_Addr[1] = ObjectEntry.LocalAddress[1]; 205 | NetworkEntry.Local.IPv4_Addr[0] = ObjectEntry.LocalAddress[0]; 206 | 207 | NetworkEntry.State = TcbListenState; 208 | 209 | NetworkEntries.push_back(NetworkEntry); 210 | } 211 | } 212 | else if (Minor > 6000) 213 | { 214 | if (g_Ext->m_Symbols->GetOffsetByName("tcpip!PartitionCount", &TableCountAddr) != S_OK) goto CleanUp; 215 | 216 | ReadPointer(GetExpression("tcpip!PartitionTable"), &TableAddr); 217 | if (!TableAddr) goto CleanUp; 218 | if (g_Ext->m_Data->ReadVirtual(TableCountAddr, &TableCount, sizeof(ULONG), NULL) != S_OK) goto CleanUp; 219 | 220 | ULONG ListEntrySize = GetTypeSize("nt!_LIST_ENTRY"); 221 | ULONG PoolHeaderSize = GetTypeSize("nt!_POOL_HEADER"); 222 | 223 | ExtRemoteUnTyped PartitionTable(TableAddr, "tcpip!_PARTITION_TABLE"); 224 | 225 | for (UINT PartitionIndex = 0; PartitionIndex < TableCount; PartitionIndex += 1) 226 | { 227 | NETWORK_ENTRY NetworkEntry = { 0 }; 228 | 229 | // g_Ext->Dml(" -> Partition[%d].HashTables = 0x%I64X\n", PartitionIndex, Partition->HashTables); 230 | ExtRemoteTyped HashTable("(nt!_RTL_DYNAMIC_HASH_TABLE *)@$extin", PartitionTable.ArrayElement(PartitionIndex).Field("HashTables").GetPtr()); 231 | 232 | ULONG64 Directory = HashTable.Field("Directory").GetPtr(); 233 | ULONG TableEntries = HashTable.Field("TableSize").GetUlong(); 234 | 235 | for (UINT i = 0; i < TableEntries; i += 1) 236 | { 237 | ExtRemoteTypedList List(Directory + i * ListEntrySize, "nt!_LIST_ENTRY", "Flink"); 238 | 239 | for (List.StartHead(); List.HasNode(); List.Next()) 240 | { 241 | ULONG64 Current = List.GetNodeOffset(); 242 | if (!IsValid(Current)) break; 243 | 244 | if (find(Nodes.rbegin(), Nodes.rend(), Current) != Nodes.rend()) { 245 | 246 | break; 247 | } 248 | 249 | Nodes.push_back(Current); 250 | 251 | ExtRemoteUnTyped Tcb(Current, "tcpip!_TCB"); 252 | Tcb.SubtractOffset("HashTableEntry"); 253 | 254 | ExtRemoteTyped PoolHeader("(nt!_POOL_HEADER *)@$extin", Tcb.GetPointerTo() - PoolHeaderSize); 255 | if (PoolHeader.Field("PoolTag").GetUlong() != 'EpcT') continue; 256 | 257 | //# Seen as 0x1f0 on Vista SP0, 0x1f8 on Vista SP2 and 0x210 on 7 258 | //# Seen as 0x320 on Win7 SP0 x64 259 | ULONG PoolSize; 260 | if (PoolHeader.Field("BlockSize").GetTypeSize() == sizeof(USHORT)) 261 | { 262 | PoolSize = PoolHeader.Field("BlockSize").GetUshort() * 0x10; 263 | } 264 | else 265 | { 266 | PoolSize = PoolHeader.Field("BlockSize").GetUlong() * 0x10; 267 | } 268 | 269 | if (PoolSize < 0x100) continue; 270 | 271 | ULONG64 SrcAddress = 0; 272 | ULONG64 DstAddress = 0; 273 | 274 | NetworkEntry.Protocol = PROTOCOL_TCP; 275 | NetworkEntry.State = Tcb.Field("State").GetUlong(); 276 | NetworkEntry.Local.Port = Tcb.Field("LocalPort").GetUshort(); 277 | NetworkEntry.Remote.Port = Tcb.Field("RemotePort").GetUshort(); 278 | 279 | DstAddress = Tcb.Field("Path", TRUE).Field("DestinationAddress").GetPtr(); 280 | if (IsValid(Tcb.Field("Path").GetPtr() && 281 | IsValid(Tcb.Field("Path", TRUE).Field("SourceAddress").GetPtr()) && 282 | IsValid(Tcb.Field("Path", TRUE).Field("SourceAddress", TRUE).Field("Identifier").GetPtr()) && 283 | IsValid(Tcb.Field("Path", TRUE).Field("SourceAddress", TRUE).Field("Identifier", TRUE).Field("Address").GetPtr()))) 284 | { 285 | SrcAddress = Tcb.Field("Path", TRUE).Field("SourceAddress", TRUE).Field("Identifier", TRUE).Field("Address").GetPtr(); 286 | } 287 | 288 | if (DstAddress && g_Ext->m_Data->ReadVirtual(DstAddress, &NetworkEntry.Remote.IPv4_Addr, sizeof(NetworkEntry.Remote.IPv4_Addr), NULL) != S_OK) goto CleanUp; 289 | if (SrcAddress && g_Ext->m_Data->ReadVirtual(SrcAddress, &NetworkEntry.Local.IPv4_Addr, sizeof(NetworkEntry.Local.IPv4_Addr), NULL) != S_OK) goto CleanUp; 290 | 291 | ExtRemoteTyped OwningProcess("(nt!_EPROCESS *)@$extin", Tcb.Field("OwningProcess").GetPtr()); 292 | 293 | NetworkEntry.ProcessId = OwningProcess.Field("UniqueProcessId").GetPtr(); 294 | OwningProcess.Field("ImageFileName").GetString((LPSTR)NetworkEntry.ProcessName, sizeof(NetworkEntry.ProcessName)); 295 | NetworkEntries.push_back(NetworkEntry); 296 | } 297 | } 298 | } 299 | } 300 | 301 | CleanUp: 302 | if (Table) free(Table); 303 | 304 | return NetworkEntries; 305 | } -------------------------------------------------------------------------------- /SwishDbgExt/Network.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Network.h 23 | 24 | Abstract: 25 | 26 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 27 | 28 | 29 | Environment: 30 | 31 | - User mode 32 | 33 | Revision History: 34 | 35 | - Matthieu Suiche 36 | 37 | --*/ 38 | 39 | #include "SwishDbgExt.h" 40 | 41 | #ifndef __NETWORK_H__ 42 | #define __NETWORK_H__ 43 | 44 | #define PROTOCOL_AH 51 45 | #define PROTOCOL_ESP 50 46 | #define PROTOCOL_COMP 108 47 | #define PROTOCOL_TCP 6 48 | #define PROTOCOL_UDP 17 49 | #define PROTOCOL_RSVP 46 50 | #define PROTOCOL_ICMP 1 51 | 52 | /* Dynamic hash table */ 53 | typedef struct _RTL_DYNAMIC_HASH_TABLE { 54 | ULONG Flags; 55 | ULONG Shift; 56 | ULONG TableSize; 57 | ULONG Pivot; 58 | ULONG DivisorMask; 59 | ULONG NumEntries; 60 | ULONG NonEmptyBuckets; 61 | ULONG NumEnumerators; 62 | ULONG64 Directory; 63 | } RTL_DYNAMIC_HASH_TABLE, *PRTL_DYNAMIC_HASH_TABLE; 64 | 65 | // 66 | // TCP_HASH_TABLES 67 | // 68 | //typedef struct DECLSPEC_CACHEALIGN _TCP_HASH_TABLES { 69 | // RTL_DYNAMIC_HASH_TABLE TcbTable; 70 | // RTL_DYNAMIC_HASH_TABLE TimeWaitTcbTable; 71 | // RTL_DYNAMIC_HASH_TABLE StandbyTcbTable; 72 | // RTL_DYNAMIC_HASH_TABLE SynTcbTable; 73 | //} TCP_HASH_TABLES, *PTCP_HASH_TABLES; 74 | 75 | // 76 | // TCP_PARTITION 77 | // 78 | // Maintains a partition of TCP connection hash-tables. 79 | // 80 | 81 | typedef struct _TCP_PARTITION { 82 | ULONG64 Lock; 83 | ULONG64 HashTables; 84 | ULONG64 IpHashTables; 85 | ULONG64 TimerWheels; 86 | LIST_ENTRY ReassemblyListHead; 87 | SINGLE_LIST_ENTRY DelayQueueEntry; 88 | } TCP_PARTITION, *PTCP_PARTITION; 89 | 90 | typedef enum { 91 | TcbClosedState, 92 | TcbListenState, 93 | TcbSynSentState, 94 | TcbSynRcvdState, 95 | TcbEstablishedState, 96 | TcbFinWait1State, 97 | TcbFinWait2State, 98 | TcbCloseWaitState, 99 | TcbClosingState, 100 | TcbLastAckState, 101 | TcbTimeWaitState, 102 | TcbMaximumState 103 | } TCB_STATE, *PTCB_STATE; 104 | 105 | typedef enum _NETIO_DISPATCH_ID { 106 | NetIoDispatchIpsec = 0, 107 | NetIoDispatchKfd = 1, 108 | NetIoDispatchAle = 2, 109 | NetIoDispatchEQOS = 3, 110 | NetIoDispatchIDP = 4, 111 | NetIoDispatchMax = 5 112 | } NETIO_DISPATCH_ID; 113 | 114 | typedef struct _NETWORK_ENTRY { 115 | ULONG64 ObjectPtr; 116 | 117 | ULONG Protocol; 118 | ULONG State; 119 | LARGE_INTEGER CreationTime; 120 | 121 | struct { 122 | union { 123 | UCHAR IPv6_Addr[16]; 124 | UCHAR IPv4_Addr[4]; 125 | }; 126 | ULONG Port; 127 | } Local; 128 | 129 | struct { 130 | union { 131 | UCHAR IPv6_Addr[16]; 132 | UCHAR IPv4_Addr[4]; 133 | }; 134 | ULONG Port; 135 | } Remote; 136 | 137 | union { 138 | ULONG64 ProcessObject; 139 | ULONG64 ProcessId; 140 | }; 141 | 142 | CHAR ProcessName[16]; 143 | } NETWORK_ENTRY, *PNETWORK_ENTRY; 144 | 145 | class Network { 146 | public: 147 | typedef struct _OBJECT_ENTRY_X86 { 148 | ULONG32 Next; 149 | UCHAR Unknow04[0x08]; 150 | UCHAR Unknow0C[0x20]; 151 | UCHAR LocalAddress[4]; 152 | UCHAR Port[2]; 153 | USHORT Protocol; 154 | UCHAR Unknow34[0x114]; 155 | ULONG ProcessId; 156 | UCHAR Unknow14C[0xC]; 157 | LARGE_INTEGER CreationTime; 158 | } OBJECT_ENTRY_X86, *POBJECT_ENTRY_X86; 159 | }; 160 | 161 | vector 162 | GetSockets( 163 | ); 164 | 165 | PSTR 166 | GetProtocolType( 167 | ULONG Type 168 | ); 169 | 170 | LPSTR 171 | GetTcbState( 172 | ULONG State 173 | ); 174 | 175 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/NtDef.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Credentials.h 23 | 24 | Abstract: 25 | 26 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | #ifndef __NTDEF_H__ 39 | #define __NTDEF_H__ 40 | 41 | /* 42 | typedef struct _LIST_ENTRY32 { 43 | ULONG32 Flink; 44 | ULONG32 Blink; 45 | } LIST_ENTRY32, *PLIST_ENTRY32; 46 | */ 47 | 48 | typedef struct _UNICODE_STRING32 { 49 | USHORT Length; 50 | USHORT MaximumLength; 51 | ULONG32 Buffer; 52 | } UNICODE_STRING32, *PUNICODE_STRING32; 53 | 54 | typedef struct _PEB_LDR_DATA32 55 | { 56 | /*0x000*/ ULONG32 Length; 57 | /*0x004*/ UINT8 Initialized; 58 | /*0x005*/ UINT8 _PADDING0_[0x3]; 59 | /*0x008*/ ULONG32 SsHandle; 60 | /*0x00C*/ LIST_ENTRY32 InLoadOrderModuleList; 61 | /*0x014*/ LIST_ENTRY32 InMemoryOrderModuleList; 62 | /*0x01C*/ LIST_ENTRY32 InInitializationOrderModuleList; 63 | /*0x024*/ ULONG32 EntryInProgress; 64 | /*0x028*/ UINT8 ShutdownInProgress; 65 | /*0x029*/ UINT8 _PADDING1_[0x3]; 66 | /*0x02C*/ ULONG32 ShutdownThreadId; 67 | } PEB_LDR_DATA, *PPEB_LDR_DATA; 68 | 69 | typedef struct _LDR_DATA_TABLE_ENTRY32 70 | { 71 | /*0x000*/ LIST_ENTRY32 InLoadOrderLinks; 72 | /*0x008*/ LIST_ENTRY32 InMemoryOrderLinks; 73 | /*0x010*/ LIST_ENTRY32 InInitializationOrderLinks; 74 | /*0x018*/ ULONG32 DllBase; 75 | /*0x01C*/ ULONG32 EntryPoint; 76 | /*0x020*/ ULONG32 SizeOfImage; 77 | /*0x024*/ UNICODE_STRING32 FullDllName; 78 | /*0x02C*/ UNICODE_STRING32 BaseDllName; 79 | /*0x034*/ ULONG32 Flags; 80 | /*0x038*/ UINT16 LoadCount; 81 | /*0x03A*/ UINT16 TlsIndex; 82 | union 83 | { 84 | LIST_ENTRY32 HashLinks; 85 | struct 86 | { 87 | ULONG32 SectionPointer; 88 | ULONG32 CheckSum; 89 | }; 90 | }; 91 | union 92 | { 93 | ULONG32 TimeDateStamp; 94 | ULONG32 LoadedImports; 95 | }; 96 | /*0x048*/ ULONG32 EntryPointActivationContext; 97 | /*0x04C*/ ULONG32 PatchInformation; 98 | /*0x050*/ LIST_ENTRY32 ForwarderLinks; // 2 elements, 0x8 bytes (sizeof) 99 | /*0x058*/ LIST_ENTRY32 ServiceTagLinks; // 2 elements, 0x8 bytes (sizeof) 100 | /*0x060*/ LIST_ENTRY32 StaticLinks; // 2 elements, 0x8 bytes (sizeof) 101 | /*0x068*/ ULONG32 ContextInformation; 102 | /*0x06C*/ ULONG32 OriginalBase; 103 | /*0x070*/ LARGE_INTEGER LoadTime; // 4 elements, 0x8 bytes (sizeof) 104 | } LDR_DATA_TABLE_ENTRY32, *PLDR_DATA_TABLE_ENTRY32; 105 | 106 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Objects.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Ob.cpp 23 | 24 | Abstract: 25 | 26 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 27 | 28 | 29 | Environment: 30 | 31 | - User mode 32 | 33 | Revision History: 34 | 35 | - Matthieu Suiche 36 | --*/ 37 | 38 | #include "stdafx.h" 39 | #include "SwishDbgExt.h" 40 | 41 | BOOLEAN ObTypeInit = FALSE; 42 | ExtRemoteTyped ObjTypeTable; 43 | 44 | 45 | BOOLEAN 46 | ObReadObject( 47 | _In_ ULONG64 Object, 48 | _Out_ PHANDLE_OBJECT HandleObj 49 | ) 50 | /*++ 51 | 52 | Routine Description: 53 | 54 | Description. 55 | 56 | Arguments: 57 | 58 | Object - 59 | HandleObj - 60 | 61 | Return Value: 62 | 63 | BOOLEAN. 64 | 65 | --*/ 66 | { 67 | BOOLEAN Result = FALSE; 68 | PWSTR ObjectName = NULL; 69 | WCHAR TypeStr[64] = {0}; 70 | ULONG BodyOffset = 0; 71 | 72 | GetFieldOffset("nt!_OBJECT_HEADER", "Body", &BodyOffset); 73 | 74 | try { 75 | 76 | ZeroMemory(HandleObj, sizeof(HANDLE_OBJECT)); 77 | 78 | if ((!Object) || (!IsValid(Object))) return FALSE; 79 | 80 | if (!ObTypeInit) 81 | { 82 | ObjTypeTable = ExtRemoteTyped("(nt!_OBJECT_TYPE **)@$extin", ObTypeIndexTableAddress); 83 | ObTypeInit = TRUE; 84 | } 85 | 86 | ULONG64 ObjHeaderAddr = Object - BodyOffset; 87 | 88 | if (!IsValid(ObjHeaderAddr)) return FALSE; 89 | 90 | ExtRemoteTyped ObjHeader("(nt!_OBJECT_HEADER *)@$extin", ObjHeaderAddr); 91 | HandleObj->ObjectPtr = Object; // ObjHeader.Field("Body").GetPointerTo().GetPtr(); 92 | 93 | if (ObjHeader.HasField("TypeIndex")) 94 | { 95 | BYTE HeaderCookie; 96 | 97 | HandleObj->ObjectTypeIndex = ObjHeader.Field("TypeIndex").GetUchar(); 98 | 99 | if (g_Ext->m_Data->ReadVirtual(ObHeaderCookieAddress, &HeaderCookie, sizeof(HeaderCookie), NULL) == S_OK) { 100 | 101 | HandleObj->ObjectTypeIndex = (((ObjHeaderAddr >> 8) & 0xff) ^ HandleObj->ObjectTypeIndex) ^ HeaderCookie; 102 | } 103 | 104 | ExtRemoteTypedEx::GetUnicodeString(ObjTypeTable.ArrayElement(HandleObj->ObjectTypeIndex).Field("Name"), TypeStr, sizeof(TypeStr)); 105 | 106 | StringCchCopyW(HandleObj->Type, _countof(HandleObj->Type), TypeStr); 107 | } 108 | else 109 | { 110 | if (!IsValid(ObjHeader.Field("Type").GetPtr())) goto CleanUp; 111 | 112 | ExtRemoteTypedEx::GetUnicodeString(ObjHeader.Field("Type").Field("Name"), TypeStr, sizeof(TypeStr)); 113 | 114 | StringCchCopyW(HandleObj->Type, _countof(HandleObj->Type), TypeStr); 115 | } 116 | 117 | if (_wcsicmp(TypeStr, L"File") == 0) 118 | { 119 | ExtRemoteTyped FileObject("(nt!_FILE_OBJECT *)@$extin", HandleObj->ObjectPtr); 120 | ObjectName = ExtRemoteTypedEx::GetUnicodeString2(FileObject.Field("FileName")); 121 | } 122 | else if (_wcsicmp(TypeStr, L"Driver") == 0) 123 | { 124 | ExtRemoteTyped DrvObject("(nt!_DRIVER_OBJECT *)@$extin", HandleObj->ObjectPtr); 125 | ObjectName = ExtRemoteTypedEx::GetUnicodeString2(DrvObject.Field("DriverName")); 126 | } 127 | else if (_wcsicmp(TypeStr, L"Process") == 0) 128 | { 129 | CHAR Buffer[MAX_PATH] = {0}; 130 | 131 | ExtRemoteTyped ProcessObj("(nt!_EPROCESS *)@$extin", HandleObj->ObjectPtr); 132 | 133 | ProcessObj.Field("ImageFileName").GetString(Buffer, ProcessObj.Field("ImageFileName").GetTypeSize()); 134 | 135 | if (strlen(Buffer)) { 136 | 137 | StringCchPrintfW(HandleObj->Name, _countof(HandleObj->Name), L"%S", Buffer); 138 | } 139 | } 140 | //else if (_wcsicmp(TypeStr, L"ALPC Port") == 0) 141 | //{ 142 | // // dt nt!_ALPC_PORT 143 | //} 144 | //else if (_wcsicmp(TypeStr, L"EtwRegistration") == 0) 145 | //{ 146 | // // dt nt!_ETW_? 147 | //} 148 | else if (_wcsicmp(TypeStr, L"Thread") == 0) 149 | { 150 | // dt nt!_ETHREAD 151 | } 152 | //else if (_wcsicmp(TypeStr, L"Event") == 0) 153 | //{ 154 | // // dt nt!_KTHREAD 155 | //} 156 | else if (_wcsicmp(TypeStr, L"Key") == 0) 157 | { 158 | ExtRemoteTyped KeyObject("(nt!_CM_KEY_BODY *)@$extin", HandleObj->ObjectPtr); 159 | HandleObj->ObjectKcb = KeyObject.Field("KeyControlBlock").GetPtr(); 160 | ObjectName = RegGetKeyName(HandleObj->ObjectKcb); 161 | // dt nt!_CM_KEY_BODY -> nt!_CM_KEY_CONTROL_BLOCK 162 | } 163 | else 164 | { 165 | ULONG Offset = 0; 166 | UCHAR InfoMask = 0; 167 | 168 | if (ObjHeader.HasField("InfoMask")) 169 | { 170 | InfoMask = ObjHeader.Field("InfoMask").GetUchar(); 171 | 172 | if (InfoMask & OBP_NAME_INFO_BIT) 173 | { 174 | if (InfoMask & OBP_CREATOR_INFO_BIT) { 175 | ExtRemoteTyped HeaderCreatorInfo("(nt!_OBJECT_HEADER_CREATOR_INFO *)@$extin", Offset); 176 | HandleObj->CreatorUniquePid = HeaderCreatorInfo.Field("CreatorUniqueProcess").GetPtr(); 177 | Offset += GetTypeSize("nt!_OBJECT_HEADER_CREATOR_INFO"); 178 | } 179 | Offset += GetTypeSize("nt!_OBJECT_HEADER_NAME_INFO"); 180 | } 181 | } 182 | else 183 | { 184 | Offset = ObjHeader.Field("NameInfoOffset").GetUchar(); 185 | } 186 | 187 | if (Offset) 188 | { 189 | ExtRemoteTyped ObjNameInfo("(nt!_OBJECT_HEADER_NAME_INFO *)@$extin", ObjHeaderAddr - Offset); 190 | ObjectName = ExtRemoteTypedEx::GetUnicodeString2(ObjNameInfo.Field("Name")); 191 | } 192 | } 193 | } 194 | catch (...) { 195 | 196 | } 197 | 198 | if (ObjectName) 199 | { 200 | StringCchCopyW(HandleObj->Name, _countof(HandleObj->Name), ObjectName); 201 | 202 | free(ObjectName); 203 | ObjectName = NULL; 204 | } 205 | 206 | Result = TRUE; 207 | 208 | CleanUp: 209 | 210 | return Result; 211 | } 212 | 213 | vector 214 | ObOpenObjectDirectory( 215 | _In_ ULONG64 InputObject 216 | ) 217 | /*++ 218 | 219 | Routine Description: 220 | 221 | Description. 222 | 223 | Arguments: 224 | 225 | InputObject - 226 | 227 | Return Value: 228 | 229 | vector. 230 | 231 | --*/ 232 | { 233 | vector Handles; 234 | vector Nodes; 235 | HANDLE_OBJECT Handle = {0}; 236 | ExtRemoteTyped Directory; 237 | ULONG64 ObjectDir = InputObject; 238 | 239 | try { 240 | 241 | if (!ObjectDir) { 242 | 243 | ReadPointer(ObpRootDirectoryObjectAddress, &ObjectDir); 244 | } 245 | 246 | Directory = ExtRemoteTyped("(nt!_OBJECT_DIRECTORY *)@$extin", ObjectDir); 247 | 248 | ObReadObject(ObjectDir, &Handle); 249 | 250 | for (UINT i = 0; i < 37; i += 1) { 251 | 252 | ULONG64 Entry = Directory.Field("HashBuckets").ArrayElement(i).GetPointerTo().GetPtr(); 253 | 254 | if (!Entry) { 255 | 256 | continue; 257 | } 258 | 259 | // 260 | // ExtRemoteTypedList requires a POINTER to the first entry. Not the offset of the first entry. 261 | // 262 | 263 | ExtRemoteTypedList EntryList(Entry, "nt!_OBJECT_DIRECTORY_ENTRY", "ChainLink"); 264 | 265 | for (EntryList.StartHead(); EntryList.HasNode(); EntryList.Next()) { 266 | 267 | ULONG64 Object = EntryList.GetTypedNode().Field("Object").GetPtr(); 268 | 269 | if (find(Nodes.rbegin(), Nodes.rend(), Object) != Nodes.rend()) { 270 | 271 | break; 272 | } 273 | 274 | Nodes.push_back(Object); 275 | 276 | ObReadObject(Object, &Handle); 277 | 278 | Handles.push_back(Handle); 279 | } 280 | } 281 | } 282 | catch (...) { 283 | 284 | } 285 | 286 | return Handles; 287 | } 288 | 289 | BOOLEAN 290 | ObOpenChildren( 291 | _In_opt_ ULONG64 Root, 292 | _In_ LPWSTR ObjName, 293 | _Out_ PHANDLE_OBJECT OutHandle 294 | ) 295 | /*++ 296 | 297 | Routine Description: 298 | 299 | Description. 300 | 301 | Arguments: 302 | 303 | Root - 304 | ObjName - 305 | OutHandle - 306 | 307 | Return Value: 308 | 309 | BOOLEAN. 310 | 311 | --*/ 312 | { 313 | vector Dir = ObOpenObjectDirectory(Root); 314 | BOOLEAN Result = FALSE; 315 | 316 | ZeroMemory(OutHandle, sizeof(HANDLE_OBJECT)); 317 | 318 | for each (HANDLE_OBJECT Handle in Dir) 319 | { 320 | if (_wcsicmp(Handle.Name, ObjName) == 0) 321 | { 322 | *OutHandle = Handle; 323 | Result = TRUE; 324 | break; 325 | } 326 | } 327 | 328 | return Result; 329 | } 330 | 331 | ULONG64 332 | ObGetFileSystemObject( 333 | VOID 334 | ) 335 | /*++ 336 | 337 | Routine Description: 338 | 339 | Description. 340 | 341 | Arguments: 342 | 343 | - 344 | 345 | Return Value: 346 | 347 | ULONG64. 348 | 349 | --*/ 350 | { 351 | ULONG64 Object = 0; 352 | 353 | HANDLE_OBJECT Handle; 354 | if (ObOpenChildren(0, L"FileSystem", &Handle)) Object = Handle.ObjectPtr; 355 | 356 | return Object; 357 | } 358 | 359 | ULONG64 360 | ObGetObjectTypesObject( 361 | VOID 362 | ) 363 | /*++ 364 | 365 | Routine Description: 366 | 367 | Description. 368 | 369 | Arguments: 370 | 371 | - 372 | 373 | Return Value: 374 | 375 | ULONG64. 376 | 377 | --*/ 378 | { 379 | ULONG64 Object = 0; 380 | 381 | HANDLE_OBJECT Handle; 382 | if (ObOpenChildren(0, L"ObjectTypes", &Handle)) Object = Handle.ObjectPtr; 383 | 384 | return Object; 385 | } 386 | 387 | ULONG64 388 | ObGetDriverObject( 389 | ) 390 | /*++ 391 | 392 | Routine Description: 393 | 394 | Description. 395 | 396 | Arguments: 397 | 398 | - 399 | 400 | Return Value: 401 | 402 | ULONG64. 403 | 404 | --*/ 405 | { 406 | ULONG64 Object = 0;; 407 | 408 | HANDLE_OBJECT Handle; 409 | if (ObOpenChildren(0, L"Driver", &Handle)) Object = Handle.ObjectPtr; 410 | 411 | return Object; 412 | } 413 | 414 | VOID 415 | ReleaseObjectTypeTable( 416 | VOID 417 | ) 418 | { 419 | if (ObTypeInit) { 420 | 421 | ObjTypeTable.Release(); 422 | 423 | ObTypeInit = FALSE; 424 | } 425 | } 426 | -------------------------------------------------------------------------------- /SwishDbgExt/Objects.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | Module Name: 20 | 21 | - Objects.h 22 | 23 | Abstract: 24 | 25 | - ExtRemoteData Pointer(GetExpression("'htsxxxxx!gRingBuffer"), m_PtrSize); // <<< works just fine 26 | 27 | 28 | 29 | Environment: 30 | 31 | - User mode 32 | 33 | Revision History: 34 | 35 | - Matthieu Suiche 36 | 37 | --*/ 38 | 39 | #ifndef __OBJECTS_H__ 40 | #define __OBJECTS_H__ 41 | 42 | BOOLEAN 43 | ObReadObject( 44 | _In_ ULONG64 Object, 45 | _Out_ PHANDLE_OBJECT HandleObj 46 | ); 47 | 48 | vector 49 | ObOpenObjectDirectory( 50 | _In_ ULONG64 ObjectDir 51 | ); 52 | 53 | BOOLEAN 54 | ObOpenChildren( 55 | _In_opt_ ULONG64 Root, 56 | _In_ LPWSTR ObjName, 57 | _Out_ PHANDLE_OBJECT OutHandle 58 | ); 59 | 60 | ULONG64 61 | ObGetDriverObject( 62 | ); 63 | 64 | ULONG64 65 | ObGetFileSystemObject( 66 | VOID 67 | ); 68 | 69 | ULONG64 70 | ObGetObjectTypesObject( 71 | VOID 72 | ); 73 | 74 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Output.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Output.h 23 | 24 | Abstract: 25 | 26 | - ExtRemoteData Pointer(GetExpression("'htsxxxxx!gRingBuffer"), m_PtrSize); // <<< works just fine 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | #ifndef __OUTPUT_H__ 39 | #define __OUTPUT_H__ 40 | 41 | extern LPSTR IrpMajor[]; 42 | 43 | VOID 44 | OutThread( 45 | PTHREAD_OBJECT Thread 46 | ); 47 | 48 | VOID 49 | OutHandles( 50 | PHANDLE_OBJECT Handle 51 | ); 52 | 53 | VOID 54 | OutDriver( 55 | MsDriverObject *Driver, 56 | ULONG ExpandFlag 57 | ); 58 | 59 | LPSTR 60 | GetLastWriteTime( 61 | PFILETIME ftWrite, 62 | LPSTR Buffer, 63 | ULONG dwSize 64 | ); 65 | 66 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Process.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Process.h 23 | 24 | Abstract: 25 | 26 | - ExtRemoteData Pointer(GetExpression("'htsxxxxx!gRingBuffer"), m_PtrSize); // <<< works just fine 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | #ifndef __PROCESS_H__ 39 | #define __PROCESS_H__ 40 | 41 | #define DEREF_POINTER(Ptr) { \ 42 | if (Ptr && (g_References[Ptr] >= 1)) \ 43 | { \ 44 | g_References[Ptr] -= 1; \ 45 | /* g_Ext->Dml("(%s:%d::%s) [%d] ", __FILE__, __LINE__, __FUNCTION__, g_References[Ptr]); */ \ 46 | if (g_References[Ptr] == 0) \ 47 | {\ 48 | /* g_Ext->Dml("free(Ptr) = %p", Ptr); */ \ 49 | free(Ptr); \ 50 | } \ 51 | Ptr = NULL; \ 52 | /* g_Ext->Dml("\n"); */\ 53 | } \ 54 | } 55 | 56 | #define REF_POINTER(Ptr) { \ 57 | if (Ptr) \ 58 | { \ 59 | if (g_References.find(Ptr) == g_References.end()) \ 60 | { \ 61 | g_References.insert(pair(Ptr, 1)); \ 62 | } \ 63 | else \ 64 | { \ 65 | g_References[Ptr] += 1; \ 66 | } \ 67 | /* g_Ext->Dml("(%s:%d::%s) [%d] Ref(%p) \n", __FILE__, __LINE__, __FUNCTION__, g_References[Ptr], Ptr); */ \ 68 | } \ 69 | } 70 | 71 | #define MM_READONLY 1 72 | #define MM_EXECUTE 2 73 | #define MM_EXECUTE_READ 3 74 | #define MM_READWRITE 4 // bit 2 is set if this is writable. 75 | #define MM_WRITECOPY 5 76 | #define MM_EXECUTE_READWRITE 6 77 | #define MM_EXECUTE_WRITECOPY 7 78 | 79 | #define PROCESS_DLLS_FLAG (1 << 0) 80 | #define PROCESS_EXPORTS_FLAG (1 << 1) 81 | #define PROCESS_DLL_EXPORTS_FLAG (1 << 2) 82 | #define PROCESS_SCAN_MALICIOUS_FLAG (1 << 3) 83 | #define PROCESS_HANDLES_FLAG (1 << 4) 84 | #define PROCESS_VADS_FLAG (1 << 5) 85 | #define PROCESS_THREADS_FLAG (1 << 6) 86 | #define PROCESS_ENVVAR_FLAG (1 << 7) 87 | #define PROCESS_IMPORTS_FLAG (1 << 8) 88 | #define PROCESS_DLL_IMPORTS_FLAG (1 << 9) 89 | 90 | #define OBP_CREATOR_INFO_BIT 0x1 91 | #define OBP_NAME_INFO_BIT 0x2 92 | #define OBP_HANDLE_INFO_BIT 0x4 93 | #define OBP_QUOTA_INFO_BIT 0x8 94 | #define OBP_PROCESS_INFO_BIT 0x10 95 | 96 | typedef struct _THREAD_OBJECT { 97 | ULONG64 StartAddress; 98 | ULONG64 ServiceTable; 99 | 100 | ULONG ThreadFlags; 101 | ULONG CrossThreadFlags; 102 | ULONG64 OwningProcess; 103 | ULONG64 AttachedProcess; 104 | 105 | ULONG64 ProcessId; 106 | ULONG64 ThreadId; 107 | 108 | LARGE_INTEGER CreateTime; 109 | LARGE_INTEGER ExitTime; 110 | 111 | ULONG64 Win32StartAddress; 112 | ULONG64 ObjectPtr; 113 | } THREAD_OBJECT, *PTHREAD_OBJECT; 114 | 115 | typedef struct _HANDLE_OBJECT { 116 | ULONG Handle; 117 | WCHAR Name[MAX_PATH]; 118 | WCHAR Type[32]; 119 | ULONG ObjectTypeIndex; 120 | ULONG64 ObjectPtr; 121 | ULONG64 ObjectKcb; // Only for Keys 122 | ULONG64 CreatorUniquePid; 123 | } HANDLE_OBJECT, *PHANDLE_OBJECT; 124 | 125 | typedef struct _VAD_OBJECT { 126 | ULONG64 ProcessObject; 127 | ULONG64 FirstNode; 128 | ULONG64 CurrentNode; 129 | ULONG64 StartingVpn; 130 | ULONG64 EndingVpn; 131 | 132 | ULONG32 VadType; 133 | ULONG32 Protection; 134 | ULONG32 PrivateMemory; 135 | ULONG32 MemCommit; 136 | 137 | ULONG64 FileObject; 138 | } VAD_OBJECT, *PVAD_OBJECT; 139 | 140 | class ModuleIterator { 141 | public: 142 | ModuleIterator(ULONG64 ModuleHead); 143 | BOOLEAN IsDone(VOID); 144 | VOID First(VOID); 145 | ExtRemoteTyped Current(VOID); 146 | // ExtRemoteTyped CurrentNode(VOID); 147 | VOID Next(VOID); 148 | VOID Prev(VOID); 149 | 150 | private: 151 | ULONG64 m_ModuleListHead; 152 | ExtRemoteTypedList m_ModuleList; 153 | }; 154 | 155 | typedef enum _PROCESS_LINKS_TYPE { 156 | ProcessLinksDefaultType = 0, 157 | ProcessLinksMmType = 1 158 | } PROCESS_LINKS_TYPE; 159 | 160 | class ProcessIterator { 161 | public: 162 | ProcessIterator(PROCESS_LINKS_TYPE Type = ProcessLinksDefaultType); 163 | BOOLEAN IsDone(VOID); 164 | VOID First(VOID); 165 | ExtRemoteTyped Current(VOID); 166 | ExtRemoteTyped CurrentNode(VOID); 167 | VOID Next(VOID); 168 | VOID Prev(VOID); 169 | 170 | private: 171 | PROCESS_LINKS_TYPE m_LinksType; 172 | ULONG64 m_ProcessHead; 173 | ExtRemoteTypedList m_ProcessList; 174 | }; 175 | 176 | class MsDllObject : public MsPEImageFile { 177 | public: 178 | typedef struct DLL_INFO { 179 | IMAGE_TYPE ImageType; // Always in first position. 180 | 181 | BOOLEAN IsWow64; 182 | 183 | ULONG64 ProcessOwner; 184 | ULONG64 DirectoryTableBase; 185 | ULONG64 DllEntry; 186 | 187 | LARGE_INTEGER LoadTime; 188 | WCHAR DllName[MAX_PATH + 1]; 189 | WCHAR FullDllName[MAX_PATH + 1]; 190 | } DLL_INFO, *PDLL_INFO; 191 | 192 | MsDllObject() 193 | { 194 | Clear(); 195 | } 196 | 197 | MsDllObject(ExtRemoteTyped Object) 198 | { 199 | Clear(); 200 | m_TypedObject = Object; 201 | Set(); 202 | } 203 | ~MsDllObject(); 204 | 205 | MsDllObject::MsDllObject(const MsDllObject& other); 206 | 207 | VOID Set(); 208 | 209 | //BOOLEAN Init(VOID); 210 | 211 | DLL_INFO mm_CcDllObject; 212 | 213 | ExtRemoteTyped m_TypedObject; 214 | }; 215 | 216 | class MsProcessObject : public MsPEImageFile { 217 | public: 218 | typedef struct _ENV_VAR_OBJECT { 219 | LPWSTR Variable; 220 | } ENV_VAR_OBJECT, *PENV_VAR_OBJECT; 221 | 222 | typedef struct _CACHED_PROCESS_OBJECT { 223 | IMAGE_TYPE ImageType; // Always in first position. 224 | 225 | ULONG64 ProcessObjectPtr; 226 | 227 | LARGE_INTEGER CreateTime; 228 | LARGE_INTEGER ExitTime; 229 | 230 | ULONG64 ParentProcessId; 231 | ULONG64 ProcessId; 232 | 233 | ULONG64 Token; 234 | 235 | ULONG64 VirtualSize; 236 | 237 | // 238 | // Additional information 239 | // 240 | BOOLEAN HiddenProcess; 241 | 242 | ULONG32 ProtectedProcess; 243 | ULONG32 BreakOnTermination; 244 | 245 | CHAR ImageFileName[16]; 246 | WCHAR FullPath[MAX_PATH + 1]; 247 | WCHAR UserName[MAX_PATH]; 248 | 249 | LPWSTR CommandLine; 250 | WCHAR WindowTitle[256]; 251 | LPWSTR DllPath; 252 | LPWSTR ImagePathName; 253 | } CACHED_PROCESS_OBJECT, *PCACHED_PROCESS_OBJECT; 254 | 255 | MsProcessObject() 256 | { 257 | Clear(); 258 | } 259 | 260 | /* 261 | MsProcessObject(MsProcessObject &other) 262 | { 263 | m_DllList = other.m_DllList; 264 | m_CcProcessObject = other.m_CcProcessObject; 265 | m_Image = other.m_Image; 266 | m_ProcessDataOffset = other.m_ProcessDataOffset; 267 | m_TypedObject = other.m_TypedObject; 268 | }*/ 269 | MsProcessObject(const MsProcessObject& other); // copy constructor 270 | 271 | MsProcessObject(ExtRemoteTyped Object) 272 | { 273 | Clear(); 274 | m_EnvVarsBuffer = NULL; 275 | m_TypedObject = Object; 276 | Set(); 277 | } 278 | ~MsProcessObject(); 279 | 280 | VOID Set(); 281 | VOID Release() throw(...); 282 | 283 | BOOLEAN GetDlls(); 284 | BOOLEAN GetHandles(ULONG64 InTableCode); 285 | 286 | BOOLEAN 287 | MsProcessObject::GetEnvironmentVariableValue( 288 | _In_ PWSTR Buffer, 289 | _In_ SIZE_T BufferSize, 290 | _In_ PWSTR VariableName 291 | ); 292 | 293 | BOOLEAN SwitchContext(VOID); 294 | BOOLEAN RestoreContext(VOID); 295 | 296 | BOOLEAN MmGetFirstVad( 297 | PVAD_OBJECT VadInfo 298 | ); 299 | BOOLEAN MmGetNextVad( 300 | PVAD_OBJECT VadInfo 301 | ); 302 | BOOLEAN MmGetVads(); 303 | BOOLEAN GetThreads(); 304 | 305 | CACHED_PROCESS_OBJECT m_CcProcessObject; 306 | 307 | vector m_EnvVars; 308 | 309 | vector m_DllList; 310 | vector m_Handles; 311 | vector m_Vads; 312 | vector m_Threads; 313 | 314 | ULONG64 m_ProcessDataOffset; 315 | 316 | ExtRemoteTyped m_TypedObject; 317 | LPWSTR m_EnvVarsBuffer; 318 | }; 319 | 320 | typedef vector ProcessArray; 321 | 322 | ProcessArray 323 | GetProcesses( 324 | _In_opt_ ULONG64 Pid, 325 | _In_ ULONG Flags 326 | ); 327 | 328 | MsProcessObject 329 | FindProcessByName( 330 | _In_ PSTR ProcessName 331 | ); 332 | 333 | MsProcessObject 334 | FindProcessByPid( 335 | _In_ ULONG64 ProcessId 336 | ); 337 | 338 | extern map g_References; 339 | 340 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Registry.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Registry.h 23 | 24 | Abstract: 25 | 26 | - 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | #ifndef __REGISTRY_H__ 39 | #define __REGISTRY_H__ 40 | 41 | #define HCELL_TYPE_MASK 0x80000000 42 | #define HCELL_TYPE_SHIFT 31 43 | 44 | #define HCELL_TABLE_MASK 0x7fe00000 45 | #define HCELL_TABLE_SHIFT 21 46 | 47 | #define HCELL_BLOCK_MASK 0x001ff000 48 | #define HCELL_BLOCK_SHIFT 12 49 | 50 | #define HCELL_OFFSET_MASK 0x00000fff 51 | 52 | #define CM_FAST_LEAF_SIGNATURE 'fl' 53 | #define CM_HASH_LEAF_SIGNATURE 'hl' 54 | #define CM_INDEX_ROOT_SIGNATURE 'ir' 55 | #define CM_INDEX_LEAF_SIGNATURE 'il' 56 | 57 | #define CM_KEY_NODE_SIGNATURE 'kn' 58 | #define CM_LINK_NODE_SIGNATURE 'kl' 59 | #define CM_KEY_VALUE_SIGNATURE 'kv' 60 | 61 | #define CM_FLAG_UNTRUSTED 0x1 62 | 63 | #define CM_HIVE_SIGNATURE 0xbee0bee0 64 | 65 | #define MAX_VALUE_NAME 16383 66 | 67 | typedef struct _CM_INDEX { 68 | ULONG CellIndex; 69 | CHAR NameHint[4]; 70 | } CM_INDEX, *PCM_INDEX; 71 | 72 | typedef struct _CM_KEY_FAST_INDEX { 73 | USHORT Signature; 74 | USHORT Count; 75 | CM_INDEX Index[1]; 76 | } CM_KEY_FAST_INDEX, *PCM_KEY_FAST_INDEX; 77 | 78 | typedef struct _CM_KEY_INDEX { 79 | USHORT Signature; 80 | USHORT Count; 81 | ULONG CellIndex[1]; 82 | } CM_KEY_INDEX, *PCM_KEY_INDEX; 83 | 84 | typedef struct _HIVE_OBJECT { 85 | ULONG64 HivePtr; 86 | ULONG64 KeyNodePtr; 87 | 88 | ULONG Flags; 89 | 90 | WCHAR FileUserName[MAX_PATH]; 91 | WCHAR HiveRootPath[MAX_PATH]; 92 | 93 | ULONG64 GetCellRoutine; 94 | ULONG64 ReleaseCellRoutine; 95 | ULONG64 Allocate; 96 | ULONG64 Free; 97 | ULONG64 FileSetSize; 98 | ULONG64 FileWrite; 99 | ULONG64 FileRead; 100 | ULONG64 FileFlush; 101 | } HIVE_OBJECT, *PHIVE_OBJECT; 102 | 103 | typedef struct _KEY_NAME { 104 | WCHAR Name[MAX_PATH]; 105 | } KEY_NAME, *PKEY_NAME ; 106 | 107 | typedef struct _KEY_NODE { 108 | WCHAR Name[MAX_PATH]; 109 | ExtRemoteTyped KeyNode; 110 | } KEY_NODE, *PKEY_NODE; 111 | 112 | typedef struct _REG_CHECK { 113 | PWSTR KeyName; 114 | PWSTR ValueName; 115 | ULONG ValueType; 116 | } REG_CHECK, *PREG_CHECK; 117 | 118 | 119 | PWSTR 120 | GetRegistryValueTypeName( 121 | _In_ ULONG ValueType 122 | ); 123 | 124 | ULONG64 125 | RegGetCellPaged( 126 | _In_ ExtRemoteTyped KeyHive, 127 | _In_ ULONG CellIndex 128 | ); 129 | 130 | VOID 131 | RegReadKeyNode( 132 | _In_ ExtRemoteTyped KeyHive, 133 | _In_ ExtRemoteTyped KeyNode 134 | ); 135 | 136 | VOID 137 | RegReadKeyValue( 138 | _In_ ExtRemoteTyped KeyHive, 139 | _In_ ExtRemoteTyped KeyValue 140 | ); 141 | 142 | PWSTR 143 | RegGetKeyName( 144 | _In_ ULONG64 KeyControlBlock 145 | ); 146 | 147 | BOOL 148 | RegGetKeyValue( 149 | _In_ PWSTR FullKeyPath, 150 | _In_ PWSTR ValueName, 151 | _Out_writes_bytes_to_(DataLength, *pDataLength) PVOID Data, 152 | _In_ ULONG DataLength, 153 | _Out_range_(0, DataLength) PULONG pValueLength 154 | ); 155 | 156 | vector 157 | RegGetKeyValuesNames( 158 | _In_ PWSTR FullKeyPath 159 | ); 160 | 161 | vector 162 | RegGetSubKeys( 163 | _In_ PWSTR FullKeyPath 164 | ); 165 | 166 | BOOL 167 | RegInitialize( 168 | VOID 169 | ); 170 | 171 | vector 172 | GetHives( 173 | ); 174 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Security.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Security.h 23 | 24 | Abstract: 25 | 26 | - Thanks to Frank Boldewin for sharing his code. 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | #ifndef __SECURITY_H__ 39 | #define __SECURITY_H__ 40 | 41 | ULONG 42 | GetMalScore( 43 | BOOLEAN Verbose, 44 | ULONG64 VirtualAddress, 45 | LPBYTE Buffer, 46 | ULONG BufferLen 47 | ); 48 | 49 | ULONG 50 | GetMalScoreEx( 51 | BOOLEAN Verbose, 52 | MsProcessObject *ProcObj, 53 | ULONG64 BaseAddress, 54 | ULONG Length 55 | ); 56 | 57 | BOOLEAN 58 | IsImageInMemory( 59 | ULONG64 Offset, 60 | PUSHORT Sig 61 | 62 | ); 63 | 64 | BOOLEAN 65 | IsImageInMemoryEx( 66 | MsProcessObject *ProcObj, 67 | ULONG64 Offset, 68 | PUSHORT Sig 69 | ); 70 | 71 | ULONG64 72 | GetPteFromAddress( 73 | ULONG64 Va 74 | ); 75 | 76 | #define IS_PTE_OWNER_USERMODE(x) ((x >> 2) & 1) 77 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Storage.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MagnetForensics/SwishDbgExt/bd3b324967bfcd0994abf9f45708982b3ebc9516/SwishDbgExt/Storage.cpp -------------------------------------------------------------------------------- /SwishDbgExt/Storage.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - Storage.h 23 | 24 | Abstract: 25 | 26 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | class StoreManager { 39 | public: 40 | #define SM_LOG_CTX_OFFSET_X64 0x880 41 | #define SMC_CACHE_MGR_OFFSET_X64 0x9a0 42 | 43 | #define SM_LOG_CTX_OFFSET_X86 0x510 44 | #define SMC_CACHE_MGR_OFFSET_X86 0x5b4 45 | 46 | #define SM_LOG_ENTRY32_PAGECOUNT_BITS ((sizeof(ULONG32) * 8) - 16) 47 | #define SM_LOG_ENTRY64_PAGECOUNT_BITS ((sizeof(ULONG64) * 8) - 16) 48 | 49 | #define SM_STORES_MAX (1 << 3) 50 | 51 | // 52 | // Structures 53 | // 54 | 55 | #define SMP_LB_ENTRY_COUNT_BITS 16 56 | 57 | typedef struct _SMC_CACHE { 58 | ULONG CacheId; 59 | ULONG u000[3]; 60 | ULONG CacheFileSize; 61 | ULONG u014[5]; 62 | ULONG FileHandle; 63 | ULONG FileObject; 64 | UCHAR u030[0x14c]; 65 | WCHAR UniqueId[256]; 66 | } SMC_CACHE, *PSMC_CACHE; 67 | 68 | typedef struct _SMC_CACHE_REF { 69 | ULONG_PTR Cache; 70 | ULONG_PTR RefCount; // not used in sminfo. 71 | ULONG_PTR AddRemoveLock; // not used in sminfo. 72 | ULONG SeqNumber; // not used in sminfo. 73 | } SMC_CACHE_REF, *PSMC_CACHE_REF; 74 | 75 | typedef struct _SMP_LOG_BUFFER32 { 76 | ULONG32 Link; // SINGLE_LIST_ENTRY 77 | ULONG EntryCount:SMP_LB_ENTRY_COUNT_BITS; 78 | ULONG EntryMax:SMP_LB_ENTRY_COUNT_BITS; 79 | } SMP_LOG_BUFFER32, *PSMP_LOG_BUFFER32; 80 | 81 | typedef struct _SMP_LOG_BUFFER64 { 82 | ULONG64 Link; // SINGLE_LIST_ENTRY 83 | ULONG EntryCount:SMP_LB_ENTRY_COUNT_BITS; 84 | ULONG EntryMax:SMP_LB_ENTRY_COUNT_BITS; 85 | } SMP_LOG_BUFFER64, *PSMP_LOG_BUFFER64; 86 | 87 | typedef enum _SM_LOG_ENTRY_TYPE { 88 | SmLogAdd, 89 | SmLogRemove, 90 | SmLogFull, 91 | SmLogStoreUpdate, 92 | SmLogEntryTypeMax 93 | } SM_LOG_ENTRY_TYPE, *PSM_LOG_ENTRY_TYPE; 94 | 95 | typedef union _SM_LOG_ENTRY_FLAGS { 96 | struct { 97 | ULONG Type:2; 98 | ULONG Priority:3; 99 | ULONG DidNotCompress:1; 100 | ULONG Spare:2; 101 | ULONG StoreSet:SM_STORES_MAX; 102 | }; 103 | 104 | struct { 105 | ULONG OverlapsWithType:2; 106 | ULONG Empty:1; 107 | ULONG Spare1:5; 108 | ULONG OverlapsWithStoreSet:SM_STORES_MAX; 109 | }; 110 | } SM_LOG_ENTRY_FLAGS, *PSM_LOG_ENTRY_FLAGS; 111 | 112 | typedef enum _SM_PAGE_TYPE { 113 | SmPageTypeProcess = 0, 114 | SmPageTypeSession, 115 | SmPageTypeSystem, 116 | SmPageTypeSection, 117 | SmPageTypeMax 118 | } SM_PAGE_TYPE, *PSM_PAGE_TYPE; 119 | 120 | typedef struct _SM_PAGE_KEY_DESCRIPTOR32 { 121 | union { 122 | struct { 123 | ULONG32 ProcessKey; 124 | ULONG32 VirtualAddress; 125 | }; 126 | struct { 127 | ULONG32 PageType:2; 128 | ULONG32 Spare:1; 129 | } Flags; 130 | }; 131 | } SM_PAGE_KEY_DESCRIPTOR32, *PSM_PAGE_KEY_DESCRIPTOR32; 132 | 133 | typedef struct _SM_LOG_ENTRY32 { 134 | SM_PAGE_KEY_DESCRIPTOR32 KeyDescriptor; 135 | union { 136 | SM_LOG_ENTRY_FLAGS Flags; 137 | struct { 138 | ULONG32 AllFlags:16; 139 | ULONG32 PageCount:SM_LOG_ENTRY32_PAGECOUNT_BITS; 140 | }; 141 | }; 142 | } SM_LOG_ENTRY32, *PSM_LOG_ENTRY32; 143 | 144 | typedef struct _SM_PAGE_KEY_DESCRIPTOR64 { 145 | union { 146 | struct { 147 | ULONG64 ProcessKey; 148 | ULONG64 VirtualAddress; 149 | }; 150 | 151 | struct { 152 | ULONG PageType:2; 153 | ULONG Spare:1; 154 | } Flags; 155 | }; 156 | } SM_PAGE_KEY_DESCRIPTOR64, *PSM_PAGE_KEY_DESCRIPTOR64; 157 | 158 | typedef struct _SM_LOG_ENTRY64 { 159 | SM_PAGE_KEY_DESCRIPTOR64 KeyDescriptor; 160 | union { 161 | SM_LOG_ENTRY_FLAGS Flags; 162 | struct { 163 | ULONG64 AllFlags:16; 164 | ULONG64 PageCount:SM_LOG_ENTRY64_PAGECOUNT_BITS; 165 | }; 166 | }; 167 | } SM_LOG_ENTRY64, *PSM_LOG_ENTRY64; 168 | 169 | vector SmLogEntries; 170 | 171 | StoreManager(); 172 | 173 | BOOLEAN GetSmLogEntries(); 174 | BOOL 175 | SmiDisplayCacheInformation( 176 | ULONG64 CacheManager, 177 | ULONG CacheIndex 178 | ); 179 | 180 | VOID 181 | SmiEnumCaches( 182 | ULONG CacheIndex 183 | ); 184 | 185 | ULONG m_SmLogCtxOffset; 186 | ULONG m_SmcCacheMgrOffset; 187 | ULONG m_SmpLogBufferSize; 188 | ULONG m_SmLogEntrySize; 189 | ULONG64 m_SmGlobalsAddress; 190 | }; -------------------------------------------------------------------------------- /SwishDbgExt/SwishDbgExt.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | 3 | ;-------------------------------------------------------------------- 4 | ; Core exports provided by the ExtCpp framework. 5 | ;-------------------------------------------------------------------- 6 | 7 | DebugExtensionInitialize 8 | DebugExtensionUninitialize 9 | DebugExtensionNotify 10 | 11 | ;-------------------------------------------------------------------- 12 | ; Extension commands. 13 | ;-------------------------------------------------------------------- 14 | 15 | ms_dump 16 | ms_hivelist 17 | ms_readkcb 18 | ms_readknode 19 | ms_readkvalue 20 | 21 | ms_consoles 22 | 23 | ms_object 24 | 25 | ms_credentials 26 | 27 | ms_netstat 28 | ms_mbr 29 | 30 | ms_drivers 31 | 32 | ms_timers 33 | ms_vacbs 34 | 35 | ms_process 36 | ms_services 37 | ms_callbacks 38 | ms_ssdt 39 | 40 | ms_idt 41 | ms_gdt 42 | 43 | ms_malscore 44 | 45 | ms_exqueue 46 | 47 | ms_store 48 | 49 | ms_scanndishook 50 | 51 | ms_checkcodecave 52 | ms_verbose 53 | ms_fixit 54 | 55 | ms_lxss 56 | 57 | ms_yarascan 58 | ms_regcheck 59 | ms_pools 60 | 61 | help -------------------------------------------------------------------------------- /SwishDbgExt/SwishDbgExt.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | Copyright (C) 2014 wLcY (@x9090) 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | 21 | Module Name: 22 | 23 | - SwishDbgExt.c 24 | 25 | Abstract: 26 | 27 | - 28 | 29 | 30 | Environment: 31 | 32 | - User mode 33 | 34 | Revision History: 35 | 36 | - Matthieu Suiche 37 | 38 | --*/ 39 | 40 | #define VERBOSE_MODE FALSE 41 | #define VVERBOSE_MODE FALSE 42 | #define JSON_SUPPORT FALSE 43 | 44 | using namespace std; 45 | 46 | #if JSON_SUPPORT 47 | #include 48 | #include 49 | 50 | using namespace web; 51 | using namespace web::http; 52 | using namespace web::http::client; 53 | #endif 54 | 55 | #pragma once 56 | 57 | #include "engextcpp.hpp" 58 | #include "EngExpCppEx.h" 59 | #include "UntypedData.h" 60 | 61 | #include "NtDef.h" 62 | #include "DbgHelpEx.h" 63 | 64 | #include "Credentials.h" 65 | #include "Process.h" 66 | #include "Drivers.h" 67 | #include "Registry.h" 68 | #include "Network.h" 69 | #include "System.h" 70 | #include "Storage.h" 71 | #include "VirusTotal.h" 72 | #include "Checks\Codecave.h" 73 | #include "Lxss.h" 74 | #include "Yara.h" 75 | 76 | #include "Security.h" 77 | #include "Objects.h" 78 | #include "Md5.h" 79 | #include "Output.h" 80 | #include "Common.h" 81 | #include "CNdiskd\CNdiskd.h" 82 | 83 | #pragma comment(lib, "version.lib") 84 | #if JSON_SUPPORT 85 | #pragma comment(lib, "cpprest120_1_4.lib") 86 | #endif 87 | 88 | #ifndef COMAE_TOOLKIT_VERSION 89 | #define COMAE_TOOLKIT_VERSION "" 90 | #endif 91 | 92 | #define API_EXPORT __declspec(dllexport) 93 | #define SIGN_EXTEND(_x_) (ULONG64)(LONG)(_x_) 94 | #define PAGE_SIZE 0x1000 95 | 96 | #if VERBOSE_MODE 97 | #define ASSERTDBG(exp) if (!(exp)) g_Ext->Dml("ASSERT: %s:%d:%s %s\n", __FILE__, __LINE__, __FUNCTION__, #exp); 98 | #define ASSERT(exp) if (!(exp)) g_Ext->Dml("ASSERT: %s:%d:%s %s\n", __FILE__, __LINE__, __FUNCTION__, #exp); 99 | #else 100 | #define ASSERTDBG(exp) ((void)0) 101 | #define ASSERT(exp) exp; 102 | #endif 103 | 104 | #define GetPtrSize() (g_Ext->m_PtrSize) 105 | #define DbgPrint(fmt,...) if (g_Verbose) g_Ext->Dml(fmt, __VA_ARGS__); 106 | 107 | #ifdef __cplusplus 108 | extern "C" { 109 | #endif 110 | 111 | // 112 | // Definition 113 | // 114 | 115 | extern BOOLEAN g_Verbose; 116 | extern ULONG64 KeNumberProcessorsAddress; 117 | extern ULONG64 KiProcessorBlockAddress; 118 | extern ULONG64 ObpRootDirectoryObjectAddress; 119 | extern ULONG64 ObTypeIndexTableAddress; 120 | extern ULONG64 ObHeaderCookieAddress; 121 | extern ULONG64 CmpRegistryRootObjectAddress; 122 | extern ULONG64 CmpMasterHiveAddress; 123 | 124 | VOID 125 | ReleaseObjectTypeTable( 126 | VOID 127 | ); 128 | 129 | #ifdef __cplusplus 130 | } 131 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/SwishDbgExt.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MagnetForensics/SwishDbgExt/bd3b324967bfcd0994abf9f45708982b3ebc9516/SwishDbgExt/SwishDbgExt.rc -------------------------------------------------------------------------------- /SwishDbgExt/SwishDbgExt.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Source Files 6 | 7 | 8 | Source Files 9 | 10 | 11 | Source Files 12 | 13 | 14 | Source Files 15 | 16 | 17 | Source Files 18 | 19 | 20 | Source Files 21 | 22 | 23 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | Source Files 36 | 37 | 38 | Source Files 39 | 40 | 41 | Source Files 42 | 43 | 44 | Source Files 45 | 46 | 47 | Source Files 48 | 49 | 50 | Source Files 51 | 52 | 53 | Source Files 54 | 55 | 56 | Source Files\CNdiskd 57 | 58 | 59 | Source Files\CNdiskd 60 | 61 | 62 | Source Files\CNdiskd 63 | 64 | 65 | Source Files\CNdiskd 66 | 67 | 68 | Source Files\CNdiskd 69 | 70 | 71 | Source Files\CNdiskd 72 | 73 | 74 | Source Files\CNdiskd 75 | 76 | 77 | Source Files\CNdiskd 78 | 79 | 80 | Source Files\Checks 81 | 82 | 83 | Source Files 84 | 85 | 86 | Source Files 87 | 88 | 89 | Source Files 90 | 91 | 92 | 93 | 94 | Header Files 95 | 96 | 97 | Header Files 98 | 99 | 100 | Header Files 101 | 102 | 103 | Header Files 104 | 105 | 106 | Header Files 107 | 108 | 109 | Header Files 110 | 111 | 112 | Header Files 113 | 114 | 115 | Header Files 116 | 117 | 118 | Header Files 119 | 120 | 121 | Header Files 122 | 123 | 124 | Header Files 125 | 126 | 127 | Header Files 128 | 129 | 130 | Header Files 131 | 132 | 133 | Header Files 134 | 135 | 136 | Header Files 137 | 138 | 139 | Header Files 140 | 141 | 142 | Header Files 143 | 144 | 145 | Header Files 146 | 147 | 148 | Header Files 149 | 150 | 151 | Header Files\CNdiskd 152 | 153 | 154 | Header Files\CNdiskd 155 | 156 | 157 | Header Files\CNdiskd 158 | 159 | 160 | Header Files\CNdiskd 161 | 162 | 163 | Header Files\CNdiskd 164 | 165 | 166 | Header Files\CNdiskd 167 | 168 | 169 | Header Files\CNdiskd 170 | 171 | 172 | Header Files\Checks 173 | 174 | 175 | Header Files 176 | 177 | 178 | Header Files 179 | 180 | 181 | Header Files 182 | 183 | 184 | Header Files 185 | 186 | 187 | Header Files 188 | 189 | 190 | 191 | 192 | {0dd35a99-cf9a-4c06-80dc-f9137415e551} 193 | 194 | 195 | {4bd195dd-04d9-4c34-a26f-c3b74cc24af8} 196 | 197 | 198 | {d9eb326a-f029-4c13-8fc8-d2ca4fa39c7d} 199 | 200 | 201 | {df22e224-3691-48dc-b5a0-65f333c891b3} 202 | 203 | 204 | {822445e7-508c-4279-bb47-5ee64b8e6109} 205 | 206 | 207 | {fbea9e81-02e3-4742-abae-834a8d90ed83} 208 | 209 | 210 | {9bf4bc88-0021-49ec-9470-f45c4cf74534} 211 | 212 | 213 | 214 | 215 | Resource Files 216 | 217 | 218 | 219 | 220 | 221 | Resource Files 222 | 223 | 224 | -------------------------------------------------------------------------------- /SwishDbgExt/System.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - System.h 23 | 24 | Abstract: 25 | 26 | - 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | 39 | #ifndef __SYSTEM_H__ 40 | #define __SYSTEM_H__ 41 | 42 | typedef struct _SSDT_ENTRY { 43 | ULONG Index; 44 | MsPEImageFile::ADDRESS_INFO Address; 45 | BOOLEAN InlineHooking; 46 | BOOLEAN PatchedEntry; 47 | } SSDT_ENTRY, *PSSDT_ENTRY; 48 | 49 | #define SC_SIGNATURE_NT6 0x48726373 // "scrH" in ASCII. 50 | #define HANDLE_SIGNATURE 0x48726573 // "serH" in ASCII. 51 | 52 | #define SC_SIGNATURE_NT5 0x6E4F6373 // "scOn" in ASCII. 53 | #define SERVICE_SIGNATURE 0x76724573 // "sErv" in ASCII. 54 | 55 | #define INTERRUPT_OBJECT_TYPE 22 56 | 57 | #define IDT_ACCESS_TYPE_MASK 0x0F00 58 | #define IDT_ACCESS_DPL_MASK 0x6000 59 | #define IDT_ACCESS_PRESENT_MASK 0x8000 60 | 61 | typedef struct _SERVICE_ENTRY { 62 | WCHAR Name[MAX_PATH]; 63 | WCHAR Desc[MAX_PATH]; 64 | WCHAR CommandLine[MAX_PATH]; 65 | WCHAR AccountName[MAX_PATH]; 66 | 67 | ULONG64 TokenHandle; 68 | ULONG64 ProcessHandle; 69 | ULONG ProcessId; 70 | 71 | ULONG ServiceCount; // number of services running in the process 72 | ULONG UseCount; // how many handles open to service 73 | 74 | SERVICE_STATUS ServiceStatus; 75 | ULONG StartType; 76 | } SERVICE_ENTRY, *PSERVICE_ENTRY; 77 | 78 | typedef struct _PARTITION_ENTRY 79 | { 80 | UCHAR BootableFlag; 81 | UCHAR StartingCHS[3]; 82 | UCHAR PartitionType; 83 | UCHAR EndingCHS[3]; 84 | ULONG StartingLBA; 85 | ULONG SizeInSectors; 86 | } PARTITION_ENTRY, *PPARTITION_ENTRY; 87 | 88 | typedef struct _PARTITION_TABLE 89 | { 90 | UCHAR u00[0x1b8]; 91 | UCHAR DiskSignature[4]; // Boot code 92 | USHORT u1bc; 93 | PARTITION_ENTRY Entry[4]; 94 | ULONG Signature; 95 | } PARTITION_TABLE, *PPARTITION_TABLE; 96 | 97 | typedef struct _VACB_OBJECT 98 | { 99 | ULONG64 Vacb; 100 | ULONG64 BaseAddress; 101 | BOOLEAN ValidBase; 102 | ULONG64 SharedCacheMap; 103 | } VACB_OBJECT, *PVACB_OBJECT; 104 | 105 | typedef struct _IDT_ENTRY { 106 | ULONG CoreIndex; 107 | ULONG Index; 108 | ULONG64 Address; 109 | 110 | USHORT Dpl; 111 | USHORT Present; 112 | USHORT Type; 113 | } IDT_ENTRY, *PIDT_ENTRY; 114 | 115 | typedef struct _IDT_TABLE { 116 | ULONG64 IdtAddress; 117 | ULONG64 PrcbAddress; 118 | } IDT_TABLE, *PIDT_TABLE; 119 | 120 | typedef struct _GDT_OBJECT 121 | { 122 | ULONG CoreIndex; 123 | ULONG Index; 124 | 125 | ULONG Selector; 126 | ULONG64 Base; 127 | ULONG64 Limit; 128 | ULONG Present; 129 | ULONG Type; 130 | ULONG Dpl; 131 | ULONG64 Entry; 132 | } GDT_OBJECT, *PGDT_OBJECT; 133 | 134 | typedef enum _KOBJECTS 135 | { 136 | EventNotificationObject = 0, 137 | EventSynchronizationObject = 1, 138 | MutantObject = 2, 139 | ProcessObject = 3, 140 | QueueObject = 4, 141 | SemaphoreObject = 5, 142 | ThreadObject = 6, 143 | GateObject = 7, 144 | TimerNotificationObject = 8, 145 | TimerSynchronizationObject = 9, 146 | Spare2Object = 10, 147 | Spare3Object = 11, 148 | Spare4Object = 12, 149 | Spare5Object = 13, 150 | Spare6Object = 14, 151 | Spare7Object = 15, 152 | Spare8Object = 16, 153 | Spare9Object = 17, 154 | ApcObject = 18, 155 | DpcObject = 19, 156 | DeviceQueueObject = 20, 157 | EventPairObject = 21, 158 | InterruptObject = 22, 159 | ProfileObject = 23, 160 | ThreadedDpcObject = 24, 161 | MaximumKernelObject = 25 162 | } KOBJECTS; 163 | 164 | typedef struct _KTIMER { 165 | ULONG CoreId; 166 | ULONG64 Timer; 167 | ULONG64 Dpc; 168 | ULONG Type; 169 | ULONG DpcType; 170 | LARGE_INTEGER DueTime; 171 | ULONG Period; 172 | ULONG64 DeferredRoutine; 173 | } KTIMER, *PKTIMER; 174 | 175 | typedef union _KGDTENTRY64 176 | { 177 | struct 178 | { 179 | USHORT LimitLow; 180 | USHORT BaseLow; 181 | union 182 | { 183 | struct { 184 | USHORT BaseHigh; 185 | }; 186 | struct 187 | { 188 | UCHAR BaseMiddle; 189 | UCHAR Flags1; 190 | UCHAR Flags2; 191 | UCHAR BaseHigh; 192 | } Bytes; 193 | struct 194 | { 195 | ULONG BaseMiddle : 8; 196 | ULONG Type : 5; 197 | ULONG Dpl : 2; 198 | ULONG Present : 1; 199 | ULONG LimitHigh : 4; 200 | ULONG System : 1; 201 | ULONG LongMode : 1; 202 | ULONG DefaultBig : 1; 203 | ULONG Granularity : 1; 204 | ULONG BaseHigh : 8; 205 | } Bits; 206 | }; 207 | ULONG BaseUpper; 208 | ULONG MustBeZero; 209 | }; 210 | UINT64 Alignment; 211 | } KGDTENTRY64, *PKGDTENTRY64; 212 | 213 | typedef struct _CALL_GATE 214 | { 215 | USHORT OffsetLow; 216 | USHORT Selector; 217 | UCHAR NumberOfArguments : 5; 218 | UCHAR Reserved : 3; 219 | UCHAR Type : 5; 220 | UCHAR Dpl : 2; 221 | UCHAR Present : 1; 222 | USHORT OffsetHigh; 223 | } CALL_GATE, *PCALL_GATE; 224 | 225 | enum GDTSystemType32 226 | { 227 | TaskStateSegment16Available = 1, 228 | LocalDescriptorTable32 = 2, 229 | TaskStateSegment16Busy = 3, 230 | CallGate16 = 4, 231 | TaskGate = 5, 232 | InterruptGate16 = 6, 233 | TrapGate16 = 7, 234 | TaskStateSegment32Available = 9, 235 | TaskStateSegment32Busy = 11, 236 | CallGate32 = 12, 237 | InterruptGate32 = 14, 238 | TrapGate32 = 15, 239 | Invalid32 = 255 240 | }; 241 | 242 | enum GDTSystemType64 243 | { 244 | UpperHalf16 = 0, 245 | LocalDescriptorTable64 = 2, 246 | TaskStateSegment64Available = 9, 247 | TaskStateSegment64Busy = 11, 248 | CallGate64 = 12, 249 | InterruptGate64 = 14, 250 | TrapGate64 = 15, 251 | Invalid64 = 255 252 | }; 253 | 254 | enum GDTType 255 | { 256 | System = 0, 257 | Data = 1, 258 | Code = 2 259 | }; 260 | 261 | 262 | typedef enum _WORK_QUEUE_TYPE { 263 | CriticalWorkQueue, 264 | DelayedWorkQueue, 265 | HyperCriticalWorkQueue, 266 | NormalWorkQueue, 267 | BackgroundWorkQueue, 268 | RealTimeWorkQueue, 269 | SuperCriticalWorkQueue, 270 | MaximumWorkQueue, 271 | CustomPriorityWorkQueue = 32 272 | } WORK_QUEUE_TYPE; 273 | 274 | vector 275 | GetVacbs( 276 | VOID 277 | ); 278 | 279 | vector 280 | GetTimers( 281 | VOID 282 | ); 283 | 284 | vector 285 | GetServiceDescriptorTable( 286 | VOID 287 | ); 288 | 289 | PSTR 290 | GetServiceStartType( 291 | _In_ ULONG StartType 292 | ); 293 | 294 | PSTR 295 | GetServiceState( 296 | _In_ ULONG State 297 | ); 298 | 299 | vector 300 | GetServices( 301 | VOID 302 | ); 303 | 304 | PSTR 305 | GetPartitionType( 306 | _In_ ULONG Type 307 | ); 308 | 309 | vector 310 | GetInterrupts( 311 | _In_opt_ ULONG64 InIdtBase 312 | ); 313 | 314 | vector 315 | GetDescriptors( 316 | _In_opt_ ULONG64 InGdtBase 317 | ); 318 | 319 | void 320 | GetExQueue( 321 | ); 322 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/UntypedData.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - UntypedData.cpp 23 | 24 | Abstract: 25 | 26 | - http://msdn.microsoft.com/en-us/windows/ff553536(v=vs.71).aspx 27 | - TODO: set symbols noisy 28 | 29 | Environment: 30 | 31 | - User mode 32 | 33 | Revision History: 34 | 35 | - Matthieu Suiche 36 | 37 | --*/ 38 | 39 | #ifndef __UNTYPED_DATA_H__ 40 | #define __UNTYPED_DATA_H__ 41 | 42 | class ExtRemoteUnTyped : public ExtRemoteData { 43 | public: 44 | typedef struct _TYPED_DATA_FIELD { 45 | LPSTR FieldName; 46 | ULONG Offset; 47 | ULONG Size; 48 | } TYPED_DATA_FIELD, *PTYPED_DATA_FIELD; 49 | 50 | typedef struct _TYPED_DATA_VERSION { 51 | ULONG MachineType; 52 | ULONG MinorVersion; 53 | ULONG MajorVersion; 54 | ULONG ServicePack; 55 | 56 | ULONG TypeSize; 57 | PTYPED_DATA_FIELD Fields; 58 | } TYPED_DATA_VERSION, *PTYPED_DATA_VERSION; 59 | 60 | typedef struct _TYPED_DATA { 61 | LPSTR TypeName; 62 | PTYPED_DATA_VERSION Type; 63 | } TYPED_DATA, *PTYPED_DATA; 64 | 65 | ExtRemoteUnTyped( 66 | ) throw(...) 67 | { 68 | } 69 | 70 | ExtRemoteUnTyped( 71 | PCSTR TypeName 72 | ) throw(...) 73 | { 74 | Set(0, TypeName); 75 | // ExtRemoteData::Set(Ptr, m_TypedData->TypeSize); 76 | } 77 | 78 | ExtRemoteUnTyped( 79 | ULONG64 Ptr, 80 | PCSTR TypeName 81 | ) throw(...) 82 | { 83 | Set(Ptr, TypeName); 84 | ExtRemoteData::Set(Ptr, m_TypedData->TypeSize); 85 | } 86 | 87 | ExtRemoteUnTyped( 88 | ULONG64 Ptr, 89 | PCSTR TypeName, 90 | PCSTR Field, 91 | ULONG Size) throw(...) 92 | { 93 | Set(Ptr, TypeName); // We keep the same structure name. TODO: Links 94 | 95 | StringCchCopyA(m_Field, _countof(m_Field), Field); 96 | m_FieldSize = Size; 97 | ExtRemoteData::Set(Ptr, Size); 98 | } 99 | 100 | ExtRemoteUnTyped operator[](_In_ LONG Index) throw(...) 101 | { 102 | return ArrayElement(Index); 103 | } 104 | ExtRemoteUnTyped operator[](_In_ ULONG Index) throw(...) 105 | { 106 | return ArrayElement((LONG64)Index); 107 | } 108 | ExtRemoteUnTyped operator[](_In_ LONG64 Index) throw(...) 109 | { 110 | return ArrayElement(Index); 111 | } 112 | ExtRemoteUnTyped operator[](_In_ ULONG64 Index) throw(...) 113 | { 114 | if (Index > 0x7fffffffffffffffUI64) 115 | { 116 | g_Ext->ThrowRemote 117 | (HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), 118 | "Array index too large"); 119 | } 120 | return ArrayElement((LONG64)Index); 121 | } 122 | 123 | VOID Set(ULONG64 Ptr, PCSTR TypeName) throw(...); 124 | 125 | ULONG64 GetPointerTo(void) throw(...); 126 | PTYPED_DATA_FIELD GetField(_In_ PCSTR Field) throw(...); 127 | BOOLEAN HasField(_In_ PCSTR Field) throw(...); 128 | ULONG GetFieldOffset(_In_ PCSTR Field) throw(...); 129 | VOID SubtractOffset(_In_ PCSTR Field) throw(...); 130 | ExtRemoteUnTyped Field(_In_ PCSTR Field) throw(...); 131 | ExtRemoteUnTyped Field(_In_ PCSTR Field, BOOLEAN IsPtr) throw(...); 132 | 133 | ExtRemoteUnTyped ArrayElement(_In_ LONG64 Index) throw(...); 134 | 135 | BOOLEAN m_Initialized; 136 | ULONG64 m_UntypedDataPtr; 137 | PTYPED_DATA_VERSION m_TypedData; 138 | 139 | CHAR m_TypeName[MAX_PATH]; 140 | CHAR m_Field[MAX_PATH]; 141 | ULONG m_FieldSize; 142 | }; 143 | 144 | ULONG 145 | GetUntypedTypeSize( 146 | _In_ PCSTR TypeName 147 | ); 148 | 149 | ULONG 150 | GetFieldOffset( 151 | _In_ PCSTR TypeName, 152 | _In_ PCSTR Field 153 | ); 154 | 155 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Version.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MagnetForensics/SwishDbgExt/bd3b324967bfcd0994abf9f45708982b3ebc9516/SwishDbgExt/Version.rc -------------------------------------------------------------------------------- /SwishDbgExt/Version.txt: -------------------------------------------------------------------------------- 1 | #define BINVERSION 3,0,0,0 2 | #define STRVERSION "3.0" 3 | #define YEAR "2017" 4 | -------------------------------------------------------------------------------- /SwishDbgExt/VirusTotal.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - VirusTotal.cpp 23 | 24 | Abstract: 25 | 26 | - 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | // 39 | // TODO: ? :-) 40 | // 41 | 42 | #include "stdafx.h" -------------------------------------------------------------------------------- /SwishDbgExt/VirusTotal.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2014 Matthieu Suiche (@msuiche) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | Module Name: 21 | 22 | - VirusTotal.h 23 | 24 | Abstract: 25 | 26 | - 27 | 28 | Environment: 29 | 30 | - User mode 31 | 32 | Revision History: 33 | 34 | - Matthieu Suiche 35 | 36 | --*/ 37 | 38 | #ifndef __VIRUSTOTAL_H__ 39 | #define __VIRUSTOTAL_H__ 40 | 41 | #include "SwishDbgExt.h" 42 | 43 | #if JSON_SUPPORT 44 | class VirusTotal { 45 | public: 46 | static pplx::task GetReport(PUCHAR Md5Section); 47 | 48 | }; 49 | #endif 50 | 51 | #endif -------------------------------------------------------------------------------- /SwishDbgExt/Yara.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2016 Comae Technologies FZE 6 | Copyright (C) 2014-2016 Matthieu Suiche (@msuiche) 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | 21 | --*/ 22 | 23 | 24 | #include "stdafx.h" 25 | #include "SwishDbgExt.h" 26 | #include 27 | 28 | 29 | INT 30 | YaraCallback( 31 | _In_ INT Message, 32 | _In_ PVOID MessageData, 33 | _In_ PVOID UserData 34 | ) 35 | { 36 | YR_RULE *Rule; 37 | YR_STRING *String; 38 | YR_MATCH *Match; 39 | ULONG64 BaseAddress; 40 | 41 | switch (Message) { 42 | 43 | case CALLBACK_MSG_RULE_MATCHING: 44 | { 45 | Rule = (YR_RULE *)MessageData; 46 | 47 | BaseAddress = *(PULONG64)UserData; 48 | 49 | g_Ext->Dml("Rule: %s\n\n", Rule->identifier); 50 | 51 | yr_rule_strings_foreach(Rule, String) { 52 | 53 | yr_string_matches_foreach(String, Match) { 54 | 55 | g_Ext->Execute("db %p", BaseAddress + Match->offset); 56 | g_Ext->Dml("\n"); 57 | } 58 | } 59 | 60 | break; 61 | } 62 | } 63 | 64 | return CALLBACK_CONTINUE; 65 | } 66 | 67 | VOID 68 | YaraScan( 69 | _In_ MsProcessObject *ProcObj, 70 | _In_ PCSTR FileName 71 | ) 72 | { 73 | YR_COMPILER *Compiler; 74 | YR_RULES *Rules; 75 | FILE *File; 76 | PBYTE Buffer = NULL; 77 | ULONG64 RangeStart; 78 | ULONG64 RangeEnd; 79 | ULONG64 Offset; 80 | 81 | if (yr_initialize() == ERROR_SUCCESS) { 82 | 83 | if (yr_compiler_create(&Compiler) == ERROR_SUCCESS) { 84 | 85 | if (fopen_s(&File, FileName, "r") == ERROR_SUCCESS) { 86 | 87 | if (yr_compiler_add_file(Compiler, File, NULL, NULL) == 0) { 88 | 89 | if (yr_compiler_get_rules(Compiler, &Rules) == ERROR_SUCCESS) { 90 | 91 | Buffer = (PBYTE)calloc(PAGE_SIZE, sizeof(BYTE)); 92 | 93 | if (Buffer) { 94 | 95 | ProcObj->MmGetVads(); 96 | 97 | ProcObj->SwitchContext(); 98 | 99 | for each (VAD_OBJECT Vad in ProcObj->m_Vads) { 100 | 101 | // 102 | // Check if VAD's range is valid. 103 | // 104 | 105 | if ((Vad.StartingVpn & ~0xFFFFFFFFFF) || (Vad.EndingVpn & ~0xFFFFFFFFFF)) { 106 | 107 | continue; 108 | } 109 | 110 | RangeStart = Vad.StartingVpn * PAGE_SIZE; 111 | RangeEnd = Vad.EndingVpn * PAGE_SIZE; 112 | 113 | for (Offset = RangeStart; Offset < RangeEnd; Offset += PAGE_SIZE) { 114 | 115 | if (ExtRemoteTypedEx::ReadVirtual(Offset, Buffer, PAGE_SIZE, NULL) != S_OK) { 116 | 117 | continue; 118 | } 119 | 120 | yr_rules_scan_mem(Rules, Buffer, PAGE_SIZE, 0, YaraCallback, &Offset, 0); 121 | } 122 | } 123 | 124 | ProcObj->RestoreContext(); 125 | 126 | free(Buffer); 127 | } 128 | } 129 | } 130 | 131 | fclose(File); 132 | } 133 | 134 | yr_compiler_destroy(Compiler); 135 | } 136 | 137 | yr_finalize(); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /SwishDbgExt/Yara.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Incident Response & Digital Forensics Debugging Extension 3 | 4 | Copyright (C) 2014 MoonSols Ltd. 5 | Copyright (C) 2016 Comae Technologies FZE 6 | Copyright (C) 2014-2016 Matthieu Suiche (@msuiche) 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | 21 | --*/ 22 | 23 | #ifndef __YARA_H__ 24 | #define __YARA_H__ 25 | 26 | 27 | VOID 28 | YaraScan( 29 | _In_ MsProcessObject *ProcObj, 30 | _In_ PCSTR FileName 31 | ); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /SwishDbgExt/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /SwishDbgExt/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by SwishDbgExt.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /SwishDbgExt/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // dll.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /SwishDbgExt/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | #define KDEXT_64BIT 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | -------------------------------------------------------------------------------- /SwishDbgExt/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | --------------------------------------------------------------------------------