在调用 FindFirstFileW 后编写 Windbg 脚本以转储 eax 寄存器

Script Windbg to dump eax register after a call to FindFirstFileW

我正在尝试编写一个简单的 windbg 脚本文件来执行以下操作:

1 - 在 FindFirstFile 上中断

2 - 执行函数完成

3 - 转储包含在 eax 寄存器中的 dword

我已经尝试了以下方法,但是它并没有像我预期的那样工作。

bp FindFirstFileW
gu; r @eax; dd @eax

HANDLE WINAPI FindFirstFile(
  _In_  LPCTSTR           lpFileName,
  _Out_ LPWIN32_FIND_DATA lpFindFileData
);

是否可以对传递给 FindFirstFile 的 lpFileName 执行模式匹配?如果匹配,则继续执行直到函数完成。然后将 dword 转储返回给 eax?如果不是继续正常执行。

FindFirstFileA / W returns handle 不是文件名。
您打算通过转储 return 值来做什么?只能在后续FindNextXXX

中使用
#include <stdio.h>
#include <windows.h>
int wmain (int argc, wchar_t *argv[]) 
{
  if(argc!=2)
  {
    printf ("pl provide a wildcard for filename\n");
    return 0;
  }
  WIN32_FIND_DATAW fd = {0};
  HANDLE fifo = NULL;
  if(( fifo = FindFirstFileW(argv[1],&fd) ) == INVALID_HANDLE_VALUE)
  {
    printf("file not found\n");
    return 0;
  }    
  printf("unicode fulname %S\n",fd.cFileName);
  return 1;
} 

假设你编译上面的代码 像这样写一个脚本文件
在 api 运行 上设置 bp 在中断显示寄存器和 goup 和重新显示寄存器上执行转储 eax 和 poi(eax) 并打印出 eax

指向的句柄的描述
bu kernel32!FindFirstFileW;
g
r
gu
r
r eax
dd @eax l1
!handle poi(@eax) ff
?? fd

和 运行 像这样的 windbg windbg -c "$$>a< script.txt" fififi.exe *.cpp

Processing initial command '$$>a< script.txt'
0:000> $$>a< script.txt
Breakpoint 0 hit
eax=0013fd24 ebx=7ffdb000 ecx=0013ff74 edx=00000000 esi=000344a8 edi=00aaf600
eip=7c80ef81 esp=0013fd14 ebp=0013ff78 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
kernel32!FindFirstFileW:
7c80ef81 8bff            mov     edi,edi
eax=00152c40 ebx=7ffdb000 ecx=000068af edx=7c97e140 esi=000344a8 edi=00aaf600
eip=00401058 esp=0013fd20 ebp=0013ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
fififi!wmain+0x58:
00401058 83f8ff          cmp     eax,0FFFFFFFFh
eax=00152c40
00152c40  000007f4
Handle 7f4
  Type          File
  Attributes    0
  GrantedAccess 0x100001:
         Synch
         Read/List
  HandleCount   2
  PointerCount  3
  No Object Specific Information available
struct _WIN32_FIND_DATAW
   +0x000 dwFileAttributes : 0x2020
   +0x004 ftCreationTime   : _FILETIME Nov 24 09:07:34 2015
   +0x00c ftLastAccessTime : _FILETIME Nov 24 09:26:53 2015
   +0x014 ftLastWriteTime  : _FILETIME Nov 24 09:26:53 2015
   +0x01c nFileSizeHigh    : 0
   +0x020 nFileSizeLow     : 0x1aa
   +0x024 dwReserved0      : 0
   +0x028 dwReserved1      : 0
   +0x02c cFileName        : [260]  "fififi.cpp"
   +0x234 cAlternateFileName : [14]  ""

编辑

  • 1 returned 句柄不透明
  • 2) 只有 !handle 信息可以从 returned handle
  • 打印出来
  • 3) 在用户模式下ObjectNameInformation一般不可用
  • 4) FindFirsFile 是一次性初始化 API 并且通常不是 再次调用直到 FindClose 被调用所以逻辑上不存在 反复出现的情况
  • 5) 对于文件名的模式匹配你应该设置条件 查找下一个
  • 6) 最后一点 ?? fd 仅在编译代码时可用 回复 fd 在哪里 WIN32_FIND_DATAW ??是 C++ 表达式 windbg 中的评估器并打印出类型信息(如果存在) 在一个局部变量上,fd 往往在上面的代码中 (IT IS 不是通用的 WINDBG 命令)

对于我的简单用例,以下 cmd 序列可以按需要工作。 设置初始 bp 使用:cdb -cf cmd.wds

bp kernel32!FindNextFileA

达到 bp 后:$<c:scripts\eax.wds

t
gu
r @eax
dd @eax l1

这是输出:

0:000> g
Breakpoint 5 hit
eax=0017fb44 ebx=00000000 ecx=004157a4 edx=0000005c esi=0017f934 edi=0017fc98
eip=74a8e27b esp=0017f928 ebp=0017fc98 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
kernel32!FindFirstFileA:
74a8e27b ff25640aa874    jmp     dword ptr [kernel32!_imp__FindFirstFileA (74a80a64)] ds:002b:74a80a64={KERNELBASE!FindFirstFileA (7572aaa9)}
0:000> $<c:\scripts\eax.wds
0:000> t
eax=0017fb44 ebx=00000000 ecx=004157a4 edx=0000005c esi=0017f934 edi=0017fc98
eip=7572aaa9 esp=0017f928 ebp=0017fc98 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
KERNELBASE!FindFirstFileA:
7572aaa9 8bff            mov     edi,edi
0:000> gu
eax=004e8818 ebx=00000000 ecx=e310b772 edx=00000000 esi=0017f934 edi=0017fc98
eip=004118c9 esp=0017f934 ebp=0017fc98 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
>  107:                 searchHandle = FindFirstFile(searchPattern, &findData);
   108:                 if (searchHandle == INVALID_HANDLE_VALUE) {
   109:                         ReportError(_T("Error opening Search Handle."), 0, TRUE);
   110:                         return FALSE;
   111:                 }
lsW!TraverseDirectory+0xb9:
004118c9 3bf4            cmp     esi,esp
0:000> r @eax
eax=004e8818
0:000> dd @eax l1
004e8818  00000034

现在我可以看到 HANDLE == 34。我可以使用 procexp 来验证它。