我如何从 dll 跟踪系统调用 -> 内核驱动程序系统调用

逆向工程 视窗 部件 C 核心 系统调用
2021-06-23 19:54:36

基本上我想跟随(系统调用/内部调用)基本上落在内核中我想例如调试特定的dll,例如:ntdll.dll并跟随它到(NtXXX)函数,它位于XXX.sys驱动程序中我希望我的问题也很清楚,如果使用windbg 来做这件事对我来说会好得多,而不是使用第三部分软件。

我也尝试使用 Rohitab api 监视器,但我无法理解它实际上是如何工作的

1个回答

假设您编写了此代码
这将在当前目录中打开一个文件
读取其内容并计算内容长度并
打印到控制台内容并计数

这是一个 crt 函数,它在用户模式下
crt 转换kernel32.dll 、 kernelbase.dll 和 ntdll.dll
从NTDLL它过渡到通过内核模式系统调用NtCreateFile在NTOSKRNL / NTKRNLMP.EXE

#include <stdio.h>
int main (void) 
{
    int c=0,n=0;
    FILE *fp = NULL;
    errno_t err = fopen_s(&fp,"test.txt","rb");
    if(fp != NULL && err == 0)
    {
        do
        {
            n++;
            c = fgetc(fp);
            printf("%c" , c);
        }while(c !=EOF);
        fclose(fp);
    }
    printf("\nfile has %d charecters\n" ,n );
    return n;    
}

您可以使用windbg uf /c命令创建一个流程图,如下所示
我使用动态分析,因为有很多间接调用并且很容易
动态找到目的地

在 windbg 中打开 fopen.exe 设置中断调用 fopen_s 并按f5中断调用

0:000> rM0
fopen!main+0x29:
00a21029 e892a50000      call    fopen!fopen_s (00a2b5c0)

输入此调用并发出 uf /c 。(注意 . 表示当前 IP)

0:000> t
fopen!fopen_s:
00a2b5c0 8bff            mov     edi,edi

0:000> uf /c .
fopen!fopen_s (00a2b5c0)
  fopen!fopen_s+0xd (00a2b5cd):
    call to fopen!_errno (00a42ffd)
  fopen!fopen_s+0x17 (00a2b5d7):
    call to fopen!_invalid_parameter_noinfo (00a42ed6)
  fopen!fopen_s+0x29 (00a2b5e9):
    call to fopen!common_fsopen<char> (00a2b383) <<<<<<<<<<<<<<
  fopen!fopen_s+0x37 (00a2b5f7):
    call to fopen!_errno (00a42ffd)

您会注意到对 fopen!common_fsopen 的调用

进入该函数并重复该过程,直到到达系统调用注释,如果该函数已内联,您可能需要设置一个 bm 断点,如下所示

0:000> g fopen!common_fsopen<char>
Couldn't resolve error at 'fopen!common_fsopen<char>'
The breakpoint expression "fopen!common_fsopen<char>" evaluates to the inline function.
Please use bm command to set breakpoints first, then g.
                                 ^ Syntax error in 'g fopen!common_fsopen<char>'
0:000> bm fopen!common_fsopen<char>;g
  1: 00a2b383          @!"fopen!common_fsopen<char>"
Breakpoint 1 hit 

过程的结果如此重复,直到 crt 从自身转换到 kernel32 如下所示滚动到最后

0:000> uf /c .
fopen!common_fsopen<char> (00a2b383)
  fopen!common_fsopen<char>+0x7 (00a2b38a):
    call to fopen!__SEH_prolog4 (00a21b30)
  fopen!common_fsopen<char>+0x13 (00a2b396):
    call to fopen!_errno (00a42ffd)
  fopen!common_fsopen<char>+0x1e (00a2b3a1):
    call to fopen!_invalid_parameter_noinfo (00a42ed6)
  fopen!common_fsopen<char>+0x38 (00a2b3bb):
    call to fopen!_errno (00a42ffd)
  fopen!common_fsopen<char>+0x49 (00a2b3cc):
    call to fopen!__acrt_stdio_allocate_stream (00a44b46)
  fopen!common_fsopen<char>+0x55 (00a2b3d8):
    call to fopen!_errno (00a42ffd)
  fopen!common_fsopen<char>+0x72 (00a2b3f5):
    call to fopen!_openfile (00a45529)
  fopen!common_fsopen<char>+0x86 (00a2b409):
    call to fopen!common_fsopen<char>+0x96 (00a2b419)
  fopen!common_fsopen<char>+0x8d (00a2b410):
    call to fopen!__SEH_epilog4 (00a21b76)
0:000> g fopen!_openfile
eax=0016f870 ebx=7ffd5000 ecx=0016f870 edx=0017a89b esi=00a62194 edi=00a62190
eip=00a45529 esp=0016f848 ebp=0016f88c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
fopen!_openfile:
00a45529 8bff            mov     edi,edi
0:000> uf /c .
fopen!_openfile (00a45529)
  fopen!common_openfile<char>+0x11 (00a4519e):
    call to fopen!__acrt_stdio_parse_mode<char> (00a44cef)
  fopen!common_openfile<char>+0x3a (00a451c7):
    call to fopen!_sopen_s (00a5320a)
0:000> g fopen!_sopen_s
eax=0016f840 ebx=7ffd5000 ecx=00a62190 edx=0017a89b esi=00a62194 edi=00a62190
eip=00a5320a esp=0016f810 ebp=0016f844 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
fopen!_sopen_s:
00a5320a 8bff            mov     edi,edi
0:000> uf /c .
fopen!_sopen_s (00a5320a)
  fopen!_sopen_s+0x16 (00a53220):
    call to fopen!common_sopen_dispatch<char> (00a528eb)
0:000> g fopen!common_sopen_dispatch<char>
Couldn't resolve error at 'fopen!common_sopen_dispatch<char>'
The breakpoint expression "fopen!common_sopen_dispatch<char>" evaluates to the inline function.
Please use bm command to set breakpoints first, then g.
                                         ^ Syntax error in 'g fopen!common_sopen_dispatch<char>'
0:000> bm fopen!common_sopen_dispatch<char>;g
  2: 00a528eb          @!"fopen!common_sopen_dispatch<char>"
Breakpoint 2 hit
eax=0016f840 ebx=7ffd5000 ecx=00a62190 edx=0017a89b esi=00a62194 edi=00a62190
eip=00a528eb esp=0016f7f0 ebp=0016f80c iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
fopen!common_sopen_dispatch<char>:
00a528eb 6a10            push    10h
0:000> uf /c .
fopen!common_sopen_dispatch<char> (00a528eb)
  fopen!common_sopen_dispatch<char>+0x7 (00a528f2):
    call to fopen!__SEH_prolog4 (00a21b30)
  fopen!common_sopen_dispatch<char>+0x13 (00a528fe):
    call to fopen!_errno (00a42ffd)
  fopen!common_sopen_dispatch<char>+0x1d (00a52908):
    call to fopen!_invalid_parameter_noinfo (00a42ed6)
  fopen!common_sopen_dispatch<char>+0x5d (00a52948):
    call to fopen!_sopen_nolock (00a5319a)
  fopen!common_sopen_dispatch<char>+0x71 (00a5295c):
    call to fopen!common_sopen_dispatch<char>+0x8b (00a52976)
  fopen!common_sopen_dispatch<char>+0x7f (00a5296a):
    call to fopen!__SEH_epilog4 (00a21b76)
0:000> g fopen!_sopen_nolock
eax=0016f7cc ebx=7ffd5000 ecx=00a62190 edx=0017a89b esi=0016f840 edi=00a62190
eip=00a5319a esp=0016f79c ebp=0016f7ec iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
fopen!_sopen_nolock:
00a5319a 8bff            mov     edi,edi
0:000> uf /c .
fopen!_sopen_nolock (00a5319a)
  fopen!_sopen_nolock+0x1d (00a531b7):
    call to fopen!__acrt_get_utf8_acp_compatibility_codepage (00a4a841)
  fopen!_sopen_nolock+0x2a (00a531c4):
    call to fopen!__acrt_mbs_to_wcs_cp<__crt_win32_buffer_internal_dynamic_resizing> (00a49bea)
  fopen!_sopen_nolock+0x50 (00a531ea):
    call to fopen!_wsopen_nolock (00a53282)
  fopen!_sopen_nolock+0x63 (00a531fd):
    call to fopen!_free_base (00a430ff)
0:000> g fopen!_wsopen_nolock
eax=00000000 ebx=7ffd5000 ecx=8b190463 edx=00000009 esi=0016f840 edi=00a62190
eip=00a53282 esp=0016f75c ebp=0016f798 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
fopen!_wsopen_nolock:
00a53282 8bff            mov     edi,edi
0:000> uf /c .
fopen!_wsopen_nolock (00a53282)
  fopen!_wsopen_nolock+0x18 (00a5329a):
    call to fopen!decode_options (00a52e85)
  fopen!_wsopen_nolock+0x32 (00a532b4):
    call to fopen!__doserrno (00a42fea)
  fopen!_wsopen_nolock+0x3f (00a532c1):
    call to fopen!_errno (00a42ffd)
  fopen!_wsopen_nolock+0x4b (00a532cd):
    call to fopen!_alloc_osfhnd (00a4cc8a)
  fopen!_wsopen_nolock+0x59 (00a532db):
    call to fopen!__doserrno (00a42fea)
  fopen!_wsopen_nolock+0x63 (00a532e5):
    call to fopen!_errno (00a42ffd)
  fopen!_wsopen_nolock+0xa4 (00a53326):
    call to fopen!create_file (00a52d97)
  fopen!_wsopen_nolock+0xe9 (00a5336b):
    call to fopen!create_file (00a52d97)
  fopen!_wsopen_nolock+0x114 (00a53396):
    call to kernel32!GetLastErrorStub (75eccde0)
  fopen!_wsopen_nolock+0x11b (00a5339d):
    call to fopen!__acrt_errno_map_os_error (00a42fc7)
  fopen!_wsopen_nolock+0x127 (00a533a9):
    call to kernel32!GetFileTypeImplementation (75ed6ab4)
  fopen!_wsopen_nolock+0x131 (00a533b3):
    call to kernel32!GetLastErrorStub (75eccde0)
  fopen!_wsopen_nolock+0x13a (00a533bc):
    call to fopen!__acrt_errno_map_os_error (00a42fc7)
  fopen!_wsopen_nolock+0x15a (00a533dc):
    call to kernel32!CloseHandleImplementation (75ece868)
  fopen!_wsopen_nolock+0x168 (00a533ea):
    call to fopen!_errno (00a42ffd)
  fopen!_wsopen_nolock+0x194 (00a53416):
    call to fopen!__acrt_lowio_set_os_handle (00a4cbd3)
  fopen!_wsopen_nolock+0x1e0 (00a53462):
    call to fopen!truncate_ctrl_z_if_present (00a53096)
  fopen!_wsopen_nolock+0x1ee (00a53470):
    call to fopen!_close_nolock (00a45761)
  fopen!_wsopen_nolock+0x215 (00a53497):
    call to fopen!configure_text_mode (00a52b42)
  fopen!_wsopen_nolock+0x2a7 (00a53529):
    call to kernel32!CloseHandleImplementation (75ece868)
  fopen!_wsopen_nolock+0x2ca (00a5354c):
    call to fopen!create_file (00a52d97)
  fopen!_wsopen_nolock+0x2d9 (00a5355b):
    call to kernel32!GetLastErrorStub (75eccde0)
  fopen!_wsopen_nolock+0x2e0 (00a53562):
    call to fopen!__acrt_errno_map_os_error (00a42fc7)
  fopen!_wsopen_nolock+0x300 (00a53582):
    call to fopen!_free_osfhnd (00a4cd93)
0:000> g fopen!create_file
eax=0016f744 ebx=0016f840 ecx=00000000 edx=00000000 esi=0016f744 edi=0016f708
eip=00a52d97 esp=0016f6e4 ebp=0016f758 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
fopen!create_file:
00a52d97 8bff            mov     edi,edi
0:000> uf /c .
fopen!create_file (00a52d97)
  fopen!create_file+0x1d (00a52db4):
    call to kernel32!CreateFileWImplementation (75ece8a5)  <<<<<<<<<<<<<<<<<

kernel32.dll 到 kernelbase.dll

0:000> uf /c 75ece8a5
kernel32!CreateFileWImplementation (75ece8a5)
  kernel32!CreateFileWImplementation+0xe (75ece8b3):
    call to ntdll!RtlInitUnicodeStringEx (77a76f0a)
  kernel32!CreateFileWImplementation+0x2a (75ece8c8):
    call to kernel32!BaseIsThisAConsoleName (75ece903)
  kernel32!CreateFileWImplementation+0x64 (75ece8ea):
    call to kernel32!CreateFileW (75ece8f8)
  kernel32!CreateFileWImplementation+0x48 (75eea050):
    call to kernel32!OpenConsoleW (75ec0853)
  kernel32!CreateFileWImplementation+0x19 (75eebe96):
    call to kernel32!BaseSetLastNTError (75ecf790)
0:000> uf /c kernel32!CreateFileW
Flow analysis was incomplete, some code may be missing
kernel32!CreateFileW (75ece8f8)
    no calls found
0:000> uf kernel32!CreateFileW
Flow analysis was incomplete, some code may be missing
kernel32!_imp__CreateFileW:
75e819e0 68a7d9755e      push    5E75D9A7h
75e819e5 44              inc     esp

kernel32!CreateFileW:
75ece8f8 ff25e019e875    jmp     dword ptr [kernel32!_imp__CreateFileW (75e819e0)]

如下所示,从 kernelbase 到 ntdll 以及从 ntdll 到 kernelmode 的转换,因为有许多间接调用,您可能需要使用run to call (pc)命令评估它们中的每一个

0:000> uf /c poi(75e819e0)
KERNELBASE!CreateFileW (75d9a768)
  KERNELBASE!CreateFileW+0x68 (75d9a799):
    call to ntdll!RtlInitUnicodeStringEx (77a76f0a)
  KERNELBASE!CreateFileW+0x9e (75d9a7d3):
    call to ntdll!RtlDosPathNameToRelativeNtPathName_U_WithStatus (77a7a6a1)
  KERNELBASE!CreateFileW+0x312 (75d9a8ed):
    call to KERNELBASE!SbSelectProcedure (75d9a755)
  KERNELBASE!CreateFileW+0x31f (75d9a8fa):
    unresolvable call: call    eax
  KERNELBASE!CreateFileW+0x35c (75d9a937):
    unresolvable call: call    esi
  KERNELBASE!CreateFileW+0x3c8 (75d9a94c):
    call to ntdll!RtlReleaseRelativeName (77a77f7a)
  KERNELBASE!CreateFileW+0x3e6 (75d9a96a):
    unresolvable call: call    esi
  KERNELBASE!CreateFileW+0x3f8 (75d9a97c):
    unresolvable call: call    esi
  KERNELBASE!CreateFileW+0x44e (75d9a997):
    call to ntdll!RtlSetLastWin32Error (77a730fb)
  KERNELBASE!CreateFileW+0x3ff (75d9a9b2):
    call to KERNELBASE!BaseSetLastNTError (75d96b4d)
  KERNELBASE!CreateFileW+0xb8 (75d9f441):
    call to ntdll!RtlSetLastWin32Error (77a730fb)
  KERNELBASE!CreateFileW+0x1a8 (75da16c6):
    call to ntdll!NtQueryInformationFile (77a66058)
  KERNELBASE!CreateFileW+0xc1 (75da446c):
    call to KERNELBASE!BaseSetLastNTError (75d96b4d)
  KERNELBASE!CreateFileW+0x423 (75da73e3):
    call to ntdll!RtlSetLastWin32Error (77a730fb)
  KERNELBASE!CreateFileW+0x46f (75db80bd):
    call to ntdll!ZwSetInformationFile (77a66678)
  KERNELBASE!CreateFileW+0x2f (75dbd130):
    call to KERNELBASE!BaseSetLastNTError (75d96b4d)
  KERNELBASE!CreateFileW+0x1bf (75dbd158):
    call to KERNELBASE!KernelBaseGetGlobalData (75d96843)
  KERNELBASE!CreateFileW+0x1d6 (75dbd16f):
    call to ntdll!RtlAllocateHeap (77a72dd6)
  KERNELBASE!CreateFileW+0x1f8 (75dbd18d):
    call to ntdll!ZwQueryEaFile (77a66008)
  KERNELBASE!CreateFileW+0x213 (75dbd1a8):
    call to ntdll!RtlFreeHeap (77a72c6a)
  KERNELBASE!CreateFileW+0x2c2 (75dbd1d5):
    call to ntdll!RtlReleaseRelativeName (77a77f7a)
  KERNELBASE!CreateFileW+0x2d8 (75dbd1eb):
    call to ntdll!RtlFreeHeap (77a72c6a)
  KERNELBASE!CreateFileW+0x2e3 (75dbd1f6):
    call to KERNELBASE!BaseSetLastNTError (75d96b4d)
  KERNELBASE!CreateFileW+0x3a2 (75dbd247):
    unresolvable call: call    esi
  KERNELBASE!CreateFileW+0x3b8 (75dbd265):
    call to KERNELBASE!AitLogFeatureUsageByApp (75dd0aef)
  KERNELBASE!CreateFileW+0x47a (75dbd27e):
    call to KERNELBASE!BaseSetLastNTError (75d96b4d)
  KERNELBASE!CreateFileW+0x482 (75dbd286):
    call to ntdll!NtClose (77a65508)
0:000> bp poi(75e819e0);g
Breakpoint 0 hit
eax=00000000 ebx=0016f840 ecx=75ece9b9 edx=00000074 esi=0016f744 edi=0016f708
eip=75d9a768 esp=0016f694 ebp=0016f6bc iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
KERNELBASE!CreateFileW:
75d9a768 8bff            mov     edi,edi
0:000> pc
eax=0016f668 ebx=0016f840 ecx=75ece9b9 edx=00000074 esi=0017a8d8 edi=0016f708
eip=75d9a799 esp=0016f61c ebp=0016f690 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
KERNELBASE!CreateFileW+0x68:
75d9a799 ff15ec11d975    call    dword ptr [KERNELBASE!_imp__RtlInitUnicodeStringEx (75d911ec)]
ds:0023:75d911ec={ntdll!RtlInitUnicodeStringEx (77a76f0a)}
0:000> pc
eax=0016f668 ebx=00000000 ecx=00000008 edx=00000000 esi=0017a8d8 edi=0016f708
eip=75d9a7d3 esp=0016f614 ebp=0016f690 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
KERNELBASE!CreateFileW+0x9e:
75d9a7d3 ff150414d975    call    dword ptr [KERNELBASE!_imp__RtlDosPathNameToRelativeNtPathName_U_WithStatus
(75d91404)] ds:0023:75d91404={ntdll!RtlDosPathNameToRelativeNtPathName_U_WithStatus (77a7a6a1)}
0:000> pc
eax=00200000 ebx=00000000 ecx=00000000 edx=00000080 esi=00000020 edi=00000000
eip=75d9a8ed esp=0016f610 ebp=0016f690 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
KERNELBASE!CreateFileW+0x312:
75d9a8ed e863feffff      call    KERNELBASE!SbSelectProcedure (75d9a755)
0:000> pc
eax=75d9a760 ebx=00000000 ecx=0016f698 edx=00000000 esi=00000020 edi=00000000
eip=75d9a8fa esp=0016f61c ebp=0016f690 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
KERNELBASE!CreateFileW+0x31f:
75d9a8fa ffd0            call    eax {KERNELBASE!CreateFileDowngrade_Vista (75d9a760)}
0:000> pc
eax=0016f688 ebx=00000000 ecx=0016f62c edx=00000000 esi=77a65608 edi=00000000
eip=75d9a937 esp=0016f5f4 ebp=0016f690 iopl=0         nv up ei ng nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000282
KERNELBASE!CreateFileW+0x35c:
75d9a937 ffd6            call    esi {ntdll!ZwCreateFile (77a65608)}
0:000> t
eax=0016f688 ebx=00000000 ecx=0016f62c edx=00000000 esi=77a65608 edi=00000000
eip=77a65608 esp=0016f5f0 ebp=0016f690 iopl=0         nv up ei ng nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000282
ntdll!ZwCreateFile:
77a65608 b842000000      mov     eax,42h
0:000> pc
eax=00000042 ebx=00000000 ecx=0016f62c edx=7ffe0300 esi=77a65608 edi=00000000
eip=77a65612 esp=0016f5f0 ebp=0016f690 iopl=0         nv up ei ng nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000282
ntdll!ZwCreateFile+0xa:
77a65612 ff12            call    dword ptr [edx]      ds:0023:7ffe0300={ntdll!KiFastSystemCall (77a670f0)}
0:000>

要映射内核模式调用,您需要使用两台机器进行内核调试会话,主机和目标(物理/虚拟机或虚拟机/虚拟机或物理/物理)

在 nt!NtCreateFile 上设置一个特定于进程的 Break 并在返回到 usermode 之前重复它很可能到达对象管理器调用 ObCreateObject() 等的过程。