添加项目文件。
This commit is contained in:
384
Etw Syscall/Etw Syscall.cpp
Normal file
384
Etw Syscall/Etw Syscall.cpp
Normal file
@@ -0,0 +1,384 @@
|
||||
// Etw Syscall.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
|
||||
//
|
||||
|
||||
#include "head.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
int g_iNumOfThreads = 0;
|
||||
DWORD* g_lpdwThreadsIdArray = NULL;
|
||||
/*
|
||||
* 维护两个个状态表
|
||||
* thread id <-> 处理器id[0],切换状态[1]
|
||||
*/
|
||||
//std::map<int, std::vector<int>> g_dwThreadsWithProcesserMap;
|
||||
/*
|
||||
* 处理器id <-> threadid[0]
|
||||
*/
|
||||
std::map<int, int> g_dwProcesserWithThreadsMap;
|
||||
/*
|
||||
* 线程id <-> 进程id
|
||||
*/
|
||||
std::map<int, DWORD> g_dwProcessWithThreadidsMap;
|
||||
/*
|
||||
* 进程pid <-> 进程名字
|
||||
*/
|
||||
std::map<DWORD, std::wstring> g_dwProcessNameWithProcessIdMap;
|
||||
BOOLEAN
|
||||
WINAPI
|
||||
Initialize(
|
||||
VOID
|
||||
);
|
||||
BOOL
|
||||
WINAPI
|
||||
GetSystemFunctionName(
|
||||
IN ULONG64 pAddress,
|
||||
OUT CHAR* pName
|
||||
);
|
||||
enum SwitchState
|
||||
{
|
||||
_SwitchState_Initialized = 0,
|
||||
_SwitchState_Ready = 1,
|
||||
_SwitchState_Running = 2,
|
||||
_SwitchState_Standby = 3,
|
||||
_SwitchState_Terminated = 4,
|
||||
_SwitchState_Waiting = 5,
|
||||
_SwitchState_Transition = 6,
|
||||
_SwitchState_DeferredReady = 6,
|
||||
};
|
||||
|
||||
std::wstring GetProcessNameByPid(DWORD pPid) {
|
||||
HANDLE hProceesSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (hProceesSnap != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
PROCESSENTRY32 pe32;
|
||||
pe32.dwSize = sizeof(pe32);
|
||||
BOOL hProcess = Process32First(hProceesSnap, &pe32);
|
||||
while (hProcess)
|
||||
{
|
||||
//printf("%ws %d\n", pe32.szExeFile, pe32.th32ProcessID);
|
||||
if (pe32.th32ProcessID == pPid) {
|
||||
CloseHandle(hProceesSnap);
|
||||
return std::wstring(pe32.szExeFile);
|
||||
}
|
||||
hProcess = Process32Next(hProceesSnap, &pe32);
|
||||
}
|
||||
CloseHandle(hProceesSnap);
|
||||
}
|
||||
return std::wstring(L"unknown");
|
||||
}
|
||||
/*
|
||||
* 这个没用,因为只有在线程为等待状态并且是阻塞的情况下才有效
|
||||
*/
|
||||
/*
|
||||
* VOID initFunctions()
|
||||
{
|
||||
HMODULE hModule = LoadLibrary(L"ntdll.dll");
|
||||
ZwQueryInformationThread = (ZWQUERYINFORMATIONTHREAD)GetProcAddress(hModule, "ZwQueryInformationThread");
|
||||
}
|
||||
DWORD GetThreadSysCallNumByHandle(DWORD pThreadId) {
|
||||
typedef struct _THREAD_LAST_SYSCALL_INFORMATION
|
||||
{
|
||||
PVOID FirstArgument;
|
||||
USHORT SystemCallNumber;
|
||||
} THREAD_LAST_SYSCALL_INFORMATION, * PTHREAD_LAST_SYSCALL_INFORMATION;
|
||||
THREAD_LAST_SYSCALL_INFORMATION lastSystemCall = {0};
|
||||
|
||||
HANDLE ThreadHandle = OpenThread(THREAD_QUERY_INFORMATION, FALSE, pThreadId);
|
||||
if (ThreadHandle != INVALID_HANDLE_VALUE && ThreadHandle != NULL) {
|
||||
ZwQueryInformationThread(
|
||||
ThreadHandle,
|
||||
ThreadLastSystemCall,
|
||||
&lastSystemCall,
|
||||
sizeof(THREAD_LAST_SYSCALL_INFORMATION),
|
||||
NULL
|
||||
);
|
||||
CloseHandle(ThreadHandle);
|
||||
printf("lastSystemCall.SystemCallNumber: %d thread id %d \n", lastSystemCall.SystemCallNumber, pThreadId);
|
||||
return lastSystemCall.SystemCallNumber;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
std::map<std::wstring, bool> g_StopDetectList;
|
||||
std::map<DWORD, std::map<std::string, bool>> g_injectList;
|
||||
VOID WINAPI NewProcessAdd(DWORD pThreadId) {
|
||||
HANDLE ThreadHandle = OpenThread(THREAD_QUERY_INFORMATION, FALSE, pThreadId);
|
||||
if (ThreadHandle != INVALID_HANDLE_VALUE && ThreadHandle != NULL) {
|
||||
DWORD ProcessId = GetProcessIdOfThread(ThreadHandle);
|
||||
if (ProcessId != NULL) {
|
||||
std::wstring TempStr = GetProcessNameByPid(ProcessId);
|
||||
if (TempStr.find(L"unknown") == std::wstring::npos) {
|
||||
g_dwProcessWithThreadidsMap[pThreadId] = ProcessId;
|
||||
g_dwProcessNameWithProcessIdMap[ProcessId] = TempStr;
|
||||
g_StopDetectList[TempStr] = false;
|
||||
}
|
||||
}
|
||||
CloseHandle(ThreadHandle);
|
||||
}
|
||||
}
|
||||
|
||||
VOID WINAPI EtwEventCallback(PEVENT_RECORD EventRecord) {
|
||||
EVENT_HEADER& hdr = EventRecord->EventHeader;
|
||||
std::string lpOldThrState = std::string();
|
||||
|
||||
UCHAR cpuId = EventRecord->BufferContext.ProcessorNumber;
|
||||
ULONG dwOldThrId = 0, dwNewThrId = 0;
|
||||
INT64 CycleTime = hdr.TimeStamp.QuadPart;
|
||||
if (EventRecord->EventHeader.EventDescriptor.Opcode == 36) {
|
||||
if (EventRecord->UserData) {
|
||||
CSwitch* pThrSwitch = (CSwitch*)EventRecord->UserData;
|
||||
_ASSERT(EventRecord->UserDataLength == sizeof(CSwitch));
|
||||
dwNewThrId = pThrSwitch->NewThreadId;
|
||||
dwOldThrId = pThrSwitch->OldThreadId;
|
||||
|
||||
g_dwProcesserWithThreadsMap[cpuId] = dwNewThrId;
|
||||
if (g_dwProcessWithThreadidsMap.count(dwNewThrId) == 0) {
|
||||
NewProcessAdd(dwNewThrId);
|
||||
}
|
||||
if (g_dwProcessWithThreadidsMap.count(dwOldThrId) == 0) {
|
||||
NewProcessAdd(dwOldThrId);
|
||||
}
|
||||
if (g_dwProcessWithThreadidsMap.count(dwOldThrId) != 0 && pThrSwitch->OldThreadState == _SwitchState_Terminated) {
|
||||
if (g_dwProcessNameWithProcessIdMap.count(g_dwProcessWithThreadidsMap[dwOldThrId]) != 0) {
|
||||
g_dwProcessNameWithProcessIdMap.erase(g_dwProcessWithThreadidsMap[dwOldThrId]);
|
||||
}
|
||||
g_dwProcessWithThreadidsMap.erase(dwOldThrId);
|
||||
}
|
||||
/*
|
||||
switch (pThrSwitch->OldThreadState)
|
||||
{
|
||||
case 0: lpOldThrState = std::string("Initialized"); break;
|
||||
case 1: lpOldThrState = std::string("Ready"); break;
|
||||
case 2: lpOldThrState = std::string("Running"); break;
|
||||
case 3: lpOldThrState = std::string("Standby"); break;
|
||||
case 4: lpOldThrState = std::string("Terminated"); break;
|
||||
case 5: lpOldThrState = std::string("Waiting"); break;
|
||||
case 6: lpOldThrState = std::string("Transition"); break;
|
||||
case 7: lpOldThrState = std::string("DeferredReady"); break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
//这边维护一个容器状态
|
||||
if (g_dwThreadsWithProcesserMap.count(dwNewThrId) == 0) {
|
||||
//没有被记录的,创建新线程
|
||||
g_dwThreadsWithProcesserMap[dwNewThrId].push_back(cpuId);
|
||||
g_dwThreadsWithProcesserMap[dwNewThrId].push_back(_SwitchState_Running);
|
||||
}
|
||||
else if (g_dwThreadsWithProcesserMap.count(dwOldThrId) == 0 && pThrSwitch->OldThreadState != _SwitchState_Terminated) {
|
||||
//老的没有被记录
|
||||
g_dwThreadsWithProcesserMap[dwOldThrId].push_back(cpuId);
|
||||
g_dwThreadsWithProcesserMap[dwOldThrId].push_back(pThrSwitch->OldThreadState);
|
||||
}
|
||||
else if (g_dwThreadsWithProcesserMap.count(dwOldThrId) != 0 && pThrSwitch->OldThreadState != _SwitchState_Terminated) {
|
||||
//更新老的状态
|
||||
g_dwThreadsWithProcesserMap[dwOldThrId][0] = -1;
|
||||
g_dwThreadsWithProcesserMap[dwOldThrId][1] = pThrSwitch->OldThreadState;
|
||||
}
|
||||
else if (g_dwThreadsWithProcesserMap.count(dwOldThrId) != 0 && pThrSwitch->OldThreadState == _SwitchState_Terminated) {
|
||||
//老的线程结束了,删除这个hashmap
|
||||
g_dwThreadsWithProcesserMap.erase(dwOldThrId);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
for (int i = 0; i < g_iNumOfThreads; i++) {
|
||||
if (g_lpdwThreadsIdArray[i] == dwNewThrId || g_lpdwThreadsIdArray[i] == dwOldThrId) {
|
||||
printf("[EtwContextSwitch] Processor: %i, New thread ID: %i, Old thread ID: %i (state: %s).\r\n", cpuId, dwNewThrId, dwOldThrId, lpOldThrState.c_str());
|
||||
//DebugBreak();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
else if (EventRecord->EventHeader.EventDescriptor.Opcode == 51) {
|
||||
//syscall enter
|
||||
if (g_dwProcesserWithThreadsMap.count(cpuId) == 0 ||
|
||||
g_dwProcessWithThreadidsMap.count(g_dwProcesserWithThreadsMap[cpuId]) == 0 ||
|
||||
g_dwProcessNameWithProcessIdMap.count(g_dwProcessWithThreadidsMap[g_dwProcesserWithThreadsMap[cpuId]]) == 0)
|
||||
return;
|
||||
DWORD ThreadId = g_dwProcesserWithThreadsMap[cpuId];
|
||||
std::wstring ProcessName = g_dwProcessNameWithProcessIdMap[g_dwProcessWithThreadidsMap[ThreadId]];
|
||||
PVOID* SsdtFucntionName = (PVOID*)EventRecord->UserData;
|
||||
|
||||
if (g_StopDetectList[ProcessName])
|
||||
return;
|
||||
|
||||
if (ProcessName.find(L"Toy") == std::wstring::npos)
|
||||
return;
|
||||
//printf("SsdtFucntionName: %p \n", SsdtFucntionName[0]);
|
||||
//DWORD SysCallNum = GetThreadSysCallNumByHandle(ThreadId);
|
||||
char NameStack[100];
|
||||
memset(NameStack, 0x0, sizeof(NameStack));
|
||||
if (GetSystemFunctionName((ULONG64)SsdtFucntionName[0], NameStack)) {
|
||||
std::string StringNameStack = std::string(NameStack);
|
||||
if (strcmp("NtCreateFile", NameStack) == 0 ||
|
||||
strcmp("NtCreateThreadEx", NameStack) == 0 ||
|
||||
strcmp("NtAllocateVirtualMemory", NameStack) == 0 ||
|
||||
strcmp("NtWriteVirtualMemory", NameStack) == 0 ||
|
||||
strcmp("NtOpenProcess", NameStack) == 0 ||
|
||||
strcmp("NtOpenProcessToken", NameStack) == 0 ||
|
||||
strcmp("NtCreateThread", NameStack) == 0) {
|
||||
int iter_num = 0;
|
||||
for (auto& value : g_injectList[g_dwProcessWithThreadidsMap[ThreadId]]) {
|
||||
if (StringNameStack == value.first) {
|
||||
g_injectList[g_dwProcessWithThreadidsMap[ThreadId]][value.first] = true;
|
||||
}
|
||||
// if(g_injectList[g_dwProcessWithThreadidsMap[ThreadId]][value.first])
|
||||
// iter_num += 1;
|
||||
}
|
||||
//if (iter_num == g_injectList[g_dwProcessWithThreadidsMap[ThreadId]].size())
|
||||
// g_StopDetectList[ProcessName] = true,
|
||||
// printf("检测到注入 进程名字: %ws \n", ProcessName.c_str());
|
||||
printf("cpuid: %d Process: %ws ThreadId: %d syscall: %s \n", cpuId, ProcessName.c_str(), ThreadId, NameStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DWORD WINAPI TraceThread(LPVOID lpParam) {
|
||||
TRACEHANDLE hConsumer = (TRACEHANDLE)lpParam;
|
||||
BOOL bRetVal = FALSE;
|
||||
DWORD dwCurProcId = GetCurrentProcessId();
|
||||
if (!hConsumer) return -1;
|
||||
|
||||
// Enumerate all the threads of this process and add it to the global list
|
||||
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
|
||||
if (h != INVALID_HANDLE_VALUE) {
|
||||
THREADENTRY32 te = { 0 };
|
||||
int count = 0;
|
||||
te.dwSize = sizeof(te);
|
||||
bRetVal = Thread32First(h, &te);
|
||||
|
||||
while (bRetVal) {
|
||||
te.dwSize = sizeof(te);
|
||||
bRetVal = Thread32Next(h, &te);
|
||||
}
|
||||
|
||||
// Allocate enough memory
|
||||
//g_lpdwThreadsIdArray = new DWORD[dwNumOfThreads];
|
||||
//g_iNumOfThreads = dwNumOfThreads;
|
||||
|
||||
bRetVal = Thread32First(h, &te);
|
||||
while (bRetVal) {
|
||||
//if (te.th32OwnerProcessID == dwCurProcId)
|
||||
// g_lpdwThreadsIdArray[count++] = te.th32ThreadID;
|
||||
if (te.th32OwnerProcessID != NULL) {
|
||||
if (g_dwProcessWithThreadidsMap.count(te.th32ThreadID) == 0) {
|
||||
std::wstring TempStr = GetProcessNameByPid(te.th32OwnerProcessID);
|
||||
if (TempStr.find(L"unknown") == std::wstring::npos) {
|
||||
g_dwProcessWithThreadidsMap[te.th32ThreadID] = te.th32OwnerProcessID;
|
||||
g_dwProcessNameWithProcessIdMap[te.th32OwnerProcessID] = TempStr;
|
||||
g_StopDetectList[TempStr] = false;
|
||||
|
||||
g_injectList[te.th32OwnerProcessID]["NtOpenProcessToken"] = 0;
|
||||
g_injectList[te.th32OwnerProcessID]["NtCreateFile"] = 0;
|
||||
g_injectList[te.th32OwnerProcessID]["NtOpenProcess"] = 0;
|
||||
g_injectList[te.th32OwnerProcessID]["NtAllocateVirtualMemory"] = 0;
|
||||
g_injectList[te.th32OwnerProcessID]["NtWriteVirtualMemory"] = 0;
|
||||
g_injectList[te.th32OwnerProcessID]["NtCreateThreadEx"] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
te.dwSize = sizeof(te);
|
||||
bRetVal = Thread32Next(h, &te);
|
||||
}
|
||||
CloseHandle(h);
|
||||
}
|
||||
|
||||
printf("开始trace");
|
||||
ProcessTrace(&hConsumer, 1, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
DWORD WINAPI TestThread1(LPVOID lpParam) {
|
||||
LARGE_INTEGER curTime = { 0 };
|
||||
while (TRUE) {
|
||||
DWORD dwKey = 0;
|
||||
QueryPerformanceCounter(&curTime);
|
||||
dwKey = _rotr(curTime.LowPart, curTime.HighPart) * 56 / 11;
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
bool StartEtwTrace() {
|
||||
PEVENT_TRACE_PROPERTIES pEtwProp = NULL;
|
||||
EVENT_TRACE_LOGFILE etwLogFile = { 0 };
|
||||
wchar_t providerName[] = KERNEL_LOGGER_NAME;
|
||||
DWORD dwCbProvName = 0,
|
||||
dwEtwPropSize = 0;
|
||||
TRACEHANDLE hTrace = NULL;
|
||||
TRACEHANDLE hConsumerTrace = NULL;
|
||||
BOOL bRetVal = FALSE;
|
||||
DWORD dwLastErr = 0;
|
||||
|
||||
dwCbProvName = (DWORD)(wcslen(providerName) + 1) * sizeof(TCHAR);
|
||||
|
||||
// Allocate the memory for the ETW data structure
|
||||
dwEtwPropSize = sizeof(EVENT_TRACE_PROPERTIES) + dwCbProvName;
|
||||
pEtwProp = (PEVENT_TRACE_PROPERTIES)new BYTE[dwEtwPropSize];
|
||||
RtlZeroMemory(pEtwProp, dwEtwPropSize);
|
||||
|
||||
pEtwProp->Wnode.ClientContext = 1;
|
||||
pEtwProp->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
|
||||
pEtwProp->Wnode.Guid = SystemTraceControlGuid;
|
||||
pEtwProp->Wnode.BufferSize = dwEtwPropSize;
|
||||
RtlCopyMemory(((LPBYTE)pEtwProp + sizeof(EVENT_TRACE_PROPERTIES)), providerName, dwCbProvName);
|
||||
|
||||
bRetVal = ControlTrace(NULL, providerName, pEtwProp, EVENT_TRACE_CONTROL_STOP);
|
||||
if (bRetVal != ERROR_WMI_INSTANCE_NOT_FOUND) {
|
||||
DWORD dwOffset = FIELD_OFFSET(EVENT_TRACE_PROPERTIES, BufferSize);
|
||||
RtlZeroMemory((LPBYTE)pEtwProp + dwOffset, dwEtwPropSize - dwOffset);
|
||||
}
|
||||
pEtwProp->EnableFlags = EVENT_TRACE_FLAG_CSWITCH | EVENT_TRACE_FLAG_SYSTEMCALL;
|
||||
pEtwProp->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
|
||||
pEtwProp->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
|
||||
|
||||
|
||||
wprintf(L"Initializing the ETW Consumer... ");
|
||||
bRetVal = StartTrace(&hTrace, providerName, pEtwProp);
|
||||
|
||||
if (bRetVal == ERROR_SUCCESS) {
|
||||
RtlZeroMemory(&etwLogFile, sizeof(EVENT_TRACE_LOGFILE));
|
||||
etwLogFile.LoggerName = (LPWSTR)providerName;
|
||||
etwLogFile.ProcessTraceMode = PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_REAL_TIME;
|
||||
etwLogFile.EventRecordCallback = EtwEventCallback;
|
||||
|
||||
hConsumerTrace = OpenTrace(&etwLogFile);
|
||||
dwLastErr = GetLastError();
|
||||
bRetVal = (hConsumerTrace != (TRACEHANDLE)INVALID_HANDLE_VALUE) ? ERROR_SUCCESS : dwLastErr;
|
||||
}
|
||||
|
||||
if (bRetVal == ERROR_SUCCESS) {
|
||||
DWORD dwThrId = 0;
|
||||
HANDLE hThread = NULL;
|
||||
printf("Success.\r\n");
|
||||
|
||||
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TestThread1, (LPVOID)NULL, 0, &dwThrId);
|
||||
CloseHandle(hThread);
|
||||
|
||||
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TraceThread, (LPVOID)hConsumerTrace, 0, &dwThrId);
|
||||
CloseHandle(hThread);
|
||||
|
||||
printf("Press ENTER key to stop the trace and exit...");
|
||||
rewind(stdin);
|
||||
getwchar();
|
||||
}
|
||||
else
|
||||
printf("Error %i.\r\n", (LPVOID)bRetVal);
|
||||
|
||||
|
||||
// Stop our Kernel Logger consumer
|
||||
if (hConsumerTrace != (TRACEHANDLE)INVALID_HANDLE_VALUE)
|
||||
bRetVal = ControlTrace(hConsumerTrace, NULL, pEtwProp, EVENT_TRACE_CONTROL_STOP);
|
||||
return bRetVal == ERROR_SUCCESS;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
Initialize();
|
||||
//SYSCALL::Resolve_sys_Call();
|
||||
//initFunctions();
|
||||
StartEtwTrace();
|
||||
//printf("GetProcessNameByPid(ProcessId) %ws \n", GetProcessNameByPid(25560).c_str());
|
||||
std::cout << "Hello World!\n";
|
||||
}
|
||||
Reference in New Issue
Block a user