在一个进程中,调用CreateThread或CreateRemoteThreadEx函数,在另一个进程内创建一个线程(因为不在同一个进程中,所以叫做远程线程)。创建的线程一般为Windows API函数LoadLibrary,来加载一个动态链接库(DLL),从而达到在另一个进程中运行自己所希望运行的代码的目的。

步骤:

  1. 打开目标进程
  2. 在目标进程中申请空间
  3. 将要注入的Dll路径写入刚申请的空间中
  4. 获取LoadLibrary函数地址
  5. 在目标进程中创建线程,线程回调函数就是LoadLibrary函数,回调函数参数就是要注入的Dll路径
  6. 等待线程结束
  7. 清理环境
BOOL CInject::ZwCreateThreadExInjectDll(DWORD dwProcessId, char* pszDllFileName)
{
HANDLE hProcess = NULL;
SIZE_T dwSize = 0;
LPVOID pDllAddr = NULL;
FARPROC pFunProcAddr = NULL;
HANDLE hRemoteThread = NULL;
DWORD dwStatus = 0; //打开目标进程 获取句柄
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (hProcess==NULL)
{
m_TipMsg += L"打开进程失败\r\n";
return FALSE;
}
else
{
m_TipMsg += L"打开进程成功\r\n";
} //在注入的进程中申请内存
dwSize = strlen(pszDllFileName) + 1;
pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
if (pDllAddr==NULL)
{
m_TipMsg += L"申请内存失败\r\n";
return FALSE;
}
else
{
m_TipMsg += L"申请内存成功\r\n";
} //向申请的内存中写入数据
BOOL bIsSucess = WriteProcessMemory(hProcess, pDllAddr, pszDllFileName, dwSize, NULL);
if (bIsSucess==FALSE)
{
m_TipMsg += L"写入内存失败\r\n";
return FALSE;
}
else
{
m_TipMsg += L"写入内存成功\r\n";
} //加载ntdll.dll
HMODULE hNtdll = LoadLibraryA("ntdll.dll");
if (hNtdll==NULL)
{
m_TipMsg += L"加载ntdll失败\r\n";
return FALSE;
}
else
{
m_TipMsg += L"加载ntdll成功\r\n";
} //获取LoadLibraryA函数地址
pFunProcAddr = GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryA");
if (pFunProcAddr==NULL)
{
m_TipMsg += L"加载LoadLibraryA函数地址失败\r\n";
return FALSE;
}
else
{
m_TipMsg += L"加载LoadLibraryA函数地址成功\r\n";
} //获取ZwCreateThread函数地址 ZwCreateThread在64位和32位下的函数声明不一样
#ifdef _WIN64
typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown);
#else
typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown);
#endif
typedef_ZwCreateThreadEx ZwCreateThreadEx = (typedef_ZwCreateThreadEx)GetProcAddress(hNtdll, "ZwCreateThreadEx");
if (ZwCreateThreadEx==NULL)
{
m_TipMsg += L"加载ZwCreateThreadEx函数地址失败\r\n";
return FALSE;
}
else
{
m_TipMsg += L"加载ZwCreateThreadEx函数地址成功\r\n";
}
//使用ZwCreateThreadEx函数创建远程线程 实现DLL注入
dwStatus = ZwCreateThreadEx(&hRemoteThread, THREAD_ALL_ACCESS, NULL,
hProcess, (LPTHREAD_START_ROUTINE)pFunProcAddr, pDllAddr, 0, 0, 0, 0, NULL);
if (hRemoteThread==NULL)
{
m_TipMsg += L"远程线程注入失败\r\n";
return FALSE;
}
else
{
m_TipMsg += L"远程线程注入成功\r\n";
} //关闭句柄
CloseHandle(hProcess);
FreeLibrary(hNtdll);
return TRUE; }
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "header.h" BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(0,"注入成功","恭喜",0);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

最新文章

  1. Java你可能不知道的事系列(1)
  2. 【转载】CSS position属性和实例应用
  3. ZT 第一范式,第二范式,第三范式
  4. PHP--Warning: Invalid argument supplied for foreach() in ...
  5. web.config connectionStrings 数据库连接字符串的解释
  6. apache2.4配置虚拟主机
  7. 从文章"避免复制与粘贴"到文章"Extract Method"的反思(3)
  8. EF Lambda 多表查询
  9. npm 安装
  10. mov sreg, r/m16 在16位和32位编程中的区别
  11. Python学习常用的好网站
  12. Spring bean 生命周期验证
  13. Git Submodules are not SVN Externals
  14. 003Java语言环境搭建
  15. SSH三大框架整合案例
  16. 树莓派+花生棒+leanote搭建自己的笔记服务器
  17. python-数据类型之题型
  18. js 读取文件
  19. Spring3.2.0 之后各个版本完整包下载地址
  20. 逃逸分析(Escape Analysis)

热门文章

  1. CTF-wtc_rsa_bbq-writeup
  2. CentOS 7 文件权限之访问控制列表(ACL)
  3. 在 .NET 中创建对象的几种方式的对比
  4. 微信小程序云开发-云函数-创建云函数
  5. pytest框架
  6. 第三十一篇 -- 理一下.h和.cpp的关系
  7. IDEA web项目小坑
  8. Typora PicGo Gitee博客写作好搭档
  9. Spring WebFlux 基础教程:参数校验
  10. 手写Pascal解释器(二)