远程线程注入的做法是通过API:CreateRemoteThread在目标进程创建远程线程,让这个线程实现LoadLibrary去加载动态库。LoadLibrary函数通过kernel32导出,在32位和64位下的地址是不同的,所以一般来说32位是无法注入64位的。
在github上有一个开源项目rewolf-wow64ext,该项目的目的是让运行在Wow64下的32位程序可以调用x64下的API。
具体方法是通过该库的函数导出LdrLoadDll,RtlCreateUserThread,RtlExitUserThread三个API,RtlCreateUserThread创建远程线程,LdrLoadDll加载动态库,RtlExitUserThread退出远程线程。代码如下:
// Wow64Injectx64.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <string>
#include "shlwapi.h"
#include "wow64ext.h"
#pragma comment(lib,"shlwapi.lib")
#pragma comment(lib,"wow64ext.lib")
using namespace std;
//
unsigned char ShellCode[] = {
0x48, 0x89, 0x4c, 0x24, 0x08, // mov qword ptr [rsp+8],rcx
0x57, // push rdi
0x48, 0x83, 0xec, 0x20, // sub rsp,20h
0x48, 0x8b, 0xfc, // mov rdi,rsp
0xb9, 0x08, 0x00, 0x00, 0x00, // mov ecx,8
0xb8, 0xcc, 0xcc, 0xcc, 0xcc, // mov eac,0CCCCCCCCh
0xf3, 0xab, // rep stos dword ptr [rdi]
0x48, 0x8b, 0x4c, 0x24, 0x30, // mov rcx,qword ptr [__formal]
0x49, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov r9,0 //PVOID* BaseAddr opt
0x49, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov r8,0 //PUNICODE_STRING Name
0x48, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rdx,0
0x48, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rcx,0
0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax,0
0xff, 0xd0, // call rax LdrLoadDll
0x48, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rcx,0
0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax,0
0xff, 0xd0 // call rax
};
BOOL Wow64Injectx64(DWORD ProcessID, const TCHAR* FilePath);
int main()
{
cout << "Input ProcessID" << endl;
ULONG_PTR ProcessID = 0;
cin >> ProcessID;
WCHAR FilePath[] = L"C:\\Users\\ChangSungsin\\Desktop\\测试\\Injectx64\\Injectx64\\Dll.dll";
if (Wow64Injectx64(ProcessID, FilePath))
{
cout << "Inject Success" << endl;
}
else
{
cout << "Failed to Inject" << endl;
}
return 0;
}
BOOL Wow64Injectx64(DWORD ProcessID, const TCHAR* FilePath)
{
if (!PathFileExists(FilePath))
{
return FALSE;
}
HANDLE hTarget = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, ProcessID);
if (INVALID_HANDLE_VALUE == hTarget)
{
return FALSE;
}
SIZE_T FilePathLength = (SIZE_T)::_tcslen(FilePath);
SIZE_T ParamemterSize = (FilePathLength + 1)*sizeof(TCHAR) + sizeof(_UNICODE_STRING_T<DWORD64>) + sizeof(DWORD64);
DWORD64 ParamemterMemAddr = (DWORD64)VirtualAllocEx64(hTarget, NULL, ParamemterSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
DWORD64 ShellCodeAddr = (DWORD64)VirtualAllocEx64(hTarget, NULL, sizeof(ShellCode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if ((!ParamemterMemAddr) || (!ShellCodeAddr))
{
return FALSE;
}
char* ParamemterMemLocal = new char[ParamemterSize];
memset(ParamemterMemLocal, 0, ParamemterSize);
_UNICODE_STRING_T<DWORD64>* UnicodeString = (_UNICODE_STRING_T<DWORD64>*)(ParamemterMemLocal + sizeof(DWORD64));
UnicodeString->Length = FilePathLength * sizeof(wchar_t);
UnicodeString->MaximumLength = (FilePathLength +1)* 2;
wcscpy((WCHAR*)(UnicodeString + 1), FilePath);
UnicodeString->Buffer = ParamemterMemAddr + sizeof(DWORD64) + sizeof(_UNICODE_STRING_T<DWORD64>);
DWORD64 Ntdll64 = GetModuleHandle64(L"ntdll.dll");
DWORD64 NtdllLdrLoadDll = GetProcAddress64(Ntdll64, "LdrLoadDll");
DWORD64 NtdllRtlCreateUserThread = GetProcAddress64(Ntdll64, "RtlCreateUserThread");
DWORD64 NtdllRtlExitThread = GetProcAddress64(Ntdll64, "RtlExitUserThread");
if (NtdllLdrLoadDll == NULL || NtdllRtlCreateUserThread == NULL || NtdllRtlExitThread == NULL)
{
return FALSE;
}
// DWORD转char
union {
DWORD64 from;
unsigned char to[8];
}Convert;
// 写入r9寄存器
Convert.from = ParamemterMemAddr;
memcpy(ShellCode + 32, Convert.to, sizeof(Convert.to));
// 写入r8寄存器
Convert.from = ParamemterMemAddr + sizeof(DWORD64);
memcpy(ShellCode + 42, Convert.to, sizeof(Convert.to));
// 写入LdrLoadDll地址
Convert.from = NtdllLdrLoadDll;
memcpy(ShellCode + 72, Convert.to, sizeof(Convert.to));
// 写入NtdllRtlExitThread地址
Convert.from = NtdllRtlExitThread;
memcpy(ShellCode + 94, Convert.to, sizeof(Convert.to));
SIZE_T WriteSize = 0;
if (!WriteProcessMemory64(hTarget, ParamemterMemAddr, ParamemterMemLocal, ParamemterSize, NULL) ||
!WriteProcessMemory64(hTarget, ShellCodeAddr, ShellCode, sizeof(ShellCode), NULL))
{
return FALSE;
}
DWORD64 hRemoteThread = 0;
struct {
DWORD64 UniqueProcess;
DWORD64 UniqueThread;
}ClientID;
int nRet = X64Call(NtdllRtlCreateUserThread, 10,
(DWORD64)hTarget, // ProcessHandle
(DWORD64)NULL, // SecurityDescriptor
(DWORD64)FALSE, // CreateSuspended
(DWORD64)0, // StackZeroBits
(DWORD64)NULL, // StackReserved
(DWORD64)NULL, // StackCommit
ShellCodeAddr, // StartAddress
(DWORD64)NULL, // StartParameter
(DWORD64)&hRemoteThread, // ThreadHandle
(DWORD64)&ClientID); // ClientID)
if (hRemoteThread != 0)
{
CloseHandle((HANDLE)hRemoteThread);
return TRUE;
}
return TRUE;
} 收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2313
- 用户1336
- 访客11759810
每日一句
Pride in your steps to dreams.
为追梦的每一步而自豪。
为追梦的每一步而自豪。
新会员