更多名人名博

上市公司专栏

实时股价每分更新

纳斯达克(美元)(市值:亿美元)
综指: 涨跌幅:
公司 股价 涨幅度 市值
盛大
网易
九城
畅游
完美
巨人
新浪
百度
恒生指数(港币)(市值:亿港币)
综指: 涨跌幅:
公司 股价 涨幅度 市值
腾讯
金山
网龙
创业板
综指: 涨跌幅:
公司 股价 涨幅度 市值
宝网
d
您现在的位置:首页> 开发|游戏程序|专业工具| > 线程远程注入

线程远程注入

来源:IIEEG04-14-2011

线程远程注入的技术并不复杂,主要用到CreateRemoteThread这个API。难点有个地方,由于要注入其他进程的空间,因此,注入用的那个线程中的代码必须使用和被注入进程的内存空间一致。换句话讲,就是需要找到线程中使用的函数在远程进程中的地址。明白这个,问题就没有了。下面是一个完整的线程注入的代码,在XP+SP3下运行成功。很简单的代码。

#include
#include "WTYPES.H"
//typedef unsigned long DWORD;// 为了在程序中使用DWORD,可以include WTYPES.H,也可以使用该行定义

//先定义参数结构
typedef struct _RemotePara{//参数结构
char pMessageBox[12];
DWORD dwMessageBox;
}RemotePara, * RemoteParam;

//定义MessageBox类型的函数指针
typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);


//线程函数定义
int __stdcall ThreadProc (void *lpPara){

RemotePara* pRP = (RemotePara*)lpPara;
PFN_MESSAGEBOX pfnMessageBox;
pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
pfnMessageBox(NULL, pRP->pMessageBox, pRP->pMessageBox, 0);

return 0;

}

//提升进程访问权限
bool enableDebugPriv()
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
return false;
}

if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
CloseHandle(hToken);
return false;
}

tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
CloseHandle(hToken);
return false;
}

return true;
}

int main(int argc, char* argv[])
{
const DWORD THREADSIZE=1024*4;//暂定线程体大小为4K
DWORD byte_write;
//提升进程访问权限
enableDebugPriv();


HANDLE hWnd = ::OpenProcess (PROCESS_ALL_ACCESS,FALSE,3196); //打开PID为3196的进程
if(!hWnd)
printf("error OpenProcess!\n ");

void *pRemoteThread =::VirtualAllocEx(hWnd,0,THREADSIZE,MEM_COMMIT| MEM_RESERVE,PAGE_EXECUTE_READWRITE);//在宿主进程中使用VirtualAllocEx函数申请一段内存
if(!pRemoteThread)
printf("error VirtualAllocEx!\n");

//将线程体拷贝到宿主进程中
if(!::WriteProcessMemory(hWnd,pRemoteThread,&ThreadProc,THREADSIZE,0))
printf("error WriteProcessMemory!\n");

//定义线程参数结构体变量
RemotePara myRemotePara;
::ZeroMemory(&myRemotePara,sizeof(RemotePara));
//填充结构体变量中的成员
HINSTANCE hUser32 = ::LoadLibrary ("User32.dll");
myRemotePara.dwMessageBox =(DWORD) ::GetProcAddress (hUser32 , "MessageBoxA");
strcat(myRemotePara.pMessageBox,"hello\0");

//为线程参数在宿主进程中开辟存储区域
RemotePara* pRemoteParam = (RemotePara*)VirtualAllocEx(
hWnd , 0, sizeof(RemoteParam), MEM_COMMIT, PAGE_READWRITE);
if(!pRemoteParam)
printf("error VirtualAllocEx!\n");

//将线程参数拷贝到宿主进程地址空间中
if (!WriteProcessMemory(hWnd ,
pRemoteParam, &myRemotePara, sizeof(myRemotePara), 0)) {
MessageBox(NULL, "Write data to target process failed !",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}

//启动线程
HANDLE hThread = ::CreateRemoteThread (hWnd ,0,0,(DWORD (__stdcall *)(void *))pRemoteThread ,pRemoteParam,0,&byte_write);
if(!hThread){ //还有内存分配未释放
printf("error CreateRemoteThread!\n");
}

CloseHandle(hThread);
return 0;
}