原本是写APC注入,但是要求线程可告警,所以把原来的代码改了。
代码:
// QueueAPC.cpp :
//
#include "stdafx.h"
#include "PrivilegeLevel.h"
#include "bypassKnlhooks.h"
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Tlhelp32.h>
typedef struct _TIDLIST
{
DWORD dwTid ;
_TIDLIST *pNext ;
} TIDLIST;
#define Log( message, value ) { printf("[vmm] %-40s [%08X]\n", message, value ); }
DWORD GetmainThread(DWORD dwProcessID)
{
DWORD dwThreadID;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID) ;
if (hProcess == NULL)
{
printf("打开进程失败\n");
return 1 ;
}
while(1)
{
dwThreadID = 0;
THREADENTRY32 te32 = {sizeof(te32)};
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if( Thread32First( hThreadSnap, &te32) )
{
do
{
if( dwProcessID == te32.th32OwnerProcessID )
{
DWORD dwRet ;
dwThreadID = te32.th32ThreadID;
printf("主线程ID: %d\n", dwThreadID);
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadID) ;
if (NULL == hThread)
{
return 0;
}
if (0xFFFFFFFF != SuspendThread(hThread))
{
CONTEXT x86;
x86.ContextFlags = CONTEXT_ALL | CONTEXT_CONTROL;
if (!GetThreadContext(hThread, &x86))
{
return 0;
}
//const char szInjectModName[] = "c:\\XGreatX.dll" ;
char szInjectModName[512];
printf("请输入dll全路径:");
scanf("%s", szInjectModName);
DWORD dwLen = strlen(szInjectModName) ;
PVOID param = VirtualAllocEx(hProcess, \
NULL, dwLen, MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE) ;
if (param != NULL)
{
WriteProcessMemory(hProcess, param, (LPVOID)szInjectModName, dwLen, &dwRet);
x86.Esp -= 4; //??esp?4,??????
DWORD oldProtect = 0;
if (!VirtualProtectEx(hProcess, (LPVOID)x86.Esp, sizeof(DWORD) * 2, PAGE_READWRITE, &oldProtect))
{
printf("修改内存属性失败!\n");
}
if (!WriteProcessMemory(hProcess, (LPVOID)x86.Esp, ¶m, sizeof(DWORD), &dwRet))
{
printf("恢复内存属性失败!\n");
}
x86.Esp -= 4; //??esp?4,??????
if (!WriteProcessMemory(hProcess, (LPVOID)x86.Esp, &x86.Eip, sizeof(DWORD), &dwRet))
{
printf("写入参数地址失败!\n");
}
if (!VirtualProtectEx(hProcess, (LPVOID)x86.Esp, sizeof(DWORD) * 2, oldProtect, &oldProtect))
{
printf("写入返回地址失败!\n");
}
x86.Eip = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
//x86.Eip = 0;
x86.ContextFlags = CONTEXT_ALL | CONTEXT_CONTROL;
if (!SetThreadContext(hThread, &x86))
{
return 0;
}
ResumeThread(hThread);
CloseHandle(hProcess);
CloseHandle(hThread);
printf("注入成功\n");
break;
}
}
}
}
while( Thread32Next( hThreadSnap, &te32) );
}
if (dwThreadID != 0)
return dwThreadID;
else
return 0;
}
}
DWORD GetProcID(const char *szProcessName)
{
PROCESSENTRY32 pe32 = {0} ;
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ;
if (hSnapshot == INVALID_HANDLE_VALUE)
{
return 0xFFFFFFFF ;
}
if (!Process32First(hSnapshot, &pe32))
{
return 0xFFFFFFFF ;
}
do
{
if (!_strnicmp(szProcessName, pe32.szExeFile, strlen(szProcessName)))
{
printf("%s进程PID是 :%d\n", pe32.szExeFile, pe32.th32ProcessID);
return pe32.th32ProcessID ;
}
}
while(Process32Next(hSnapshot, &pe32));
return 0xFFFFFFFF ;
}
BOOL IsWow64 = FALSE;
VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
printf("Timer\n");
}
int _tmain(int argc, _TCHAR *argv[])
{
TIDLIST *pTidHead = (TIDLIST *)malloc(sizeof(TIDLIST)) ;
if (false == EnableDebugPrivilege())
{
printf("权限提升失败\n");
}
if(!IsWow64Process(GetCurrentProcess(), &IsWow64))
{
printf("Detour HACKSHIELD ssdt and inline hooks fail\n");
}
if (!IsWow64)
{
fakeX86ImagePath();
}
else
{
fakeX64ImagePath();
}
if (pTidHead == NULL)
{
return 1 ;
}
RtlZeroMemory(pTidHead, sizeof(TIDLIST)) ;
DWORD dwPID = 0 ;
char szPEname[512] = {0};
printf("请输入进程名");
scanf("%s", szPEname);
if ((dwPID = GetProcID(szPEname)) == 0xFFFFFFFF)
{
printf("进程ID获取失败!\n") ;
return 1 ;
}
//
// ????ID
//
//EnumThreadID(dwPID, pTidHead) ;
GetmainThread(dwPID);
system("pause");
return 0;
}