首页
社区
课程
招聘
驱动向应用层(R0-R3) 创建线程的一种实现
发表于: 2024-5-30 11:31 5257

驱动向应用层(R0-R3) 创建线程的一种实现

2024-5-30 11:31
5257

在网上找了很长时间也没找到驱动向应用层创建线程的方法,于是自己研究了一份,现在把研究的结果共享给大家。

1.获取NtCreateThreadEx接口的地址
NtCreateThreadEx是未导出函数,需要我们手动获取地址。对于各位大手子来说在驱动里获取一个未导出接口的地址肯定不是难事,这里不多赘述。

2.构造NtCreateThreadEx的参数


NtCreateThreadEx函数的定义

NTSTATUS NtCreateThreadEx(
    OUT PHANDLE ThreadHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN HANDLE ProcessHandle,
    IN PVOID StartRoutine,
    IN PVOID Argument,
    IN ULONG CreateFlags,
    IN SIZE_T ZeroBits,
    IN SIZE_T StackSize,
    IN SIZE_T MaximumStackSize,
    OUT PPS_ATTRIBUTE_LIST AttributeList);

构造ObjectAttributes参数

OBJECT_ATTRIBUTES objAttr;
CLIENT_ID clientId;
InitializeObjectAttributes(&objAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);


构造 shellcode,也就是线程的启动地址。这里我用的是FreeLibrary 函数作为启动地址,当然具体的函数参数(RCX)和函数地址都是动态的,需要执行的时候进行赋值。

UCHAR opcodes[] = {
    0x48, 0x83, 0xEC, 0x28, // sub rsp, 0x28
    0x48, 0x31, 0xC9, // xor rcx, rcx
    0x48, 0x31, 0xc0,// xor rax, rax
    0x48, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,//mov rcx, ModuleBase
    0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,//mov rax, func_FreeLibrary
    0xff, 0xd0,//call   rax
    0x48, 0x83, 0xC4, 0x28, // add rsp, 0x28
    0xc3,//ret};



3.在应用程序中分配内存并创建线程这里采用附加读写的方式进行内存分配


KAPC_STATE ApcState = { 0 };

KeStackAttachProcess(TargetProcess, &ApcState);

//设置当前线程运行在用户模式

_KTHREAD->PreviousMode = UserMode

//给shellcode分配内存

PVOID codeBuffer = 0;

    ZwAllocateVirtualMemory(ZwCurrentProcess(), &codeBuffer, 0, &Size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    RtlZeroMemory(codeBuffer, Size);

    memcpy(codeBuffer, opcodes, sizeof(opcodes));

//设置当前线程运行在内核模式并创建线程

_KTHREAD->PreviousMode = KernelMode

 NTSTATUS status;

 HANDLE hThread;

 status = NtCreateThreadEx(&hThread,

        THREAD_ALL_ACCESS,

        &objAttr,

        NtCurrentProcess(),

        (PVOID)codeBuffer,

        (PVOID)NULL,

        0,

        0,

        0x1000,

        0x1000,

        NULL);

//重新设置为用户模式,并等待线程执行完毕

_KTHREAD->PreviousMode = UserMode

    if (NT_SUCCESS(status)) {

        // 延迟 60s

        LARGE_INTEGER Timeout = { 0 };

        Timeout.QuadPart = -(60ll * 10 * 1000 * 1000);

        status = ZwWaitForSingleObject(hThread, TRUE, &Timeout);

        NtClose(hThread);

    }

//释放分配的内存

status = ZwFreeVirtualMemory(NtCurrentProcess(), &codeBuffer, &Size, MEM_RELEASE);

 

//恢复原来的运行模式

_KTHREAD->PreviousMode = oldMode;

KeUnstackDetachProcess(&ApcState);


以上就是内核向用户层创建线程的全部思路,如果有问题可以在评论区留言。


收藏
免费 1
支持
分享
最新回复 (10)
雪    币: 778
活跃值: (9741)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
2

谢谢楼主分享,可以参考下 blackbone 的实现.里面有现成的,可以学习下.

最后于 2024-9-2 10:59 被TkBinary编辑 ,原因: 加入学习资料说明
2024-5-30 13:36
0
雪    币: 22
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
我今天早上实现了MessageBoxA创建对话框,忘了发一篇帖子了
2024-5-30 17:22
0
雪    币: 213
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
啥意思,是直接用NtCreateThreadEx 创建线程执行FreeLibrary 吗。都上驱动了应该不至于费这劲了吧。
2024-5-31 14:02
0
雪    币: 778
活跃值: (9741)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
5
虎皮狗 我今天早上实现了MessageBoxA创建对话框,忘了发一篇帖子了
厉害呀,那应该发. 可以把MessageBox底层执行流程发出来.  让我观摩观摩
2024-5-31 16:36
0
雪    币: 1
活跃值: (624)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
TkBinary 首先谢谢楼主分享资料.其次.PsCreateSystemThread . 是可以创建用户层线程的吧.  提出质疑确定找过资料?  ...
PsCreateSystemThread 这个API我确实没找到,因为急着用所以就选择了NtCreateThreadEx函数。应该都能实现创建远程线程的目的
2024-6-3 16:18
0
雪    币: 778
活跃值: (9741)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
7
wx_pretty^ PsCreateSystemThread 这个API我确实没找到,因为急着用所以就选择了NtCreateThreadEx函数。应该都能实现创建远程线程的目的
创建远程线程是用NtCreate Ps是创建用户线程.
2024-6-4 14:12
0
雪    币: 334
活跃值: (2563)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
PsCreateSystemThread能创建用户态线程?msdn明确说了不行的哦。
2024-6-4 16:52
0
雪    币: 2325
活跃值: (2304)
能力值: ( LV6,RANK:89 )
在线值:
发帖
回帖
粉丝
9
PsCreateSystemThread创建r3线程 ?逆天
2024-6-13 23:36
0
雪    币: 19
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
TkBinary 首先谢谢楼主分享资料.其次.PsCreateSystemThread . 是可以创建用户层线程的吧.  提出质疑确定找过资料?  ...
进厂
2024-8-24 23:21
0
雪    币: 778
活跃值: (9741)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
11
美少女昕昕 进厂
此话怎讲
2024-9-2 10:57
0
游客
登录 | 注册 方可回帖
返回
//