Перехват NtXxxFile в Windows 7
От: miksayer  
Дата: 14.09.10 21:07
Оценка:
Доброго времени суток!
Мне необходимо мониторить у некоторого процесса все его обращения к файловой системе. Для этого я решил перехватывать функции 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?
Re: Перехват NtXxxFile в Windows 7
От: ononim  
Дата: 14.09.10 22:12
Оценка: +1
M>[/ccode]
M>Если внедрить эту дллку в процесс, который ВООБЩЕ не вызывает NtOpenFile(даже неявно, в моем случае это был просто стандартный шаблон win32 приложения из студии), то начинается нечто странное. При запуске вылетает мессаджбокс с надписью "NtOpenFile", т.е. будто бы эта АПИ-функция перхватилась, а при закрытии программы начинается бесконечный поток таких же месаджбоксов.
NtOpenFile/NtCreateFile вызываются не только если ваше приложение вызвало ее. Ваше приложение — это не только код который вы написали, но еще и туева хуча системных длл который могут работать с файлами, драйверами, пайпами etc — все это ходит через Nt***File. Даже загрузка длл, то бишь LoadLibrary — это прежде всего открытие файла этой длл с последующим его мапингом в память. То есть LoadLibrary "внутри" вызывает как минимум — NtCreateFile/NtCreateSection/NtMapViewOfSection.

M>Если аналогично перехватывать NtCreateFile, то процесс вообще падает сразу после запуска.

M>Из-за чего может происходить такое веселье? Вроде все правильно. Аналогичный перехват, например, MessageBox работает нормально.
M>И еще: мне почему-то кажется, что тут дело в ОС. Возможно в Windows 7 запретили так перехватывать функции из Ntdll.dll?
Показывать MessageBox да и ваще пользоваться высокоуровневым по отношению к NT kernel services функционалом — надо как минимум очень, очень осторожно. MessageBox — это ведь создание диалога. А значит может быть открытие файла с ресурсами. Потом — user32 может начать подгружать разные длл с хуками, а это LoadLibrary, а LoadLibrary — это см выше, а это — бесконечная рекурсия, а вы против нее никаких мер не предприняли. Кроме того MessageBox как и другие win32 API может менять результат GetLastError, в то время как Nt* вызовы этим не занимаются что так же может поломать логику приложения. Вобщем с хуками на ntdll надо быть как ежикам с сексом.


PS кроме того ваш код не thread-safe, — при одновременном вызове перехваченной ф-ии из разных потоков будет плохо. Кроме того он может содержать и другие проблемы. И вообще — скачайте детурс, вроде он бесплатный еще.
Как много веселых ребят, и все делают велосипед...
Re: Перехват NtXxxFile в Windows 7
От: Were  
Дата: 14.09.10 23:19
Оценка:
Здравствуйте, miksayer, Вы писали:

Дополнительно к предыдущему оратору могу добавить, что не видно кода снятия защиты со страниц памяти ntdll. Не показано объявление JmpNtOpenFile, установлено-ли там выравнивание по 1 байту?
Re[2]: Перехват NtXxxFile в Windows 7
От: miksayer  
Дата: 15.09.10 05:47
Оценка:
Здравствуйте, ononim, Вы писали:

А какие меры надо предпринять против бесконечной рекурсии?
И еще: я веду лог-файл обращений к ФС. Т.е. вы хотите сказать, что надежнее будет писать посредством NtXxxFile функций?
Re[2]: Перехват NtXxxFile в Windows 7
От: miksayer  
Дата: 15.09.10 05:48
Оценка:
Здравствуйте, Were, Вы писали:

W>Здравствуйте, miksayer, Вы писали:


W>Дополнительно к предыдущему оратору могу добавить, что не видно кода снятия защиты со страниц памяти ntdll. Не показано объявление JmpNtOpenFile, установлено-ли там выравнивание по 1 байту?


Выравнивание стоит. А про снятие защиты со страниц памяти ntdll никогда не слышал. Как это делается?
Re[2]: Перехват NtXxxFile в Windows 7
От: miksayer  
Дата: 15.09.10 05:51
Оценка:
И по поводу thread-safe. Т.е. мне в принципе можно просто в начале функции-перехватчика вызывать StopThreads, а в конце RunThreads(их код я привел в первом сообщении)?
Re[3]: Перехват NtXxxFile в Windows 7
От: Were  
Дата: 15.09.10 06:33
Оценка:
Здравствуйте, miksayer, Вы писали:

M>Здравствуйте, Were, Вы писали:


W>>Здравствуйте, miksayer, Вы писали:


W>>Дополнительно к предыдущему оратору могу добавить, что не видно кода снятия защиты со страниц памяти ntdll. Не показано объявление JmpNtOpenFile, установлено-ли там выравнивание по 1 байту?


M>Выравнивание стоит. А про снятие защиты со страниц памяти ntdll никогда не слышал. Как это делается?


Нужно использовать VirtualProtect, чтобы убрать атрибут "только чтение" со страницы памяти ntdll, в которой находится нужная функции. Странно, если модификация работает без этого.
Re[4]: Перехват NtXxxFile в Windows 7
От: Pavel Dvorkin Россия  
Дата: 15.09.10 07:28
Оценка:
Здравствуйте, Were, Вы писали:

W>Нужно использовать VirtualProtect, чтобы убрать атрибут "только чтение" со страницы памяти ntdll, в которой находится нужная функции. Странно, если модификация работает без этого.


Ничего странного, если дело идет под отладчиком, он мог снять, ему же брекпойнты ставить.
With best regards
Pavel Dvorkin
Re: Перехват NtXxxFile в Windows 7
От: Jolly Roger  
Дата: 15.09.10 08:50
Оценка:
Здравствуйте, miksayer, Вы писали:

M> ReadProcessMemory(GetCurrentProcess(), AdrNtOpenFile, &OldNtOpenFile, sizeof(far_jmp), &Written);

M> WriteProcessMemory(GetCurrentProcess(), AdrNtOpenFile, &JmpNtOpenFile, sizeof(far_jmp), &Written);

Любопытный "ход конём" А почему-бы просто не memcpy?
"Нормальные герои всегда идут в обход!"
Re: Перехват NtXxxFile в Windows 7
От: De-Bugger  
Дата: 15.09.10 08:56
Оценка: +1
Здравствуйте, miksayer, Вы писали:

M>Доброго времени суток!

M>Мне необходимо мониторить у некоторого процесса все его обращения к файловой системе.

Драйвер-фильтр ФС. Все остальные способы — гемор на свою задницу, вечно падающие костыли и лучи поноса от благодарных пользователей в вашу сторону.
Re[2]: Перехват NtXxxFile в Windows 7
От: miksayer  
Дата: 15.09.10 13:25
Оценка: -1
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, miksayer, Вы писали:


JR>Любопытный "ход конём" А почему-бы просто не memcpy?


Потому что так у Рихтера было
Re[2]: Перехват NtXxxFile в Windows 7
От: miksayer  
Дата: 15.09.10 13:25
Оценка:
Здравствуйте, De-Bugger, Вы писали:

DB>Здравствуйте, miksayer, Вы писали:


DB>Драйвер-фильтр ФС. Все остальные способы — гемор на свою задницу, вечно падающие костыли и лучи поноса от благодарных пользователей в вашу сторону.


блин, нету никакого желания пока что учиться писать драйверы
Re[3]: Перехват NtXxxFile в Windows 7
От: x64 Россия  
Дата: 15.09.10 13:52
Оценка: 1 (1)
M>блин, нету никакого желания пока что учиться писать драйверы

Это единственно правильное решение данной задачи. Если сам не можешь, ну обратись к начальству, пусть закажут на стороне.
Re[4]: Перехват NtXxxFile в Windows 7
От: miksayer  
Дата: 15.09.10 14:40
Оценка:
Здравствуйте, x64, Вы писали:

M>>блин, нету никакого желания пока что учиться писать драйверы


x64>Это единственно правильное решение данной задачи. Если сам не можешь, ну обратись к начальству, пусть закажут на стороне.

это лаба вообще-то Вот задание:

5. Разработать программу, которая запускает приложение, переданное программе
на вход. После запуска приложения должна выполняться журнализация всех
обращений приложения к реестру и файловой системе. Для этого в запущенное
приложение должна подгружаться DLL-библиотека, перехватывающая функции
работы с файловой системой (NtXxxx). Перехват обращений к реестру можно
осуществить любым известным способом.

Как я понимаю, тут идет речь о том способе, которым я пытаюсь сделать.
Re[5]: Перехват NtXxxFile в Windows 7
От: x64 Россия  
Дата: 15.09.10 15:03
Оценка: +1 -2
M>это лаба вообще-то... Вот задание:

Ёлки, я вообще поражаюсь, как только наглости хватает в сраных универах давать задачи, которые люди решают в коммерческих компаниях за вполне приличные деньги, между прочим. Ну ты объясни преподу, что если он тебе заплатит пару тыщ зелени, то ты с радостью выполнишь это задание. А если нет, тогда не стоит, наверное, тратить на него время, учитывая что в соседней конторе (ну или во всяком случае в Москве точно) тебе будут за этот гемор ещё и приплачивать, и это будет явно не стипендия. Ну слов нет.
Re[5]: Перехват NtXxxFile в Windows 7
От: Pavel Dvorkin Россия  
Дата: 15.09.10 15:07
Оценка:
Здравствуйте, miksayer, Вы писали:

M>5. Разработать программу, которая запускает приложение, переданное программе

M>на вход. После запуска приложения должна выполняться журнализация всех
M>обращений приложения к реестру и файловой системе.

Хм. Напрашивается флаг DEBUG_ONLY_THIS_PROCESS в CreateProcess и WaitForDebugEvent

case CREATE_PROCESS_DEBUG_EVENT:
// As needed, examine or change the registers of the
// process's initial thread with the GetThreadContext and
// SetThreadContext functions; read from and write to the
// process's virtual memory with the ReadProcessMemory and
// WriteProcessMemory functions; and suspend and resume
// thread execution with the SuspendThread and ResumeThread
// functions. Be sure to close the handle to the process image
// file with CloseHandle.
With best regards
Pavel Dvorkin
Re[6]: Перехват NtXxxFile в Windows 7
От: -prus-  
Дата: 16.09.10 07:16
Оценка:
Здравствуйте, x64, Вы писали:

x64>Ну ты объясни преподу, что если он тебе заплатит пару тыщ зелени, то ты с радостью выполнишь это задание.


Боюсь, как бы после этого препод у него не попросил пару тыщ зелени потом за экзамен или зачет .
С уважением,
Евгений
Re[7]: Перехват NtXxxFile в Windows 7
От: x64 Россия  
Дата: 16.09.10 07:32
Оценка:
P>Боюсь, как бы после этого препод у него не попросил пару тыщ зелени потом за экзамен или зачет :).

Ну так расставаться надо с такими учебными заведениями. Это, правда, моё скромное мнение. Сам-то я без высшего.
Re[8]: Перехват NtXxxFile в Windows 7
От: -prus-  
Дата: 16.09.10 07:43
Оценка:
Здравствуйте, x64, Вы писали:

x64>Ну так расставаться надо с такими учебными заведениями. Это, правда, моё скромное мнение. Сам-то я без высшего.


Да не, я к тому, что просто не поставят зачет или экзамен, если начнет выпендриваться. Задание есть задание и его нужно выполнять.
Тем более такая непростая задача откроет ему много нового. Это имхо все.
С уважением,
Евгений
Re[6]: Перехват NtXxxFile в Windows 7
От: Pavel Dvorkin Россия  
Дата: 16.09.10 09:45
Оценка:
Здравствуйте, x64, Вы писали:

M>>это лаба вообще-то... Вот задание:


x64>Ёлки, я вообще поражаюсь, как только наглости хватает в сраных универах давать задачи, которые люди решают в коммерческих компаниях за вполне приличные деньги, между прочим. Ну ты объясни преподу, что если он тебе заплатит пару тыщ зелени, то ты с радостью выполнишь это задание. А если нет, тогда не стоит, наверное, тратить на него время, учитывая что в соседней конторе (ну или во всяком случае в Москве точно) тебе будут за этот гемор ещё и приплачивать, и это будет явно не стипендия. Ну слов нет.


Категорически не согласен.

Сразу скажу — не обсуждаю конкретную ситуацию в вузе, так как не знаю деталей. Так что только по задаче.

А что тут, собственно, плохого ? Нормальная задача по системному программированию. Даже если студент не напишет полностью корректное решение, то по крайней мере познакомится с перехватом АПИ-функций, поймет, как импорт-экспорт устроены. А на каких тогда примерах их системному программированию обучать ? Или же вообще вуз должен ограничиться классом class Person и всеми его наследниками с Hibernate? Так ведь и за это в соседних конторах тоже платят.
Кстати, а где те, что в соседних конторах за деньги это делают, учились это делать ?
With best regards
Pavel Dvorkin
Re[7]: Перехват NtXxxFile в Windows 7
От: De-Bugger  
Дата: 16.09.10 10:43
Оценка: +3
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А что тут, собственно, плохого ? Нормальная задача по системному программированию. Даже если студент не напишет полностью корректное решение, то по крайней мере познакомится с перехватом АПИ-функций, поймет, как импорт-экспорт устроены. А на каких тогда примерах их системному программированию обучать ?


Со многим с вами согласен, кроме отцитированного. Поставленная задача в том виде как ее описал топикстартер, действительно очень трудоемкая но и бестолковая одновременно. Ежели и обучать студента методам "перехвата АПИ-функций", то уж явно не на ядренных Nt.., а если и на ядренных Nt.. то уж никак не на NtCreateFile. Если преподаватель толковый, то может дать задание "поэкспериментировать" ну например с NtCreateKey. Это на порядок проще и понять и отладить и поиграться. А дать задание, не имеющей практической пользы в дальнейшем, но потратив полезное время на подпорки с костылями, нежели чем на основную тему задания — ядреного перехвата, это извините, перебор.
Re[8]: Перехват NtXxxFile в Windows 7
От: Pavel Dvorkin Россия  
Дата: 16.09.10 12:38
Оценка:
Здравствуйте, De-Bugger, Вы писали:

DB>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>А что тут, собственно, плохого ? Нормальная задача по системному программированию. Даже если студент не напишет полностью корректное решение, то по крайней мере познакомится с перехватом АПИ-функций, поймет, как импорт-экспорт устроены. А на каких тогда примерах их системному программированию обучать ?


DB>Со многим с вами согласен, кроме отцитированного. Поставленная задача в том виде как ее описал топикстартер, действительно очень трудоемкая но и бестолковая одновременно. Ежели и обучать студента методам "перехвата АПИ-функций", то уж явно не на ядренных Nt.., а если и на ядренных Nt.. то уж никак не на NtCreateFile. Если преподаватель толковый, то может дать задание "поэкспериментировать" ну например с NtCreateKey. Это на порядок проще и понять и отладить и поиграться. А дать задание, не имеющей практической пользы в дальнейшем, но потратив полезное время на подпорки с костылями, нежели чем на основную тему задания — ядреного перехвата, это извините, перебор.


Согласен. В первом варианте моего предыдущего сообщения была фраза "хотя я лично считаю эту задачу слишком сложной". Выкинул я ее из-за того, что не знаю деталей — может, это группа, где именно крутых системщиков готовят
With best regards
Pavel Dvorkin
Re[9]: Перехват NtXxxFile в Windows 7
От: miksayer  
Дата: 21.09.10 07:02
Оценка:
Доброго времени суток всем еще раз! Поговорил с преподом, он разрешил перехватывать вместо NtXxx-функций обычные(CreateFile, WriteFile и т.п.). Вот код dll-библиотеки:

// dllmain.cpp: определяет точку входа для приложения DLL.
#include "stdafx.h"
#include <Tlhelp32.h>
#include <string.h>
#include <stdlib.h>
#include <Winternl.h>
#include <Dbghelp.h>

#pragma comment(lib, "Dbghelp.lib")

#pragma pack(push)
#pragma pack(1)
struct far_jmp
{
    BYTE PushOp;
    PVOID PushArg;
    BYTE RetOp;
};
#pragma pack(pop)
HANDLE CurrProc;

far_jmp OldOpenFile, JmpOpenFile;
PVOID AdrOpenFile;
far_jmp OldCreateFile, JmpCreateFile;
PVOID AdrCreateFile;
far_jmp OldNtDeleteFile, JmpNtDeleteFile;
PVOID AdrNtDeleteFile;
far_jmp OldWriteFile, JmpWriteFile;
PVOID AdrWriteFile;
far_jmp OldReadFile, JmpReadFile;
PVOID AdrReadFile;

HANDLE hLog;
HANDLE mutex;
CRITICAL_SECTION cs;

void WriteLogString(const TCHAR * str)
{
    DWORD dwBytesWritten = 0;
       WriteFile(hLog, str, lstrlen(str) * sizeof(TCHAR), &dwBytesWritten, NULL);
    WriteFile(hLog, L"\r\n", lstrlen(L"\r\n") * sizeof(TCHAR), &dwBytesWritten, NULL);
}

HANDLE WINAPI NewCreateFile(LPCTSTR lpFileName,
                              DWORD dwDesiredAccess,
                              DWORD dwShareMode,
                              LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                              DWORD dwCreationDisposition,
                              DWORD dwFlagsAndAttributes,
                              HANDLE hTemplateFile)

{
    EnterCriticalSection(&cs);
    DWORD Written;
    WriteProcessMemory(GetCurrentProcess(), AdrCreateFile, &OldCreateFile, sizeof(far_jmp), &Written);
    HANDLE ret = CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
                            dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
    WriteLogString(lpFileName);
    WriteProcessMemory(GetCurrentProcess(), AdrCreateFile, &JmpCreateFile, sizeof(far_jmp), &Written);
    LeaveCriticalSection(&cs);
    return ret;
}
BOOL WINAPI NewWriteFile(HANDLE hFile,
                      LPCVOID lpBuffer,
                      DWORD nNumberOfBytesToWrite,
                      LPDWORD lpNumberOfBytesWritten,
                      LPOVERLAPPED lpOverlapped)
{
    EnterCriticalSection(&cs);
    DWORD Written;
    WriteProcessMemory(GetCurrentProcess(), AdrWriteFile, &OldWriteFile, sizeof(far_jmp), &Written);    
    BOOL ret = WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
    WriteLogString(L"WriteFile");
    WriteProcessMemory(GetCurrentProcess(), AdrWriteFile, &JmpWriteFile, sizeof(far_jmp), &Written);
    LeaveCriticalSection(&cs);
    return ret;
}


BOOL WINAPI NewReadFile(HANDLE hFile,
                     LPVOID lpBuffer,
                     DWORD nNumberOfBytesToRead,
                     LPDWORD lpNumberOfBytesRead,
                     LPOVERLAPPED lpOverlapped)
{
    EnterCriticalSection(&cs);
    DWORD Written;
    WriteProcessMemory(GetCurrentProcess(), AdrReadFile, &OldReadFile, sizeof(far_jmp), &Written);
    BOOL ret = ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
    WriteLogString(L"ReadFile");
    WriteProcessMemory(GetCurrentProcess(), AdrReadFile, &JmpReadFile, sizeof(far_jmp), &Written);
    LeaveCriticalSection(&cs);
    return ret;
}
void SetHook(LPCSTR procName, LPCWSTR libName, PVOID procHandler, PVOID * procAdr, far_jmp * old_header, far_jmp * new_header)
{
    DWORD Written;

    *procAdr = GetProcAddress(GetModuleHandle(libName), procName);
    
    if (*procAdr == 0)
    {
        MessageBox(0, 0, 0, 0);
        return;
    }
    
    new_header->PushOp = 0x68;
    new_header->PushArg = procHandler;
    new_header->RetOp = 0xC3;

    ReadProcessMemory(GetCurrentProcess(), *procAdr, old_header, sizeof(far_jmp), &Written);
    WriteProcessMemory(GetCurrentProcess(), *procAdr, new_header, sizeof(far_jmp), &Written);
}



BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    DWORD Written;
    unsigned char bom[] = {0xFF, 0xFE};
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        hLog = CreateFile(L"c:\\log.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        WriteFile(hLog, bom, 2, &Written, NULL);
        InitializeCriticalSection(&cs);
        SetHook("CreateFileW", L"kernel32.dll", NewCreateFile, &AdrCreateFile, &OldCreateFile, &JmpCreateFile);
        SetHook("ReadFile", L"kernel32.dll", NewReadFile, &AdrReadFile, &OldReadFile, &JmpReadFile);
        SetHook("WriteFile", L"kernel32.dll", NewWriteFile, &AdrWriteFile, &OldWriteFile, &JmpWriteFile);
        break;

    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        CloseHandle(hLog);
        DeleteCriticalSection(&cs);
        //CloseHandle(mutex);
        //WriteProcessMemory(GetCurrentProcess(), AdrNtOpenFile, &OldNtOpenFile, sizeof(far_jmp), &Written);
        break;
    }
    return TRUE;
}

Вроде как все работало, пока не начал писать информацию о вызовах в лог-файл(это делается с помощью ф-ции WriteLogString). Почему-то при подгрузке этой библиотеки, например, в стандартный Блокнот лог-файл после некоторых действий получает вид:

C:\Windows\Fonts\staticcache.datWriteFile

WriteFile
C:\Users\Сергей\AppData\Roaming\Dropbox\shellext\l\4c979f96WriteFile

WriteFile
WriteFile
WriteFile
WriteFile
WriteFile
WriteFile
WriteFile
WriteFile
\\.\PIPE\srvsvcWriteFile

WriteFile
C:\WriteFile

WriteFile
C:\Users\Сергей\AppData\Local\Microsoft\Windows\Caches\cversions.1.dbWriteFile

WriteFile
C:\Users\Сергей\AppData\Local\Microsoft\Windows\Caches\{AFBF9F1A-8EE8-4C77-AF34-C647E37CA0D9}.1.ver0x000000000000001f.dbWriteFile

WriteFile
C:\Users\desktop.iniWriteFile

WriteFile
ReadFileWriteFile

WriteFile
C:\UsersWriteFile
.............
.............
и т.д.

т.е. периодически нет переносов строки, которые должны быть. Сначала я подумал, что это происходит из-за того, что моя библиотека была непотокобезопасна(хотя что-то я сомневаюсь в многопоточности Блокнота), но после добавления критических секций в функции перехвата ситуация не поменялась.
Из-за чего это может быть и как это можно исправить?
Re[10]: Перехват NtXxxFile в Windows 7
От: Pavel Dvorkin Россия  
Дата: 21.09.10 09:41
Оценка:
Здравствуйте, miksayer, Вы писали:

M>т.е. периодически нет переносов строки, которые должны быть. Сначала я подумал, что это происходит из-за того, что моя библиотека была непотокобезопасна(хотя что-то я сомневаюсь в многопоточности Блокнота), но после добавления критических секций в функции перехвата ситуация не поменялась.

M>Из-за чего это может быть и как это можно исправить?

Я не вижу здесь собственно хука, то есть SetWindowsHookEx. Не вижу тут и претендента на звание хуковой функции. SetHook просто изменяет адрес, хорошо, но каким образом этот код оказался в Notepad, зачем и почему Notepad его загрузил ?
With best regards
Pavel Dvorkin
Re[10]: Перехват NtXxxFile в Windows 7
От: ononim  
Дата: 21.09.10 10:12
Оценка: 3 (1)
M>Из-за чего это может быть и как это можно исправить?
WriteLogString вызванный из вашего обработчика CreateFile вначале переходит в ваш обработчик WriteFile'а и только потом вызывает оригинал, отсюда спецэффекты
А код хуков все равно не потокобезопасный
Как много веселых ребят, и все делают велосипед...
Re[11]: Перехват NtXxxFile в Windows 7
От: miksayer  
Дата: 21.09.10 14:14
Оценка:
Здравствуйте, ononim, Вы писали:

M>>Из-за чего это может быть и как это можно исправить?

O>WriteLogString вызванный из вашего обработчика CreateFile вначале переходит в ваш обработчик WriteFile'а и только потом вызывает оригинал, отсюда спецэффекты
O>А код хуков все равно не потокобезопасный

о! точно! спасибо огромное, попробую поковыряться в этом направлении
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.