******参考GitHub上的AntiInject******
1,远程进程注入DLL调用CreateRemoteThread这个API进行注入,而这个API会在目标进程中创建一个进程来调用LoadLibrary来加载自己想注入的DLL从而达到注入效果。
2,在一个进程已经加载的DLL中,每当一个Thread创建的时候就会给每一个加载的DLL发送一个消息DLL_THREAD_ATTACH,我们可以在自己的DLL中来截获每一个线程创建时候的消息,然后判断这个线程起始地址是否是LoadLibraryA/W来判断这个线程是否是通过远程线程注入进来的。
实现代码:
void CheckInject(DWORD dwProcessId);
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_THREAD_ATTACH:
CheckInject(GetCurrentProcessId()); //每次新的线程创建时候检测
break;
}
return TRUE;
}
DWORD GetThreadStartAddr(DWORD dwThreadId)
{
HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION,FALSE,dwThreadId);
DWORD dwStartAddr,dwReturnLen;
if (hThread == NULL)
return 0;
NtQueryInformationThread(hThread, //查询线程起始地址
ThreadQuerySetWin32StartAddress,
&dwStartAddr,
4,
&dwReturnLen);
return dwStartAddr;
}
void Check_StartAddr(DWORD dwStartAddr,DWORD dwThreadId)
{
DWORD dwAddr_LoadLibraryA = (DWORD)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryA");
DWORD dwAddr_LoadLibraryW = (DWORD)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryW");
if (dwStartAddr == dwAddr_LoadLibraryA || dwStartAddr == dwAddr_LoadLibraryW)
{
if (MessageBoxA(0, "发现注入的DLL线程,是否杀掉?", "提示", MB_OKCANCEL) == IDOK)
{
TerminateThread(OpenThread(THREAD_ALL_ACCESS,FALSE,dwThreadId),0);
}
}
}
void CheckInject(DWORD dwProcessId)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessId);
THREADENTRY32 te32 = { sizeof(te32) };
Thread32First(hSnapshot, &te32);
do
{
if (te32.th32OwnerProcessID == dwProcessId)
{
Check_StartAddr(GetThreadStartAddr(te32.th32ThreadID),te32.th32ThreadID); //遍历当前进程所有线程的起始地址
}
} while (Thread32Next(hSnapshot, &te32));
}