首页
社区
课程
招聘
[求助]关于用户apc的执行
发表于: 2021-1-5 13:28 6394

[求助]关于用户apc的执行

2021-1-5 13:28
6394

假设有两个进程分别为A和B,A进程现在向B进程的某个线程插入一个用户级的APC,我们知道插入APC的本质就是让被插入的线程执行一段代码,所以B进程中被插入的那个线程要执行的代码在A进程中,那么如果要执行这段代码有以下两种方案:

一.把这段要执行的代码复制到B进程中;

二.B进程挂靠到A进程;


请问windows用的是以上方案中的哪一种?


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

收藏
免费 0
支持
分享
最新回复 (18)
雪    币: 1062
活跃值: (901)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
动手写一哈APC inject,你应该会得到答案。
2021-1-5 14:18
0
雪    币: 48
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
Apc注入了代码之后,代码会在目标进程的地址空间运行
2021-1-6 06:15
0
雪    币: 12
活跃值: (438)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
KeTestAlertThread
2021-1-6 09:54
0
雪    币: 3625
活跃值: (4559)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
已自行解决,不过评论的回答基本上都是错的,我提出来的两种方案本身也是错的,看来搞内核的门槛还是很高的。
2021-1-6 15:16
0
雪    币: 1062
活跃值: (901)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Mr.hack 已自行解决,不过评论的回答基本上都是错的,我提出来的两种方案本身也是错的,看来搞内核的门槛还是很高的。
您可真是小母牛拉电线,牛逼带闪电啊!
2021-1-6 16:06
0
雪    币: 919
活跃值: (1340)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
7

用户APC,你肯定是在用户层,那么存在进程隔离,所以代码肯定是在目标进程里面,那么官方的操作,应该是挂靠,然后插入队列(应该此时是代码)。最后在特定时机执行!

最后于 2021-1-6 16:26 被丿一叶知秋编辑 ,原因:
2021-1-6 16:20
1
雪    币: 3625
活跃值: (4559)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
事实上根本没有那么复杂,按我说的那样QueueUserApc这个函数会执行成功,但是,这只是表象,实际上这样做被插入APC的线程会直接崩溃,因为插入的APC(代码)根本不在当前进程中。所以QueueUserApc执行成功与否并不代表真的插入成功,真相往往出乎所有人意料并且简单又合理——那就是被插入的APC(一段代码)一定得在被插入线程的所属进程中,否则根本就不能正确插入,即便QueueUserApc看似运行成功了。APC注入这种东西之所以可行是因为在同一操作系统中所有进程中Kernel32这个DLL的装载基地址是相同的,那么这个DLL中的所有导出的API无论在当前操作系统中的哪个进程中都是相同的,这其中就包括LoadLibray这个API
2021-1-6 17:15
0
雪    币: 3625
活跃值: (4559)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
丿一叶知秋 用户APC,你肯定是在用户层,那么存在进程隔离,所以代码肯定是在目标进程里面,那么官方的操作,应该是挂靠,然后插入队列(应该此时是代码)。最后在特定时机执行!
事实上根本没有那么复杂,按我说的那样QueueUserApc这个函数会执行成功,但是,这只是表象,实际上这样做被插入APC的线程会直接崩溃,因为插入的APC(代码)根本不在当前进程中。所以QueueUserApc执行成功与否并不代表真的插入成功,真相往往出乎所有人意料并且简单又合理——那就是被插入的APC(一段代码)一定得在被插入线程的所属进程中,否则根本就不能正确插入,即便QueueUserApc看似运行成功了。APC注入这种东西之所以可行是因为在同一操作系统中所有进程中Kernel32这个DLL的装载基地址是相同的,那么这个DLL中的所有导出的API无论在当前操作系统中的哪个进程中都是相同的,这其中就包括LoadLibray这个API
2021-1-6 17:21
0
雪    币: 63
活跃值: (3175)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
10
没有挂靠,是往目标进程写shellcode 才能插用户态APC执行shellcode,你的执行函数的地址是你目标进程的空间之中的。不过挂靠进程确实会将线程的APC_STATE的保存,这也是为什么会有两个挂靠进程的导出函数,自己去逆向ntos就明白了。具体用户态APC只是你初始化了APC后插入到了线程APC_STATE中的用户态LIST中,当线程处于警醒状态时会去搜索APC队列,判断是否是执行用户态APC,如果是就直接返回到用户态去执行,执行完了之后用zwcontiune返回内核。用户态APC执行的是你自己进程的用户态的代码。不存在跨进程调用的。然后你说基地址是相同的,嘿嘿 这个你自己去研究吧,相同是相同的,你可以研究一下为什么在开启了ALSR后 这些基地址还是相同的,这里面涉及到的东西也不少。
2021-1-6 17:41
1
雪    币: 7319
活跃值: (3421)
能力值: ( LV4,RANK:52 )
在线值:
发帖
回帖
粉丝
11
插入APC,是内核给进程构造了一个_KTRAP_FRAME假的结构,并保存原始的结构,从而进程从内核中返回的时候,由于假的_KTRAP_FRAME结构,所以直接调用到Ntdll的KiUserApcDispatcher上面,将apc地址直接进行call,最后通过ZwContinue进行返回。所以本质上,插入APC,并不是插入代码,而是插入了一次执行代码的机会,具体非系统dll代码怎么放进去,还得需要自己手动分配空间写进去。
2021-1-6 17:41
1
雪    币: 3625
活跃值: (4559)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
不对 插入APC,是内核给进程构造了一个_KTRAP_FRAME假的结构,并保存原始的结构,从而进程从内核中返回的时候,由于假的_KTRAP_FRAME结构,所以直接调用到Ntdll的KiUserApcDi ...
“插入APC不是插入代码,而是插入一次执行代码的机会”这句话说的太妙了
2021-1-6 17:56
0
雪    币: 919
活跃值: (1340)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
13

“一次执行机会说的比较好”,APC本身就是从中断的思想演变过来的,但是为了防止你频繁的打断被人,所以别人设置了一个标志(很关键),也就是你打断它的机会!至于用户层APC执行,不管什么执行都是在相同的空间,资源下,共享亦是如此。你的插入只不过是别人去帮你执行一下! 如果你连执行什么都不给,那么肯定不会执行。  挂靠可能我这里记得不清楚了!,不管从设计的思想角度,挂靠应该是为了保存原来的APC。


挂靠的本质是什么? 是切换CR3,就是获取别人的资源。如果你是自己主导执行,那么就是挂靠的第一重含义! 如果是别人执行,那么挂靠是为了保存一些环境。

最后于 2021-1-6 18:37 被丿一叶知秋编辑 ,原因:
2021-1-6 18:33
0
雪    币: 1553
活跃值: (2919)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
14
这不是 apc运行 机制么?
2021-1-8 14:32
0
雪    币: 362
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15

实际上你不用管windows怎么实现

你完全可以自己设计一套apc 机制

首先在目标进程分配一个栈 以及 执行shellcode代码的内存

你需要通过vt hook 系统调用入口 或者中断入口

在某一次目标进程 发生系统调用 或者中断的时候

在hook的入口点 保存所有寄存器状态并写入到之前分配的栈的顶部

然后构建iretq的空间 rsp指向你分配的栈的顶部 ,rip 指向shellcode入口

直接iretq返回 等到ring3 shellcode执行完 在通过syscall 进入到

你自己写的一个功能类似于ntContinue的函数

根据栈顶上保存的寄存器状态 ,

恢复到原先系统调用入口或者中断入口的状态

这就实现了apc

2021-2-10 03:31
1
雪    币: 3625
活跃值: (4559)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
gdgdgdg 实际上你不用管windows怎么实现你完全可以自己设计一套apc 机制首先在目标进程分配一个栈 以及 执行shellcode代码的内存你需要通过vt hook 系统调用入口 或者中断入口在某一次目标进 ...
用不用处理irq,apc执行的时候irq为apc_level
2021-2-10 10:58
0
雪    币: 362
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
Mr.hack 用不用处理irq,apc执行的时候irq为apc_level
我没有处理irq  按照上面的方法不停的构建apc插入 好像没什么问题 
不过不要调用任何ring3的api  你写的dll不要有任何导入表
2021-2-10 12:34
0
雪    币: 329
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
我记得 x86 windows实现的用户apc返回3环执行和系统调用一样修改上下文实现的..x64没逆过不清楚
2021-2-26 10:09
0
雪    币: 5766
活跃值: (2437)
能力值: ( LV4,RANK:42 )
在线值:
发帖
回帖
粉丝
19
用户apc本质就是让线程rip/eip 到一个地址执行,至于这个地址能不能执行,那是插入者的事。
2021-2-26 11:50
0
游客
登录 | 注册 方可回帖
返回