#include "drvCommon.h"
#include "ProcNativeApiWork.h"
#include "WorkItemUtils.h"
#include "ServiceTableUtils.h"
#include "StringUtils.h"
#include <string>
extern "C"
{
typedef NTSTATUS (*NtQuerySystemInfoPtr)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
}// extern "C"
namespace DetectDriver
{
const wchar_t* strZwQuerySystemInfo = L"ZwQuerySystemInformation";
const wchar_t* strNtQuerySystemInfo = L"NtQuerySystemInformation";
void GetZwQuerySysInfoPointers(PVOID* sstPtr,PVOID* fncPtr)
{
std::wstring functionNameZw(strZwQuerySystemInfo);
UNICODE_STRING functionNameZwUnc = utils::wstring2UnicodeStr(functionNameZw);
std::wstring functionNameNt(strNtQuerySystemInfo);
UNICODE_STRING functionNameNtUnc = utils::wstring2UnicodeStr(functionNameNt);
*sstPtr = utils::GetFunctionSSTPtr(&functionNameZwUnc);
*fncPtr = MmGetSystemRoutineAddress(&functionNameNtUnc);
if( *fncPtr == NULL )
throw std::exception("Can't get system routine address");
}
void GetProcListsImpl(NtQuerySystemInfoPtr originalFnc,
NtQuerySystemInfoPtr hookedFnc,
std::vector<char>* originalListBuffer,
std::vector<char>* hookListBuffer)
{
ULONG retLength;
NTSTATUS status;
// Request needed size
ULONG originalDataSize;
status = originalFnc(SystemProcessesAndThreadsInformation,NULL,0,&originalDataSize);
if( status != STATUS_INFO_LENGTH_MISMATCH )
throw std::exception("Can't get original process info data size.");
ULONG hookedDataSize;
status = hookedFnc(SystemProcessesAndThreadsInformation,NULL,0,&hookedDataSize);
if( status != STATUS_INFO_LENGTH_MISMATCH )
throw std::exception("Can't get hooked process info data size.");
// Resize buffers
hookListBuffer->resize(hookedDataSize);
originalListBuffer->resize(originalDataSize);
// Request information
status = originalFnc(SystemProcessesAndThreadsInformation,
&originalListBuffer->front(),originalListBuffer->size(),&retLength);
if( !NT_SUCCESS(status) )
throw std::exception("Can't get process info by original function.");
status = hookedFnc(SystemProcessesAndThreadsInformation,
&hookListBuffer->front(),hookListBuffer->size(),&retLength);
if( !NT_SUCCESS(status) )
throw std::exception("Can't get process info by hooked function.");
}
struct GetProcListParams
{
NtQuerySystemInfoPtr originalFnc;
NtQuerySystemInfoPtr hookedFnc;
std::vector<char>* originalListBuffer;
std::vector<char>* hookListBuffer;
};
void GetProcListsProxy(GetProcListParams* params)
{
GetProcListsImpl(params->originalFnc,
params->hookedFnc,
params->originalListBuffer,
params->hookListBuffer);
}
void GetProcLists(NtQuerySystemInfoPtr originalFnc,
NtQuerySystemInfoPtr hookedFnc,
std::vector<char>* originalListBuffer,
std::vector<char>* hookListBuffer)
{
GetProcListParams params = {originalFnc,
hookedFnc,
originalListBuffer,
hookListBuffer};
utils::CallFromWorkerThread(&GetProcListsProxy,¶ms);
}
void GetProcessInfo(std::vector<char> *hookListBuffer,
std::vector<char> *originalListBuffer)
{
PVOID hookedFncPtr,originalFncPtr;
GetZwQuerySysInfoPointers(&hookedFncPtr,&originalFncPtr);
if(hookedFncPtr == originalFncPtr)
throw std::exception("No hooks detected.");
NtQuerySystemInfoPtr hookedFnc = (NtQuerySystemInfoPtr)hookedFncPtr;
NtQuerySystemInfoPtr originalFnc = (NtQuerySystemInfoPtr)originalFncPtr;
GetProcLists(originalFnc,hookedFnc,originalListBuffer,hookListBuffer);
}
}