首页
社区
课程
招聘
大家有没有试过64位DLL注入到32位EXE程序,研究过的可以说下思路
发表于: 2016-2-19 19:37 20103

大家有没有试过64位DLL注入到32位EXE程序,研究过的可以说下思路

2016-2-19 19:37
20103
以前看过32位DLL注入到64位EXE的思路,大家有没有试过64位DLL注入到32位EXE程序,研究过的可以说下思路。如果可以实现的话,对于游戏辅助防破解这块还是有很大的帮助。

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 0
支持
分享
最新回复 (31)
雪    币: 8197
活跃值: (3302)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
2
64位dll注入到32位进程??????????
2016-2-19 20:52
0
雪    币: 61
活跃值: (1046)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
山哥,这个问题提的太有水平了,防破解带上钞票找我。
2016-2-19 20:56
0
雪    币: 1260
活跃值: (101)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
只想知道64位DLL能不能注入32位EXE进程
2016-2-19 22:34
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
5
64位DLL是不能注入32位EXE进程的,原因是指令的长度和编码是不一样的,所以不能注入,即使通过自己的函数强行写入内存中,也会导致不能执行,要是真的能注入的话,微软早就这么干了,还用你在这提问么?
2016-2-19 22:46
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6

前几天刚写完。。。
wow64本来就是64位程序
2016-2-20 00:01
0
雪    币: 272
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
可以把,32位进程其实是64位进程中的32位模式,最终还是要切换到64位模式的。
2016-2-20 03:50
0
雪    币: 11
活跃值: (224)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
Tesla.Angela

在 15年的时候, 已经实现过这个了, 但是方法 好像没有共享出来
2016-2-20 09:56
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
9
这个调用都是有严格约定的,这个调用是用户程序呼叫内核程序时用到的调用,调用约定都是事先定义好的,并且有转换的,不知道你看了WRK了么?X32调用X64的内核函数都是经过转换的,而且转换的只是数据结构,并不涉及指令长度的转换,而是转换了数据长度之后,通过中断进入内核的,但是不是内核程序的话,你不止需要转换数据长度,还需要进行指令的转换,你也不知道什么时候系统会调用你的dll,系统也不会知道需要转换数据结构和指令长度,例如加载DLL的时候系统需要调用DLLEntry,由于指令长度和指针长度不一样,系统也不知道你调用的函数的指令长度和系统认为的指令长度不一样,所以系统并不会去转换,你可以想想系统寻找和调用DLLEntry的时候会出现什么后果,不信的话,你可以自己试一试,将DLL中的标识强行改为32位,然后让系统加载,你就会看到效果了
2016-2-20 12:43
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
10
人家是通过虚拟机解决的,估计是内建了虚拟机,不过,内建虚拟机的话,应该不算解决问题吧?毕竟如果是虚拟机的话,不仅可以虚拟X64的指令,甚至还可以虚拟ARM的指令呢!
2016-2-20 12:47
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
11
不过你可以使用COM来实现,虽然说COM也是不能在32位的情况下调用64位的DLL的,但是COM是一个比较不错的接口,数据结构都是事先定义好的,其会在32位进程内部虚拟一个对象,你可以直接调用这个对象中的方法,在初始化这个对象过程中,windows会用一个64位的程序加载你的COM DLL,这个时候,你对对象的调用,会被按照事先约定的方法转换,并且转发到这个64位程序加载的DLL上,这样看起来就是可以用32位程序直接调用64位程序的DLL,但是这不是真的调用,只是WINDOWS对这个调用的一个虚拟而已
2016-2-20 12:58
0
雪    币: 81
活跃值: (115)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
GitHub - DarthTon Xenos

Features

Supports x86 and x64 processes and modules
Kernel-mode injection feature (driver required)
Manual map of kernel drivers (driver required)
Injection of pure managed images without proxy dll
Windows 7 cross-session and cross-desktop injection
Injection into native processes (those having only ntdll loaded)
Calling custom initialization routine after injection
Unlinking module after injection
Injection using thread hijacking
Injection of x64 images into WOW64 process
Image manual mapping
Injection profiles

源码慢慢读,都是很成熟的技术了
2016-2-23 10:13
0
雪    币: 295
活跃值: (363)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
xjj
13
b64K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3y4G2M7Y4y4A6P5q4)9J5k6h3!0J5k6#2)9J5c8X3y4G2L8Y4c8W2L8Y4c8Q4x3V1k6V1L8r3I4Q4x3X3c8A6L8X3A6W2j5%4c8A6L8$3&6Q4x3X3c8S2L8X3c8Q4x3X3c8%4L8%4M7$3y4l9`.`.
2016-2-23 13:09
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
双向都可以注入, 前提是手工获取api地址,硬编码。
2016-2-26 01:05
0
雪    币: 808
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
15
64位程序中的va在32位程序中无法定位,长度无法匹配,看楼下怎么说
2016-2-26 21:56
0
雪    币: 227
活跃值: (450)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
16
你给我解释下X64位下 ntdll,wow64cpu,wow64win,wow64 这几个64位的模块是怎么回事.
2016-2-27 15:23
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
17
得,我还是给你解释一下吧!原来我也认为能将X64位的模块远程加载到X86的进程中,用远程线程加载64位模块的时候,进程里面的LoadLibrary返回了一个0,提示有错误发生,我认为可能是我的DLL出错,我就继续修改代码,使得远程线程加载模块之后能调用GetLastError给我返回错误消息,当我再次加载这个代码的时候,远程进程崩溃了,我不甘心,将VC IDE调试器附加到远程进程之后,继续注入这个远程进程,结果VC给我报错,我发现,远程进程执行了一段不合法的指令,所以出错!既然指令不合法,那我就修改指令,然后在本进程执行,等本进程执行指令通过之后,再次远程注入,发现VC同样报错,原因同样是不合法的指令
我还是不甘心,我在想WINDOWS 不是有消息钩子么?这个可以注入DLL了吧?我就弄了一个消息钩子的DLL,用来全局拦截消息,当拦截消息时,DLL应该会被加载进入X86的进程中了吧?好,这时我在消息回调函数中用一个MessageBox显示当前的进程名字,以及进程ID,还有是X86的还是X64的

我弄了一个X64下的钩子DLL,运行这个DLL,然后启动一个X86的文本编辑程序,当我安息一个按键的时候,奇怪的事情发生了,MessageBox弹出的提示中,我看到显示的是我自己的进程ID 和进程名,我和惊讶,马上使用 xuetr查看DLL加载到了什么进程,结果发现,x86的编辑器中没有我的模块,我还是不甘心,想到,我的DLL消息钩子的进程本来就加载了我的DLL的,那是不是DLL拦截了我自己的消息导致的?于是,我就将安装消息钩子的函数放在了DLL中,然后弄一个Rundll32的接口,使用系统的Rundll32来加载并且运行DLL中安装钩子的函数来安装钩子,想到这样应该可以了吧?可是,事情却不是这样的,弹出的消息中,显示的是RUNDLL32的进程,消息dll并没有注入到X86的编辑器中,我还是不甘心,直接找到X64系统下的32位的RUNDLL32来加载这个64位的DLL,运行之后,我发现,这是RUNDLL32确实加载了我的64位的DLL,我高兴了半天,“认为终于能解决问题了”,可是当我仔细看的时候,却发现了问题,DLL加载的命令被转发到了64位的RUNDLL32中,弹出的提示也是64位的RUNDLL32弹出的,我立马崩溃,

我想,我直接将代码远程注入到X86的程序,在只调用LoadLibrary的时候却能执行,但是加载DLL却失败!但是,在远程代码中加入连续调用LoadLibrary和GetLastError的时候却失败了,而且使用消息钩子和RUNDLL32加载时也不能实现的时候,我就想,为什么直接远程调用LoadLibrary却能成功呢?

后来我仔细观察了一下,远程调用LoadLibrary的时候,在远程调用LoadLibrary的时候,发生了溢出,将堆栈的数据覆盖了,只是覆盖参数的堆栈,没有覆盖返回地址,所以调用成功,但是加入调用一段指令时就会失败!

我还是不甘心,去看了MSDN,看到了一段原话,意思是,使用RUNDLL32加载不同位的模块的时候,相应的加载请求会被转发到对应位的RUNDLL32上,而且用消息钩子的话,消息DLL如果是32位的模块,而目标是64位进程的话,消息会被转发到安装这个DLL的进程当中,同样,如果消息钩子模块是64位的,而目标是32位的进程的话,同样消息也会被转发到安装钩子的进程上!

我看到MSDN的说明之后,明白了,微软是不支持加载不同位的模块的!那既然这样,如果进程是32位的,那为什么能在64位系统中运行呢?对NTDLL中函数的调用,可都是64位的啊!
我决心看个明白,就下载了微软的WRK,然后用OD看个明白!

我注意到了,一个细节,就是如果进程是32位的,那么加载系统的NTDLL等关键模块的时候,实际上加载的模块是windows\syswow64目录下的模块,这里的模块是32位的,同样,如果是64位的进程,那么加载的就是windows\system32下的模块,而这里的模块是64位的!看到这,我才知道,原来系统的模块是区分是32位的,还是64位的,当一个进程试图加载不同位的系统的DLL的时候,会被重定向到对应的位的DLL上,这也就解释了,为什么32位和64位进程同时调用NTDLL等系统DLL时,为什么不会出现问题!原来它们都被重定向了!

这时候,我又有疑惑了,既然DLL加载会被重定向,那系统调用呢?那可是32位进程调用64位的系统服务啊!为什么不会出现问题呢?
这时候我打开OD,跟踪一个系统调用,我选择了一个系统调用NtQueryInformationProcess,然后跟进,发现这个调用不是普通的sysenter\int指令而是一个jmp xxxx:xxxxxxxx的跳转指令,继续跟入,发现已经没有权限跟踪了,说明已经跳转到了内核空间!跟踪停止,关闭OD,打开WRK,查看了NtQueryInformationProcess的实现,我发现了其中的奥秘,原来,NtQueryInformationProcess等系统调用检查了调用是否来自32位的进程,如果是来自32的进程的话,就将参数转换位64位的参数,而NtQueryInformationProcess本身的地址,则通过32位进程的jmp xxxx:xxxxxxxx指令跳转到内核空间,然后通过SSDT来取得地址,然后转换之后再调用的!

看到这里,我全部明白了,原来64位的进程只能加载64位的模块,32位的进程也只能加载32位的模块,那为什么64位的系统能运行32位的程序呢?原来只是系统通过重定向技术和虚拟的办法,将加载的模块进行了虚拟化,已经对对应的系统调用进行了转换而已,通过虚拟化和转换,使得32位的程序能运行在64位的系统中!

到现在,我明白了,32位的程序调用系统服务时,它的调用是经过了转换的,而加载系统的模块的时候,系统将调用的模块重定向到了syswow64目录中!
因此,我得出结论,64位的进程只能加载64位的模块,而32位的进程也只能加载32位的模块,然后我放弃了将64位模块加载到32位进程当中的想法,只能无奈的放弃了!
2016-2-28 23:22
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
18
你可以试一试,看看系统加载不同位的DLL的时候是否会重定向!
你写一个64位的DLL,然后写一个64位的程序,将DLL移动到windows\system32目录下,(不要复制,而是要移动,这样能防止DLL和EXE程序在同一个目录下,导致系统加载同一个目录下的程序,而影响试验)这时候你用64位程序加载你的DLL会加载成功的!

然后,你将你的程序编译为32位的程序,然后加载windows\system32中的那个64位DLL,你会发现,系统返回错误,原因是DLL文件不存在!为什么会这样呢?

接着,你删除了那个64位的DLL,然后编译一个32位的DLL,然后移动到windows\syswow64目录下,接着用你的32位的程序加载同样是windows\system32目录下这个DLL,这个时候,有趣的现象发生了,你会发现,对windows\system32下的DLL的调用会被重定向到windows\syswow64目录下,
看到这,你应该明白为什么32位程序调用64位系统DLL的时候不会出现问题了吧?它们的调用都被重定向到了32位的系统DLL上,那当然不会出现问题了!

那你应该问了,既然重定向了,那获取这个DLL路径的时候,为什么还是windows\system32目录下呢?那这个更加简单了,既然是重定向,那就做的彻底一点,系统在你试图获取DLL路径的时候,将得到的路径,改为了windows\system32目录,使得你看起来,DLL加载的路径是windows\system32,这样重定向看起来更加逼真,也增加了兼容性!
2016-2-28 23:46
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
19
另外,说一下,使用mklink就可以实现同样的文件重定向的效果!
2016-2-28 23:49
0
雪    币: 298
活跃值: (74)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
20
哥们,你这只是说了64位系统下的文件系统重定向,这是可以在进程里关掉的,然后注册表也有重定向。
但是你这个并不能解释那位哥们提的问题啊,就是:在64位系统下,32位进程里有3个模块wow64win.dll、wow64cpu.dll、wow64.dll,这三个模块是在system32下面,不是在重定向的syswow64下面,而且模块也确实是64位的。
2016-3-1 16:43
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
21
这三个模块是负责在将用户层转换从驱动处返回或者回调时的地址,指针以及堆栈转换为32位的地址,指针和堆栈的,换句话说,就是负责将64位模式,转换成32位模式的模块,我们32位程序调用驱动的服务的时候,就由驱动实现模式的转换,而64位驱动回调32位的程序的时候,就由这3个DLL实现的模式的转换,由于驱动回调过来的是64位的地址和指针,以及堆栈,所以必须有一个模块对它实现转换才行,不过,这些调用也是预定义好的!
2016-3-3 19:51
0
雪    币: 227
活跃值: (450)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
22
首先切换模式那是CPU做的事情.然后问题来,这几个模块是不是64位模块?又是不是在32位的进程内呢?
2016-3-3 20:13
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
23
是在32位进程内,可是无法实现楼主要的功能啊!
2016-3-4 19:54
0
雪    币: 227
活跃值: (450)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
24
可以,64位的模块注入到32位的进程内.这有很多人实现了.包括我在内.
2016-3-6 16:36
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
25
我想知道,那你怎么处理系统回调32位的DLL呢?要知道两者的堆栈布局有点不同啊
2016-3-8 21:35
0
游客
登录 | 注册 方可回帖
返回