本文共计3454个字,预计阅读时长12.9分钟。
UserMode下注入系统服务进程
头文件代码
#include <iostream>
#include <Windows.h>
#ifdef _X86_
// 定义32位函数模型
typedef DWORD (WINAPI *pZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParamets,
BOOL CreateSuspended,
DWORD dwStackBize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown
);
#else
// 定义64位函数模型
typedef DWORD(WINAPI *pZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParamets,
ULONG CreateTheadFlags,
SIZE_T ZeroBits,
SIZE_T StackBize,
SIZE_T MaximunStackSize,
LPVOID pUnkown
);
#endif
注入代码
// UserMode下注入系统服务
BOOL RemoteThreadInjectDllEx(DWORD Pid, CHAR * DllName)
{
DWORD dwStatus = NULL, dwSizeLen = NULL;
CHAR * szDllName = DllName; // 为loadlibrary所需要的参数
PVOID pLoadLibraryA = NULL;
HANDLE hRemoteThread;
// 获取进程句柄
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
if (hProcess == NULL)
{
printf("hNtdllBase Error:%x\n", GetLastError());
return FALSE;
}
// 在远程进程中申请空间
dwSizeLen = 1 + ::lstrlenA(szDllName);
LPVOID DllSpace = ::VirtualAllocEx(hProcess/*申请内存所在的进程句柄*/,
NULL/*保留页面的内存地址,一般用NULL自动分配*/, dwSizeLen/*分配内存的大小*/,
MEM_COMMIT/*为特定的页面区域分配内存中或磁盘中的页面文件中的物理存储*/,
PAGE_READWRITE/*内存模块可写可读*/);
if (NULL == DllSpace)
{
printf("VirtualAllocEx Error:%x\n", GetLastError());
return FALSE;
}
// 注入线程函数参数
if (!::WriteProcessMemory(hProcess/*由OpenProcess返回的进程句柄*/,
DllSpace/*要写的内存首地址,在写入之前,此函数将先检查目标地址是否可用,并能容纳待写入的数据。*/,
szDllName/*要写入数据的首地址*/, dwSizeLen/*要写入的字节数,非零值代表成功。*/,
NULL/*实际写入的长度*/))
{
printf("WriteProcessMemory Error:%x\n", GetLastError());
return FALSE;
}
// 加载 ntdll.dll 基址
HMODULE hNtdllBase = ::LoadLibraryA("ntdll.dll");
if (hNtdllBase == NULL)
{
printf("hNtdllBase Error:%x\n", GetLastError());
return FALSE;
}
// 获取 LoadLibraryA 地址
pLoadLibraryA = ::GetProcAddress(::GetModuleHandleA("Kernel32.dll"), "LoadLibraryA");
if (pLoadLibraryA == NULL)
{
printf("pLoadLibraryA Error:%x\n", GetLastError());
return FALSE;
}
// 获取 ZwCreateTheadEx
pZwCreateThreadEx ZwCreateThreadEx =
(pZwCreateThreadEx)::GetProcAddress(hNtdllBase, "ZwCreateThreadEx");
if (ZwCreateThreadEx == NULL)
{
printf("ZwCreateTheadEx Error:%x\n", GetLastError());
return FALSE;
}
// 使用 ZwCreateTheadEx 创建远程线程, 实现DLL注入
dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL,
hProcess, (LPTHREAD_START_ROUTINE)pLoadLibraryA, DllSpace, 0,0,0,0,NULL);
if (hRemoteThread == NULL)
{
printf("hRemoteThread Error:%x\n", GetLastError());
return FALSE;
}
return TRUE;
}
int main()
{
RemoteThreadInjectDllEx(3796, (CHAR *)"C:\\InjectDll.dll");
system("pause");
}
用户模式下的远程注入Ex