Pin-инструмент для отслеживания вызовов CreateFile

Я сделал пин-инструмент для вывода вызовов Win32 CreatFile (в моем случае 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.) После второго вызова он возвращается дважды (?)

Я также пытался создать простую программу на С ++, которая непосредственно вызывает CreateFileW один раз, результат:

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

Файл, который я пытался открыть, не существует, поэтому возвращаемое значение (-1 == INVALID_HANDLE_VALUE), по крайней мере, является правильным.

Есть идеи? Заранее спасибо!

4

Решение

Хорошо, через некоторое время я наконец выяснил причины этих проблем.

О возвращаемом значении, равном 0:

Ну, документация PIN-кода гласит:

ПРИМЕЧАНИЕ: IPOINT_AFTER реализуется путем инструментирования каждой инструкции возврата в подпрограмме. Пин пытается найти все инструкции по возврату, но успех не гарантирован

Если вы дампаете адрес функции при возврате, оказывается, что 0 не вернулся из CreateFileW. Он возвращается из другой функции, в которую CreateFileW вызывает. Это ошибочное поведение ПИН-кода может быть исправлено путем переноса метода CreateFileW в вашу собственную версию (сброс параметров, вызов исходной функции, возврат возвращаемого значения).

О двух вызовах функций вместо одного:

Оказывается, что в моей системе CreateFileW вызывает функцию Kernelbase.dll, которая имеет точно такое же имя. Поскольку я инструктировал подпрограммы по их имени, это правильное поведение. Проверка имени образа против kernel32.dll решила эту проблему.

2

Другие решения

Я бы предложил перехватить его на уровне системных вызовов, а не на одном из этих неуверенных промежуточных уровней (в какой бы библиотеке он ни находился). В Windows номера системных вызовов и интерфейс не являются общедоступными, но их легко найти в любом случае.

1

По вопросам рекламы [email protected]