Доброго времени суток!
Мне необходимо мониторить у некоторого процесса все его обращения к файловой системе. Для этого я решил перехватывать функции NtXxxFile. Я внедрил в этот процесс DLL-ку через CreateRemoteProcess(по Рихтеру). Тут проблем ничего не составило, а дальше они начались. Вот основные куски кода моей dll-ки(перехватываю заменой первых байт машинного кода функции):
void StopThreads()
{
DWORD CurrTh, CurrPr;
HANDLE h, ThrHandle;
THREADENTRY32 Thread;
CurrTh = GetCurrentThreadId();
CurrPr = GetCurrentProcessId();
h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (h != INVALID_HANDLE_VALUE)
{
Thread.dwSize = sizeof(THREADENTRY32);
if (Thread32First(h, &Thread))
do
{
if ((Thread.th32ThreadID != CurrTh) && (Thread.th32OwnerProcessID == CurrPr))
{
ThrHandle = OpenThread(THREAD_SUSPEND_RESUME, FALSE, Thread.th32ThreadID);
if (ThrHandle > 0)
{
SuspendThread(ThrHandle);
CloseHandle(ThrHandle);
}
}
} while (Thread32Next(h, &Thread));
CloseHandle(h);
}
}
void RunThreads()
{
DWORD CurrTh, CurrPr;
HANDLE h, ThrHandle;
THREADENTRY32 Thread;
CurrTh = GetCurrentThreadId();
CurrPr = GetCurrentProcessId();
h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (h != INVALID_HANDLE_VALUE)
{
Thread.dwSize = sizeof(THREADENTRY32);
if (Thread32First(h, &Thread))
do
{
if ((Thread.th32ThreadID != CurrTh) && (Thread.th32OwnerProcessID == CurrPr))
{
ThrHandle = OpenThread(THREAD_SUSPEND_RESUME, FALSE, Thread.th32ThreadID);
if (ThrHandle > 0)
{
ResumeThread(ThrHandle);
CloseHandle(ThrHandle);
}
}
} while (Thread32Next(h, &Thread));
CloseHandle(h);
}
}
NTSTATUS WINAPI NewNtOpenFile(PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess,
ULONG OpenOptions
)
{
DWORD Written;
WriteProcessMemory(GetCurrentProcess(), AdrNtOpenFile, &OldNtOpenFile, sizeof(far_jmp), &Written);
MessageBox(0, L"NtOpenFile", 0, 0);
WriteLogString(L"NtOpenFile\n");
typedef NTSTATUS (WINAPI * NtOpenFileFuncType)(PHANDLE,
ACCESS_MASK,
POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK,
ULONG, ULONG);
NtOpenFileFuncType NtOpenFileFunc = (NtOpenFileFuncType)AdrNtOpenFile;
NTSTATUS ret = NtOpenFileFunc(FileHandle, DesiredAccess,
ObjectAttributes, IoStatusBlock,
ShareAccess, OpenOptions);
WriteProcessMemory(GetCurrentProcess(), AdrNtOpenFile, &JmpNtOpenFile, sizeof(far_jmp), &Written);
return ret;
}
void SetNtOpenFileHook()
{
DWORD Written;
AdrNtOpenFile = GetProcAddress(GetModuleHandle(L"Ntdll.dll"), "NtOpenFile");
if (AdrNtOpenFile == 0)
{
MessageBox(NULL, L"Can't get NtOpenFile", L"Error!", 0);
return;
}
JmpNtOpenFile.PushOp = 0x68;
JmpNtOpenFile.PushArg = NewNtOpenFile;
JmpNtOpenFile.RetOp = 0xC3;
ReadProcessMemory(GetCurrentProcess(), AdrNtOpenFile, &OldNtOpenFile, sizeof(far_jmp), &Written);
WriteProcessMemory(GetCurrentProcess(), AdrNtOpenFile, &JmpNtOpenFile, sizeof(far_jmp), &Written);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
DWORD Written;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
StopThreads();
hLog = CreateFile(L"c:\\log.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetNtOpenFileHook();
RunThreads();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
//WriteProcessMemory(GetCurrentProcess(), AdrNtOpenFile, &OldNtOpenFile, sizeof(far_jmp), &Written);
break;
}
return TRUE;
}
Если внедрить эту дллку в процесс, который ВООБЩЕ не вызывает NtOpenFile(даже неявно, в моем случае это был просто стандартный шаблон win32 приложения из студии), то начинается нечто странное. При запуске вылетает мессаджбокс с надписью "NtOpenFile", т.е. будто бы эта АПИ-функция перхватилась, а при закрытии программы начинается бесконечный поток таких же месаджбоксов.
Если аналогично перехватывать NtCreateFile, то процесс вообще падает сразу после запуска.
Из-за чего может происходить такое веселье? Вроде все правильно. Аналогичный перехват, например, MessageBox работает нормально.
И еще: мне почему-то кажется, что тут дело в ОС. Возможно в Windows 7 запретили так перехватывать функции из Ntdll.dll?