利用CreateRemoteThread进行远程代码注入的技术在64位机上可能遇到的问题

先看看相关函数的原型 :

    1.模块的加载与卸载
HMODULE WINAPI LoadLibraryA(const char* name);
HMODULE WINAPI LoadLibraryW(const wchar_t* name);
BOOL WINAPI FreeLibrary(HMODULE module);
逆风编程精品

    2.线程函数占位符
DWORD WINAPI ThreadFunc(LPVOID param); // windows.h
unsigned __stdcall thread_proc(void* param); // process.h

    3.获得线程返回值
BOOL WINAPI GetExitCodeThread(HANDLE thread,LPDWORD result);



一、 利用CreateRemoteThread在远程进程中加载模块应该是没有问题的。

LoadLibraryA( const char*  );
LoardLibraryW( const wchar_t * );
ThreadFunc( LPVOID  );
thread_proc( void * );
第1个参数均为指针,位长相同。

所以仍然可以
模块加载函数 线程函数
被加载模块的文件名 线程参数
启动远程线程

CreateRemoteThread( ... , LoadLibraryA , "injectant.dll" , ...);

注意: 一开始我是把 dll 与应用放到一个目录下 的  就是用了相对了路径, 其他最好应该用绝对的路径,要不然其他的程序注入不 了


当然, 这是伪代码。
该方法能工作还需要取得LoadLibraryA在远程进程中的地址,和在远程进程的地址空间中,写入"injectant.dll"。



二、 利用CreateRemoteThread在远程进程中卸载模块也应该是没有问题的。

FreeLibrary(HMODULE );
ThreadFunc(LPVOID );
thread_proc(void* );

指针为了能指向64位的地址空间, 需要64位长。
HMODULE用来表示模块的基地址, 而地址空间是64位, HMODULE也需要64位。

所以仍然可以
模块卸载函数线程函数
被加载模块句柄线程参数
启动远程线程
CreateRemoteThread( ... , FreeLibrary , hModule , ... );



三、 问题发生在:

如何取得被远程进程加载的模块句柄?


    三.1、 线程返回值

线程函数的原型从返回值类型可以分为2种: DWORD和unsigned

可以说,返回机器字长, 也就是unsigned是比较合理的。
而依赖于返回DWORD的代码也不会因为返回类型改为unsigned而出问题。
因为前者需求更少, 后者给于更多。
前者还需要作一次截断, 来取得32位的DWORD返回值。

线程函数以DWORD的原因, 可能是在16位机器上, 如果使用机器字长作返回值, 取值范围太少。
所以,线程函数的返回值, 有可能会改为 uint_least32_t
16位机器上, 使用2个机器字长拼装返回值  32位
32位机器上, 使用机器字长作返回值            32位
64位机器上, 使用机器字长作返回值            64位

也就是说, 线程函数是有可能返回64位的模块句柄的。
为什么不呢?  难道要在返回前作没必要的自行截断么?

    三.2、 取得线程返回值

BOOL GetExitCodeThread(HANDLE thread,LPDWORDresult);

可以将第2个参数改为指向机器字长数据的指针么?  也许不能。
因为函数要求更多 : result必须是指向机器字长数据的指针, 即result所指的连续8个字节都是可写的。
但调用者提供更少 : 调用者很有可能不提供机器字长, 而只提供指向连续4个字节的指针。

想想如下代码是多么普遍(尤其是喜欢使用windows定义的数据类型的同学)
DWORD code = 0;
GetExitCodeThread( thread , &code );
GetExitCodeThread绝对不可以写入8字节内容。

所以, 很有可能无法取得前一步所加载的模块的句柄, 从而无法卸载。



四、 总结

在64位机上, 仍然可以使用该技术远程加载模块。

但是否可以卸载, 还得看:
1. 64位的线程返回值类型
2. 取得线程返回值的函数能够取得多少字节的返回值。
如果2者都是64位, 该技术依然可行。

Win7 CreateRemoteThread 另类使用方法

没有发现在win7 不能注入的问题,按楼上说的,64为注入要用64位的dll,exe也要是64的,在64位下要操作注入,既要DLL是64位的,就连注入动作的EXE也要是64位的才行。感谢诸位的解答了。正解就是要用VS2010把DLL编译成64位的就行了

VS2010编译成64位设置值: Project ->properties->Configuration Properties ->Linker ->Advanced ->Target Machine

Lib库也要是 64 位的 : Project ->properties->Configuration Properties -> VC++ Directories

Properties->Configuration Properties,点击右上的Configuration Manager,查看列表中对应工程的platform是否设置为x64。我的问题,设置为x64就解决了。
x64cm.png 




判断系统是否是64位函数

/************************************************************************/
/* 
	return TRUE位64位  仅使用在应用程序是 32位的时候, 64位无效的
*/
/************************************************************************/
BOOL CDllInjectionDlg::IsWow64()
{
	typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
	LPFN_ISWOW64PROCESS fnIsWow64Process;

	BOOL bIsWow64 = FALSE;
	fnIsWow64Process =(LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
	if (NULL != fnIsWow64Process)
	{
		if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
		{
			MessageBox(TEXT("IsWow64 error!"));
		}

	}
	return bIsWow64;
}

注入相关链接: http://blog.csdn.net/ithzhang/article/details/7051558

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 示例代码:#include <windows.h> #include <stdio.h> #include <tlhelp32.h> // 远程线程注入dll BOOL InjectDLL(DWORD dwPID, char *szDLLName); int main(int argc, char *argv[]) { printf("远程线程注入dll演示程序\n"); if (argc == 3) { DWORD dwPID = atoi(argv[1]); char *szDLLName = argv[2]; InjectDLL(dwPID, szDLLName); } else { printf("用法:InjectDLL.exe <PID> <DLLName>\n"); } return 0; } // 远程线程注入dll BOOL InjectDLL(DWORD dwPID, char *szDLLName) { HANDLE hProcess, hThread; LPVOID lpBaseAddress; LPTHREAD_START_ROUTINE lpStartAddress; DWORD dwSize, dwThreadId; char szPath[256]; char szBuffer[1024]; // 打开进程 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); if (hProcess == NULL) { printf("OpenProcess() Error: %d\n", GetLastError()); return FALSE; } // 获取DLL的完整路径 GetFullPathName(szDLLName, 256, szPath, NULL); // 在进程中申请虚拟内存 dwSize = strlen(szPath) + 1; lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); if (lpBaseAddress == NULL) { printf("VirtualAllocEx() Error: %d\n", GetLastError()); return FALSE; } // 将DLL路径写入到虚拟内存 int nBytesWritten; WriteProcessMemory(hProcess, lpBaseAddress, szPath, dwSize, &nBytesWritten); if (nBytesWritten != dwSize) { printf("WriteProcessMemory() Error: %d\n", GetLastError()); return FALSE; } // 加载Kernel32.dll HMODULE hKernel32 = GetModuleHandle("Kernel32"); if (hKernel32 == NULL) { printf("GetModuleHandle() Error: %d\n", GetLastError()); return FALSE; } // 获取LoadLibraryA函数地址 lpStartAddress = GetProcAddress(hKernel32, "LoadLibraryA"); if (lpStartAddress == NULL) { printf("GetProcAddress() Error: %d\n", GetLastError()); return FALSE; } // 创建远程线程 hThread = CreateRemoteThread(hProcess, NULL, 0, lpStartAddress, lpBaseAddress, 0, &dwThreadId); if (hThread == NULL) { printf("CreateRemoteThread() Error: %d\n", GetLastError()); return FALSE; } // 等待远程线程结束 WaitForSingleObject(hThread, INFINITE); // 读取线程退出码 DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); if (dwExitCode == 0) { printf("LoadLibrary() Error: %d\n", GetLastError()); return FALSE; } // 关闭句柄 CloseHandle(hProcess); CloseHandle(hThread); return TRUE; }我不能帮助你编写代码,但是我可以提供一些参考资料,帮助你编写远程线程注入dll代码。 ### 回答2: 远程线程注入DLL是一种技术,用于在目标进程中注入自定义的动态链接库(DLL)并执行其中的代码。以下是一个使用C语言编写的远程线程注入DLL代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <windows.h> int main() { // 目标进程的进程ID DWORD pid = 1234; // 加载要注入DLL路径 char dllPath[] = "C:\\path_to_dll\\mydll.dll"; // 获取目标进程句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (hProcess == NULL) { printf("无法打开目标进程"); return -1; } // 在目标进程中为DLL路径分配内存 LPVOID dllPathAddr = VirtualAllocEx(hProcess, NULL, sizeof(dllPath), MEM_COMMIT, PAGE_READWRITE); if (dllPathAddr == NULL) { printf("无法在目标进程中分配内存"); CloseHandle(hProcess); return -1; } // 在目标进程中写入DLL路径 if (!WriteProcessMemory(hProcess, dllPathAddr, dllPath, sizeof(dllPath), NULL)) { printf("无法写入DLL路径到目标进程"); VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; } // 获取Kernel32.dll中LoadLibrary函数的地址 HMODULE kernel32 = GetModuleHandle("kernel32.dll"); FARPROC loadLibrary = GetProcAddress(kernel32, "LoadLibraryA"); // 创建远程线程在目标进程中执行LoadLibrary函数,将DLL路径作为参数 HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibrary, dllPathAddr, 0, NULL); if (hThread == NULL) { printf("无法在目标进程中创建远程线程"); VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; } // 等待远程线程执行结束 WaitForSingleObject(hThread, INFINITE); // 清理资源 VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hThread); CloseHandle(hProcess); printf("远程线程注入DLL成功"); return 0; } ``` 这段代码首先通过`OpenProcess`函数打开目标进程,然后使用`VirtualAllocEx`在目标进程中为DLL路径分配内存,并使用`WriteProcessMemory`将DLL路径写入目标进程内存。接着,使用`GetModuleHandle`和`GetProcAddress`获取`LoadLibrary`函数的地址,然后使用`CreateRemoteThread`在目标进程中创建一个远程线程,让其执行`LoadLibrary`函数,将DLL路径作为参数传递给它。最后,使用`WaitForSingleObject`等待远程线程执行完毕,并释放之前分配的资源。 ### 回答3: 使用C语言编写远程线程注入DLL代码可以通过以下步骤实现: 1. 首先,需要创建一个目标进程的句柄。可以使用`OpenProcess`函数来打开目标进程,并获得进程的句柄。 2. 接下来,需要在目标进程中分配一块内存空间,用于存储DLL的路径和名称。可以使用`VirtualAllocEx`函数在目标进程内部分配内存。 3. 在分配的内存空间中写入DLL的路径和名称。可以使用`WriteProcessMemory`函数将DLL的路径和名称写入到目标进程的内存中。 4. 使用`GetProcAddress`函数获取`LoadLibraryA`函数的地址,该函数用于加载DLL。可以使用`GetModuleHandle`函数获取kernel32.dll的句柄,然后再调用`GetProcAddress`函数来获取`LoadLibraryA`函数的地址。 5. 使用`CreateRemoteThread`函数在目标进程中创建一个远程线程,将`LoadLibraryA`函数地址作为线程的入口点,将DLL的路径和名称作为线程的参数传递。这样,在目标进程中就会自动加载并执行DLL。 完整的代码示例如下: ```c #include <windows.h> int main() { // Step 1: 打开目标进程句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PROCESS_ID); // Step 2: 分配内存空间 LPVOID lpRemoteBuffer = VirtualAllocEx(hProcess, NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // Step 3: 写入DLL路径和名称 char dllPath[] = "C:\\path\\to\\dll.dll"; WriteProcessMemory(hProcess, lpRemoteBuffer, (LPVOID)dllPath, sizeof(dllPath), NULL); // Step 4: 获取LoadLibraryA函数地址 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); FARPROC lpLoadLibraryA = GetProcAddress(hKernel32, "LoadLibraryA"); // Step 5: 创建远程线程注入DLL HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibraryA, lpRemoteBuffer, 0, NULL); // 关闭句柄 CloseHandle(hThread); CloseHandle(hProcess); return 0; } ``` 以上就是使用C语言编写远程线程注入DLL代码。请注意,使用远程线程注入DLL可能存在一些安全风险,请谨慎使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值