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...
Пока на собственное сообщение не было ответов, его можно удалить.