能力值:
( LV2,RANK:10 )
|
-
-
2 楼
动手写一哈APC inject,你应该会得到答案。
|
能力值:
( LV1,RANK:0 )
|
-
-
3 楼
Apc注入了代码之后,代码会在目标进程的地址空间运行
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
KeTestAlertThread
|
能力值:
( LV3,RANK:20 )
|
-
-
5 楼
已自行解决,不过评论的回答基本上都是错的,我提出来的两种方案本身也是错的,看来搞内核的门槛还是很高的。
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
Mr.hack
已自行解决,不过评论的回答基本上都是错的,我提出来的两种方案本身也是错的,看来搞内核的门槛还是很高的。
您可真是小母牛拉电线,牛逼带闪电啊!
|
能力值:
( LV2,RANK:15 )
|
-
-
7 楼
用户APC,你肯定是在用户层,那么存在进程隔离,所以代码肯定是在目标进程里面,那么官方的操作,应该是挂靠,然后插入队列(应该此时是代码)。最后在特定时机执行!
最后于 2021-1-6 16:26
被丿一叶知秋编辑
,原因:
|
能力值:
( LV3,RANK:20 )
|
-
-
8 楼
事实上根本没有那么复杂,按我说的那样QueueUserApc这个函数会执行成功,但是,这只是表象,实际上这样做被插入APC的线程会直接崩溃,因为插入的APC(代码)根本不在当前进程中。所以QueueUserApc执行成功与否并不代表真的插入成功,真相往往出乎所有人意料并且简单又合理——那就是被插入的APC(一段代码)一定得在被插入线程的所属进程中,否则根本就不能正确插入,即便QueueUserApc看似运行成功了。APC注入这种东西之所以可行是因为在同一操作系统中所有进程中Kernel32这个DLL的装载基地址是相同的,那么这个DLL中的所有导出的API无论在当前操作系统中的哪个进程中都是相同的,这其中就包括LoadLibray这个API
|
能力值:
( LV3,RANK:20 )
|
-
-
9 楼
丿一叶知秋
用户APC,你肯定是在用户层,那么存在进程隔离,所以代码肯定是在目标进程里面,那么官方的操作,应该是挂靠,然后插入队列(应该此时是代码)。最后在特定时机执行!
事实上根本没有那么复杂,按我说的那样QueueUserApc这个函数会执行成功,但是,这只是表象,实际上这样做被插入APC的线程会直接崩溃,因为插入的APC(代码)根本不在当前进程中。所以QueueUserApc执行成功与否并不代表真的插入成功,真相往往出乎所有人意料并且简单又合理——那就是被插入的APC(一段代码)一定得在被插入线程的所属进程中,否则根本就不能正确插入,即便QueueUserApc看似运行成功了。APC注入这种东西之所以可行是因为在同一操作系统中所有进程中Kernel32这个DLL的装载基地址是相同的,那么这个DLL中的所有导出的API无论在当前操作系统中的哪个进程中都是相同的,这其中就包括LoadLibray这个API
|
能力值:
( LV7,RANK:110 )
|
-
-
10 楼
没有挂靠,是往目标进程写shellcode 才能插用户态APC执行shellcode,你的执行函数的地址是你目标进程的空间之中的。不过挂靠进程确实会将线程的APC_STATE的保存,这也是为什么会有两个挂靠进程的导出函数,自己去逆向ntos就明白了。具体用户态APC只是你初始化了APC后插入到了线程APC_STATE中的用户态LIST中,当线程处于警醒状态时会去搜索APC队列,判断是否是执行用户态APC,如果是就直接返回到用户态去执行,执行完了之后用zwcontiune返回内核。用户态APC执行的是你自己进程的用户态的代码。不存在跨进程调用的。然后你说基地址是相同的,嘿嘿 这个你自己去研究吧,相同是相同的,你可以研究一下为什么在开启了ALSR后 这些基地址还是相同的,这里面涉及到的东西也不少。
|
能力值:
( LV4,RANK:52 )
|
-
-
11 楼
插入APC,是内核给进程构造了一个_KTRAP_FRAME假的结构,并保存原始的结构,从而进程从内核中返回的时候,由于假的_KTRAP_FRAME结构,所以直接调用到Ntdll的KiUserApcDispatcher上面,将apc地址直接进行call,最后通过ZwContinue进行返回。所以本质上,插入APC,并不是插入代码,而是插入了一次执行代码的机会,具体非系统dll代码怎么放进去,还得需要自己手动分配空间写进去。
|
能力值:
( LV3,RANK:20 )
|
-
-
12 楼
不对
插入APC,是内核给进程构造了一个_KTRAP_FRAME假的结构,并保存原始的结构,从而进程从内核中返回的时候,由于假的_KTRAP_FRAME结构,所以直接调用到Ntdll的KiUserApcDi ...
“插入APC不是插入代码,而是插入一次执行代码的机会”这句话说的太妙了
|
能力值:
( LV2,RANK:15 )
|
-
-
13 楼
“一次执行机会说的比较好”,APC本身就是从中断的思想演变过来的,但是为了防止你频繁的打断被人,所以别人设置了一个标志(很关键),也就是你打断它的机会!至于用户层APC执行,不管什么执行都是在相同的空间,资源下,共享亦是如此。你的插入只不过是别人去帮你执行一下! 如果你连执行什么都不给,那么肯定不会执行。 挂靠可能我这里记得不清楚了!,不管从设计的思想角度,挂靠应该是为了保存原来的APC。
挂靠的本质是什么? 是切换CR3,就是获取别人的资源。如果你是自己主导执行,那么就是挂靠的第一重含义! 如果是别人执行,那么挂靠是为了保存一些环境。
最后于 2021-1-6 18:37
被丿一叶知秋编辑
,原因:
|
能力值:
( LV5,RANK:60 )
|
-
-
14 楼
这不是 apc运行 机制么?
|
能力值:
( LV1,RANK:0 )
|
-
-
15 楼
实际上你不用管windows怎么实现 你完全可以自己设计一套apc 机制 首先在目标进程分配一个栈 以及 执行shellcode代码的内存 你需要通过vt hook 系统调用入口 或者中断入口 在某一次目标进程 发生系统调用 或者中断的时候 在hook的入口点 保存所有寄存器状态并写入到之前分配的栈的顶部 然后构建iretq的空间 rsp指向你分配的栈的顶部 ,rip 指向shellcode入口 直接iretq返回 等到ring3 shellcode执行完 在通过syscall 进入到 你自己写的一个功能类似于ntContinue的函数 根据栈顶上保存的寄存器状态 , 恢复到原先系统调用入口或者中断入口的状态 这就实现了apc
|
能力值:
( LV3,RANK:20 )
|
-
-
16 楼
gdgdgdg
实际上你不用管windows怎么实现你完全可以自己设计一套apc 机制首先在目标进程分配一个栈 以及 执行shellcode代码的内存你需要通过vt hook 系统调用入口 或者中断入口在某一次目标进 ...
用不用处理irq,apc执行的时候irq为apc_level
|
能力值:
( LV1,RANK:0 )
|
-
-
17 楼
Mr.hack
用不用处理irq,apc执行的时候irq为apc_level
我没有处理irq 按照上面的方法不停的构建apc插入 好像没什么问题 不过不要调用任何ring3的api 你写的dll不要有任何导入表
|
能力值:
( LV1,RANK:0 )
|
-
-
18 楼
我记得 x86 windows实现的用户apc返回3环执行和系统调用一样修改上下文实现的..x64没逆过不清楚
|
能力值:
( LV4,RANK:42 )
|
-
-
19 楼
用户apc本质就是让线程rip/eip 到一个地址执行,至于这个地址能不能执行,那是插入者的事。
|
|
|