Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> перехват FindNextFile для Windows NT(Windows 7) 
:(
    Опции темы
Fishtel
Дата 29.5.2010, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Здравствуйте, помогите решить задачу. Пишу программку для скрытия файлов(папок) для Windows 7
Внедрение dll через удаленный поток, метод перехвата : используя таблицу импорта

Сложности : 
1 Проводник не перехватывает FindNextFileW(Windows Explorer)
2 Не получается скрыть файлы используя myFindNextFileW (как пример в WinRAR) хотя видно что библиотека загружена и вызывается двойник myFindNextFileW  Уже работает 

код внедрения библиотеки:
Код

void injDLL(DWORD procID)   //параметр id процесса в который внедряем
    {
    LPDWORD hTr;
    DWORD pdwNumBytesWritten;
    LPVOID  p_code;
    PDWORD pfnThreadRtn;    
    TCHAR Buffer[BUFSIZE];
    DWORD dwRet = GetCurrentDirectory(BUFSIZE, Buffer);
    strcat(Buffer,"\\myDLL.dll");
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_VM_WRITE, TRUE, procID);
    p_code = VirtualAllocEx(hProcess, NULL, 512, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    BOOL res = WriteProcessMemory( hProcess, p_code, (LPCVOID)Buffer, strlen(Buffer), &pdwNumBytesWritten);
    pfnThreadRtn = (PDWORD)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA"); 
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pfnThreadRtn, p_code, 0, hTr);
    CloseHandle(hThread);
}


MAIN библиотеки:
Код

bool APIENTRY DllMain(HANDLE hModule, DWORD  ulReasonForCall, LPVOID lpReserved)
{
    if(ulReasonForCall == DLL_PROCESS_ATTACH)
    {    
        PROC adrReal, adrMyFun;
        adrReal = GetProcAddress(GetModuleHandle("Kernel32.dll"), "FindNextFileW");
        realAdrFindNextFileW = adrReal;
        adrMyFun = (PROC)&myFindNextFileW;
        myChangeAdress("Kernel32.dll", adrReal, adrMyFun);

    }
    return true;
}


функция подмены адресов:
Код

bool myChangeAdress(PCSTR sysLibrName, PROC adrRealFunc, PROC adrMyFun)
{
    HMODULE hmodCaller =  GetModuleHandle(NULL);    //описатель текущего модуля
    ULONG Size;
    LoadLibrary("dbghelp.dll");
    PVOID (WINAPI * _ImageDirectoryEntryToData)(PVOID, BOOLEAN, USHORT, PULONG);
    HINSTANCE hKernel = GetModuleHandle("dbghelp.dll");
    *(FARPROC *)&_ImageDirectoryEntryToData = GetProcAddress(hKernel, "ImageDirectoryEntryToData");
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)_ImageDirectoryEntryToData(hmodCaller, TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT, &Size);

    if (pImportDesc == NULL)
    {
        return false;
    }
    for (; pImportDesc->Name; pImportDesc++)
    {    
        PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name);
        if (lstrcmpiA(pszModName, sysLibrName) == 0)
        {    
            if (pImportDesc->Name == 0)
            {
                return false;
            }
            PIMAGE_THUNK_DATA pImportAddressTable = (PIMAGE_THUNK_DATA) ((PBYTE) hmodCaller + pImportDesc->FirstThunk);
            // заменяем адреса исходных функций адресами своих функций
            for (; pImportAddressTable->u1.Function; pImportAddressTable++)
            {
                // получаем адрес адреса функции
                PROC  *ppfn;    
                ppfn = (PROC*)&(pImportAddressTable->u1.Function);
                if(*ppfn == adrRealFunc)
                {    
                    DWORD pdwNumBytesWritten, op;
                    VirtualProtect(ppfn,sizeof(ppfn),PAGE_READWRITE, &op);
                    WriteProcessMemory(GetCurrentProcess(), ppfn, &adrMyFun, sizeof(ppfn), &pdwNumBytesWritten);
                    return true;
                } 
            } 
        }
    } 
}


сам двойник :
Код

BOOL WINAPI myFindNextFileW (HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
{    
    BOOL retVal;
    bool res = lstrcmpW(L"имя.файла", lpFindFileData->cFileName);
    if(res)
    {    
        retVal = ((BOOL (__stdcall*)(HANDLE, LPWIN32_FIND_DATAW))realAdrFindNextFileW)(hFindFile, lpFindFileData);
        return retVal;
    }
}



Спасибо. Надеюсь на помощь.

Это сообщение отредактировал(а) Fishtel - 6.6.2010, 14:08
PM MAIL   Вверх
xvr
Дата 30.5.2010, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



На первый взгляд - функция двойник myFindNextFileW написана неверно - она не всегда возвращает результат и не всегда заполняет сруктуру lpFindFileData
И вообще она крайне подозрительна - параметр lpFindFileData у FindNextFileW - это out параметр (т.е. ваша функция должна его заполнять), а вы из него зачем то читатете

PM MAIL   Вверх
12usver12
Дата 30.5.2010, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 5.1.2007

Репутация: 1
Всего: 1



попробуй таким способом

Код

BOOL WINAPI myFindNextFileW (HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
{    
    BOOL retVal = ((BOOL (__stdcall*)(HANDLE, LPWIN32_FIND_DATAW))realAdrFindNextFileW)(hFindFile, lpFindFileData);
    if ( !lstrcmpW(L"имя.файла", lpFindFileData->cFileName))
   {
     retVal = 0;
// ну или ZeroMemory(lpFindFileData->cFileName, 2*MAX_PATH);  х.з. потренируйся
   }
        return retVal;
   
}


а вообще читай внимательно мсдн,описание функций и возвращаемые значения 


Это сообщение отредактировал(а) 12usver12 - 30.5.2010, 11:23
PM MAIL   Вверх
Fishtel
Дата 30.5.2010, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



12usver12 и xvr, спасибо.
12usver12 работает код:
Код

BOOL WINAPI myFindNextFileW (HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
{    
    BOOL retVal = ((BOOL (__stdcall*)(HANDLE, LPWIN32_FIND_DATAW))realAdrFindNextFileW)(hFindFile, lpFindFileData);
    if ( !lstrcmpW(L"blacklist.txt", lpFindFileData->cFileName))
    {
        ZeroMemory(lpFindFileData->cFileName, 2*MAX_PATH);
    }
    return retVal;
}


xvr прочитав, ваше сообщение только понял))))
мне почему раньше казалось, что lpFindFileData уже приходит заполненная, а я ведь перехватываю вызов и она еще не успела заполниться, точно....  =)

 smile 

протестировал в Total, WinRAR, все ок

а вот проводник вылетает при замене адресов ((((

Это сообщение отредактировал(а) Fishtel - 30.5.2010, 11:58
PM MAIL   Вверх
bra1ny
Дата 30.5.2010, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 26.12.2008

Репутация: 2
Всего: 3



перехватите NtQueryDirectoryFile.
--------------------
Что вас манит сюдаИз заморзких широт?Там гораздо сытней и красивей.Или воля не та, или воздух не тот -Знать и вам не прожить без России.
PM   Вверх
12usver12
Дата 30.5.2010, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 5.1.2007

Репутация: 1
Всего: 1



Цитата

Код

ZeroMemory(lpFindFileData->cFileName, 2*MAX_PATH);


вообще жестокий способ, может быть из-за него вылеты 
а что мой первоначальный код не работает ? 
в случае с explorer можно попробовать чота типа такого 
  
Код

   if ( !lstrcmpW(L"имя.файла", lpFindFileData->cFileName))
   {
     retVal = 0;
SetLastError(...); // INVALID_FILE_SIZE или что-то в этом роде 
   }

PM MAIL   Вверх
xvr
Дата 30.5.2010, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(12usver12 @ 30.5.2010,  13:10)
Цитата

Код

ZeroMemory(lpFindFileData->cFileName, 2*MAX_PATH);


вообще жестокий способ, может быть из-за него вылеты 

Угу
Цитата

в случае с explorer можно попробовать чота типа такого 
  
Код

   if ( !lstrcmpW(L"имя.файла", lpFindFileData->cFileName))
   {
     retVal = 0;
SetLastError(...); // INVALID_FILE_SIZE или что-то в этом роде 
   }

Этого недостаточно - таким образом перебор директории будет оборванн на файле "имя.файла", все, что окажется после него тоже пропадет.
Здесь нужно в цикле вызывать realAdrFindNextFileW пока она не вернет FALSE или пока возвращенное имя не будет отличаться от "имя.файла"
Как то так
Код

while(BOOL retVal = ((BOOL (__stdcall*)(HANDLE, LPWIN32_FIND_DATAW))realAdrFindNextFileW)(hFindFile, lpFindFileData))
   if ( lstrcmpW(L"blacklist.txt", lpFindFileData->cFileName)) return retVal;
return 0;


PS. А FindFirstFileW нормально перехвачен?


Это сообщение отредактировал(а) xvr - 30.5.2010, 13:37
PM MAIL   Вверх
12usver12
Дата 30.5.2010, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 5.1.2007

Репутация: 1
Всего: 1



Цитата

Этого недостаточно - таким образом перебор директории будет оборванн на файле "имя.файла"

впринципе да - но просто в случае с эксплорером, стоит попробовать возможно он ориентируется по коду ошибки ERROR_NO_MORE_FILES 

впринципе можно быстро решить проблему в обработчике lstrcpyW(lpFindFileData->cFileName, L"111.txt"); 
но это будет некрасиво и неуниверсально, но все-таки решение  
PM MAIL   Вверх
Fishtel
Дата 30.5.2010, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



с Explorer проблема в том, что он вылетает в функции myChangeAdress
на строчках :
Код

VirtualProtect(ppfn,sizeof(ppfn),PAGE_READWRITE, &op);
WriteProcessMemory(GetCurrentProcess(), ppfn, &adrMyFun, sizeof(ppfn), &pdwNumBytesWritten);


Цитата
впринципе можно быстро решить проблему в обработчике lstrcpyW(lpFindFileData->cFileName, L"111.txt"); 

я пока так и тестирую )))
в дальнейшем в if() будет функция которая читает список запрещенных файлов и если найдет нужный возвратит false

Цитата
FindFirstFileW нормально перехвачен?


да, там пока ток вызов оригинальной функции, но я этот перехватчик планирую использовать только, чтобы получить полный путь к файлу...

Это сообщение отредактировал(а) Fishtel - 30.5.2010, 14:51
PM MAIL   Вверх
12usver12
Дата 30.5.2010, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 5.1.2007

Репутация: 1
Всего: 1



to Fishtel не забывай в конце return retVal; а то опять будет что-то вылетать...
тут еще зависит от конкретной программы...возможно перечисление файлов выполняется 
таким образом в простых прогах
Код

HANDLE hFile = FindFirstFile(path,&fd);
    do 
    { 
          ...
        }
    while (FindNextFile(hFile,&fd)); 
 
или что-то наподобие такого
Код

HANDLE hFile = FindFirstFile(path,&fd);
    do 
    { 
          ...
        }
    while (FindNextFile(hFile,&fd) && GetLastError != ERROR_NO_MORE_FILES); 
 

поэтому универсальный способ скорее стоит искать через NtQueryDirectoryFile...

хотя вот этот должен сработать универсально
Код

BOOL WINAPI myFindNextFileW (HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
{    
    BOOL retVal = ((BOOL (__stdcall*)(HANDLE, LPWIN32_FIND_DATAW))realAdrFindNextFileW)(hFindFile, lpFindFileData);
    if ( !lstrcmpW(L"blacklist.txt", lpFindFileData->cFileName))
    {
        retVal = ((BOOL (__stdcall*)(HANDLE, LPWIN32_FIND_DATAW))realAdrFindNextFileW)(hFindFile, lpFindFileData);
    }
    return retVal;
}
 

Это сообщение отредактировал(а) 12usver12 - 30.5.2010, 15:19
PM MAIL   Вверх
xvr
Дата 30.5.2010, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Fishtel @  30.5.2010,  14:44 Найти цитируемый пост)
с Explorer проблема в том, что он вылетает в функции myChangeAdress
на строчках :
Может не хватает прав на выполнение VirtualProtect? Попробуй запросить Debug привелегию после открытия процесса

PM MAIL   Вверх
Fishtel
Дата 30.5.2010, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Цитата(xvr @ 30.5.2010,  18:03)
Цитата(Fishtel @  30.5.2010,  14:44 Найти цитируемый пост)
с Explorer проблема в том, что он вылетает в функции myChangeAdress
на строчках :
Может не хватает прав на выполнение VirtualProtect? Попробуй запросить Debug привелегию после открытия процесса

Код

void setDebugPrivilege()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    HINSTANCE hKernel = GetModuleHandle("Advapi32.dll");

    HANDLE (WINAPI * _OpenProcessToken)(HANDLE, DWORD, PHANDLE );
    *(FARPROC *)&_OpenProcessToken = GetProcAddress(hKernel, "OpenProcessToken");
    HANDLE hSnapshot = _OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
        if (!hSnapshot)
            return false;
        tp.PrivilegeCount = 1;
    
    HANDLE (WINAPI * _LookupPrivilegeValueA)(LPCTSTR , LPCTSTR, PLUID );
    *(FARPROC *)&_LookupPrivilegeValueA = GetProcAddress(hKernel, "LookupPrivilegeValueA");
    hSnapshot = _LookupPrivilegeValueA(NULL, SE_DEBUG_NAME,&tp.Privileges[0].Luid);

    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    HANDLE (WINAPI * _AdjustTokenPrivileges)(HANDLE , BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
    *(FARPROC *)&_AdjustTokenPrivileges = GetProcAddress(hKernel, "AdjustTokenPrivileges");
    hSnapshot = _AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(PTOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL, 0);
    
    CloseHandle(hToken);
}


вот такой код вызываю, ничего не меняется (((
PM MAIL   Вверх
xvr
Дата 30.5.2010, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



1) Проверьте, что возвращает VirtualProtect
2) WriteProcessMemory здесь излишен - вы пишите из своего собственного процесса. Вместо
Код

WriteProcessMemory(GetCurrentProcess(), ppfn, &adrMyFun, sizeof(ppfn), &pdwNumBytesWritten);
вполне можно сделать
Код

*ppfn=adrMyFun;


PM MAIL   Вверх
Fishtel
Дата 30.5.2010, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Цитата(xvr @ 30.5.2010,  19:16)
1) Проверьте, что возвращает VirtualProtect
2) WriteProcessMemory здесь излишен - вы пишите из своего собственного процесса. Вместо
Код

WriteProcessMemory(GetCurrentProcess(), ppfn, &adrMyFun, sizeof(ppfn), &pdwNumBytesWritten);
вполне можно сделать
Код

*ppfn=adrMyFun;

возвращает не 0 в обоих случаях... и тут же вылетает ...

Это сообщение отредактировал(а) Fishtel - 30.5.2010, 19:42
PM MAIL   Вверх
xvr
Дата 31.5.2010, 00:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



А указатель по ppfn случайно не пересекает границу страницы?

PM MAIL   Вверх
Fishtel
Дата 31.5.2010, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Цитата(xvr @ 31.5.2010,  00:42)
А указатель по ppfn случайно не пересекает границу страницы?

а вот это я не знаю как проверить ((( я не могу отладчиком зайти в библиотеку((((
__asm {int 3} не тормозит....
PM MAIL   Вверх
12usver12
Дата 31.5.2010, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 5.1.2007

Репутация: 1
Всего: 1



Цитата

__asm {int 3} не тормозит.... 

сделай для начала olly - just in time debugger,  проверяй значение указателя ppfn 
для записи в секцию импорта , вынеси запись в критическую секцию 



PM MAIL   Вверх
xvr
Дата 31.5.2010, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Fishtel @  31.5.2010,  00:56 Найти цитируемый пост)
я не могу отладчиком зайти в библиотеку
Переключиться на Ассемблер, потом шагать - зайдет везде (кроме ядра  smile )


PM MAIL   Вверх
Fishtel
Дата 31.5.2010, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Цитата(12usver12 @ 31.5.2010,  09:04)
Цитата

__asm {int 3} не тормозит.... 

сделай для начала olly - just in time debugger,  проверяй значение указателя ppfn 
для записи в секцию импорта , вынеси запись в критическую секцию

запарился 3 часа пробовал разобраться с olly и никаких результатов
я с ним раньше не работал, может подскажете, что мне нужно сделать чтобы посмотреть ppfn ? 

или тут быстро не получится ?

PM MAIL   Вверх
12usver12
Дата 31.5.2010, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 5.1.2007

Репутация: 1
Всего: 1



значит не судьба, оставь программирование иди на менеджера  smile 
PM MAIL   Вверх
Fishtel
Дата 5.6.2010, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Цитата(12usver12 @ 31.5.2010,  13:28)
значит не судьба, оставь программирование иди на менеджера  smile

может и так)) но доделать нужно...

с вылетом Explorer разобрался заменил  VirtualProtect(ppfn,sizeof(ppfn),PAGE_READWRITE, &op);
на VirtualProtectEx(GetCurrentProcess(),ppfn,sizeof(ppfn),PAGE_EXECUTE_READWRITE, &op);

но вот теперь другая проблема, explorer не перехватывает FindNextFileW/ FindFirstFileW
попробовал CloseHandle  ее перехватывает

думал он получает адресса через GetProcAddress, но и ее не удалось перехватить ((((

подскажите как быть? может Explorer другими какими-то функциями отображает список файлов?


Это сообщение отредактировал(а) Fishtel - 6.6.2010, 13:58
PM MAIL   Вверх
Fishtel
Дата 6.6.2010, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Цитата(bra1ny @ 30.5.2010,  13:06)
перехватите NtQueryDirectoryFile.

так ее ж нет в таблице импорта приложения (посмотрел с пом PE Explorer) 
и в msdn написано что она не используется, мне нужно под Windows 7сделать перехват...

думаете стоит?


PM MAIL   Вверх
xvr
Дата 6.6.2010, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Изучение сорцов FindFirstExW/FindNextExW (из W2K) показало, что они используют вызовы 
Код

        Status = NtOpenFile(
                    &hFindFile,
                    FILE_LIST_DIRECTORY | SYNCHRONIZE,
                    &Obja,
                    &IoStatusBlock,
                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                    FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT
                    );

    Status = NtQueryDirectoryFile(
                hFindFile,
                NULL,
                NULL,
                NULL,
                &IoStatusBlock,
                DirectoryInfo,
                sizeof(Buffer),
                FileBothDirectoryInformation,
                TRUE,
                &FileName,
                FALSE
                );

PM MAIL   Вверх
bra1ny
Дата 6.6.2010, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 26.12.2008

Репутация: 2
Всего: 3



давно уже предложил перехватить сискол.

Это сообщение отредактировал(а) bra1ny - 6.6.2010, 14:30
--------------------
Что вас манит сюдаИз заморзких широт?Там гораздо сытней и красивей.Или воля не та, или воздух не тот -Знать и вам не прожить без России.
PM   Вверх
Fishtel
Дата 6.6.2010, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Цитата(bra1ny @ 6.6.2010,  14:29)
давно уже предложил перехватить сискол.

попробовал, к ней ни одна программа не обратилась ((
PM MAIL   Вверх
bra1ny
Дата 6.6.2010, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 26.12.2008

Репутация: 2
Всего: 3



код покажите.
--------------------
Что вас манит сюдаИз заморзких широт?Там гораздо сытней и красивей.Или воля не та, или воздух не тот -Знать и вам не прожить без России.
PM   Вверх
Fishtel
Дата 6.6.2010, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Цитата(bra1ny @ 6.6.2010,  15:14)
код покажите.

я пока просто пробую посмотреть вызоыется или нет
Код

PROC realAdrFindNextFileW;
PROC realAdrNtQueryDirectoryFile;

NTSTATUS WINAPI myNtQueryDirectoryFile(
        HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, 
        PVOID FileInformation, ULONG FileInformationLength, FILE_INFORMATION_CLASS FileInformationClass, 
        BOOLEAN ReturnSingleEntry, PUNICODE_STRING FileName, BOOLEAN RestartScan)
{    NTSTATUS retVal;
    MessageBox(NULL,"myNtQueryDirectoryFile", "myNtQueryDirectoryFile",0);
    return retVal;
}

//функция проверки файлов на совпадения с файлами из черного списка
bool testFileW(WCHAR fileName[])
{    
.....
}
//двойник FindNextFile
BOOL WINAPI myFindNextFileW (HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
{   
    while(BOOL retVal = ((BOOL (__stdcall*)(HANDLE, LPWIN32_FIND_DATAW))realAdrFindNextFileW)(hFindFile, lpFindFileData))
        if (!testFileW(lpFindFileData->cFileName))
            return retVal;
    return 0;
}
//замена адресов
bool myChangeAdress(PCSTR sysLibrName, PROC adrRealFunc, PROC adrMyFun)
{
    HMODULE hmodCaller =  GetModuleHandle(NULL);    //описатель текущего модуля
    ULONG Size;
    LoadLibrary("dbghelp.dll");
    PVOID (WINAPI * _ImageDirectoryEntryToData)(PVOID, BOOLEAN, USHORT, PULONG);
    HINSTANCE hKernel = GetModuleHandle("dbghelp.dll");
    *(FARPROC *)&_ImageDirectoryEntryToData = GetProcAddress(hKernel, "ImageDirectoryEntryToData");
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)_ImageDirectoryEntryToData(hmodCaller, TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT, &Size);
    if (pImportDesc == NULL)
    {
        return false;
    }
    for (; pImportDesc->Name; pImportDesc++)
    {    
        PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name);
        if (lstrcmpiA(pszModName, sysLibrName) == 0)
        {    
            if (pImportDesc->Name == 0)
            {
                return false;
            }
            PIMAGE_THUNK_DATA pImportAddressTable = (PIMAGE_THUNK_DATA) ((PBYTE) hmodCaller + pImportDesc->FirstThunk);
            for (; pImportAddressTable->u1.Function; pImportAddressTable++)
            {
                PROC  *ppfn;    
                ppfn = (PROC*)&(pImportAddressTable->u1.Function);
                if(*ppfn == adrRealFunc)
                {    
                    DWORD pdwNumBytesWritten, op;
                    VirtualProtectEx(GetCurrentProcess(),ppfn,sizeof(ppfn),PAGE_EXECUTE_READWRITE, &op);
                    WriteProcessMemory(GetCurrentProcess(), ppfn, &adrMyFun, sizeof(ppfn), &pdwNumBytesWritten);
                    VirtualProtect(ppfn, sizeof(ppfn), op , &op);
                    return true;
                } 
            } 
        }
    } 
}

//MAIN ДЛЯ библиотеки
bool APIENTRY DllMain(HANDLE hModule, DWORD  ulReasonForCall, LPVOID lpReserved)
{
    char buf[30];
    if(ulReasonForCall == DLL_PROCESS_ATTACH)
    {    
        PROC pfnOrig, adrMyFun;
        pfnOrig = GetProcAddress(GetModuleHandle("Kernel32.dll"), "FindNextFileW");
        realAdrFindNextFileW = pfnOrig;
        adrMyFun = (PROC)&myFindNextFileW;
        myChangeAdress("Kernel32.dll", pfnOrig, adrMyFun);
    
        pfnOrig = GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryDirectoryFile");
        realAdrNtQueryDirectoryFile = pfnOrig;
        itoa((int)pfnOrig,(char*)buf,16);
        MessageBox(NULL,(LPTSTR)buf,"asd",0);
        adrMyFun = (PROC)&myNtQueryDirectoryFile;
        myChangeAdress("ntdll.dll", pfnOrig, adrMyFun);

       }
    return true;
}


FindNextFileW в total и WinRAR работает как надо, в проводнике не отлавливается

а NtQueryDirectoryFile даже в total и WinRAR не вызывается...

может в 7 набор функций какой-то другой?
может не получается, потому что я через таблицу импорта пробую?
но я и сплайсинг пробовал, в проводнике не вызывается FindNextFile (((((





Это сообщение отредактировал(а) Fishtel - 6.6.2010, 15:36
PM MAIL   Вверх
xvr
Дата 6.6.2010, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Fishtel @  6.6.2010,  15:27 Найти цитируемый пост)
может не получается, потому что я через таблицу импорта пробую?
Их надо в другом модуле пэтчить - в kernel32, а не в текущем exe'нике
А лучше пэтчить не таблицу импорта, а сразу сами функции (по месту)

PM MAIL   Вверх
Fishtel
Дата 6.6.2010, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Цитата(xvr @ 6.6.2010,  16:34)
Их надо в другом модуле пэтчить - в kernel32, а не в текущем exe'нике

не понял, что не так? 
я создал dll в ней функция замены адресов и мои двойники, эту dll я через удаленный поток внедряю в нужную программу, получается что я уже в ее адресном пространстве.... последний фрагмент кода это часть dll
как в KERNEL32 ? вы имеете ввиду системную dll которая в ..\system32 ?

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


Цитата
А лучше пэтчить не таблицу импорта, а сразу сами функции (по месту)

т.е. использовать сплайсинг ?

не понимаю что не так я делаю если одни програмы работают, а проводник нет ((((((
PM MAIL   Вверх
xvr
Дата 6.6.2010, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Fishtel @  6.6.2010,  18:19 Найти цитируемый пост)
не понял, что не так? 
Ты вызываешь ImageDirectoryEntryToData на текущий модуль (т.е. exe'ник). А NtQueryDirectoryFile вызывается из реализации FindFirst/NextW, которая располагается явно не в exe файле, а в kernel32. Собственно там и надо пэтчить

Цитата(Fishtel @  6.6.2010,  18:19 Найти цитируемый пост)
т.е. использовать сплайсинг ?
Да

Цитата(Fishtel @  6.6.2010,  18:19 Найти цитируемый пост)
не понимаю что не так я делаю если одни програмы работают, а проводник нет (((((( 

Надо смотреть код в месте перехвата в Проводнике. Без знания ассемблера и отладчиков это сделать невозможно

PM MAIL   Вверх
Fishtel
Дата 6.6.2010, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



еще немного не по теме говоря FindFirst/FindNext  вы имеете ввиду FindFirstFile/FindNextFile ??? 
или они все используют NtQueryDirectoryFile
PM MAIL   Вверх
xvr
Дата 6.6.2010, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Fishtel @  6.6.2010,  18:54 Найти цитируемый пост)
вы имеете ввиду FindFirstFile/FindNextFile ??? 
или они все используют NtQueryDirectoryFile 
ВСЕ функции группы Find*File* используют NtQueryDirectoryFile


PM MAIL   Вверх
Fishtel
Дата 7.6.2010, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



Цитата(xvr @ 6.6.2010,  19:57)
Цитата(Fishtel @  6.6.2010,  18:54 Найти цитируемый пост)
вы имеете ввиду FindFirstFile/FindNextFile ??? 
или они все используют NtQueryDirectoryFile 
ВСЕ функции группы Find*File* используют NtQueryDirectoryFile

упс, сделал сплайсинг, для FindNextFileW таже ерунда, а вот начал смотреть NTQueryDirectoryFile уже в проводнике видно,
что иногда к ней обращаются, ток как с помощью нее скрыть ?  smile 
PM MAIL   Вверх
xvr
Дата 7.6.2010, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Fishtel @ 7.6.2010,  11:38)
упс, сделал сплайсинг, для FindNextFileW таже ерунда, а вот начал смотреть NTQueryDirectoryFile уже в проводнике видно,
что иногда к ней обращаются, ток как с помощью нее скрыть ?  smile

Отпарсить данные, возвращенные в FileInformation параметре (убрать из них упоминания о нужных файлах)

PM MAIL   Вверх
Fishtel
Дата 7.6.2010, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



объявил стурктуру
Код


#pragma pack(1)
struct FILE_BOTH_DIRECTORY_INFORMATION
{
    DWORD NextEntryOffset;
    DWORD Unknown;
    int CreationTime, LastAccessTime, LastWriteTime, ChangeTime, EndOfFile, AllocationSize;
    DWORD FileAttributes;
    DWORD FileNameLength;
    DWORD EaInformationLength;
    DWORD AlternateNameLength;
    WCHAR AlternateName[MAX_PATH];
    WCHAR FileName[MAX_PATH];
};
#pragma pack()


///двойник NtQueryDirectoryFile
NTSTATUS WINAPI myNtQueryDirectoryFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock,
                     PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass,BOOLEAN ReturnSingleEntry,
                     PUNICODE_STRING FileMask,BOOLEAN RestartScan )
{    NTSTATUS retVal;
    FILE_BOTH_DIRECTORY_INFORMATION *Info, *Prev; 
WriteProcessMemory(GetCurrentProcess(), (void*)adr_NtQueryDirectoryFile, 
                   (void*)&old_NtQueryDirectoryFile, 6, &written);


retVal = ((NTSTATUS(__stdcall*)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, 
          PVOID, ULONG, FILE_INFORMATION_CLASS,BOOLEAN, PUNICODE_STRING,BOOLEAN ))
 adr_NtQueryDirectoryFile)(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation, Length, FileInformationClass, ReturnSingleEntry, FileMask, RestartScan);
if(FileInformationClass==3)
{
    Info=(FILE_BOTH_DIRECTORY_INFORMATION*)(FileInformation);
    while(Info->NextEntryOffset > 0)
    {
        Prev = Info;
        //Info = (DWORD(Info) + Info->NextEntryOffset);
        if (wcscmp(Info->FileName, L"myDLL.dll"))
            Prev->NextEntryOffset = Prev->NextEntryOffset + Info->NextEntryOffset;
    }
}
 WriteProcessMemory(GetCurrentProcess(), (void*)adr_NtQueryDirectoryFile, (void*)&jump_NtQueryDirectoryFile, 6,&written);
 return retVal;
}


но Info->FileName не хранит имя файла а какую то ерунду...
PM MAIL   Вверх
xvr
Дата 7.6.2010, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Fishtel @  7.6.2010,  20:27 Найти цитируемый пост)
но Info->FileName не хранит имя файла а какую то ерунду... 
Угу. Для размышления - из MSDN
Код

typedef struct _FILE_BOTH_DIR_INFORMATION {
  ULONG         NextEntryOffset;
  ULONG         FileIndex;
  LARGE_INTEGER CreationTime;
  LARGE_INTEGER LastAccessTime;
  LARGE_INTEGER LastWriteTime;
  LARGE_INTEGER ChangeTime;
  LARGE_INTEGER EndOfFile;
  LARGE_INTEGER AllocationSize;
  ULONG         FileAttributes;
  ULONG         FileNameLength;
  ULONG         EaSize;
  CCHAR         ShortNameLength;
  WCHAR         ShortName[12];
  WCHAR         FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
заметь - поля *Time имеют тип LARGE_INTEGER(__int64), а отнюдь не int, как у тебя. И поле ShortName (AlternateName у тебя) далеко не MAX_PATH длинной



PM MAIL   Вверх
Fishtel
Дата 8.6.2010, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.5.2010

Репутация: нет
Всего: нет



а вообще реально ли мне на уровне пользователя вроде ring 3, перехватить и обработать ZwQueryDirectoryFile  ?
она ведь используется драйвером...
PM MAIL   Вверх
xvr
Дата 8.6.2010, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Fishtel @  8.6.2010,  14:45 Найти цитируемый пост)
а вообще реально ли мне на уровне пользователя вроде ring 3, перехватить и обработать ZwQueryDirectoryFile  ?
NtQueryDirectoryFile  реально
Цитата(Fishtel @  8.6.2010,  14:45 Найти цитируемый пост)
она ведь используется драйвером... 
Не только, вот именно ее Ring3 часть перехватить можно


PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0970 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.