首页
社区
课程
招聘
[求助]C语言 傀儡进程替换报错0Xc0000005 求大神帮忙看看
发表于: 2020-1-22 16:37 8986

[求助]C语言 傀儡进程替换报错0Xc0000005 求大神帮忙看看

2020-1-22 16:37
8986

创建了一个CREATE_SUSPENDED的傀儡进程,用幕后进程替换了傀儡进程之后报错0xc0000005,弄了好几天也没弄懂,我裂开了,哪位大侠路过帮帮忙

WIN7 x64系统,vs2017 x86编译器,两个进程都是32位进程。

typedef NTSYSAPI NTSTATUS(__stdcall *ZwUnmapViewOfSection)(HANDLE, PVOID);
int main()
{
//加载ZwUnmapViewOfSection函数
HMODULE hModule = GetModuleHandle(L"ntdll.dll");
if (hModule == NULL)
    return FALSE;
    ZwUnmapViewOfSection UnmapViewOfSection =  (ZwUnmapViewOfSection)GetProcAddress(hModule, "ZwUnmapViewOfSection");

//将幕后进程读取到缓存
FILE* pFile = NULL;

_wfopen_s(&pFile, filePath1, L"rb");
if (pFile == NULL) 
{
    MessageBox(0, L"fopen_s fail", 0, MB_OK);
    return (INT_PTR)TRUE;
}

fseek(pFile, 0, SEEK_END);                            
DWORD szFile = ftell(pFile);                        
fseek(pFile, 0, SEEK_SET);                            

BYTE* pFileBuffer = (BYTE*)malloc(szFile);        
fread(pFileBuffer, szFile, 1, pFile);    
fclose(pFile);

//幕后进程的头信息
PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)pFileBuffer;
PIMAGE_FILE_HEADER pFileH = (PIMAGE_FILE_HEADER)((BYTE*)pDosH + pDosH->e_lfanew + 4);
PIMAGE_OPTIONAL_HEADER pOptH = (PIMAGE_OPTIONAL_HEADER)((BYTE*)pFileH + IMAGE_SIZEOF_FILE_HEADER);
PIMAGE_SECTION_HEADER pSectionH = (PIMAGE_SECTION_HEADER)((BYTE*)pOptH + pFileH->SizeOfOptionalHeader);

PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 };
si.cb = sizeof(STARTUPINFO);
BOOL created = CreateProcess(filePath3, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
int err;
if (!created) {
    err = GetLastError();
    return 0;
}

CONTEXT context = { 0 };
context.ContextFlags = CONTEXT_FULL;
GetThreadContext(pi.hThread, &context);

//从线程上下获取取基址
SIZE_T read;
DWORD oldBase;
bool hasRead = ReadProcessMemory(pi.hProcess, (PDWORD)(context.Ebx + 0X8), &oldBase, sizeof(DWORD), &read);
if (!hasRead) {
    return 0;
}

//卸载傀儡进程镜像
NTSTATUS flag = UnmapViewOfSection(pi.hProcess, (BYTE*)oldBase);
if (flag < 0) {
    return 0;
}

//申请虚拟空间的内存
LPVOID addrExe = VirtualAllocEx(pi.hProcess, (LPVOID)pOptH->ImageBase,
    pOptH->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

if (addrExe == NULL) {
    return 0;
}

//替换傀儡进程
SIZE_T written;
bool isOk = FALSE;
//头部分
isOk = WriteProcessMemory(pi.hProcess, (LPVOID)addrExe, pFileBuffer, pOptH->SizeOfHeaders, &written);
//节部分
for (int i = 0; i < pFileH->NumberOfSections; i++) {
    isOk = WriteProcessMemory(pi.hProcess,
                                (LPVOID)((BYTE*)addrExe + pSectionH[i].VirtualAddress), 
                                pFileBuffer + pSectionH[i].PointerToRawData, 
                                pSectionH[i].SizeOfRawData, 
                                &written);
}

//修改线程上下文
DWORD imageBase = (DWORD)addrExe;
context.Eax = imageBase + pOptH->AddressOfEntryPoint;
WriteProcessMemory(pi.hProcess, (PDWORD)(context.Ebx + 0X8), &imageBase, sizeof(DWORD), &written);
SetThreadContext(pi.hProcess, &context);

ResumeThread(pi.hThread);
return 0;
}

1.调用Nt/ZwUnmapViewOfSection()卸载镜像会报错

2.不卸载镜像,在空闲内存插入别的进程然后修改重定位表显示停止工作


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-1-23 13:58 被吸语言编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (28)
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
2
UnmapViewOfSection去掉,然后加上SetThreadContext试试
2020-1-22 22:50
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
刘铠文 UnmapViewOfSection去掉,然后加上SetThreadContext试试
感谢帮助!SetThreadContext函数在代码上有后来向网页上贴代码的时候漏掉了,不是这个问题。去掉UnmapViewOfSection函数不卸载原先的镜像,申请内存的时候返回值是0,不能申请内存写入,最后任务管理器里只有原先挂起的傀儡进程。
2020-1-23 10:20
0
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
4
吸语言 感谢帮助!SetThreadContext函数在代码上有后来向网页上贴代码的时候漏掉了,不是这个问题。去掉UnmapViewOfSection函数不卸载原先的镜像,申请内存的时候返回值是0,不能申请内 ...
原镜像貌似不能随意卸载,会炸,至少我炸了,不卸载就不会炸
2020-1-23 10:47
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
刘铠文 原镜像貌似不能随意卸载,会炸,至少我炸了,不卸载就不会炸
我不卸载原镜像,申请的空闲内存,然后修复了重定位还是一样炸,我裂开了
2020-1-23 10:49
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
刘铠文 原镜像貌似不能随意卸载,会炸,至少我炸了,不卸载就不会炸
老哥,你这个是启动成功后的进程吗?
2020-1-23 18:17
0
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
7
吸语言 老哥,你这个是启动成功后的进程吗?
是的
2020-1-23 18:27
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
刘铠文 是的
UnmapViewOfSection函数去掉后直接就能用了啊?不是申请的随机地址,也没修复重定位表吗?
2020-1-23 18:45
0
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
9
吸语言 UnmapViewOfSection函数去掉后直接就能用了啊?不是申请的随机地址,也没修复重定位表吗?
肯定得修复
2020-1-24 07:17
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
刘铠文 肯定得修复
我修复了重定位表,一运行就崩了,我还特意试了一下修复重定位表的代码,也没问题,context修改的应该也是正确的。可现在程序已启动就弹出窗口崩溃
2020-1-24 09:00
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
吸语言 我修复了重定位表,一运行就崩了,我还特意试了一下修复重定位表的代码,也没问题,context修改的应该也是正确的。可现在程序已启动就弹出窗口崩溃
context我只修改了OEP和ImageBase,EIP不用改吧?
2020-1-24 09:01
0
雪    币: 405
活跃值: (1071)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
12
1、傀儡进程的SizeOfImage>=自己程序的SizeOfImage
2、tls填充
3、检查自己程序的编译选项
2020-1-24 12:19
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
东京好嗨冷 1、傀儡进程的SizeOfImage>=自己程序的SizeOfImage 2、tls填充 3、检查自己程序的编译选项
感谢!
我之前试过将同一个程序的ImageBase和重定位表修改了,然后替换该程序没修改的傀儡进程还是不行。


2020-1-24 12:56
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
吸语言 感谢! 我之前试过将同一个程序的ImageBase和重定位表修改了,然后替换该程序没修改的傀儡进程还是不行。
tls填充和检查自己程序的编译选项是什么意思我不太懂,求指点
2020-1-24 12:57
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
吸语言 感谢! 我之前试过将同一个程序的ImageBase和重定位表修改了,然后替换该程序没修改的傀儡进程还是不行。
我合计可能是context设置的问题,网上说修改OEP和ImageBase就行了,但是我觉得是不是还得改别的
2020-1-24 13:00
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16
东京好嗨冷 1、傀儡进程的SizeOfImage>=自己程序的SizeOfImage 2、tls填充 3、检查自己程序的编译选项
我是只猪,原来用傀儡进程序本身修改一下ImageBase和重定位表替换一下这个傀儡程序,无论是随机地址还是原镜像地址都是能用的,只要不调用Zw/NtUnmapViewOfSection函数就不会崩溃。但是用别的程序来替换傀儡进程是肯定会崩的,开来不是代码的问题,应该是我电脑或者编译器有问题,气死了
2020-1-25 09:58
0
雪    币: 7133
活跃值: (3902)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
https://bbs.pediy.com/thread-153508.htm
2020-1-26 14:20
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
sinkay https://bbs.pediy.com/thread-153508.htm
谢谢,我看了一下那个帖子,方法基本都是一样,但是我代码已启动就崩,我看到底下有人评论说win7 x64用这种方法跑不起来,不知道是不是这种原因
2020-1-29 05:26
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
win10 64位下必须去掉UnmapViewOfSection 才能运行,我也不知道为什么。
2020-3-5 23:08
0
雪    币: 127
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
楼主解决了嘛?
2020-4-19 13:10
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
夏鱼儿 楼主解决了嘛?
后来我自己搞了一下,代码没什么毛病(我电脑上的,看雪贴出来的没太注意因为太多就删了一些注释验证的步骤).自己写的hello world是可以替换的,但是网上下的应用不行,我估计可能是网上的程序有保护或者与其他dll文件的基址冲突,虽然helloworld不用重定(因为没有重定位表),但是我感觉跟重定位表没关系.
2020-6-10 21:40
0
雪    币: 123
活跃值: (316)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
https://bbs.pediy.com/thread-153508.htm
这个ok
2020-6-24 16:51
0
雪    币: 169
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
taizhong https://bbs.pediy.com/thread-153508.htm 这个ok
谢谢,这个我看过了,评论有人说win7x64替换傀儡进程不好使.
2020-6-29 11:48
0
雪    币: 0
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
有可能是傀儡进程的随机基址问题,我最近在做一个简单加壳程序练习也碰到类似的问题,我把一个程序追加到一个壳子程序最后一个节里,模拟验证后通过创建傀儡进程解密运行最后一个节点里的程序,也是一运行就跳C005错误,后来发现加壳后的程序每次运行的基址都不一样,然后把壳程序编译的时候随机基址去掉后编译的壳程序在追加其他程序到节里,都能够通过傀儡程序运行成功。也不知道你的问题是不是和我的一样,希望对你有所帮助。我的环境也是win10 64位的。
2020-7-24 17:45
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
太感谢了, 今天搞了整整一天, 被整疯了, 竟然是这个错误, 太恶心...
2020-12-24 23:24
0
游客
登录 | 注册 方可回帖
返回
//