├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── syscall-names-grabber.py ├── syscall_extractor.sln └── syscall_extractor ├── common.hpp ├── disassembler.cpp ├── disassembler.hpp ├── main.cpp ├── syscall_extractor.vcxproj ├── syscall_extractor.vcxproj.filters ├── syscalls.cpp └── syscalls.hpp /.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 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Deputation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # syscall_extractor 2 | An x64 only C++ syscall ID extractor for Windows. Developed, debugged and tested in 20H2. It contains 471 syscall names extracted from https://github.com/j00ru/windows-syscalls for Windows 20H2. PRs are open! 3 | 4 | # How? 5 | It extracts Windows syscall IDs by disassembling stubs located in ``ntdll.dll``, it then looks for any ``mov eax`` instructions and tries to grab the syscall hex code contained in the stubs. Notes and explanations about special cases can be found in the source files as well as an explanation regarding how errors are "reported". [Zydis](https://github.com/zyantific/zydis) is used as a disassembler for the project. 6 | 7 | # Documentation 8 | Documentation is already present in the header files to thoroughly explain what each function and class member is supposed to do, if not already clear at first. 9 | 10 | # Notes 11 | Make sure you have zydis installed, either via [vcpkg](https://github.com/microsoft/vcpkg) or included manually in the project's folder (you will likely need to edit the project settings if you plan on doing this). The triplet I used when developing the extractor was ``zydis:x64-windows-static``. 12 | 13 | # Credits 14 | To format the syscalls nicely and get an output that can be easily converted to a C-style array from j00ru's repository, [AgentBlackout](https://github.com/AgentBlackout) gave me a nice python script that I'll leave here, feel free to customize it as you desire since it's very simple to understand. A copy of the file can be found in the repository as well with the name syscall-names-grabber.py. 15 | 16 | ```py 17 | import requests 18 | import json 19 | x = requests.get("https://raw.githubusercontent.com/j00ru/windows-syscalls/master/x64/json/nt-per-system.json") 20 | p = json.loads(x.text) 21 | print(p["Windows 10"]["20H2"].keys()) 22 | ``` 23 | -------------------------------------------------------------------------------- /syscall-names-grabber.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | x = requests.get("https://raw.githubusercontent.com/j00ru/windows-syscalls/master/x64/json/nt-per-system.json") 4 | p = json.loads(x.text) 5 | print(p["Windows 10"]["20H2"].keys()) 6 | -------------------------------------------------------------------------------- /syscall_extractor.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31112.23 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "syscall_extractor", "syscall_extractor\syscall_extractor.vcxproj", "{A31A80C3-2B15-4100-830A-22DEFB4A8BC7}" 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 | {A31A80C3-2B15-4100-830A-22DEFB4A8BC7}.Debug|x64.ActiveCfg = Debug|x64 17 | {A31A80C3-2B15-4100-830A-22DEFB4A8BC7}.Debug|x64.Build.0 = Debug|x64 18 | {A31A80C3-2B15-4100-830A-22DEFB4A8BC7}.Debug|x86.ActiveCfg = Debug|Win32 19 | {A31A80C3-2B15-4100-830A-22DEFB4A8BC7}.Debug|x86.Build.0 = Debug|Win32 20 | {A31A80C3-2B15-4100-830A-22DEFB4A8BC7}.Release|x64.ActiveCfg = Release|x64 21 | {A31A80C3-2B15-4100-830A-22DEFB4A8BC7}.Release|x64.Build.0 = Release|x64 22 | {A31A80C3-2B15-4100-830A-22DEFB4A8BC7}.Release|x86.ActiveCfg = Release|Win32 23 | {A31A80C3-2B15-4100-830A-22DEFB4A8BC7}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {E89E9A01-0085-4E22-B5AB-1DC3FF105131} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /syscall_extractor/common.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | 13 | #include "syscalls.hpp" 14 | #include "disassembler.hpp" -------------------------------------------------------------------------------- /syscall_extractor/disassembler.cpp: -------------------------------------------------------------------------------- 1 | #include "common.hpp" 2 | 3 | std::vector zydis_t::disassemble(void* address, size_t bytes_length) 4 | { 5 | std::vector disassembled_instructions; 6 | 7 | ZyanU64 runtime_address = 0; 8 | ZyanUSize offset = 0; 9 | 10 | ZydisDecodedInstruction instruction; 11 | 12 | while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&this->decoder, 13 | reinterpret_cast(address) + offset, bytes_length - offset, &instruction))) 14 | { 15 | char buffer[256]; 16 | 17 | ZydisFormatterFormatInstruction(&this->formatter, &instruction, buffer, sizeof(buffer), 18 | runtime_address); 19 | 20 | disassembled_instructions.push_back(std::string(buffer)); 21 | 22 | offset += instruction.length; 23 | runtime_address += instruction.length; 24 | } 25 | 26 | return disassembled_instructions; 27 | } 28 | 29 | zydis_t::zydis_t() 30 | { 31 | ZydisDecoderInit(&this->decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); 32 | ZydisFormatterInit(&this->formatter, ZYDIS_FORMATTER_STYLE_INTEL); 33 | } 34 | 35 | std::shared_ptr disassembler::zydis; 36 | 37 | void disassembler::initialize() 38 | { 39 | zydis = std::make_shared(); 40 | } -------------------------------------------------------------------------------- /syscall_extractor/disassembler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class zydis_t 4 | { 5 | private: 6 | /// 7 | /// Refer to Zydis' docs. 8 | /// 9 | ZydisDecoder decoder; 10 | /// 11 | /// Refer to Zydis' docs. 12 | /// 13 | ZydisFormatter formatter; 14 | 15 | public: 16 | /// 17 | /// Disassemble code at an address. 18 | /// 19 | /// The address to start disassembling at. 20 | /// How many bytes to disassemble. 21 | /// An std::vector filled with std::strings, each std::vector 22 | /// element will contain the text representation of an instruciton. 23 | std::vector disassemble(void* address, size_t bytes_length); 24 | 25 | /// 26 | /// Initialize the zydis decoder and formatter. 27 | /// 28 | zydis_t(); 29 | }; 30 | 31 | namespace disassembler 32 | { 33 | /// 34 | /// Represents the zydis wrapper that only performs the task we need it to perform. 35 | /// 36 | extern std::shared_ptr zydis; 37 | 38 | /// 39 | /// Initialize the zydis disassembling backend. 40 | /// 41 | void initialize(); 42 | } -------------------------------------------------------------------------------- /syscall_extractor/main.cpp: -------------------------------------------------------------------------------- 1 | #include "common.hpp" 2 | 3 | int main(void) 4 | { 5 | // Initialize the shared_ptr vector with all the syscall_t objects containing the data needed 6 | // to exxtract a syscall's ID. Syscalls that cannot be found on this system will not be pushed in. 7 | data::initialize(); 8 | 9 | // Initialize the zydis disassembler backend 10 | disassembler::initialize(); 11 | 12 | // Loop through the syscals that we obtained and try to retrieve all the IDs. 13 | // Some "syscalls" might not have an ID simply because they're not implemented as canonical syscalls, but 14 | // follow the same naming conventions and are treated as such by Windows, such as NtQuerySystemTime, which 15 | // jumps straight to RtlQuerySystemTime like this: 16 | // 17 | // NtQuerySystemTime proc 18 | // jmp RtlQuerySystemTime; 19 | // NtQuerySystemTime endp 20 | 21 | auto gathered_syscall_ids = 0; 22 | 23 | for (const auto& syscall : data::syscall_data) 24 | { 25 | // Try getting the ID of the syscall by disassembling its stub in ntdll.dll. 26 | const auto id = syscall->get_id(); 27 | 28 | // If there were no errors, print the syscall's name and its id. 29 | if (id > 0) 30 | { 31 | std::cout << "[+] " << syscall->get_name() << "'s ID is: 0x" << std::hex << id << std::endl; 32 | 33 | gathered_syscall_ids++; 34 | } 35 | } 36 | 37 | std::cout << "[+] Gathered a total of " << std::dec << gathered_syscall_ids << " syscall IDs." << std::endl; 38 | 39 | return 0; 40 | } -------------------------------------------------------------------------------- /syscall_extractor/syscall_extractor.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {a31a80c3-2b15-4100-830a-22defb4a8bc7} 25 | syscallextractor 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | true 87 | 88 | 89 | true 90 | 91 | 92 | 93 | Level3 94 | true 95 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 96 | true 97 | 98 | 99 | Console 100 | true 101 | 102 | 103 | 104 | 105 | Level3 106 | true 107 | true 108 | true 109 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 110 | true 111 | 112 | 113 | Console 114 | true 115 | true 116 | true 117 | 118 | 119 | 120 | 121 | Level3 122 | true 123 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 124 | true 125 | MultiThreadedDebug 126 | 127 | 128 | Console 129 | true 130 | 131 | 132 | 133 | 134 | Level3 135 | true 136 | true 137 | true 138 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 139 | true 140 | MultiThreaded 141 | 142 | 143 | Console 144 | true 145 | true 146 | true 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /syscall_extractor/syscall_extractor.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | -------------------------------------------------------------------------------- /syscall_extractor/syscalls.cpp: -------------------------------------------------------------------------------- 1 | #include "common.hpp" 2 | 3 | std::string syscall_t::get_name() 4 | { 5 | return this->name; 6 | } 7 | 8 | void* syscall_t::get_address() 9 | { 10 | return this->address; 11 | } 12 | 13 | uint32_t syscall_t::get_id() 14 | { 15 | if (this->id_initialized) 16 | { 17 | return this->id; 18 | } 19 | 20 | if (!this->address) 21 | { 22 | this->id_initialized = true; 23 | this->id = e_syscall_extractor_errors::syscall_address_not_found; 24 | 25 | return this->id; 26 | } 27 | 28 | auto disassembly_output = disassembler::zydis->disassemble(this->address, 8); 29 | auto mov_eax_string = std::string(); 30 | 31 | auto found_eax = false; 32 | 33 | for (const auto& instruction : disassembly_output) 34 | { 35 | if (instruction.find("mov eax") != std::string::npos) 36 | { 37 | mov_eax_string = instruction; 38 | 39 | found_eax = true; 40 | break; 41 | } 42 | } 43 | 44 | if (!found_eax) 45 | { 46 | this->id = e_syscall_extractor_errors::mov_eax_instruction_not_found; 47 | this->id_initialized = true; 48 | 49 | return this->id; 50 | } 51 | 52 | auto comma_position = mov_eax_string.find(','); 53 | auto number_as_string = mov_eax_string.substr(comma_position + 2); 54 | 55 | uint32_t final_syscall_id; 56 | 57 | std::stringstream stream; 58 | stream << std::hex << number_as_string; 59 | 60 | stream >> final_syscall_id; 61 | this->id = final_syscall_id; 62 | this->id_initialized = true; 63 | 64 | return this->id; 65 | } 66 | 67 | syscall_t::syscall_t(std::string name) : 68 | name(name), id(e_syscall_extractor_errors::uninitialized), 69 | address(GetProcAddress(LoadLibrary(L"ntdll.dll"), name.c_str())), id_initialized(false) 70 | { 71 | 72 | } 73 | 74 | std::vector> data::syscall_data; 75 | 76 | uint32_t data::get_syscall_id(std::string name) 77 | { 78 | for (const auto& syscall : syscall_data) 79 | { 80 | if (!syscall->get_name().compare(name)) 81 | { 82 | return syscall->get_id(); 83 | } 84 | } 85 | 86 | return e_syscall_extractor_errors::syscall_name_not_found; 87 | } 88 | 89 | const char* const data::windows_20h2_syscalls[] = { "NtAccessCheck", "NtWorkerFactoryWorkerReady", "NtAcceptConnectPort", "NtMapUserPhysicalPagesScatter", "NtWaitForSingleObject", "NtCallbackReturn", "NtReadFile", "NtDeviceIoControlFile", "NtWriteFile", "NtRemoveIoCompletion", "NtReleaseSemaphore", "NtReplyWaitReceivePort", "NtReplyPort", "NtSetInformationThread", "NtSetEvent", "NtClose", "NtQueryObject", "NtQueryInformationFile", "NtOpenKey", "NtEnumerateValueKey", "NtFindAtom", "NtQueryDefaultLocale", "NtQueryKey", "NtQueryValueKey", "NtAllocateVirtualMemory", "NtQueryInformationProcess", "NtWaitForMultipleObjects32", "NtWriteFileGather", "NtSetInformationProcess", "NtCreateKey", "NtFreeVirtualMemory", "NtImpersonateClientOfPort", "NtReleaseMutant", "NtQueryInformationToken", "NtRequestWaitReplyPort", "NtQueryVirtualMemory", "NtOpenThreadToken", "NtQueryInformationThread", "NtOpenProcess", "NtSetInformationFile", "NtMapViewOfSection", "NtAccessCheckAndAuditAlarm", "NtUnmapViewOfSection", "NtReplyWaitReceivePortEx", "NtTerminateProcess", "NtSetEventBoostPriority", "NtReadFileScatter", "NtOpenThreadTokenEx", "NtOpenProcessTokenEx", "NtQueryPerformanceCounter", "NtEnumerateKey", "NtOpenFile", "NtDelayExecution", "NtQueryDirectoryFile", "NtQuerySystemInformation", "NtOpenSection", "NtQueryTimer", "NtFsControlFile", "NtWriteVirtualMemory", "NtCloseObjectAuditAlarm", "NtDuplicateObject", "NtQueryAttributesFile", "NtClearEvent", "NtReadVirtualMemory", "NtOpenEvent", "NtAdjustPrivilegesToken", "NtDuplicateToken", "NtContinue", "NtQueryDefaultUILanguage", "NtQueueApcThread", "NtYieldExecution", "NtAddAtom", "NtCreateEvent", "NtQueryVolumeInformationFile", "NtCreateSection", "NtFlushBuffersFile", "NtApphelpCacheControl", "NtCreateProcessEx", "NtCreateThread", "NtIsProcessInJob", "NtProtectVirtualMemory", "NtQuerySection", "NtResumeThread", "NtTerminateThread", "NtReadRequestData", "NtCreateFile", "NtQueryEvent", "NtWriteRequestData", "NtOpenDirectoryObject", "NtAccessCheckByTypeAndAuditAlarm", "NtQuerySystemTime", "NtWaitForMultipleObjects", "NtSetInformationObject", "NtCancelIoFile", "NtTraceEvent", "NtPowerInformation", "NtSetValueKey", "NtCancelTimer", "NtSetTimer", "NtAccessCheckByType", "NtAccessCheckByTypeResultList", "NtAccessCheckByTypeResultListAndAuditAlarm", "NtAccessCheckByTypeResultListAndAuditAlarmByHandle", "NtAcquireCrossVmMutant", "NtAcquireProcessActivityReference", "NtAddAtomEx", "NtAddBootEntry", "NtAddDriverEntry", "NtAdjustGroupsToken", "NtAdjustTokenClaimsAndDeviceGroups", "NtAlertResumeThread", "NtAlertThread", "NtAlertThreadByThreadId", "NtAllocateLocallyUniqueId", "NtAllocateReserveObject", "NtAllocateUserPhysicalPages", "NtAllocateUserPhysicalPagesEx", "NtAllocateUuids", "NtAllocateVirtualMemoryEx", "NtAlpcAcceptConnectPort", "NtAlpcCancelMessage", "NtAlpcConnectPort", "NtAlpcConnectPortEx", "NtAlpcCreatePort", "NtAlpcCreatePortSection", "NtAlpcCreateResourceReserve", "NtAlpcCreateSectionView", "NtAlpcCreateSecurityContext", "NtAlpcDeletePortSection", "NtAlpcDeleteResourceReserve", "NtAlpcDeleteSectionView", "NtAlpcDeleteSecurityContext", "NtAlpcDisconnectPort", "NtAlpcImpersonateClientContainerOfPort", "NtAlpcImpersonateClientOfPort", "NtAlpcOpenSenderProcess", "NtAlpcOpenSenderThread", "NtAlpcQueryInformation", "NtAlpcQueryInformationMessage", "NtAlpcRevokeSecurityContext", "NtAlpcSendWaitReceivePort", "NtAlpcSetInformation", "NtAreMappedFilesTheSame", "NtAssignProcessToJobObject", "NtAssociateWaitCompletionPacket", "NtCallEnclave", "NtCancelIoFileEx", "NtCancelSynchronousIoFile", "NtCancelTimer2", "NtCancelWaitCompletionPacket", "NtCommitComplete", "NtCommitEnlistment", "NtCommitRegistryTransaction", "NtCommitTransaction", "NtCompactKeys", "NtCompareObjects", "NtCompareSigningLevels", "NtCompareTokens", "NtCompleteConnectPort", "NtCompressKey", "NtConnectPort", "NtContinueEx", "NtConvertBetweenAuxiliaryCounterAndPerformanceCounter", "NtCreateCrossVmEvent", "NtCreateCrossVmMutant", "NtCreateDebugObject", "NtCreateDirectoryObject", "NtCreateDirectoryObjectEx", "NtCreateEnclave", "NtCreateEnlistment", "NtCreateEventPair", "NtCreateIRTimer", "NtCreateIoCompletion", "NtCreateJobObject", "NtCreateJobSet", "NtCreateKeyTransacted", "NtCreateKeyedEvent", "NtCreateLowBoxToken", "NtCreateMailslotFile", "NtCreateMutant", "NtCreateNamedPipeFile", "NtCreatePagingFile", "NtCreatePartition", "NtCreatePort", "NtCreatePrivateNamespace", "NtCreateProcess", "NtCreateProfile", "NtCreateProfileEx", "NtCreateRegistryTransaction", "NtCreateResourceManager", "NtCreateSectionEx", "NtCreateSemaphore", "NtCreateSymbolicLinkObject", "NtCreateThreadEx", "NtCreateTimer", "NtCreateTimer2", "NtCreateToken", "NtCreateTokenEx", "NtCreateTransaction", "NtCreateTransactionManager", "NtCreateUserProcess", "NtCreateWaitCompletionPacket", "NtCreateWaitablePort", "NtCreateWnfStateName", "NtCreateWorkerFactory", "NtDebugActiveProcess", "NtDebugContinue", "NtDeleteAtom", "NtDeleteBootEntry", "NtDeleteDriverEntry", "NtDeleteFile", "NtDeleteKey", "NtDeleteObjectAuditAlarm", "NtDeletePrivateNamespace", "NtDeleteValueKey", "NtDeleteWnfStateData", "NtDeleteWnfStateName", "NtDirectGraphicsCall", "NtDisableLastKnownGood", "NtDisplayString", "NtDrawText", "NtEnableLastKnownGood", "NtEnumerateBootEntries", "NtEnumerateDriverEntries", "NtEnumerateSystemEnvironmentValuesEx", "NtEnumerateTransactionObject", "NtExtendSection", "NtFilterBootOption", "NtFilterToken", "NtFilterTokenEx", "NtFlushBuffersFileEx", "NtFlushInstallUILanguage", "NtFlushInstructionCache", "NtFlushKey", "NtFlushProcessWriteBuffers", "NtFlushVirtualMemory", "NtFlushWriteBuffer", "NtFreeUserPhysicalPages", "NtFreezeRegistry", "NtFreezeTransactions", "NtGetCachedSigningLevel", "NtGetCompleteWnfStateSubscription", "NtGetContextThread", "NtGetCurrentProcessorNumber", "NtGetCurrentProcessorNumberEx", "NtGetDevicePowerState", "NtGetMUIRegistryInfo", "NtGetNextProcess", "NtGetNextThread", "NtGetNlsSectionPtr", "NtGetNotificationResourceManager", "NtGetWriteWatch", "NtImpersonateAnonymousToken", "NtImpersonateThread", "NtInitializeEnclave", "NtInitializeNlsFiles", "NtInitializeRegistry", "NtInitiatePowerAction", "NtIsSystemResumeAutomatic", "NtIsUILanguageComitted", "NtListenPort", "NtLoadDriver", "NtLoadEnclaveData", "NtLoadKey", "NtLoadKey2", "NtLoadKeyEx", "NtLockFile", "NtLockProductActivationKeys", "NtLockRegistryKey", "NtLockVirtualMemory", "NtMakePermanentObject", "NtMakeTemporaryObject", "NtManageHotPatch", "NtManagePartition", "NtMapCMFModule", "NtMapUserPhysicalPages", "NtMapViewOfSectionEx", "NtModifyBootEntry", "NtModifyDriverEntry", "NtNotifyChangeDirectoryFile", "NtNotifyChangeDirectoryFileEx", "NtNotifyChangeKey", "NtNotifyChangeMultipleKeys", "NtNotifyChangeSession", "NtOpenEnlistment", "NtOpenEventPair", "NtOpenIoCompletion", "NtOpenJobObject", "NtOpenKeyEx", "NtOpenKeyTransacted", "NtOpenKeyTransactedEx", "NtOpenKeyedEvent", "NtOpenMutant", "NtOpenObjectAuditAlarm", "NtOpenPartition", "NtOpenPrivateNamespace", "NtOpenProcessToken", "NtOpenRegistryTransaction", "NtOpenResourceManager", "NtOpenSemaphore", "NtOpenSession", "NtOpenSymbolicLinkObject", "NtOpenThread", "NtOpenTimer", "NtOpenTransaction", "NtOpenTransactionManager", "NtPlugPlayControl", "NtPrePrepareComplete", "NtPrePrepareEnlistment", "NtPrepareComplete", "NtPrepareEnlistment", "NtPrivilegeCheck", "NtPrivilegeObjectAuditAlarm", "NtPrivilegedServiceAuditAlarm", "NtPropagationComplete", "NtPropagationFailed", "NtPssCaptureVaSpaceBulk", "NtPulseEvent", "NtQueryAuxiliaryCounterFrequency", "NtQueryBootEntryOrder", "NtQueryBootOptions", "NtQueryDebugFilterState", "NtQueryDirectoryFileEx", "NtQueryDirectoryObject", "NtQueryDriverEntryOrder", "NtQueryEaFile", "NtQueryFullAttributesFile", "NtQueryInformationAtom", "NtQueryInformationByName", "NtQueryInformationEnlistment", "NtQueryInformationJobObject", "NtQueryInformationPort", "NtQueryInformationResourceManager", "NtQueryInformationTransaction", "NtQueryInformationTransactionManager", "NtQueryInformationWorkerFactory", "NtQueryInstallUILanguage", "NtQueryIntervalProfile", "NtQueryIoCompletion", "NtQueryLicenseValue", "NtQueryMultipleValueKey", "NtQueryMutant", "NtQueryOpenSubKeys", "NtQueryOpenSubKeysEx", "NtQueryPortInformationProcess", "NtQueryQuotaInformationFile", "NtQuerySecurityAttributesToken", "NtQuerySecurityObject", "NtQuerySecurityPolicy", "NtQuerySemaphore", "NtQuerySymbolicLinkObject", "NtQuerySystemEnvironmentValue", "NtQuerySystemEnvironmentValueEx", "NtQuerySystemInformationEx", "NtQueryTimerResolution", "NtQueryWnfStateData", "NtQueryWnfStateNameInformation", "NtQueueApcThreadEx", "NtRaiseException", "NtRaiseHardError", "NtReadOnlyEnlistment", "NtRecoverEnlistment", "NtRecoverResourceManager", "NtRecoverTransactionManager", "NtRegisterProtocolAddressInformation", "NtRegisterThreadTerminatePort", "NtReleaseKeyedEvent", "NtReleaseWorkerFactoryWorker", "NtRemoveIoCompletionEx", "NtRemoveProcessDebug", "NtRenameKey", "NtRenameTransactionManager", "NtReplaceKey", "NtReplacePartitionUnit", "NtReplyWaitReplyPort", "NtRequestPort", "NtResetEvent", "NtResetWriteWatch", "NtRestoreKey", "NtResumeProcess", "NtRevertContainerImpersonation", "NtRollbackComplete", "NtRollbackEnlistment", "NtRollbackRegistryTransaction", "NtRollbackTransaction", "NtRollforwardTransactionManager", "NtSaveKey", "NtSaveKeyEx", "NtSaveMergedKeys", "NtSecureConnectPort", "NtSerializeBoot", "NtSetBootEntryOrder", "NtSetBootOptions", "NtSetCachedSigningLevel", "NtSetCachedSigningLevel2", "NtSetContextThread", "NtSetDebugFilterState", "NtSetDefaultHardErrorPort", "NtSetDefaultLocale", "NtSetDefaultUILanguage", "NtSetDriverEntryOrder", "NtSetEaFile", "NtSetHighEventPair", "NtSetHighWaitLowEventPair", "NtSetIRTimer", "NtSetInformationDebugObject", "NtSetInformationEnlistment", "NtSetInformationJobObject", "NtSetInformationKey", "NtSetInformationResourceManager", "NtSetInformationSymbolicLink", "NtSetInformationToken", "NtSetInformationTransaction", "NtSetInformationTransactionManager", "NtSetInformationVirtualMemory", "NtSetInformationWorkerFactory", "NtSetIntervalProfile", "NtSetIoCompletion", "NtSetIoCompletionEx", "NtSetLdtEntries", "NtSetLowEventPair", "NtSetLowWaitHighEventPair", "NtSetQuotaInformationFile", "NtSetSecurityObject", "NtSetSystemEnvironmentValue", "NtSetSystemEnvironmentValueEx", "NtSetSystemInformation", "NtSetSystemPowerState", "NtSetSystemTime", "NtSetThreadExecutionState", "NtSetTimer2", "NtSetTimerEx", "NtSetTimerResolution", "NtSetUuidSeed", "NtSetVolumeInformationFile", "NtSetWnfProcessNotificationEvent", "NtShutdownSystem", "NtShutdownWorkerFactory", "NtSignalAndWaitForSingleObject", "NtSinglePhaseReject", "NtStartProfile", "NtStopProfile", "NtSubscribeWnfStateChange", "NtSuspendProcess", "NtSuspendThread", "NtSystemDebugControl", "NtTerminateEnclave", "NtTerminateJobObject", "NtTestAlert", "NtThawRegistry", "NtThawTransactions", "NtTraceControl", "NtTranslateFilePath", "NtUmsThreadYield", "NtUnloadDriver", "NtUnloadKey", "NtUnloadKey2", "NtUnloadKeyEx", "NtUnlockFile", "NtUnlockVirtualMemory", "NtUnmapViewOfSectionEx", "NtUnsubscribeWnfStateChange", "NtUpdateWnfStateData", "NtVdmControl", "NtWaitForAlertByThreadId", "NtWaitForDebugEvent", "NtWaitForKeyedEvent", "NtWaitForWorkViaWorkerFactory", "NtWaitHighEventPair", "NtWaitLowEventPair", "NtLoadKey3" }; 90 | 91 | void data::initialize() 92 | { 93 | for (auto i = 0; i < sizeof(windows_20h2_syscalls) / sizeof(windows_20h2_syscalls[0]); i++) 94 | { 95 | auto call = std::make_shared(windows_20h2_syscalls[i]); 96 | 97 | if (!call->get_address()) 98 | { 99 | continue; 100 | } 101 | 102 | syscall_data.push_back(call); 103 | } 104 | } -------------------------------------------------------------------------------- /syscall_extractor/syscalls.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum e_syscall_extractor_errors : int32_t 4 | { 5 | // Couldn't find a mov eax, ID instruction while disassembling the syscall's address. 6 | mov_eax_instruction_not_found = -3, 7 | 8 | // Couldn't find a valid address when calling GetProcAddress to find the syscall stub in ntdll.dll. 9 | syscall_address_not_found = -2, 10 | 11 | // Couldn't find the syscall's object in the syscall_data vector. The syscall likely doesn't exist 12 | // in this windows version. 13 | syscall_name_not_found = -1, 14 | 15 | // Used to "initialize" a yet to be initialized id. 16 | uninitialized = 0 17 | }; 18 | 19 | class syscall_t 20 | { 21 | private: 22 | std::string name; 23 | void* address; 24 | 25 | /// 26 | /// Represents the syscall's ID. It's going to sit uninitialized until syscall_t::get_id() is called. 27 | /// 28 | uint32_t id; 29 | 30 | /// 31 | /// bool that represents whether or not the syscall has been disassembled and its ID cached. 32 | /// 33 | /// It will be true even if the syscall's ID couldn't be found for whatever reason / error, in this case the 34 | /// error will be stored in the ID property and can be retrieved with syscall_t::get_id(). 35 | /// 36 | bool id_initialized; 37 | 38 | public: 39 | /// 40 | /// Gets the syscall's name. 41 | /// 42 | /// A copy of the name property as initialized. 43 | std::string get_name(); 44 | 45 | /// 46 | /// Get the address this syscall's stub resides in. 47 | /// 48 | /// The addrses this syscall's stub resides in. 49 | void* get_address(); 50 | 51 | /// 52 | /// Will try to retrieve the syscall's id, if the id field has not been initialized or the disassembling previously 53 | /// errored out, there won't be any disassembling performed, the same will happen if the id has already been retrieved 54 | /// successfully, and a the cached id will be returned. 55 | /// 56 | /// If > 0, the syscall's id, otherwise, an error code from the e_syscall_extractor_errors enum. 57 | uint32_t get_id(); 58 | 59 | /// 60 | /// Will instantiate a syscall object instance and will immediately try retrieving its address by name via GetProcAddress from ntdll.dll. 61 | /// 62 | /// The syscall's name. 63 | syscall_t(std::string name); 64 | }; 65 | 66 | namespace data 67 | { 68 | /// 69 | /// Hardcoded constant data representing the names of all syscalls in windows 20h2. 70 | /// 71 | extern const char* const windows_20h2_syscalls[]; 72 | 73 | /// 74 | /// Vector containing std::shared_ptrs that we will need to be able to store and retrieve data. 75 | /// 76 | extern std::vector> syscall_data; 77 | 78 | /// 79 | /// The get_syscall_id function will get a syscall's id via disassembling, if the syscall has already been disassembled 80 | /// in the past, or its address is zero for whatever reason, either an error will be returned, or the syscall's ID. 81 | /// All errors are represented by a negative number in the e_syscall_extractor_errors enum. 82 | /// 83 | /// The syscall's name. 84 | /// If > 0, the syscall's ID, otherwise, an error from e_syscall_extractor_errors. 85 | uint32_t get_syscall_id(std::string name); 86 | 87 | /// 88 | /// Populate the syscall_data std::vector with the objects that we'll need. 89 | /// 90 | void initialize(); 91 | } --------------------------------------------------------------------------------