标签: windows-kernel

Windows 内核驱动程序:如何确定线程是否终止?

我有一个线程用于某些操作,它需要保持活动状态,直到标志另有说明为止。

我使用PsCreateSystemThread创建线程,然后使用ObReferenceObjectByHandle获取ETHREAD对象引用,以在使用KeWaitForSingleObject卸载驱动程序之前等待线程终止。

创建线程并检索对它的引用的函数:

ntStatus = PsCreateSystemThread(
    &hThread,
    (ACCESS_MASK)0, NULL,
    (HANDLE)0, NULL,
    ThreadRoutine,
    (PVOID)pThreadData
);
if (!NT_SUCCESS(ntStatus))
{
    return ntStatus;
}

ntStatus = ObReferenceObjectByHandle(
    hThread,
    THREAD_ALL_ACCESS,
    NULL,
    KernelMode,
    (PVOID*)&ptThreadObject,
    NULL
);
if (!NT_SUCCESS(ntStatus))
{
    bStopThread = TRUE;
    ptThreadObject = NULL;
    return ntStatus;
}
Run Code Online (Sandbox Code Playgroud)

线程例程:

LARGE_INTEGER liSleepTime;
while (FALSE == bThread)
{
    liSleepTime.QuadPart = 1000 * RELATIVE_MILLISECOND;
    KeDelayExecutionThread(KernelMode, FALSE, (&liSleepTime));

    ExAcquireFastMutex(&fmMutex);
    //DO SOMTHING
    ExReleaseFastMutex(&fmMutex);
}

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

卸载驱动函数:

if (NULL != ptThreadObject)
{
    bStopThread = …
Run Code Online (Sandbox Code Playgroud)

c windows multithreading driver windows-kernel

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

我可以直接访问 Windows 内核系统调用吗?

我一直在研究 Windows 内部,最近刚刚了解了系统调用,我想知道是否可以像函数一样使用这些系统调用?我知道它们并不是真的要从外部访问。

例如:NtUserEmptyClipboard是 Win32k.sys 中的系统调用,其地址为0x117f

如果我想像函数一样使用这个调用,我该怎么做?

c c++ windows system-calls windows-kernel

4
推荐指数
2
解决办法
7497
查看次数

WinDBG的命令类别?

我看到一些关于WinDBG的commnads的参考和教程.他们中的一些人喜欢这个lm,这个.echo,这个!running和这个nt!_PDB.

这些类别之间有什么区别

  • XXX
  • .XXX
  • !XXX
  • XXX!YYY

他们看起来很困惑.

debugging windbg wdk windows-kernel

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

为什么这个mov gs指令导致运行Windows 7操作系统的VMWare Workstation guest虚拟机出现故障?

当我在VMWare Workstation虚拟机中运行的Windows 7 x64的内核模式下运行以下汇编序列时:

xor eax, eax
mov ax, gs
mov gs, ax     ; this instruction
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

最后一条mov gs, ax指令会立即导致该VM崩溃(或可能是错误检查),并显示以下弹出消息:

在此输入图像描述

发生故障导致虚拟CPU进入关闭状态.如果此故障发生在虚拟机之外,则会导致物理计算机重新启动.通过错误配置虚拟机,客户机操作系统中的错误或VMWare Workstation中的问题可以达到关闭状态.

重新加载gs寄存器会导致内核中的问题,还是虚拟化问题?

我没有看到mov英特尔手册中有关该指令的任何异常.

PS.顺便说一句,更换gs寄存器fs不会导致此错误.


编辑:回答有关GDT中段描述符状态的问题.这里是:

0: kd> r gs
gs=002b
0: kd> dg 28
                                                    P Si Gr Pr Lo
Sel        Base              Limit          Type    l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0028 00000000`00000000 00000000`ffffffff Data RW Ac 3 Bg Pg P …
Run Code Online (Sandbox Code Playgroud)

virtualization vmware assembly kernel windows-kernel

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

x86_64汇编:中断标志和TPR寄存器的作用

我熟悉任务优先级寄存器cr8(Windows 上的 IRQL),当然我知道如何使用 和 来启用和禁用cli中断sti。不过,我对两者有几个疑问。

首先,清除中断标志是否会cli“覆盖”TPR 中存储的当前值?例如:TPR 是PASSIVE_LEVEL (0)。如果中断被禁用,TPR 中的值就不再重要了吗?第二:我是从维基百科上读到的:

将 TPR 加载为 0 会启用所有外部中断。用 15 (1111b) 加载 TPR 将禁用所有外部中断。

这是否意味着将 TPR 设置为0xF KzRaiseIrql(HIGH_LEVEL)相当于cli?如果我的 TPR 是0xF并且中断标志被清除,会发生什么情况?如果中断标志使能怎么办?

x86 assembly x86-64 interrupt windows-kernel

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

如何使用 NDIS 筛选器驱动程序发送任意数据包?

我目前正在尝试使用Windows 驱动程序示例中的 NDIS 筛选器驱动程序发送我自己的数据包。

我认为我必须使用该功能发送数据包FilterSendNetBufferLists。但我不知道如何创建这些数据包,也不知道是否应该将它们添加到现有的 NetBufferList 中或创建自己的数据包。

我还需要修改功能吗FilterSendNetBufferListsComplete

windows ndis driver wdk windows-kernel

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

只要线程的任何句柄都打开,线程ID是否保持唯一/有效?

如果我有一个Win32线程,我通过句柄引用它,也可以获取它的线程ID.

我关闭手柄之前,手柄仍然有效且可用,即使线程已经终止.(否则,无法使用例如GetExitCodeThread

然而,似乎文档未能一致地提及线程终止后线程ID的"发生",但只要任何人仍然拥有终止线程的线程句柄.

线程句柄和标识符表明了这一点

标识符从创建线程到线程终止之间有效.

然后,当我们查看GetThreadId API时,如果ID在线程终止之前只有效,我们可能想知道对于终止线程应该返回什么.(并且还有一个用户评论这个网站:"不正确.只要有一个打开的句柄线程,它的线程ID仍然有效且唯一."这确实回答了这个问题,是的,但没有更多上下文我很谨慎.)

另外,我在SO上的答案中找到了这个片段:

ID是系统中运行的线程的唯一数字标识符.与任何内核对象句柄一样,线程句柄可以看作是指向内核对象的特殊类型的引用计数指针.

如果这是正确的并且线程ID确实是内核对象的ID,那么只要任何句柄打开(因为内核对象需要保留在那里进行查询),似乎必须使该ID保持有效.

我的推理是否合理?只要任何句柄打开,线程ID是否有效?是否有任何 MS文档或权威的书,明确规定一个或其他?

windows winapi multithreading visual-c++ windows-kernel

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

从 Windows 10 内核模式驱动程序记录到 txt 文件

我希望从 Windows 10 内核模式驱动程序 (C) 进行一些日志记录。我在驱动程序内部有很多日志记录,但是在这种情况下,我无法附加内核调试器,因此我想将调试字符串转储到 txt 文件(甚至事件日志)。

例如,这是一个例子

#include <stdio.h>
#include <stdlib.h>
VOID Log(char * text) {
    FILE *f = fopen("c:\\temp\\logger.txt", "a+");
    if (f == NULL) return;

    fprintf(f, "%s\n", text);

    fclose(f);
}
Run Code Online (Sandbox Code Playgroud)

不过我得到

driver.obj : error LNK2019: unresolved external symbol fclose referenced in function Log
driver.obj : error LNK2019: unresolved external symbol fopen referenced in function Log
tdriver.obj : error LNK2019: unresolved external symbol fprintf referenced in function Log
Run Code Online (Sandbox Code Playgroud)

我已经包含了 stdio.h,我还需要做些什么才能链接到它吗?

或者是因为这是一个内核驱动程序,我无法使用这些库,并且必须执行不同的低级过程才能写入日志文件?

编辑:看来我无法从内核驱动程序使用 fopen 。

我尝试了这个,但是没有任何内容写入文件。我基于这个例子编写了代码:

https://support.microsoft.com/en-us/help/891805/how-to-open-a-file-from-a-kernel-mode-device-driver-and-how-to-read-fr

我所做的更改是将标志设置为 FILE_OPEN_IF …

c linker logging windows-kernel

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

如何使用 NDIS 过滤器驱动程序读取接收到的数据包?

我目前正在试验NDIS 驱动程序示例。我正在尝试打印数据包内容(包括 MAC 地址、以太网类型和数据)。

我的第一个猜测是在函数中实现它FilterReceiveNetBufferLists。不幸的是,我不确定如何从NetBufferLists.

windows ndis driver wdk windows-kernel

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

设备驱动程序未安装在任何设备上,如果 Visual Studio 2019 打算使用原始驱动程序,请使用原始驱动程序?

我将我的 Visual Studio 从 2017 年升级到 2019 年,似乎他们在最新版本中对 Visual Studio 做了一些奇妙的更改,因为我在 VS 2017 中没有这个问题,甚至编译了你可以在任何地方找到的简单的 hello world 驱动程序更长的编译时间,它们给出以下错误:

Device driver does not install on any devices, use primitive driver if this is intended
Run Code Online (Sandbox Code Playgroud)

看起来它与默认的 INF 文件有关:

https://github.com/MicrosoftDocs/windows-driver-docs/issues/2067

但那里的答案毫无用处,并且对 INF 文件提到的更改都没有帮助,这是我的 INF 文件,它是 VS 2019 上的默认 INF :

;
; HelloWorld.inf
;

[Version]
Signature="$WINDOWS NT$"
Class=System
ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
Provider=%ManufacturerName%
DriverVer=
CatalogFile=HelloWorld.cat
PnpLockDown=1

[DestinationDirs]
DefaultDestDir = 12


[SourceDisksNames]
1 = %DiskName%,,,""

[SourceDisksFiles]


[Manufacturer]
%ManufacturerName%=Standard,NT$ARCH$

[Standard.NT$ARCH$]


[Strings]
ManufacturerName="<Your manufacturer name>" ;TODO: Replace with your manufacturer …
Run Code Online (Sandbox Code Playgroud)

wdk visual-studio inf windows-kernel visual-studio-2019

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

内核空间是否映射到Linux x86上的用户空间?

似乎在Windows 32位上,内核将从完全4G用户虚拟内存空间中保留1G虚拟内存,并将一些内核空间映射到此1G空间.

所以我的问题是:

  1. 在32位Linux上是否有类似的情况?
  2. 如果是这样,我们怎样才能看到整个内存布局?

我认为

cat /proc/pid/map
Run Code Online (Sandbox Code Playgroud)

只能看到某些进程的用户空间布局..

谢谢!

linux memory memory-layout linux-kernel windows-kernel

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

如何为GetModuleFileNameEx禁用WOW64文件系统重定向?

我在64位Windows 10上运行以下32位进程:

#ifndef _DEBUG
    WCHAR buffPath[MAX_PATH] = {0};
    FARPROC pfn = (FARPROC)::GetModuleHandleEx;
    HMODULE hMod = NULL;
    ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 
        GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
        (LPCTSTR)pfn, &hMod);

    PVOID pOldVal = NULL;
    if(::Wow64DisableWow64FsRedirection(&pOldVal))
    {
        ::GetModuleFileNameEx(::GetCurrentProcess(), hMod, buffPath, _countof(buffPath));
        ::Wow64RevertWow64FsRedirection(pOldVal);

        wprintf(L"Path=%s\n", buffPath);
    }
#else
#error run_in_release_mode
#endif
Run Code Online (Sandbox Code Playgroud)

而且我期待收到路径c:\windows\syswow64\KERNEL32.DLL,但它给了我:

Path=C:\Windows\System32\KERNEL32.DLL
Run Code Online (Sandbox Code Playgroud)

知道为什么吗?

c winapi ntfs wow64 windows-kernel

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

如何将应用程序转换为内核模式运行代码?

我有C应用程序,可以确定我的笔记本电脑上何时打开电源.它仅在我打开此.exe文件时才有效

有没有办法让它在内核模式下工作?这意味着我不想运行.exe,只需打开笔记本电脑,并在电量不足时接收有关电源的消息.

这是我的.exe:

#include <windows.h>

const char g_szClassName[] = "myWindowClass";




 // Step 4: the Window Procedure
 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
short x ;

SYSTEM_POWER_STATUS status; 


switch(msg)
{
case WM_CLOSE:
    DestroyWindow(hwnd);
    break;
case WM_DESTROY:
    PostQuitMessage(0);
    break;

case WM_POWERBROADCAST:
                switch (wParam)
                    {
                        case PBT_APMPOWERSTATUSCHANGE :
                            x = GetSystemPowerStatus(&status);
                            if (x > 0) // function succeeded
                                {
                                    if (status.ACLineStatus == 1)
                                    {
                                        printf("power is off");
                                        MessageBox(NULL, "power is on" , "NOTICE" ,MB_OK );
                                    }
                                    else if …
Run Code Online (Sandbox Code Playgroud)

c windows operating-system windows-kernel

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