首页
社区
课程
招聘
[求助]x64下动态加载EXE文件到内存执行遇到的问题 0xc0000005
发表于: 2018-8-5 09:04 9337

[求助]x64下动态加载EXE文件到内存执行遇到的问题 0xc0000005

2018-8-5 09:04
9337
看得多说的少。。小透明第一次发帖询问
目的主要是想在内存中执行一个EXE文件,查了一些资料,这种手法好像也称为进程注入,或者傀儡进程方法。
其流程大致如下

1. 通过给CreateProcess传递一个CREATE_SUSPENDED来启动A程序

2. 通过调用GetThreadContext来获取被挂起进程A的CONTEXT。

    其中ebx寄存器指向进程的PEB,eax寄存器的值为进程的入口点地址。通过PEB来获取进程的基地址,如[EBX + 8]

3. 把要从内存启动的可执行程序(B)加载到内存中并进行对齐处理。

      这里情况分为几种,先调用ZwUnmapViewOfSection来取消可执行程序A的映像映射,

      a) 通过VirtualAllocEx在进程A中为可执行程序B在程序B的默认基地址分配足够的空间。成功后,把可执行程序B的镜像复制到进程A的内存空间并从分配的空间的起始地址开始执行

      b) 调用VirtualAllocEx的时候失败,而可执行程序B时可重定位的(存在重定位表),那么可以从A的内存空间的任意位置为B分配足够的空间,然后基于所分配的空间进行为B进行重定位处理,然后把可执行程序B的镜像复制到进程A的内存空间并从分配的空间的起始地址开始执行。

4. 把进程A的PEB中的基地址改为可执行程序B的基地址。同时把线程上下文中的EAX寄存器的值设置为可执行程序B的入口点。

5. 通过调用SetThreadContext来设置线程的上下文。

6 . 通过调用ResumeThread来执行被挂起的进程。


这个网上有比较多的代码采用这种方式,其中大同小异。我在win10 x64上用32位的程序去实现这个过程,发现了一些问题。如下

一. 如果A程序和B程序有相同的基地址,那么上面流程3.a)中的操作可以成功,而且整个程序也可以执行。整个方法通过

二.如果A程序与B程序的基地址不同,那么3.a)也就是从B的基地址分配内存这步总是会失败,返回的错误是0x1e7,是权限问题

     但是3.b)是可以成功的。再进行相应的重定位操作以后,4.5两步也都可以成功,但是第6步执行的时候,

      总是会报一个0xc0000005的错误,这个错误应该是权限错误。


在网上搜索了一些资料,发现碰到这个问题的人有一些,但是都没有得到一个解决。我能想到的可能造成这个错误的原因有两种,

第一是重定位的代码有问题。

重定位的代码修复后如下,已经确认可以使用,所以可以排除这种原因了。

void DoRelocation(PIMAGE_NT_HEADERS peH, void *OldBase, void *NewBase)
{
	IMAGE_BASE_RELOCATION ;
	unsigned long Delta = (unsigned long)NewBase - peH->OptionalHeader.ImageBase;
	PImageBaseRelocation p = (PImageBaseRelocation)((unsigned long)OldBase
		+ peH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
	while (p->VirtualAddress + p->SizeOfBlock)
	{
		unsigned short *pw = (unsigned short *)((int)p + sizeof(*p));
		for (unsigned int i = 1; i <= (p->SizeOfBlock - sizeof(*p)) / 2; ++i)
		{
                        //网上找到的代码这里少了一个括号,修改了一下
			if (((*pw) & 0xF000) == 0x3000) {
				unsigned long *t = (unsigned long *)((char*)(OldBase)+p->VirtualAddress + ((*pw) & 0x0FFF));
				*t += Delta;
			}
			++pw;
		}
		p = (PImageBaseRelocation)pw;
	}
}

第二,32位程序在64位系统上运行,是运行在Wow64中,

那么是不是Context或者PEB和32位系统有什么不同?

进行了一些思考也尝试了一些方法: 

如果A和B基地址相同,整个方法通过,那么在基地址不同的时候,我在A的基地址上为B分配内存而不是如3.b)中所说的在任意位置分配,

这个时候,内存分配一般是可以成功,然后我把B向A的基地址进行重定位,这样可以保证PEB和Context中其他的内容不变,而只是需要需改入口点,

这时大部分情况可以通过。。。。我也还在继续尝试。。。发现傀儡程序使用自己写的exe大部分是可以,用了原来代码中使用的计算器(calc.exe),记事本(notpad.exe)就不行了,应该是Windows添加了某种保护?

求大神帮忙看看,这到底是什么问题。。有没有朋友愿意一起讨论


     






[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2018-8-5 17:11 被airing编辑 ,原因: 后续进行了一些实验,发现了一些改进方法
收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 182
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
后续进一步试验了一下,目前基本可以确定是系统的问题,不是代码错误。在傀儡进程空间里,不使用任意位置分配内存可以解决这个问题,但是还是想知道出错的具体原因。
2018-8-5 17:12
0
雪    币: 5734
活跃值: (1737)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
- -这种问题 挂上调试器 不是秒解决么
2018-8-9 21:58
0
雪    币: 1
活跃值: (359)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
您好 大哥。这个问题解决了吗   最近我也出了这种问题
2018-8-29 16:29
0
雪    币: 39
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
你好,我也遇到这个问题,不知道你解决了吗?
2018-9-17 22:20
0
雪    币: 220
活跃值: (711)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
airing 后续进一步试验了一下,目前基本可以确定是系统的问题,不是代码错误。在傀儡进程空间里,不使用任意位置分配内存可以解决这个问题,但是还是想知道出错的具体原因。
怎么解决的啊?
2018-10-28 17:20
0
雪    币: 30050
活跃值: (2422)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
0xc0000005的错误===>不要执行“这里情况分为几种,先调用ZwUnmapViewOfSection来取消可执行程序A的映像映射,”这一步即可。
2019-1-12 01:49
0
雪    币: 182
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
bestbird 0xc0000005的错误===>不要执行“这里情况分为几种,先调用ZwUnmapViewOfSection来取消可执行程序A的映像映射,”这一步即可。
调用了也是解决不了的
2019-1-27 15:35
0
雪    币: 219
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
使用WOW64下的计算器(calc.exe)和记事本(notpad.exe)替换,报0xC0000005错误
2019-4-18 10:08
0
雪    币: 7181
活跃值: (2019)
能力值: ( LV4,RANK:42 )
在线值:
发帖
回帖
粉丝
10
请问 楼主解决这个问题了吗? 我最近也出现了这个问题。
2019-12-23 19:07
0
游客
登录 | 注册 方可回帖
返回
//