mirror of
https://github.com/rbmm/LdrpKernel32DllName
synced 2026-06-08 17:03:20 +00:00
204 lines
3.4 KiB
C++
204 lines
3.4 KiB
C++
#include "StdAfx.h"
|
|
|
|
_NT_BEGIN
|
|
#include "threads.h"
|
|
|
|
#ifdef _X86_
|
|
#define __IMP(x) _imp__ ## x
|
|
#pragma comment(linker, "/include:__imp__Dbg_Print")
|
|
#else
|
|
#define __IMP(x) __imp_ ## x
|
|
#pragma comment(linker, "/include:__imp_Dbg_Print")
|
|
#endif
|
|
|
|
EXTERN_C
|
|
NTSYSAPI
|
|
NTSTATUS NTAPI NtGetNextThread(
|
|
_In_ HANDLE ProcessHandle,
|
|
_In_ HANDLE ThreadHandle,
|
|
_In_ ACCESS_MASK DesiredAccess,
|
|
_In_ ULONG HandleAttributes,
|
|
_In_ ULONG Flags,
|
|
_Out_ PHANDLE NewThreadHandle
|
|
);
|
|
|
|
void __cdecl Nop_Print(_In_z_ _Printf_format_string_ PCSTR , ...)
|
|
{
|
|
}
|
|
|
|
EXTERN_C PVOID __IMP(Dbg_Print) = Nop_Print;
|
|
|
|
struct ThreadInfo : CONTEXT
|
|
{
|
|
HANDLE hThread = 0;
|
|
ThreadInfo* next = 0;
|
|
HANDLE UniqueThread; // for debug only
|
|
|
|
~ThreadInfo()
|
|
{
|
|
Dbg_Print("%s<%p>(%p)\n", __FUNCTION__, this, UniqueThread);
|
|
}
|
|
|
|
ThreadInfo(HANDLE UniqueThread) : UniqueThread(UniqueThread)
|
|
{
|
|
RtlZeroMemory(static_cast<CONTEXT*>(this), sizeof(CONTEXT));
|
|
ContextFlags = CONTEXT_CONTROL;
|
|
Dbg_Print("%s<%p>(%p)\n", __FUNCTION__, this, UniqueThread);
|
|
}
|
|
};
|
|
|
|
void ResumeAndFree(_In_ ThreadInfo* next)
|
|
{
|
|
if (ThreadInfo* pti = next)
|
|
{
|
|
do
|
|
{
|
|
next = pti->next;
|
|
|
|
if (HANDLE hThread = pti->hThread)
|
|
{
|
|
ZwResumeThread(hThread, 0);
|
|
NtClose(hThread);
|
|
}
|
|
|
|
delete pti;
|
|
|
|
} while (pti = next);
|
|
}
|
|
}
|
|
|
|
NTSTATUS SuspendAll(_Out_ ThreadInfo** ppti)
|
|
{
|
|
ThreadInfo* pti = 0;
|
|
HANDLE ThreadHandle = 0, hThread;
|
|
NTSTATUS status;
|
|
BOOL bClose = FALSE;
|
|
|
|
HANDLE UniqueThread = (HANDLE)GetCurrentThreadId();
|
|
|
|
loop:
|
|
status = NtGetNextThread(NtCurrentProcess(), ThreadHandle,
|
|
THREAD_QUERY_LIMITED_INFORMATION|THREAD_SUSPEND_RESUME|THREAD_GET_CONTEXT|THREAD_SET_CONTEXT,
|
|
0, 0, &hThread);
|
|
|
|
if (bClose)
|
|
{
|
|
NtClose(ThreadHandle);
|
|
bClose = FALSE;
|
|
}
|
|
|
|
if (0 <= status)
|
|
{
|
|
ThreadHandle = hThread;
|
|
|
|
THREAD_BASIC_INFORMATION tbi;
|
|
|
|
if (0 <= (status = ZwQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof(tbi), 0)))
|
|
{
|
|
if (tbi.ClientId.UniqueThread == UniqueThread)
|
|
{
|
|
bClose = TRUE;
|
|
goto loop;
|
|
}
|
|
|
|
if (0 <= (status = ZwSuspendThread(hThread, 0)))
|
|
{
|
|
status = STATUS_NO_MEMORY;
|
|
|
|
if (ThreadInfo* next = new ThreadInfo(tbi.ClientId.UniqueThread))
|
|
{
|
|
if (0 <= (status = ZwGetContextThread(hThread, next)))
|
|
{
|
|
next->next = pti;
|
|
pti = next;
|
|
next->hThread = hThread;
|
|
goto loop;
|
|
}
|
|
|
|
delete next;
|
|
}
|
|
|
|
ZwResumeThread(hThread, 0);
|
|
}
|
|
}
|
|
|
|
if (status == STATUS_THREAD_IS_TERMINATING)
|
|
{
|
|
bClose = TRUE;
|
|
goto loop;
|
|
}
|
|
|
|
NtClose(hThread);
|
|
}
|
|
|
|
switch (status)
|
|
{
|
|
case STATUS_NO_MORE_ENTRIES:
|
|
case STATUS_SUCCESS:
|
|
*ppti = pti;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
ResumeAndFree(pti);
|
|
|
|
*ppti = 0;
|
|
return status;
|
|
}
|
|
|
|
#if defined(_M_IX86)
|
|
#define Xip Eip
|
|
#elif defined (_M_X64)
|
|
#define Xip Rip
|
|
#else
|
|
#error
|
|
#endif
|
|
|
|
#include "threads.h"
|
|
|
|
BOOLEAN MovePc(_In_ ThreadInfo* pti, _In_ ULONG_PTR PcFrom, _In_ ULONG_PTR PcTo, _In_ ULONG cb, _In_ DTA* Lens)
|
|
{
|
|
BOOLEAN fOk = FALSE;
|
|
|
|
if (pti)
|
|
{
|
|
do
|
|
{
|
|
SIZE_T s = pti->Xip - PcFrom;
|
|
|
|
if (s < cb)
|
|
{
|
|
pti->Xip = PcTo + s;
|
|
|
|
ULONG ofs;
|
|
|
|
if (ofs = Lens->ofs1)
|
|
{
|
|
if (ofs <= s)
|
|
{
|
|
pti->Xip += Lens->add1;
|
|
}
|
|
}
|
|
|
|
if (ofs = Lens->ofs2)
|
|
{
|
|
if (ofs <= s)
|
|
{
|
|
pti->Xip += Lens->add2;
|
|
}
|
|
}
|
|
|
|
Dbg_Print("MovePc: %p -> %p\n", PcFrom + s, pti->Xip);
|
|
|
|
if (0 > ZwSetContextThread(pti->hThread, pti))
|
|
{
|
|
fOk = FALSE;
|
|
}
|
|
}
|
|
|
|
} while (pti = pti->next);
|
|
}
|
|
|
|
return fOk;
|
|
}
|
|
|
|
_NT_END |