@@ -428,11 +428,21 @@ using fnNtFlushInstructionCache = NTSTATUS(NTAPI*)(HANDLE ProcessHandle, PVOID B
428
428
429
429
using fnDllMain = BOOL (WINAPI*)(HINSTANCE, DWORD, LPVOID);
430
430
431
+ using fnNtOpenThread = NTSTATUS (NTAPI*)(PHANDLE ThreadHandle, ACCESS_MASK AccessMask, POBJECT_ATTRIBUTES ObjectAttributes, CLIENT_ID* ClientId);
432
+ using fnNtSuspendThread = NTSTATUS (NTAPI*)(HANDLE ThreadHandle, PULONG PreviousSuspendCount);
433
+ using fnNtResumeThread = NTSTATUS (NTAPI*)(HANDLE ThreadHandle, PULONG SuspendCount);
434
+
431
435
typedef struct _LOADER_DATA {
432
436
void * m_pImageAddress;
433
437
438
+ DWORD m_unMainThread;
439
+
434
440
HMODULE m_hNTDLL;
435
441
442
+ fnNtOpenThread m_pNtOpenThread;
443
+ fnNtSuspendThread m_pNtSuspendThread;
444
+ fnNtResumeThread m_pNtResumeThread;
445
+
436
446
fnRtlDosPathNameToNtPathName_U m_pRtlDosPathNameToNtPathName_U;
437
447
438
448
fnRtlFreeUnicodeString m_pRtlFreeUnicodeString;
@@ -779,27 +789,62 @@ DEFINE_CODE_IN_SECTION(".load") DWORD WINAPI Loader(LPVOID lpParameter) { SELF_I
779
789
return EXIT_FAILURE;
780
790
}
781
791
792
+ HANDLE hMainThread = nullptr ;
793
+
794
+ CLIENT_ID cid = {};
795
+ cid.UniqueProcess = nullptr ;
796
+ cid.UniqueThread = reinterpret_cast <HANDLE>(static_cast <ULONG_PTR>(pLD->m_unMainThread ));
797
+
798
+ OBJECT_ATTRIBUTES oa = {};
799
+ InitializeObjectAttributes (&oa, nullptr , 0 , nullptr , nullptr );
800
+
801
+ if (!NT_SUCCESS (pLD->m_pNtOpenThread (&hMainThread, THREAD_SUSPEND_RESUME, &oa, &cid))) {
802
+ return EXIT_FAILURE;
803
+ }
804
+
805
+ ULONG unSuspendCount = 0 ;
806
+ if (!NT_SUCCESS (pLD->m_pNtSuspendThread (hMainThread, &unSuspendCount))) {
807
+ return EXIT_FAILURE;
808
+ }
809
+
782
810
if (!MapImage (pLD)) {
783
811
return EXIT_FAILURE;
784
812
}
785
813
786
814
if (!FixRelocations (pLD)) {
815
+ SIZE_T unSize = 0 ;
816
+ pLD->m_pNtFreeVirtualMemory (reinterpret_cast <HANDLE>(-1 ), &pLD->m_pImageAddress , &unSize, MEM_RELEASE);
787
817
return EXIT_FAILURE;
788
818
}
789
819
790
820
if (!ResolveImports (pLD)) {
821
+ SIZE_T unSize = 0 ;
822
+ pLD->m_pNtFreeVirtualMemory (reinterpret_cast <HANDLE>(-1 ), &pLD->m_pImageAddress , &unSize, MEM_RELEASE);
791
823
return EXIT_FAILURE;
792
824
}
793
825
794
826
if (!ProtectSections (pLD)) {
827
+ SIZE_T unSize = 0 ;
828
+ pLD->m_pNtFreeVirtualMemory (reinterpret_cast <HANDLE>(-1 ), &pLD->m_pImageAddress , &unSize, MEM_RELEASE);
795
829
return EXIT_FAILURE;
796
830
}
797
831
798
832
if (!ExecuteTLS (pLD, DLL_PROCESS_ATTACH)) { // Useless for simple patching dlls
833
+ SIZE_T unSize = 0 ;
834
+ pLD->m_pNtFreeVirtualMemory (reinterpret_cast <HANDLE>(-1 ), &pLD->m_pImageAddress , &unSize, MEM_RELEASE);
799
835
return EXIT_FAILURE;
800
836
}
801
837
802
838
if (!CallDllMain (pLD, DLL_PROCESS_ATTACH)) {
839
+ SIZE_T unSize = 0 ;
840
+ pLD->m_pNtFreeVirtualMemory (reinterpret_cast <HANDLE>(-1 ), &pLD->m_pImageAddress , &unSize, MEM_RELEASE);
841
+ return EXIT_FAILURE;
842
+ }
843
+
844
+ unSuspendCount = 0 ;
845
+ if (!NT_SUCCESS (pLD->m_pNtResumeThread (hMainThread, &unSuspendCount))) {
846
+ SIZE_T unSize = 0 ;
847
+ pLD->m_pNtFreeVirtualMemory (reinterpret_cast <HANDLE>(-1 ), &pLD->m_pImageAddress , &unSize, MEM_RELEASE);
803
848
return EXIT_FAILURE;
804
849
}
805
850
@@ -1165,6 +1210,18 @@ bool FillLoaderData(HANDLE hProcess, PLOADER_DATA pLoaderData) {
1165
1210
return false ;
1166
1211
}
1167
1212
1213
+ if (!GetRemoteProcAddress (hProcess, _T (" ntdll.dll" ), " NtOpenThread" , &pLoaderData->m_pNtOpenThread )) {
1214
+ return false ;
1215
+ }
1216
+
1217
+ if (!GetRemoteProcAddress (hProcess, _T (" ntdll.dll" ), " NtSuspendThread" , &pLoaderData->m_pNtSuspendThread )) {
1218
+ return false ;
1219
+ }
1220
+
1221
+ if (!GetRemoteProcAddress (hProcess, _T (" ntdll.dll" ), " NtResumeThread" , &pLoaderData->m_pNtResumeThread )) {
1222
+ return false ;
1223
+ }
1224
+
1168
1225
if (!GetRemoteProcAddress (hProcess, _T (" ntdll.dll" ), " RtlDosPathNameToNtPathName_U" , &pLoaderData->m_pRtlDosPathNameToNtPathName_U )) {
1169
1226
return false ;
1170
1227
}
@@ -1260,7 +1317,7 @@ void OnExitThreadEvent(DWORD unProcessID, DWORD unThreadID, DWORD unExitCode) {
1260
1317
#endif // _DEBUG
1261
1318
}
1262
1319
1263
- void OnLoadModuleEvent (DWORD unProcessID, LPVOID pImageBase) {
1320
+ void OnLoadModuleEvent (DWORD unProcessID, DWORD unThreadID, LPVOID pImageBase) {
1264
1321
auto Process = GetDebugProcess (unProcessID);
1265
1322
if (!Process) {
1266
1323
return ;
@@ -1297,9 +1354,7 @@ void OnLoadModuleEvent(DWORD unProcessID, LPVOID pImageBase) {
1297
1354
1298
1355
DWORD dwAttrib = GetFileAttributes (ProcessHiJackLibraryPath.c_str ());
1299
1356
if (!((dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY))) { // File not exist
1300
- #ifndef HIJACK_DETACH_IF_NO_INJECTABLE
1301
1357
g_bContinueDebugging = false ;
1302
- #endif
1303
1358
return ;
1304
1359
}
1305
1360
@@ -1418,6 +1473,7 @@ void OnLoadModuleEvent(DWORD unProcessID, LPVOID pImageBase) {
1418
1473
}
1419
1474
1420
1475
LoaderData.m_pImageAddress = pImageAddress;
1476
+ LoaderData.m_unMainThread = unThreadID;
1421
1477
1422
1478
if (!FillLoaderData (Process, &LoaderData)) {
1423
1479
VirtualFreeEx (Process, pImageAddress, 0 , MEM_RELEASE);
@@ -1459,7 +1515,7 @@ void OnLoadModuleEvent(DWORD unProcessID, LPVOID pImageBase) {
1459
1515
}
1460
1516
}
1461
1517
1462
- void OnUnloadModuleEvent (DWORD unProcessID, LPVOID ImageBase) {
1518
+ void OnUnloadModuleEvent (DWORD unProcessID, DWORD unThreadID, LPVOID ImageBase) {
1463
1519
#ifdef _DEBUG
1464
1520
#ifdef _WIN64
1465
1521
_tprintf_s (_T (" MODULE UNLOAD: 0x%016llX\n " ), reinterpret_cast <size_t >(ImageBase));
@@ -1579,7 +1635,7 @@ bool DebugProcess(DWORD unTimeout, bool* pbContinue, bool* pbStopped) {
1579
1635
g_Modules[DebugEvent.dwProcessId ][DebugEvent.u .CreateProcessInfo .lpBaseOfImage ] = GetFilePath (DebugEvent.u .CreateProcessInfo .hFile );
1580
1636
OnCreateProcessEvent (DebugEvent.dwProcessId );
1581
1637
OnCreateThreadEvent (DebugEvent.dwProcessId , DebugEvent.dwThreadId );
1582
- OnLoadModuleEvent (DebugEvent.dwProcessId , DebugEvent.u .CreateProcessInfo .lpBaseOfImage );
1638
+ OnLoadModuleEvent (DebugEvent.dwProcessId , DebugEvent.dwThreadId , DebugEvent. u .CreateProcessInfo .lpBaseOfImage );
1583
1639
SafeCloseHandle (DebugEvent.u .CreateProcessInfo .hFile );
1584
1640
break ;
1585
1641
@@ -1614,12 +1670,12 @@ bool DebugProcess(DWORD unTimeout, bool* pbContinue, bool* pbStopped) {
1614
1670
1615
1671
case LOAD_DLL_DEBUG_EVENT:
1616
1672
g_Modules[DebugEvent.dwProcessId ][DebugEvent.u .LoadDll .lpBaseOfDll ] = GetFilePath (DebugEvent.u .LoadDll .hFile );
1617
- OnLoadModuleEvent (DebugEvent.dwProcessId , DebugEvent.u .LoadDll .lpBaseOfDll );
1673
+ OnLoadModuleEvent (DebugEvent.dwProcessId , DebugEvent.dwThreadId , DebugEvent. u .LoadDll .lpBaseOfDll );
1618
1674
SafeCloseHandle (DebugEvent.u .LoadDll .hFile );
1619
1675
break ;
1620
1676
1621
1677
case UNLOAD_DLL_DEBUG_EVENT:
1622
- OnUnloadModuleEvent (DebugEvent.dwProcessId , DebugEvent.u .UnloadDll .lpBaseOfDll );
1678
+ OnUnloadModuleEvent (DebugEvent.dwProcessId , DebugEvent.dwThreadId , DebugEvent. u .UnloadDll .lpBaseOfDll );
1623
1679
1624
1680
g_Modules[DebugEvent.dwProcessId ].erase (DebugEvent.u .UnloadDll .lpBaseOfDll );
1625
1681
if (g_Modules[DebugEvent.dwProcessId ].empty ()) {
0 commit comments