【问题标题】:Script Windbg to dump eax register after a call to FindFirstFileW脚本 Windbg 在调用 FindFirstFileW 后转储 eax 寄存器
【发布时间】:2015-11-24 05:42:55
【问题描述】:

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

1 - 在 FindFirstFile 上中断

2 - 执行函数完成

3 - 转储 eax 寄存器中包含的双字

我尝试了以下方法,但它没有按我的预期工作。

bp FindFirstFileW
gu; r @eax; dd @eax

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

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

【问题讨论】:

  • 这是两个问题吗?一个关于在方法结束时获取@eax 的值,第二个关于模式匹配lpFileName?
  • 我明白这个问题是如何不清楚的。我想根据条件提取 eax 的 dword。
  • 请参阅stackoverflow.com/questions/20069961/… 了解字符串的模式匹配。

标签: debugging winapi windbg


【解决方案1】:

FindFirstFileA / W 返回 handle 而不是文件名。
您打算通过转储返回值来做什么?只能用于后续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 run 上设置一个 bp 以在 break 显示寄存器和 goup 和重新显示寄存器时执行 dump 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

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 返回的句柄是不透明的
  • 2) 只有 !handle 信息可以从返回的句柄中打印出来
  • 3) 在用户模式下 ObjectNameInformation 一般不可用
  • 4) FindFirsFile 是一次性初始化 API,一般不会 再次调用,直到 FindClose 在逻辑上被调用,所以不存在 反复出现的情况
  • 5) 对于文件名的模式匹配,您应该设置条件 查找下一个
  • 6) 最后但并非最不重要的 ?? fd 只有在你编译代码时才可用 回复 fd 在哪里 WIN32_FIND_DATAW ?? is 是 c++ 表达式 windbg 中的评估器并打印出类型信息(如果存在) 在 fd 往往在上述代码中的局部变量上 (它是 不是通用的 WINDBG 命令)

【讨论】:

  • 我同意你关于退货的看法。我想看到返回的句柄。这将帮助我验证存储系统返回错误值时遇到的问题。
  • 所以脚本不适合我。它返回错误的句柄和?? fd 失败。什么是 ?? fd ?
  • @d_blk, fd 是 blabb 代码第 10 行中定义的变量的名称。如果您正在调试没有私有符号的代码,您可以查看[ebp+c],它包含FindFirstFile 的第二个参数。
  • 我不能就此罢休。您可以在 blabb 的代码中使用以下条件断点:bu kernel32!FindFirstFileW "r @$t0 = poi(esp+8); gu; .if (@eax == -1) { .printf \"FindFirstFile returned INVALID_HANDLE_VALUE\\n\"; !gle; } .else { .printf \"Found file: %mu\\n\", @$t0+2c; }"。如果找到文件,将显示它的名称。否则它将使用!gle 扩展名来显示最后一个错误。
【解决方案2】:

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

设置初始 bp
bp kernel32!FindNextFileA

到达 bp 后:$&lt;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 来验证。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 2013-10-22
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    相关资源
    最近更新 更多