Wow64(32位进程)注入DLL到64位进程
转载自: https://blog.poxiao.me/p/wow64-process-inject-dll-into-x64-process/
向其他进程注入DLL通常的做法是通过调用CreateRemoteThread这个API在目标进程内创建一个远程线程,用这个线程来调用LoadLibraryA或LoadLibraryW(下文统称LoadLibrary)以实现让目标进程加载指定的DLL文件。使用CreateRemoteThread创建一个远程线程需要传入一个线程过程函数的地址,并且这个函数地址是需要在目标进程中有效的。由于LoadLibrary是kernel32.dll的导出函数,所以对于运行在同一个系统上的同为32位的进程或同为64位的进程可以假定彼此进程内的LoadLibrary函数的地址是相同的。并且CreateRemoteThread的线程过程函数和LoadLibrary的参数个数相同,且参数都是指针,因此通常都是直接将LoadLibrary作为CreateRemoteThread的过程函数。然后使用VirtualAllocEx在目标进程中分配内存,使用WriteProcessMemory往这块内存中写入DLL文件路径,将这块内存的地址作为线程过程函数(LoadLibrary)的参数。
在64位的Windows操作系统上32位进程中的LoadLibrary函数地址与64位进程的函数地址不同,因此如果想对64位进程注入DLL,简单的做法就是使用64位进程来执行注入工作。但是如果能让32位进程注入DLL到64位进程显然更好。
在一番Google之后找到了这篇文章。这篇文章的作者研究出来一种在Wow64进程中执行x64代码的方法,并且将其封装成了这个库。
本文就是介绍如何使用这个库实现Wow64环境下32位进程向64位进程注入DLL。
Wow64环境下32位进程注入64位进程
32位进程难以注入DLL进64位进程是由于两个进程内LoadLibrary的地址不同,32位进程无法知道64位进程的LoadLibrary函数地址。使用wow64ext这个库在Wow64环境下可以让32位进程获取到64位的ntdll.dll的导出函数(得到的地址与64进程的地址是一样的)。
本文使用ntdll中的这3个未文档的函数来注入DLL。
1 |
NTSTATUS |
使用RtlCreateUserThread创建远程线程,在远程线程中调用LdrLoadDll加载要注入的DLL文件,最后在远程线程中调用RtlExitUserThread退出线程。
为了在远程线程中调用两个函数(LdrLoadDll、RtlExitUserThread),需要将要执行的x64代码写入目标进程,然后让远程线程执行这段代码,在这之前需要了解一些预备知识。可以看MSDN中的这篇文章。通过这个篇文章我们知道了。
- 在调用约定上Windows在x64进行了统一,也就是说不管你有没有显式指定调用约定,指定了何种调用约定,最终编译后都使用
__fastcall这一种调用约定。 - 在参数传递上对于Integer类型(含指针)前4个参数通过
RCX、RDX、R8、R9寄存器传递,其他参数通过栈传递。
LdrLoadDll有4个参数都是指针,RtlExitUserThread只有1个参数是Integer类型。为这两个函数传递参数只通过寄存器就足够了。
当然我们不需要自己去写汇编代码再将汇编代码转成机器码,首先先写下面这样一段代码。
1 |
typedef unsigned long long DWORD64; typedef DWORD64 (*Func4_Type)(DWORD64, DWORD64, DWORD64, DWORD64); |
然后使用VC编译器将其编译成x64的代码,再反汇编它。
VS2013 Debug 反汇编的结果
跟据内存地址,容易得到下面的机器码与汇编代码的对应关系。
1 |
0x48 0x89 0x4c 0x24 0x08 mov qword ptr [rsp+8],rcx |
只要在运行的时候根据获取到的函数地址和参数地址替换对应机器码然后将机器码写入目标进程,创建线程执行这段代码就能够实现Wow64进程注入DLL到64位进程了。
完整的实现代码如下(VS2012编译通过,Windows 8 x64测试注入成功)。
1 |
#include <memory> |
这段代码在创建远程线程成功即认为注入成功,为了更加准确的判断是否注入成功可以在注入的机器码增加额外的代码来判断是否注入成功。
Wow64(32位进程)注入DLL到64位进程的更多相关文章
- Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储
在VS2013中调试Silverlight项目时,提示:无法附加.Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储.请改用64位版本. ...
- 解决32位plsql客户端连接不64位Oracle11g上数据库
一.解决方案 因为本人安装的是64位的Oracle,plsql 是32位的故连接不上.网上有方法能连接. 1. 文件下载 下载PLSQL_Developer地址 http://pan.baidu.co ...
- Hook任务栏时钟窗口(原理其实很简单,就是注入DLL到时钟窗口进程(explorer.exe))
用过一些日历软件的小伙伴应该都知道它们都实现了在时钟窗口上的Hook,也就是屏蔽了系统原有的功能,实现自己的功能 某日历软件Hook时钟窗口后的效果 经过一番研究,发现原理其实很简单,就是注入DLL到 ...
- openstack安装系列问题:window7 64位安装的virtualBox 只能选择32位的系统安装不能选择64位的系统安装
个人原创,转载请注明作者,出处,否则依法追究法律责任 2017-10-03-12:22:22 现象:window7 64位安装的virtualBox 只能选择32位的系统安装不能选择64位的系统安装 ...
- (64位oracle使用32位的PLSQL)安装64位的oracle数据库软件,使用32位的PLSQL Developer连接方法
因为PLSQL Developer没有提供64位的,于是依据网上的资料做了一下整理,发上来 1.下载并安装Oracle 11g R2 64位,在server上安装时忽略硬件检測失败信息: 2.下载Or ...
- C#如何使SQLite程序集既能适应32位系统也能适应64位系统
分享5: 需求:都知道Sqlite3是分32位和64位版本的,那如果将一个Sqlite3.dll文件全适用 分析:Sqlite是种轻量级的数据库文件,使用了混合编程而成的,一部分采用非托管的C++代码 ...
- 无光驱在32位windows系统下安装64位windows系统
位的系统. 大家都知道,32位的操作系统最多只能支持3.2G的内存,现在内存白菜价,很多人都在原有基础上购入新内存,这样最少也有4G了,为了让内存不浪费,我 们只有升级到64位操作系统.但是很多朋友又 ...
- windows目标进程注入dll
在别的程序注入dll 步骤: ,获取目标进程ID,CreateToolhelp32Snapshot()函数; ,获取目标进程句柄,OpenProcess()函数; ,目标进程要一块内存,Virtual ...
- 解决C#的64位打包程序,在64位机器上运行出现BadImageFormatException异常。
转载自:http://msdn.microsoft.com/zh-cn/library/system.badimageformatexception%28v=vs.100%29.aspx BadIma ...
随机推荐
- golang struct
ex1 /* https://golangbot.com/structs/ struct 结构 结构就是一组字段. */ package main import "fmt" // ...
- SVG分组和引用
这是我在掘金中的文章链接地址:https://juejin.im/post/5bcfe0fa51882577e3760467
- SQLite 读取数据时,随机顺序
SELECT * FROM [数据表] ORDER BY random() 通过 random() 这个函数来排序
- Html中video的属性和方法大全
<video>标签的属性 src :视频的属性 poster:视频封面,没有播放时显示的图片 preload:预加载 autoplay:自动播放 loop:循环播放 controls:浏览 ...
- python logging 日志轮转文件不删除问题的解决方法
项目使用了 logging 的 TimedRotatingFileHandler : #!/user/bin/env python # -*- coding: utf-8 -*- import log ...
- SQL动态长度行列转置
一,案列问题描述: 某销售系统中,注册的用户会在随后的月份中购物下单,需要按月统计注册的用户中各个月下单的金额.源数据表如下: FM::注册月份,CM: 下单月份, AMT:下单金额 期望得到如下统计 ...
- python矩阵的切片(或截取)
矩阵一般有行也有列,所以矩阵的截取也需要包含行和列两个参数. 假设a是一个矩阵,a的截取就可写成:a[起始行:终止行,起始列:终止列],中括号中有一个逗号,逗号前的是为了分割行的,逗号后的是为了分割列 ...
- ServletContext、ServletRequest和HttpSession的生命周期
学习web的Listener监听器的时,监听域对象创建的监听器.通过监听器重新分析着三个对象的生命周期,清晰明了. 首先域对象的监听器有三个ServletContextListene.ServletR ...
- hql和sql的一些区别
日期格式化查询的区别: selectSql.append(" AND DATE_FORMAT(o.createDate,\'%Y-%m-%d\') = :createDate"); ...
- Python中serial的使用
一.概述 pyserial模块封装了对串口的访问. 二.特性 在支持的平台上有统一的接口. 通过python属性访问串口设置. 支持不同的字节大小.停止位.校验位和流控 ...