c++ - 用于跟踪 CreateFile 调用的 Pin 工具

标签 c++ winapi intel-pin

我制作了一个 pin 工具来转储 CreatFile win32 调用(在我的例子中是 CreateFileW)及其返回值。它看起来像这样:

/* ... */

VOID Image(IMG img, VOID *v)
{
    RTN cfwRtn = RTN_FindByName(img, "CreateFileW");
    if (RTN_Valid(cfwRtn))
    {
        RTN_Open(cfwRtn);
    
        RTN_InsertCall(cfwRtn, IPOINT_BEFORE, (AFUNPTR)CreateFileWArg,
        IARG_ADDRINT, "CreateFileW",
        IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
        IARG_END);
        RTN_InsertCall(cfwRtn, IPOINT_AFTER, (AFUNPTR)CreateFileWafter,
        IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);

        RTN_Close(cfwRtn);
    }
}

/* ... */

VOID CreateFileWArg(CHAR * name, wchar_t * filename)
{
    TraceFile << name << "(" << filename << ")" << endl;
}

VOID CreateFileWafter(ADDRINT ret)
{
    TraceFile << "\tReturned handle: " << ret << endl;
}

它给出了有趣的结果。例如,在一个只打开现有文件而不做任何其他事情的小程序上,它给出:

CreateFileW(file.txt)
    Returned handle: 0
CreateFileW(file.txt)
    Returned handle: 0x74
    Returned handle: 0x74

很多异常。

  1. 为什么有两个电话?
  2. 如果我没记错的话,CreateFile 应该永远不会返回 0。
  3. 第二次调用后,返回两次(?)

我还尝试检测一个简单的 c++ 程序,该程序直接调用 CreateFileW 一次,结果:

CreateFileW(file.txt)
    Returned handle: 0
CreateFileW(file.txt)
    Returned handle: 0xffffffff
    Returned handle: 0xffffffff

我试图打开的文件不存在,所以返回值(-1 == INVALID_HANDLE_VALUE)至少是正确的。

有什么想法吗?提前致谢!

最佳答案

好吧,一段时间后我终于弄清楚了这些问题的原因。

关于返回值显示为0:

嗯,PIN 文档说:

NOTE: IPOINT_AFTER is implemented by instrumenting each return instruction in a routine. Pin tries to find all return instructions, but success is not guaranteed

如果您在返回时转储函数的地址,结果是 0 不是从 CreateFileW 返回。它是从调用 CreateFileW 的另一个函数返回的。 PIN 的这种错误行为可以通过在您自己的版本中包装 CreateFileW 方法来修复(转储参数、调用原始函数、转储返回值)。

关于两个函数调用而不是一个:

事实证明,在我的系统上,CreateFileW 调用 Kernelbase.dll 的函数,该函数具有完全相同的名称。因为我用它们的名字检测例程,所以这是正确的行为。根据 kernel32.dll 检查图像名称解决了这个问题。

关于c++ - 用于跟踪 CreateFile 调用的 Pin 工具,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14093952/

相关文章:

C++ 对 shared_ptr 的引用与引用

intel-pin - 如何指定代码区域以通过 pintool 对其进行检测?

c++ - 如何注册另一个 win32 消息处理程序

Delphi - 相当于需要 C# DateTime.IsDaylightSavingTime() 方法

intel-pin - 使用 intel pintool 记录所有指令

c++ - 使用 Intel PIN 在寻址模式下使用特定寄存器检测 mov dword ptr [rbp - ...] 指令

C++ LNK1561 错误(包含 main() 时)

c++ - 为什么要避免在 C++ 中使用单例

c++ - 用于编辑文本框的 SDL

c++ - 防止dll被修改