X32进程注入x64DLL到x64进程
在x32程序中获得x64函数地址是找到这个项目,之后根据自己的理解稍微改了改代码,测试之后能够正常的注入,代码如下
#include "stdafx.h"
#include "x32Injectx64.h"
#include <Windows.h>
#include "wow64ext.h"#pragma comment(lib,"wow64ext.lib")CWinApp theApp;using namespace std;typedef struct _UNICODE_STRING {USHORT Length; USHORT MaximumLength; DWORD64 Buffer;
} UNICODE_STRING ,*PUNICODE_STRING;//这里是返回到x32模式
char RetFar[10] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00 };UCHAR Code[] = {0x48, 0x83, 0xEC, 0x28, // sub rsp, 0x28 ,第一个是48,这里改为cc方便调试0x48, 0x31, 0xC9, // xor rcx, rcx0x48, 0x31, 0xD2, // xor rdx, rdx0x49, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov r8, ModuleFileName offset +120x49, 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, // mov r9, ModuleHandle offset +220x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov rax, LdrLoadDll offset +320xFF, 0xD0, // call rax0x48, 0x83, 0xC4, 0x28, // add rsp, 0x280xC3 // ret //如果是32位需要将这里返回为32位状态,64位用它/*0x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov rax, RetFar offset+480x48, 0x8B, 0x0C, 0x24, // mov rcx,qword ptr ss : [rsp] 0x48, 0x89, 0x08, // mov qword ptr ds : [rax],rcx 0x48,0xff,0x28 //jmp far tword ptr ds:[rax] */
};UCHAR code32To64[] = {0xea,0x00,0x10,0x40, 0x00,0x33,0x00 //jmp 33:401000 ea};enum InjectResult{OK,Error_NoSuchFile,Error_OpenProcess,Error_VirtualAllocEx,Error_GetProcAddress,Error_WriteProcessMemory,Error_CreateRemoteThread
};InjectResult Wow64Injectx64(DWORD processid, const TCHAR* file_path) {if (!PathFileExists(file_path)) {return Error_NoSuchFile;}HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processid);if (INVALID_HANDLE_VALUE == handle) {return Error_OpenProcess;}size_t file_path_mem_length = (size_t)::_tcslen(file_path) +1;size_t paramemter_size = file_path_mem_length * sizeof(TCHAR) + sizeof(UNICODE_STRING) + sizeof(DWORD64) ;//申请的大小DWORD64 paramemter_mem_addr = (DWORD64)VirtualAllocEx64(handle, NULL, paramemter_size, MEM_COMMIT, PAGE_READWRITE);//目标地址DWORD64 shell_code_addr = (DWORD64)VirtualAllocEx64(handle, NULL, sizeof(Code), MEM_COMMIT, PAGE_EXECUTE_READWRITE);//申请的shellcode的大小是多少DWORD64 shell_code_32 = (DWORD64)VirtualAllocEx64(handle, NULL, sizeof(shell_code_32), MEM_COMMIT, PAGE_EXECUTE_READWRITE);DWORD64 ret_32 = (DWORD64)VirtualAllocEx64(handle, NULL, sizeof(RetFar), MEM_COMMIT, PAGE_EXECUTE_READWRITE);if ((!paramemter_mem_addr) || (!shell_code_addr)) {return Error_VirtualAllocEx;}DWORD64 ntdll64 = GetModuleHandle64(L"ntdll.dll");DWORD64 ntdll_LdrLoadDll = GetProcAddress64(ntdll64, "LdrLoadDll");DWORD64 ntdll_RtlCreateUserThread = GetProcAddress64(ntdll64, "RtlCreateUserThread");DWORD64 ntdll_RtlExitThread = GetProcAddress64(ntdll64, "RtlExitUserThread");if (NULL == ntdll_LdrLoadDll || NULL == ntdll_RtlCreateUserThread || NULL == ntdll_RtlExitThread) {return Error_GetProcAddress;}// Fill stubs*(ULONGLONG*)((PUCHAR)Code + 12) = paramemter_mem_addr + 8;//第二个参数放到是paramemter_mem_addr+0x10*(ULONGLONG*)((PUCHAR)Code + 22) = paramemter_mem_addr;//第一个参数放到是句柄*(ULONGLONG*)((PUCHAR)Code + 32) = ntdll_LdrLoadDll;//*(ULONGLONG*)((PUCHAR)Code + 48) = ret_32;//*(ULONG*)((PUCHAR)code32To64+1) = shell_code_addr;file_path_mem_length *= 2;//最大为多大DWORD tmpSize = file_path_mem_length - 2;//当前字符串的大小DWORD64 address = paramemter_mem_addr + 0x18;if (!WriteProcessMemory64(handle, paramemter_mem_addr + 8, &tmpSize, 2, NULL) ||!WriteProcessMemory64(handle, paramemter_mem_addr + 10, &file_path_mem_length, 2, NULL) ||!WriteProcessMemory64(handle, paramemter_mem_addr + 0x10, &address, 8, NULL) ||//记录的字符串的地址,这里不是以12开始是因为8字节对齐,!WriteProcessMemory64(handle, paramemter_mem_addr + 0x18, (LPVOID)file_path, (size_t)::_tcslen(file_path) * sizeof(TCHAR), NULL) ||!WriteProcessMemory64(handle, shell_code_addr, Code, sizeof(Code), NULL)||!WriteProcessMemory64(handle, shell_code_32, code32To64, sizeof(code32To64), NULL)||!WriteProcessMemory64(handle, ret_32, RetFar, sizeof(RetFar), NULL)) {return Error_WriteProcessMemory;}DWORD64 hRemoteThread = 0;struct {DWORD64 UniqueProcess;DWORD64 UniqueThread;} client_id;DWORD64 a = X64Call(ntdll_RtlCreateUserThread, 10,(DWORD64)handle, // ProcessHandle(DWORD64)NULL, // SecurityDescriptor(DWORD64)FALSE, // CreateSuspended(DWORD64)0, // StackZeroBits(DWORD64)NULL, // StackReserved(DWORD64)NULL, // StackCommitshell_code_addr, // StartAddress,如果是注入64位进程把这里改为shell_code_addr就行(DWORD64)NULL, // StartParameter(DWORD64)&hRemoteThread, // ThreadHandle(DWORD64)&client_id); // ClientID)//if (INVALID_HANDLE_VALUE == (HANDLE)hRemoteThread) {return Error_CreateRemoteThread;}return OK;
}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){cout<<"What ID You Want To Inject"<<endl; ULONG_PTR ProcessID = 0;printf("Input ProcessID\r\n");cin>>ProcessID;WCHAR file_path[] = L"C:\\64.dll";if (OK==Wow64Injectx64(ProcessID,file_path)){printf("Inject Success!\n");}return 0;
}
这里又引发了一个问题,就是既然是通过切换cs的方式加载的dll,那么x32能不能加载x64的dll,于是把上面的代码改了改,主要是这部分的改动。
由于启动线程之后当前的状态是x32模式下的,所以使用远跳切换cs,后面的401000不是固定,是根据后面申请的地址填的,最后当我们加载dll之后在把当前的cs给改回来(这里不改回来程序会崩掉),之后测试。最后的测试结果是不行,按照正常的理解也是不行了,如果加载导出函数,那么解析的时候是根据x32去解析x64的代码肯定是会出现问题的,有兴趣的朋友可以去试一下。改了之后的代码如下。
//这里是返回到x32模式
char RetFar[10] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00 };UCHAR Code[] = {0x48, 0x83, 0xEC, 0x28, // sub rsp, 0x28 ,第一个是48,这里改为cc方便调试0x48, 0x31, 0xC9, // xor rcx, rcx0x48, 0x31, 0xD2, // xor rdx, rdx0x49, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov r8, ModuleFileName offset +120x49, 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, // mov r9, ModuleHandle offset +220x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov rax, LdrLoadDll offset +320xFF, 0xD0, // call rax0x48, 0x83, 0xC4, 0x28, // add rsp, 0x28//0xC3 // ret //如果是32位需要将这里返回为32位状态,64位用它0x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov rax, RetFar offset+480x48, 0x8B, 0x0C, 0x24, // mov rcx,qword ptr ss : [rsp] 0x48, 0x89, 0x08, // mov qword ptr ds : [rax],rcx 0x48,0xff,0x28 //jmp far tword ptr ds:[rax]
};UCHAR code32To64[] = {0xea,0x00,0x10,0x40, 0x00,0x33,0x00 //jmp 33:401000 ea};enum InjectResult{OK,Error_NoSuchFile,Error_OpenProcess,Error_VirtualAllocEx,Error_GetProcAddress,Error_WriteProcessMemory,Error_CreateRemoteThread
};InjectResult Wow64Injectx64(DWORD processid, const TCHAR* file_path) {if (!PathFileExists(file_path)) {return Error_NoSuchFile;}HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processid);if (INVALID_HANDLE_VALUE == handle) {return Error_OpenProcess;}size_t file_path_mem_length = (size_t)::_tcslen(file_path) +1;size_t paramemter_size = file_path_mem_length * sizeof(TCHAR) + sizeof(UNICODE_STRING) + sizeof(DWORD64) ;//申请的大小DWORD64 paramemter_mem_addr = (DWORD64)VirtualAllocEx64(handle, NULL, paramemter_size, MEM_COMMIT, PAGE_READWRITE);//目标地址DWORD64 shell_code_addr = (DWORD64)VirtualAllocEx64(handle, NULL, sizeof(Code), MEM_COMMIT, PAGE_EXECUTE_READWRITE);//申请的shellcode的大小是多少DWORD64 shell_code_32 = (DWORD64)VirtualAllocEx64(handle, NULL, sizeof(shell_code_32), MEM_COMMIT, PAGE_EXECUTE_READWRITE);DWORD64 ret_32 = (DWORD64)VirtualAllocEx64(handle, NULL, sizeof(RetFar), MEM_COMMIT, PAGE_EXECUTE_READWRITE);if ((!paramemter_mem_addr) || (!shell_code_addr)) {return Error_VirtualAllocEx;}DWORD64 ntdll64 = GetModuleHandle64(L"ntdll.dll");DWORD64 ntdll_LdrLoadDll = GetProcAddress64(ntdll64, "LdrLoadDll");DWORD64 ntdll_RtlCreateUserThread = GetProcAddress64(ntdll64, "RtlCreateUserThread");DWORD64 ntdll_RtlExitThread = GetProcAddress64(ntdll64, "RtlExitUserThread");if (NULL == ntdll_LdrLoadDll || NULL == ntdll_RtlCreateUserThread || NULL == ntdll_RtlExitThread) {return Error_GetProcAddress;}// Fill stubs*(ULONGLONG*)((PUCHAR)Code + 12) = paramemter_mem_addr + 8;//第二个参数放到是paramemter_mem_addr+0x10*(ULONGLONG*)((PUCHAR)Code + 22) = paramemter_mem_addr;//第一个参数放到是句柄*(ULONGLONG*)((PUCHAR)Code + 32) = ntdll_LdrLoadDll;*(ULONGLONG*)((PUCHAR)Code + 48) = ret_32;*(ULONG*)((PUCHAR)code32To64+1) = shell_code_addr;file_path_mem_length *= 2;//最大为多大DWORD tmpSize = file_path_mem_length - 2;//当前字符串的大小DWORD64 address = paramemter_mem_addr + 0x18;if (!WriteProcessMemory64(handle, paramemter_mem_addr + 8, &tmpSize, 2, NULL) ||!WriteProcessMemory64(handle, paramemter_mem_addr + 10, &file_path_mem_length, 2, NULL) ||!WriteProcessMemory64(handle, paramemter_mem_addr + 0x10, &address, 8, NULL) ||//记录的字符串的地址,这里不是以12开始是因为8字节对齐,!WriteProcessMemory64(handle, paramemter_mem_addr + 0x18, (LPVOID)file_path, (size_t)::_tcslen(file_path) * sizeof(TCHAR), NULL) ||!WriteProcessMemory64(handle, shell_code_addr, Code, sizeof(Code), NULL)||!WriteProcessMemory64(handle, shell_code_32, code32To64, sizeof(code32To64), NULL)||!WriteProcessMemory64(handle, ret_32, RetFar, sizeof(RetFar), NULL)) {return Error_WriteProcessMemory;}DWORD64 hRemoteThread = 0;struct {DWORD64 UniqueProcess;DWORD64 UniqueThread;} client_id;DWORD64 a = X64Call(ntdll_RtlCreateUserThread, 10,(DWORD64)handle, // ProcessHandle(DWORD64)NULL, // SecurityDescriptor(DWORD64)FALSE, // CreateSuspended(DWORD64)0, // StackZeroBits(DWORD64)NULL, // StackReserved(DWORD64)NULL, // StackCommitshell_code_32, // StartAddress,如果是注入64位进程把这里改为shell_code_addr就行(DWORD64)NULL, // StartParameter(DWORD64)&hRemoteThread, // ThreadHandle(DWORD64)&client_id); // ClientID)//if (INVALID_HANDLE_VALUE == (HANDLE)hRemoteThread) {return Error_CreateRemoteThread;}return OK;
}
X32进程注入x64DLL到x64进程相关推荐
- 【Android 逆向】Android 进程注入工具开发 ( 远程进程注入动态库文件操作 | 注入动态库 加载 业务动态库 | 业务动态库启动 | pthread_create 线程开发 )
文章目录 前言 一.加载 libnattive.so 动态库 二. libnattive.so 动态库启动 三. pthread_create 线程开发 四. 线程执行函数 前言 libbridge. ...
- 【Android 逆向】Android 进程注入工具开发 ( SO 进程注入环境及 root 权限获取 | 进程注入时序分析 )
文章目录 一.SO 进程注入环境及 root 权限获取 二.进程注入时序分析 一.SO 进程注入环境及 root 权限获取 SO 注入的前提必须有 root 权限 , 有了 root 权限后 , 才能 ...
- 【Android 逆向】Android 进程注入工具开发 ( 调试进程中寄存器的作用 | 通过 EIP 寄存器控制程序运行 | EIP 寄存器的存档与恢复 )
文章目录 一.调试进程中寄存器的作用 二.通过 EIP 寄存器控制程序运行 三.EIP 寄存器的存档与恢复 一.调试进程中寄存器的作用 内存是一个线性结构 , 将动态库加载到内存中后 , 每个动态库文 ...
- 【Android 逆向】Android 进程注入工具开发 ( 远程进程 注入动态库 文件操作 | Android 进程读取文件所需的权限 | fopen 打开文件标志位 | 验证文件权限 )
文章目录 前言 一.Android 进程读取文件所需的权限 二.fopen 打开文件标志位 三.验证文件权限 前言 一.Android 进程读取文件所需的权限 通过 注入工具 , 将 libbridg ...
- 进程注入的研究与实现
为了对内存中的某个进程进行操作,并且获得该进程地址空间里的数据,或者修改进程的私有数据结构,必须将自己的代码放在目标进程的地址空间里运行,这时就避免不了使用进程注入方法了. 进程注入的方法分类如下: ...
- 【Android 逆向】Android 进程注入工具开发 ( 总结 | 源码编译 | 逆向环境搭建使用 | 使用进程注入工具进行逆向操作 ) ★★★
文章目录 一.Android 进程注入工具开发系列博客 二.Android 进程注入工具 源码下载编译 三.逆向环境搭建 四.使用注入工具进行逆向操作 1.获取远程进程号 2.注入工具准备 3.注入动 ...
- 【Android 逆向】Android 进程注入工具开发 ( 远程调用总结 | 远程调用注意事项 )
文章目录 一.远程调用总结 二.远程调用注意事项 一.远程调用总结 在之前的博客 [Android 逆向]Android 进程注入工具开发 ( 调试进程中寄存器的作用 | 通过 EIP 寄存器控制程序 ...
- Windows权限提升—令牌窃取、UAC提权、进程注入等提权
Windows权限提升-令牌窃取.UNC提权.进程注入等提权 1. 前言 2. at本地命令提权 2.1. 适用范围 2.2. 命令使用 2.3. 操作步骤 2.3.1. 模拟提权 2.3.2. at ...
- 易语言对x64进程卸载DLL技术(可卸载64位进程里DLL)
易语言对x64进程卸载DLL技术(可卸载64位进程里DLL) 代码非常简单: 以上是注入和卸载的代码 下面示范64位游戏魔兽世界: 详细视频教程:链接: https://pan.baidu.com/s ...
最新文章
- 深入分析Volatile的实现原理
- 如何扩展分布式日志组件(Exceptionless)的日志通知?
- quantaxis使用docker安装,解决了一个很奇特的问题
- typescript get方法_.NET手撸绘制TypeScript类图——上篇
- mysql 80070057_返回E_INVALIDARG (0x80070057)
- 深入探討 SCOM 2007 管理技術
- 用ubuntu制作ubuntu系统启动盘
- 使用wav2sbc.exe无法转换WAV文件问题
- 视频教程-人工智能-必备数学基础视频教程-机器学习
- win10录屏怎么用_不会用电脑录屏怎么办?教你两种录屏方式,少学一个都遗憾...
- 《Dreamweaver CS6 完全自学教程》笔记 第九章:插入多媒体对象
- 如何有效制服一个杠精
- 11款惊艳的HTML5粒子动画特效
- 数据结构----二叉树已知先序和中序遍历序列求后序遍历
- 计算几何(证明三角形内心公式: aOA+bOB+cOC = 0)
- pdf以文件流的形式导出乱码问题解决
- 【字体分享】各种角度都不一样?带你走进意瞑字的世界
- Cause java lang IllegalArgumentException Mapped Statements
- html刷新css样式,让IE浏览器即时刷新CSS样式_HTML与CSS教程_电脑知识学习_培训之家...
- liunx c语言制作 微型web服务器 300行代码