inline T gen_syscall(DWORD syscallid, LPCSTR szCallName)
{
auto p = NtCall::get<T>(std::string(szCallName));
if (p)
{
return p;
}
auto KiServiceEntry = (ULONG64)ddk::util::get_KiServiceEntry(); 这个get_KiServiceEntry()究竟是获取什么?
if (!KiServiceEntry)
{
return reinterpret_cast<T>(nullptr);
}
LOG_DEBUG("Entry = %p\r\n", (PVOID)KiServiceEntry);
//這裏Build
unsigned char syscall_shellcode[] =
{
0x48, 0x8B, 0xC4, 0xFA, 0x48, 0x83, 0xEC, 0x10, 0x50, 0x9C,
0x6A, 0x10, 0x48, 0x8D, 0x05, 0x0C, 0x00, 0x00, 0x00, 0x50,
0xB8, 0x78, 0x56, 0x34, 0x12, 0xFF, 0x25, 0x01, 0x00, 0x00,
0x00, 0xC3, 0x66, 0x66, 0x77, 0x77, 0x88, 0x88, 0x99, 0x99
};
size_t offset_syscallnumber = 0x15;
size_t offset_kiserviceAddr = 0x20;
auto pshellcode = reinterpret_cast<PUCHAR>(ExAllocatePoolWithTag(NonPagedPool, sizeof(syscall_shellcode), 'scsc'));
if (!pshellcode)
{
return reinterpret_cast<T>(nullptr);
}
RtlCopyMemory(pshellcode, syscall_shellcode, sizeof(syscall_shellcode));
auto psyscallid = (PDWORD)(&pshellcode[offset_syscallnumber]);
auto pKiServiceAddr = (PULONG64)(&pshellcode[offset_kiserviceAddr]);
*psyscallid = syscallid;
*pKiServiceAddr = KiServiceEntry;
_funcs.insert(std::make_pair(std::string(szCallName), (PVOID)pshellcode));
_syscalltable.push_back(pshellcode);
LOG_DEBUG("syscall = %p\r\n", pshellcode);
return reinterpret_cast<T>(pshellcode);
}
template<typename T, typename... Args>
inline auto CallNtUser(const std::string& name, Args&&... args) -> typename std::result_of<T(Args...)>::type
{
bool win32 = false;
KAPC_STATE apcstate = {};
auto syscallid = mmTable[name];
auto pfn = gen_syscall<T>(syscallid, name.c_str()); 这里调用上面的gen_syscall函数
LOG_DEBUG("call %p\r\n", pfn);
if (!PsGetProcessWin32Process(PsGetCurrentProcess()))
{
LOG_DEBUG("Switch To Csrss\r\n");
win32 = true;
KeStackAttachProcess(Win32Process, &apcstate);
}
auto result = pfn ? pfn(std::forward<Args>(args)...) : (std::result_of<T(Args...)>::type)(0);
if(win32)
KeUnstackDetachProcess(&apcstate);
return result;
}
CallNtUser(NtUserGetForegroundWindow,....); 这里调用CallNtUser函数,原先不是这样写的,我只是为了方便阅读,放在这里的