Skip to content

Commit 74dfd63

Browse files
committed
Updated to V4.5, improved handle hijacking routines, better start/stop download functionality, added FakeVEH shellcode execution method, fixed symbol issue and handle hijacking crash (hopefully)
1 parent 6f1796f commit 74dfd63

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+4984
-2173
lines changed

GH Injector Library.sln

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.29306.81
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31612.314
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GH Injector Library", "GH Injector Library\GH Injector Library.vcxproj", "{AC732425-E265-40FF-842F-C59CECE9A96C}"
77
EndProject

GH Injector Library/Download Manager.cpp

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
#include "Download Manager.h"
44

5-
DownloadManager::DownloadManager()
5+
DownloadManager::DownloadManager(bool ForceRedownload)
66
{
77
m_hInterruptEvent = nullptr;
88
m_fProgress = 0.0f;
99
m_fOldProgress = 0.0f;
10+
m_bForceRedownload = ForceRedownload;
1011
}
1112

1213
DownloadManager::~DownloadManager()
@@ -40,7 +41,7 @@ HRESULT __stdcall DownloadManager::OnStartBinding(DWORD dwReserved, IBinding * p
4041
UNREFERENCED_PARAMETER(dwReserved);
4142
UNREFERENCED_PARAMETER(pib);
4243

43-
LOG(" DownloadManager: OnStartBinding\n");
44+
LOG(2, "DownloadManager: OnStartBinding\n");
4445

4546
return S_OK;
4647
}
@@ -49,7 +50,7 @@ HRESULT __stdcall DownloadManager::GetPriority(LONG * pnPriority)
4950
{
5051
UNREFERENCED_PARAMETER(pnPriority);
5152

52-
LOG(" DownloadManager: GetPriority\n");
53+
LOG(2, "DownloadManager: GetPriority\n");
5354

5455
return S_OK;
5556
}
@@ -58,7 +59,7 @@ HRESULT __stdcall DownloadManager::OnLowResource(DWORD reserved)
5859
{
5960
UNREFERENCED_PARAMETER(reserved);
6061

61-
LOG(" DownloadManager: OnLowResource\n");
62+
LOG(2, "DownloadManager: OnLowResource\n");
6263

6364
return S_OK;
6465
}
@@ -68,17 +69,28 @@ HRESULT __stdcall DownloadManager::OnStopBinding(HRESULT hresult, LPCWSTR szErro
6869
UNREFERENCED_PARAMETER(hresult);
6970
UNREFERENCED_PARAMETER(szError);
7071

71-
LOG(" DownloadManager: OnStopBinding\n");
72+
LOG(2, "DownloadManager: OnStopBinding\n");
7273

7374
return S_OK;
7475
}
7576

7677
HRESULT __stdcall DownloadManager::GetBindInfo(DWORD * grfBINDF, BINDINFO * pbindinfo)
7778
{
78-
UNREFERENCED_PARAMETER(grfBINDF);
79-
UNREFERENCED_PARAMETER(pbindinfo);
79+
LOG(2, "DownloadManager: GetBindInfo\n");
8080

81-
LOG(" DownloadManager: GetBindInfo\n");
81+
if (m_bForceRedownload)
82+
{
83+
if (grfBINDF)
84+
{
85+
*grfBINDF = BINDF_GETNEWESTVERSION | BINDF_NEEDFILE;
86+
}
87+
88+
if (pbindinfo)
89+
{
90+
pbindinfo->dwOptions = BINDINFO_OPTIONS_WININETFLAG;
91+
pbindinfo->dwOptionsFlags = INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD;
92+
}
93+
}
8294

8395
return S_OK;
8496
}
@@ -90,7 +102,7 @@ HRESULT __stdcall DownloadManager::OnDataAvailable(DWORD grfBSCF, DWORD dwSize,
90102
UNREFERENCED_PARAMETER(pformatetc);
91103
UNREFERENCED_PARAMETER(pstgmed);
92104

93-
LOG(" DownloadManager: OnDataAvailable\n");
105+
LOG(2, "DownloadManager: OnDataAvailable\n");
94106

95107
return S_OK;
96108
}
@@ -100,7 +112,7 @@ HRESULT __stdcall DownloadManager::OnObjectAvailable(const IID & riid, IUnknown
100112
UNREFERENCED_PARAMETER(riid);
101113
UNREFERENCED_PARAMETER(punk);
102114

103-
LOG(" DownloadManager: OnObjectAvailable\n");
115+
LOG(2, "DownloadManager: OnObjectAvailable\n");
104116

105117
return S_OK;
106118
}
@@ -112,7 +124,7 @@ HRESULT __stdcall DownloadManager::OnProgress(ULONG ulProgress, ULONG ulProgress
112124

113125
if (m_hInterruptEvent && WaitForSingleObject(m_hInterruptEvent, 0) == WAIT_OBJECT_0)
114126
{
115-
LOG(" DownloadManager: Interrupting download\n");
127+
LOG(2, "DownloadManager: Interrupting download\n");
116128

117129
return E_ABORT;
118130
}
@@ -123,7 +135,7 @@ HRESULT __stdcall DownloadManager::OnProgress(ULONG ulProgress, ULONG ulProgress
123135

124136
if (m_fProgress - m_fOldProgress >= 0.1f)
125137
{
126-
LOG(" DownloadManager: %2.0f%%\n", m_fProgress * 100.0f);
138+
LOG(2, "DownloadManager: %2.0f%%\n", 100.0 * m_fProgress);
127139
m_fOldProgress = m_fProgress;
128140
}
129141
}
@@ -135,15 +147,22 @@ BOOL DownloadManager::SetInterruptEvent(HANDLE hInterrupt)
135147
{
136148
if (m_hInterruptEvent)
137149
{
138-
CloseHandle(m_hInterruptEvent);
150+
if (!CloseHandle(m_hInterruptEvent))
151+
{
152+
LOG(2, "Failed to close previous interrupt handle object: %08X\n", GetLastError());
153+
}
154+
155+
m_hInterruptEvent = nullptr;
139156
}
140157

141-
LOG(" DownloadManager: New interrupt event specified\n");
158+
LOG(2, "DownloadManager: New interrupt event specified\n");
159+
160+
auto current_process = GetCurrentProcess();
142161

143-
return DuplicateHandle(GetCurrentProcess(), hInterrupt, GetCurrentProcess(), &m_hInterruptEvent, NULL, FALSE, DUPLICATE_SAME_ACCESS);
162+
return DuplicateHandle(current_process, hInterrupt, current_process, &m_hInterruptEvent, NULL, FALSE, DUPLICATE_SAME_ACCESS);
144163
}
145164

146-
float DownloadManager::GetDownloadProgress()
165+
float DownloadManager::GetDownloadProgress() const
147166
{
148167
return m_fProgress;
149168
}

GH Injector Library/Download Manager.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ class DownloadManager : public IBindStatusCallback
1111
HANDLE m_hInterruptEvent;
1212
float m_fProgress;
1313
float m_fOldProgress;
14+
bool m_bForceRedownload;
1415

1516
public:
1617

17-
DownloadManager();
18+
DownloadManager(bool ForceRedownload = true);
1819

1920
~DownloadManager();
2021

@@ -42,5 +43,5 @@ class DownloadManager : public IBindStatusCallback
4243

4344
BOOL SetInterruptEvent(HANDLE hInterrupt);
4445

45-
float GetDownloadProgress();
46+
float GetDownloadProgress() const;
4647
};

GH Injector Library/Eject.cpp

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,76 @@
11
#include "pch.h"
22

33
#include "Eject.h"
4+
#include "Start Routine.h"
45

5-
bool EjectDll(HANDLE hTargetProc, HINSTANCE hModule)
6+
bool EjectDll(HANDLE hTargetProc, HINSTANCE hModule, bool WOW64)
67
{
7-
LOG(" EjectDll called\n");
8-
LOG(" PID = %08X\n", GetProcessId(hTargetProc));
9-
LOG(" hModule = %p\n", hModule);
8+
LOG(3, "EjectDll called\n");
9+
LOG(4, "PID = %08X\n", GetProcessId(hTargetProc));
10+
LOG(4, "hModule = %p\n", hModule);
1011

11-
HANDLE hThread = nullptr;
12-
auto ntRet = NATIVE::NtCreateThreadEx(&hThread, THREAD_ALL_ACCESS, nullptr, hTargetProc, NATIVE::LdrUnloadDll, ReCa<void *>(hModule), NULL, 0, 0, 0, nullptr);
13-
if (FAILED(ntRet))
14-
{
15-
LOG(" NtCreateThreadEx failed: %08X\n", ntRet);
12+
ERROR_DATA eject_data;
13+
DWORD remote_ret = 0;
14+
DWORD ret = 0;
1615

17-
return false;
16+
#ifdef _WIN64
17+
if (WOW64)
18+
{
19+
ret = StartRoutine_WOW64(hTargetProc, WOW64::LdrUnloadDll_WOW64, MDWD(hModule), LAUNCH_METHOD::LM_NtCreateThreadEx, NULL, remote_ret, INJ_EJECT_TIMEOUT, eject_data);
1820
}
19-
20-
if (WaitForSingleObject(hThread, 500) != WAIT_OBJECT_0)
21+
else
2122
{
22-
LOG(" Ejection thread timed out\n");
23+
ret = StartRoutine(hTargetProc, ReCa<f_Routine>(NATIVE::LdrUnloadDll), hModule, LAUNCH_METHOD::LM_NtCreateThreadEx, NULL, remote_ret, INJ_EJECT_TIMEOUT, eject_data);
24+
}
25+
#else
26+
UNREFERENCED_PARAMETER(WOW64);
2327

24-
TerminateThread(hThread, 0);
25-
CloseHandle(hThread);
28+
ret = StartRoutine(hTargetProc, ReCa<f_Routine>(NATIVE::LdrUnloadDll), hModule, LAUNCH_METHOD::LM_NtCreateThreadEx, NULL, remote_ret, INJ_EJECT_TIMEOUT, eject_data);
29+
#endif
30+
31+
if (ret != SR_ERR_SUCCESS)
32+
{
33+
LOG(3, "Failed to eject dll:\n");
34+
LOG(4, "ret = %08X\n", ret);
35+
LOG(4, "advanced = %08X\n", eject_data.AdvErrorCode);
2636

2737
return false;
2838
}
29-
30-
if (!GetExitCodeThread(hThread, ReCa<DWORD *>(&ntRet)))
39+
else if (NT_FAIL(remote_ret))
3140
{
32-
LOG(" GetExitCodeThread failed: %08X\n", GetLastError());
33-
34-
CloseHandle(hThread);
41+
LOG(3, "Failed to eject dll:\n");
42+
LOG(4, "remote_ret = %08X:\n", remote_ret);
3543

3644
return false;
3745
}
3846

39-
CloseHandle(hThread);
47+
LOG(3, "Dll ejected successfully\n");
4048

41-
if (NT_FAIL(ntRet))
42-
{
43-
LOG(" LdrUnloadDll failed: %08X\n", ntRet);
49+
return true;
50+
}
4451

45-
return false;
52+
bool EjectHijackLibrary(HANDLE hTargetProc, HINSTANCE hInjectionModuleEx, bool Interrupt)
53+
{
54+
LOG(2, "Ejecting hijack library\n");
55+
56+
if (!Interrupt)
57+
{
58+
return EjectDll(hTargetProc, hInjectionModuleEx);
4659
}
4760

48-
LOG(" Dll ejected successfully\n");
61+
ERROR_DATA interrupt_data;
62+
DWORD remote_ret = 0;
63+
DWORD ret = 0;
64+
f_Routine pInterruptDownloadEx = ReCa<f_Routine>(ReCa<UINT_PTR>(InterruptDownloadEx) - ReCa<UINT_PTR>(g_hInjMod) + ReCa<UINT_PTR>(hInjectionModuleEx));
4965

50-
return true;
66+
ret = StartRoutine(hTargetProc, pInterruptDownloadEx, nullptr, LAUNCH_METHOD::LM_NtCreateThreadEx, NULL, remote_ret, INJ_EJECT_TIMEOUT, interrupt_data);
67+
68+
if (ret != SR_ERR_SUCCESS)
69+
{
70+
LOG(2, "Failed to interrupt hijack library:\n");
71+
LOG(3, "ret = %08X\n", ret);
72+
LOG(3, "advanced = %08X\n", interrupt_data.AdvErrorCode);
73+
} //try to eject even if interrupt failed
74+
75+
return EjectDll(hTargetProc, hInjectionModuleEx);
5176
}

GH Injector Library/Eject.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
#include "Import Handler.h"
44

5-
bool EjectDll(HANDLE hTargetProc, HINSTANCE hModule);
5+
#define INJ_EJECT_TIMEOUT 200
6+
7+
bool EjectDll(HANDLE hTargetProc, HINSTANCE hModule, bool WOW64 = false);
68
//Unloads a dll using LdrUnloadDll by creating a thread in the target process using NtCreateThreadEx (native only).
79
//
810
//Arguments:
@@ -15,6 +17,29 @@ bool EjectDll(HANDLE hTargetProc, HINSTANCE hModule);
1517
/// PROCESS_VM_READ
1618
// hModule (HINSTANCE):
1719
/// The baseaddress of the module to unload.
20+
// WOW64 (bool):
21+
/// Set to true if the target process is running under WOW64 and the calling process is native.
22+
/// If the calling process is not native this argument is ignored.
23+
//
24+
//Returnvalue (bool):
25+
/// true: the module was unloaded successfully.
26+
/// false: something went wrong, see logs
27+
28+
bool EjectHijackLibrary(HANDLE hTargetProc, HINSTANCE hInjectionModuleEx, bool Interrupt = true);
29+
//Unloads the injection library from another process during handle hijacking.
30+
//
31+
//Arguments:
32+
// hTargetProc (HANDLE):
33+
/// HANDLE to the target process which needs:
34+
/// PROCESS_CREATE_THREAD
35+
/// PROCESS_QUERY_INFORMATION
36+
/// PROCESS_VM_OPERATION
37+
/// PROCESS_VM_WRITE
38+
/// PROCESS_VM_READ
39+
// hInjectionModuleEx (HINSTANCE):
40+
/// The baseaddress of the injection library in the target process.
41+
// Interrupt (bool):
42+
/// If set to true InterruptDownloadEx is called remotely before unloading the dll.
1843
//
1944
//Returnvalue (bool):
2045
/// true: the module was unloaded successfully.

0 commit comments

Comments
 (0)