//提升进程访问权限
enableDebugPriv(); printf("请输入进程名称(区分大小写):");
scanf("%s",&name); //得到被注入进程ID
DWORD pid=GetProceeId(name); printf("进程的PID为:%d\n",pid); //打开进程
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (! hProcess)
{
printf("调用OpenProcess打开进程失败。..");
return 0;
}
void *pRemoteThread = VirtualAllocEx(hProcess,0,dwThreadSize,MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (! pRemoteThread)
{
printf("为远程线程开辟内存失败。..");
return 0;
} //把线程写入宿主进程中
if (!WriteProcessMemory(hProcess,pRemoteThread,&threadProc,dwThreadSize,0))
{
printf("将线程写入进程失败。..\n");
return 0;
} //定义线程参数结构体变量
RemoteParam remoteData;
ZeroMemory(&remoteData,sizeof(RemoteParam)); //填充结构体变量中的成员
HINSTANCE hUser32=LoadLibrary("User32.dll");
remoteData.dwMessageBox = (DWORD)GetProcAddress(hUser32,"MessageBoxA");
strcat(remoteData.szMsg,"也,我被注入到进程中了哦");
//在宿主进程中分配存储空间
RemoteParam *pRemoteParam=(RemoteParam*)VirtualAllocEx(hProcess,0,sizeof(RemoteParam),
MEM_COMMIT,PAGE_READWRITE);
if (!pRemoteParam)
{
printf("在宿主中分开存储空间失败...");
return 0;
} //将字符串和MessageBox函数的入口地址写入宿主进程
if (! WriteProcessMemory(hProcess,pRemoteParam,&remoteData,sizeof(remoteData),0))
{
printf("将MessageBox函数的入口写入宿主地址失败。..");
return 0;
}
//在宿主进程中创建线程
HANDLE hRemoteThread=CreateRemoteThread(hProcess,NULL,0,(DWORD (__stdcall*)(void*))pRemoteThread,
NULL,0,&dwWriteBytes);
if (!hRemoteThread)
{
printf("远程注入线程失败。..\n");
return 0;
}
CloseHandle(hRemoteThread);根据我的测试,程序是执行完毕了的。。
但是被注入的程序却提示“应用程序错误”然后直接关闭了,我是用文本文档(txt)这个系统自带的程序做的测试。。
那么应该是什么错误呢,初学线程注入,大伙有相关经验的给看看吧,在这里感激不尽呀~~ :)
NULL,0,&dwWriteBytes);
怎么给远程线程送入了参数呢?
NULL,0,&dwWriteBytes);
怎么给远程线程送入了参数呢?
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile)
{ BOOL fOk = FALSE; // Assume that the function fails
HANDLE hProcess = NULL, hThread = NULL;
PWSTR pszLibFileRemote = NULL; TCHAR szBuffer[512] = {0};
wsprintfA(szBuffer, "%S", pszLibFile); Log(szBuffer);
__try {
// Get a handle for the target process.
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | // Required by Alpha
PROCESS_CREATE_THREAD | // For CreateRemoteThread
PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx
PROCESS_VM_WRITE, // For WriteProcessMemory
FALSE, dwProcessId);
if (hProcess == NULL)
{
Log("OpenProcess failed!, error = %d", GetLastError());
__leave;
} Log("111111111111111111111111111"); // Calculate the number of bytes needed for the DLL's pathname
int cch = 1 + lstrlenW(pszLibFile);
int cb = cch * sizeof(WCHAR); // Allocate space in the remote process for the pathname
pszLibFileRemote = (PWSTR)
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL)
{
Log("VirtualAllocEx failed!, error = %d", GetLastError());
__leave;
} Log("222222222222222222222222222222222");
// Copy the DLL's pathname to the remote process's address space
if (!WriteProcessMemory(hProcess, pszLibFileRemote,
(PVOID) pszLibFile, cb, NULL))
{
Log("WriteProcessMemory failed! error = %d", GetLastError());
__leave;
} Log("333333333333333333333333333333");
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
if (pfnThreadRtn == NULL)
{
Log("GetProcAddress LoadLibraryW failed! error = %d", GetLastError());
__leave;
}
Log("444444444444444444444444444444"); // Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = CreateRemoteThread(hProcess, NULL, 0,
pfnThreadRtn, pszLibFileRemote, 0, NULL);
if (hThread == NULL)
{
Log("CreateRemoteThread failed! error = %d", GetLastError());
__leave;
} Log("555555555555555555555555555555, hThread = %p", hThread);
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE); Log("666666666666666666666666666666");
fOk = TRUE; // Everything executed successfully
}
__finally { // Now, we can clean everthing up Log("InjectLibW Error! crush!!");
// Free the remote memory that contained the DLL's pathname
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE); if (hThread != NULL)
CloseHandle(hThread); if (hProcess != NULL)
CloseHandle(hProcess);
} return(fOk);
}给你个例子,你自己比较一下吧,LOG是个无关的函数了,不用管他
步骤1:首先在你的进程中创建函数MyFunc,我们将把它放在另一个进程中运行,这里以windows
计算器为目标进程。
static DWORD WINAPI MyFunc (LPVOID pData)
{
//do something
//...
//pData输入项可以是任何类型值
//这里我们会传入一个DWORD的值做示例,并且简单返回
return *(DWORD*)pData;
}
static void AfterMyFunc (void) {
}
这里有个小技巧,定义了一个static void AfterMyFunc (void);为了下面确定我们的代码大小
步骤2:定位目标进程,这里是一个计算器
HWND hStart = ::FindWindow (TEXT("SciCalc"),NULL);
步骤3:获得目标进程句柄,这里用到两个不太常用的函数(当然如果经常做线程/进程等方面的 项目的话,就很面熟了),但及有用
DWORD PID, TID;
TID = ::GetWindowThreadProcessId (hStart, &PID);
HANDLE hProcess;
hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,PID);
步骤4:在目标进程中配变量地址空间,这里我们分配10个字节,并且设定为可以读
写PAGE_READWRITE,当然也可设为只读等其它标志,这里就不一一说明了。
char szBuffer[10];
*(DWORD*)szBuffer=1000;//for test
void *pDataRemote =(char*) VirtualAllocEx( hProcess, 0, sizeof(szBuffer), MEM_COMMIT,
PAGE_READWRITE );
步骤5:写内容到目标进程中分配的变量空间
::WriteProcessMemory( hProcess, pDataRemote, szBuffer,(sizeof(szBuffer),NULL);
步骤6:在目标进程中分配代码地址空间
计算代码大小
DWORD cbCodeSize=((LPBYTE) AfterMyFunc - (LPBYTE) MyFunc);
分配代码地址空间
PDWORD pCodeRemote = (PDWORD) VirtualAllocEx( hProcess, 0, cbCodeSize, MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
步骤7:写内容到目标进程中分配的代码地址空间
WriteProcessMemory( hProcess, pCodeRemote, &MyFunc, cbCodeSize, NULL);
步骤8:在目标进程中执行代码
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE) pCodeRemote,
pDataRemote, 0 , NULL);
DWORD h;
if (hThread)
{
::WaitForSingleObject( hThread, INFINITE );
::GetExitCodeThread( hThread, &h );
TRACE("run and return %d\n",h);
::CloseHandle( hThread );
}
这里有几个值得说明的地方:
使用WaitForSingleObject等待线程结束;
使用GetExitCodeThread获得返回值;
最后关闭句柄CloseHandle。
步骤9:清理现场
释放空间
::VirtualFreeEx( hProcess, pCodeRemote,
cbCodeSize,MEM_RELEASE );
::VirtualFreeEx( hProcess, pDataRemote,
cbParamSize,MEM_RELEASE );
关闭进程句柄
::CloseHandle( hProcess );
- -!windows核心编程的代码