标签: kernel-mode

如何在 Windows 内核驱动程序中正确实现线程?

我正在尝试学习如何编写 Windows 内核驱动程序。在我的驱动程序中,我有 2 个线程,它们是在某个时刻创建的PsCreateSystemThread

我有一个名为的全局变量Kill,它指示线程像这样终止。

VOID AThread(IN PVOID Context)
{
    for (;;)
    {
        if(Kill == True)
            break;

        KmWriteProcessMemory(rProcess, &NewValue, dwAAddr, sizeof(NewValue));
    }


    PsTerminateSystemThread(STATUS_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)

在我的卸载功能中我设置Kill = TRUE

VOID f_DriverUnload(PDRIVER_OBJECT pDriverObject)
{
    Kill = TRUE;
    IoDeleteSymbolicLink(&SymLinkName);
    IoDeleteDevice(pDeviceObject);
    DbgPrint("Driver Unloaded successfully..\r\n");
}
Run Code Online (Sandbox Code Playgroud)

大多数时候没有问题,但有时当我尝试卸载驱动程序时机器会崩溃。当我在线程中使用某种睡眠函数时,这种情况会更频繁地发生,所以我假设它正在崩溃,因为在驱动程序尝试卸载之前线程尚未终止。

我不太确定如何使用同步等,并且我能找到的明确信息并不多。那么我如何正确实现线程并确保它们在驱动程序卸载之前终止?

c windows multithreading kernel-mode

4
推荐指数
1
解决办法
4072
查看次数

为什么call_usermodehelper在大多数情况下会失败?

从内核模块,我试图使用call_usermodehelper函数来执行可执行文件sha1,该文件将文件作为参数并将文件的SHA1哈希值写入另一个文件(命名为output)。可执行文件完美运行。

int result=-1;
name = "/home/file"
char *hargv[] = {"/home/sha1", name,NULL };
char *henvp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
result = call_usermodehelper("/home/sha1", hargv, henvp, 1);
Run Code Online (Sandbox Code Playgroud)

但是大多数情况下,call_usermodehelper返回-14并无法执行可执行文件。可能是什么原因?

有时它可以工作,但是随后创建的输出文件被锁定(与直接运行sha1时不同),我必须先运行chown才能正确使用它。如何预防?

无论如何,没有call_usermodehelper可以执行此操作吗?

linux kernel-module linux-kernel user-mode-linux kernel-mode

2
推荐指数
1
解决办法
857
查看次数

用户程序的内核模式

我知道内核模式是一种特权,因此在内核模式下,所有硬件功能和指令集中的所有指令都可用。我也知道,当我们进行过程调用(比如 read())时,它又会进行系统调用。但在此之前它会陷入内核模式。我想知道如果每个用户程序都可以在内核模式下运行,因为所有过程调用和系统调用都可供用户程序使用,那么内核模式有什么用处。

kernel processor instruction-set cpu-architecture kernel-mode

2
推荐指数
1
解决办法
669
查看次数

如何将char*(char指针)转换为PCSZ?

我有一个方法,有一个强制参数char*,我想转换为PCSZ之前RtlInitiAnsiString(),uName后面的结果RtlAnsiStringToUnicodeString()是正确的值.

我怎样才能做到这一点?

NTSTATUS myMethod(char *myName)
{        
    ANSI_STRING aName;
    UNICODE_STRING uName;
    OBJECT_ATTRIBUTES ObjAttr;

    RtlInitAnsiString(&aName, myName);
    status = RtlAnsiStringToUnicodeString(&uName, &aName, TRUE);
    if(!NT_SUCCESS(status))
    {
       DbgPrint("RtlAnsiStringToUnicodeString Error");
       return status;
    }

    InitializeObjectAttributes(&ObjAttr, &uName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); 
    // some code here
    //...
    RtlFreeUnicodeString(&uName);
    return status;    
}
Run Code Online (Sandbox Code Playgroud)

版01:

为了更好地理解这里是如何MyMethod()在我的内核驱动程序中使用:

struct MyData
{
    ULONG Value[3];
    char *Str1;
    char *Str2;
};

NTSTATUS Function_IRP_DEVICE_CONTROL(PDEVICE_OBJECT pDeviceObject, PIRP Irp)
{
    PIO_STACK_LOCATION pIoStackLocation;
    struct MyData *pData = (struct MyData*) …
Run Code Online (Sandbox Code Playgroud)

c c++ driver visual-studio kernel-mode

1
推荐指数
1
解决办法
261
查看次数

在Rings之间跳转时的处理器行为

当某些内核代码(Ring 0)对用户代码(Ring 3)例程进行"调用"时,我找不到任何关于标准CPU(即:x86)的真正含义的具体信息.

1)执行该例程时,CPU模式状态是否变为用户模式?

2)在用户级例程执行最后的'ret'指令后,由于尝试返回内核空间代码而引发异常?

x86 cpu-architecture osdev kernel-mode

1
推荐指数
1
解决办法
69
查看次数

系统调用是应用程序/用户程序请求操作系统服务来执行特权操作的唯一方式吗?

尽管我知道这个主题的范围要广泛得多,但我处于 Linux 环境中

假设我正在编写一个简单的 C 程序,并且想向终端写入“Hello”。显而易见的方法是使用 C 标准库 printf,它又使用 write 系统调用(包装函数而不是系统调用本身),而 write 系统调用又调用实际的汇编系统调用指令(或 int)。不太明显的方法是在我的 C 源文件中使用一些内联汇编,或者直接创建一个包含系统调用指令的汇编文件。

我的问题

  1. 似乎在一天结束时,我们以某种方式结束了系统调用(指令 syscall 或 int)。这是唯一的方法吗?

  2. 在现代 PC 中,术语“应用程序”与“用户程序”的含义相同吗?

  3. 我编写的 PowerPoint、Google Chrome、Visual Studio Code、Photoshop 或 C 程序都是需要系统调用来请求操作系统服务以执行写入文件等特权操作的应用程序/用户程序的示例,这样说是否正确?

linux assembly system-calls usermode kernel-mode

1
推荐指数
1
解决办法
248
查看次数