远程线程 注入、、
注入有几个核心的API函数、、
OpenProcess - 打开目标进程。
VirtualAllocEx/VirtualFreeEx - 在目标进程中分配/释放内存空间。
WriteProcessMemory - 在目标进程中写入要加载的DLL路径。
CreateRemoteThread - 远程加载DLL的关键函数,用于控制目标进程调用API函数。
//在这里调LoadLibrary(地址不用传因为同一机器加载它所在的Kerner32.dll是相同的、、)
//且LoadLibrary正好只有一个参数符合远程线程规则、、
LoadLibrary - 目标进程通过调用此函数来加载我们自己编写的DLL。
思路已经有了看细节实现吧、、
void CMyDllInjectDlg::OnInject() //界面按钮(向它注入本地DLL)
{
if (bMouseDown) //用于判断是否有进程选中的变量前边已经说过、、
{
enableDebugPriv(); //提权 此函数在后边会记录、有了它就可以OpenProcess任何进程、、
//下边是弹出查找对话框 使用MFC封装的类:CFileDialog、
CString filter;
CString PathDll;
filter=("(*.dll)|*.dll|All files (*.*)|*.*||"); //过滤这里只要显示DLL文件就好、、
CFileDialog FindDll(true,NULL,NULL,OFN_HIDEREADONLY,filter); //隐藏只读复选框
if(FindDll.DoModal()==IDOK)
{
PathDll = FindDll.GetPathName(); //获取DLL完整路径名字、、
}
char* Path = PathDll.GetBuffer(PathDll.GetLength()); //Cstring 转char*
GetBuffer 这个函数是为一个CString对象重新获取其内部字符缓冲区的指针、、返回非const故可以修改
//现在得到了注入目标进程的 DLL的完整路径名、、存放于Path、、
//打开目标进程
hkernel32=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION,1,iID);
原型 HANDLE OpenProcess(
DWORD dwDesiredAccess, // access flag
BOOL bInheritHandle, // handle inheritance option
DWORD dwProcessId // process identifier ); 这里说一下第一个参数、、
OpenProcess第一个参数指定了三种权限。在Win32系统下,每个进程都拥有自己的4G虚拟地址空间,各个进程之间都相互独立。如果一个进程需要完成跨进程的工作的话,那么它必须拥有目标进程的相应操作权限。
PROCESS_CREATE_THREAD表示我可以通过返回的进程句柄在该进程中创建新的线程,也就是调用CreateRemoteThread的权限;
同理,PROCESS_VM_OPERATION则表示在该进程中分配/释放内存的权限,也就是调用VirtualAllocEx/VirtualFreeEx的权限;
PROCESS_VM_WRITE表示可以向该进程的地址空间写入数据,也就是调用WriteProcessMemory的权限。
//申请空间将我们的DLL路径写到目标进程地址空间里、、(进程是独立的哦)、、
//之前的IAT HOOK是更改内存信息VirtualQuery VirtualProtect、、现在是申请内存空间、、VirtualAllocEx
LPVOID pDllAddr=VirtualAllocEx(hkernel32,NULL,strlen(Path),MEM_COMMIT,PAGE_READWRITE);
//将DLL路径Path写到申请的pDllAddr地址空间去、、、
WriteProcessMemory(hkernel32, pDllAddr,LPVOID(Path),strlen(Path),NULL);
//得到LoadLibraryA函数的地址因为kernel32.dll加载时候的基地址对于一个机器是固定的、、
//如果是一个不固定需要将函数地址也向DLL路径那样写到目标进程的地址空间中、、
DWORD pLoadAddr=(DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA");
//通过CreateRemoteThread将LoadLibrary作为目标进程的一个线程来启动、、
//这样就可以可以做到使目标进程调用LoadLibrary加载咱得DLL文件了、、
Handle hThread = CreateRemoteThread(hkernel32,NULL,0,(LPTHREAD_START_ROUTINE) pLoadAddr, pDllAddr,NULL,0);
//等待LoadLibrary加载完毕即这个远程线程执行完毕、、
WaitForSingleObject( hThread, INFINITE ); //返回0核心对象已被激活
//第二个参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。
//若为0,则该函数立即返回;
//若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止。
CloseHandle(hkernel32);
CloseHandle(Thread);
//释放目标进程中申请的空间
VirtualFreeEx(hThread , pDllAddr, strlen(Path), MEM_DECOMMIT );
CloseHandle( hThread );
CloseHandle( hProcess ); //关闭句柄释放申请的内存空间、、、
}
else
{
MessageBox("当前没有进程被选中、无法操作!","进程小软!",MB_OK);
}
}
//至此结束、、测试程序可以随便写一个调MessageBox的、、
#include "stdio.h"
#include "windows.h"
int main()
{
Printf(“输入一个字符 启动 MessageBox 以便测试、、”);
getchar(); //此时打开注入工具向此进程注入DLL、、
MessageBoxA(NULL, "HOOK失败", "源程序的MessageBox", MB_OK);
return 0;