tllyf 2014年01月06日
一个DLL注入器线程参数传递问题,不知能否行得通,求解
网上的一个很普通的DLL注入代码,突发奇想:看能否通过寄存器给线程my_threadProc传个参数过去,很可惜的是VC2010的调试器总是崩溃,查看不到变量及寄存器的数值,发到这里求高手答疑,先谢谢了。

代码附上:
#include <TlHelp32.h>

typedef struct _RemoteParam {
DWORD dwLoadLibrary;
WCHAR szDLLName[128];
} RemoteParam, * PRemoteParam;

//定义LoadLibrary类型的函数指针
typedef HMODULE (__stdcall *PFN_LOADLIBRARY)(WCHAR *lpLibFileName);

//线程函数定义
void My_threadProc()
{
DWORD dwParam;
_asm MOV dwParam,EDX
RemoteParam* pRP = (RemoteParam*)dwParam;
PFN_LOADLIBRARY pfnLoadLibrary;
pfnLoadLibrary=(PFN_LOADLIBRARY)pRP->dwLoadLibrary;
pfnLoadLibrary(pRP->szDLLName);
return;
}

class CDllInjector {
bool enableDebugPriv();
public:
CDllInjector();
int InstallHook(LPCTSTR lpRunFileName,LPCTSTR lpDllName);
};

bool CDllInjector::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;
}

CDllInjector::CDllInjector() {

}



int CDllInjector::InstallHook(LPCTSTR lpRunFileName,LPCTSTR lpDllName)
{
enableDebugPriv();
CONTEXT context;
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
memset(&context,0,sizeof(context));
context.ContextFlags = CONTEXT_CONTROL;
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
DWORD bOk = CreateProcessW(NULL,
(LPWSTR)lpRunFileName, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
FALSE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL,// current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
if(bOk==0) return -1;
WaitForInputIdle(piProcInfo.hProcess,-1);

//定义线程参数结构体变量
RemoteParam remoteData;
ZeroMemory(&remoteData, sizeof(RemoteParam));

//填充结构体变量中的成员
LPVOID lpFunc=GetProcAddress(GetModuleHandle(TEXT("Kernel32.dll")),"LoadLibraryW");
if (lpFunc == NULL){
return -2;
}
remoteData.dwLoadLibrary =(DWORD)lpFunc;
wsprintfW(remoteData.szDLLName,TEXT("%s"),lpDllName);
DWORD remoteDataSize=sizeof(RemoteParam);
RemoteParam* pRemoteParam = (RemoteParam*)VirtualAllocEx(piProcInfo.hProcess,NULL,remoteDataSize,MEM_COMMIT,PAGE_READWRITE);
if (!pRemoteParam) {
return -3;
}
DWORD dwHasWrite;
if(!WriteProcessMemory(piProcInfo.hProcess,pRemoteParam,&remoteData,remoteDataSize,&dwHasWrite)){
VirtualFreeEx(piProcInfo.hProcess,pRemoteParam,remoteDataSize,MEM_COMMIT);
return -4;
}
if(dwHasWrite != remoteDataSize) {
VirtualFreeEx(piProcInfo.hProcess,pRemoteParam,remoteDataSize,MEM_COMMIT);
return -5;
}

DWORD dwThreadSize =4096;
void* pRemoteThread = VirtualAllocEx(piProcInfo.hProcess,0,dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!pRemoteThread) {
VirtualFreeEx(piProcInfo.hProcess,pRemoteParam,remoteDataSize,MEM_COMMIT);
return -6;
}

//将线程体拷贝到宿主进程中
if (!WriteProcessMemory(piProcInfo.hProcess,pRemoteThread, &My_threadProc, dwThreadSize, &dwHasWrite)) {
VirtualFreeEx(piProcInfo.hProcess,pRemoteParam,remoteDataSize,MEM_COMMIT);
VirtualFreeEx(piProcInfo.hProcess,pRemoteThread,dwThreadSize,MEM_COMMIT);
return -7;
}
if(dwHasWrite != dwThreadSize) {
VirtualFreeEx(piProcInfo.hProcess,pRemoteParam,remoteDataSize,MEM_COMMIT);
VirtualFreeEx(piProcInfo.hProcess,pRemoteThread,dwThreadSize,MEM_COMMIT);
return -8;
}

//挂起目标进程的主线程
SuspendThread(piProcInfo.hThread);
//获取目标线程的CPU上下文信息
if(!GetThreadContext(piProcInfo.hThread,&context)) return -9;

//更改Eip指令为我们拷贝好的threadProc函数
context.Eip =(DWORD)pRemoteThread;
context.Edx=(DWORD)pRemoteParam;//求解:是否能达到传递参数到my_threadPro线程?
//设置目标线程的CPU上下文信息

if(!SetThreadContext(piProcInfo.hThread,&context)) return -10;

//唤醒目标线程,
ResumeThread(piProcInfo.hThread);
//目标线程此时就会执行我们的threadProc函数了,执行完后还会继续沿着自己原先的代码序列执行下去。
return 0;
}
...全文
61 点赞 收藏 1
写回复
1 条回复

还没有回复,快来抢沙发~

发动态
发帖子
C++ 语言
创建于2007-09-28

3.1w+

社区成员

24.8w+

社区内容

C++ 语言相关问题讨论,技术干货分享
社区公告
暂无公告