从内核调试模式调试 dll 和 sys

Debugging dll and sys from Kernel debugging Mode

我需要中断已经加载的 dll 函数。我怎样才能做到这一点?我尝试了以下内容。 dll 名称:test.dll 函数名称:allocate()

bp test!allocate
bp allocate

我正在使用 windbg,尝试调试内核驱动程序。在进行内核调试时,我还需要打入一些用户 space dll 函数,我有这些函数的代码。我该怎么做?

在设备驱动程序代码 (.sys) 中设置断点很容易,因为加载的驱动程序总是映射到系统内存 space。进程用户 space 中的断点是另一回事,因为用户 space 中的特定内存范围可能被调出,或者它可能被映射到多个进程的用户 space (例如共享系统dll)。

仍然可以在用户 space 中设置断点。您必须使用 .process 命令的 invasive 调试 ( /i ) 选项,如 MSDN page 中所述。完成后,命令 bp /p 将开始工作,允许您在进程用户 space:

中设置断点
.process /i My_EPROCESS_block_address
g  $ <-- this command will break in few seconds
bp /p My_EPROCESS_block_address MyDll!MyFunction

虽然可能,但从内核调试器调试用户进程非常不方便,因为所有用户模式调试器扩展和许多用户模式命令在内核调试器中都不起作用。在用户模式调试器下启动要调试的进程会更快更容易。内核调试器和用户模式调试器之间的协调如下:

  • 启动调试器时使用命令行 ntsd -d。选项 -d 使 ntsd 通过内核调试器通过管道传输 input/output,因此您将看到用户模式调试器提示(例如内核调试器中的 0:000> 并且可以执行用户模式调试器命令)。
  • 要从用户模式调试器中断到内核模式调试器,请键入 .breakin
  • 要返回到用户模式调试器,请在内核模式提示符下键入 g

这工作起来更容易,所有调试器扩展都按预期工作。

如果您在代码中散布 __debugbreak() 代码将使您的代码在正确的位置插入 kd

主机 OS xpsp3 运行 32bit processor
客人 OS xp64 运行 里面 QEMU
主机
上的调试器 32bit windbg 编译为 x64 withvs2k10express and 7.1 psdk toolset

预编译目录内容

:dir /b
compile.bat
dbgbrk.cpp

来源

:type dbgbrk.cpp
#include <stdio.h>
#include <intrin.h>
#include <windows.h>
#define DBGBRK //comment this out to remove dbgspew
#ifdef DBGBRK
//using .ocommand mycommand in usermode windbg stacktrace will be printed out on break
#define DBRK  OutputDebugString("mycommand kb;"); __debugbreak();
#else
#define DBRK
#endif

int main (void)
{
    printf("hello we are debugging\n");
    DBRK
    printf("we broke in kd above\n");
    DBRK
    return 0;
}

bat 文件内容

:type compile.bat
IF %1 == "" goto usage
IFEXIST %1.cpp goto comlincpystr

:comlincpystr
@call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\setenv.cmd" /x64 /RELEAS
E

cl /c /Zi /nologo /W4 %1.cpp
link /DEBUG /MACHINE:X64 /nologo /RELEASE %1.obj

symstore add /f %1.exe /s f:\symbols /t "xp64" /v "vc2ktenexp_and_psdksevenpoint
one_toolset"
symstore add /f %1.pdb /s f:\symbols /t "xp64" /v "vc2ktenexp_and_psdksevenpoint
one_toolset"

copy %1.exe \xp64\shared\. /y

goto exit

:usage

echo usage compile.bat <source.cpp>

:exit

post编译

:start compile.bat dbgbrk

:dir /b *.exe
dbgbrk.exe

:file dbgbrk.exe
dbgbrk.exe; PE32+ executable for MS Windows (console) Mono/.Net assembly

:

执行可执行文件立即中断 kd

kd> .lastevent
Last event: Break instruction exception - code 80000003 (first chance)
  debugger time: Wed Jan 14 17:36:00.937 2015 
kd> lsa .
    10: 
    11: int main (void)
    12: {
    13:     printf("hello we are debugging\n");
>   14:     DBRK
    15:     printf("we broke in kd above\n");
    16:     DBRK
    17:     return 0;
    18: }

kd> uf @rip
dbgbrk!main+0x1d [dbgbrk.cpp @ 14]:
   14 00000001`4000101d cc              int     3
   15 00000001`4000101e 488d0df3120100  lea     rcx,[dbgbrk!__xt_z+0x50 (00000001`40012318)]
   15 00000001`40001025 e816000000      call    dbgbrk!printf (00000001`40001040)
   16 00000001`4000102a 488d0dff120100  lea     rcx,[dbgbrk!__xt_z+0x68 (00000001`40012330)]
   16 00000001`40001031 ff15c90f0100    call    qword ptr [dbgbrk!_imp_OutputDebugStringA (00000001`40012000)]
   16 00000001`40001037 cc              int     3
   17 00000001`40001038 33c0            xor     eax,eax
   18 00000001`4000103a 4883c428        add     rsp,28h
   18 00000001`4000103e c3              ret
kd> !dbgprint

mycommand kb;mycommand kb;