Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > перехват FindNextFile для Windows NT(Windows 7)


Автор: Fishtel 29.5.2010, 19:28
Здравствуйте, помогите решить задачу. Пишу программку для скрытия файлов(папок) для 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;
    }
}



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

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

Автор: 12usver12 30.5.2010, 11:11
попробуй таким способом

Код

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;
   
}


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

Автор: Fishtel 30.5.2010, 11:58
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, все ок

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

Автор: bra1ny 30.5.2010, 13:06
перехватите NtQueryDirectoryFile.

Автор: 12usver12 30.5.2010, 13:10
Цитата

Код

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


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

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

Автор: xvr 30.5.2010, 13:36
Цитата(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 нормально перехвачен?

Автор: 12usver12 30.5.2010, 14:26
Цитата

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

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

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

Автор: Fishtel 30.5.2010, 14:44
с 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 нормально перехвачен?


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

Автор: 12usver12 30.5.2010, 14:48
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;
}
 

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

Автор: Fishtel 30.5.2010, 19:09
Цитата(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);
}


вот такой код вызываю, ничего не меняется (((

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

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

*ppfn=adrMyFun;


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

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

*ppfn=adrMyFun;

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

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

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

а вот это я не знаю как проверить ((( я не могу отладчиком зайти в библиотеку((((
__asm {int 3} не тормозит....

Автор: 12usver12 31.5.2010, 09:04
Цитата

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

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



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


Автор: Fishtel 31.5.2010, 11:50
Цитата(12usver12 @ 31.5.2010,  09:04)
Цитата

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

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

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

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

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

Автор: Fishtel 5.6.2010, 22:35
Цитата(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:50
Цитата(bra1ny @ 30.5.2010,  13:06)
перехватите NtQueryDirectoryFile.

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

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


Автор: xvr 6.6.2010, 14:07
Изучение сорцов 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
                );

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

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

попробовал, к ней ни одна программа не обратилась ((

Автор: bra1ny 6.6.2010, 15:14
код покажите.

Автор: Fishtel 6.6.2010, 15:27
Цитата(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 (((((




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

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

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

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


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

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

не понимаю что не так я делаю если одни програмы работают, а проводник нет ((((((

Автор: xvr 6.6.2010, 18:25
Цитата(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 Найти цитируемый пост)
не понимаю что не так я делаю если одни програмы работают, а проводник нет (((((( 

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

Автор: Fishtel 6.6.2010, 18:54
еще немного не по теме говоря FindFirst/FindNext  вы имеете ввиду FindFirstFile/FindNextFile ??? 
или они все используют NtQueryDirectoryFile

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


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

упс, сделал сплайсинг, для FindNextFileW таже ерунда, а вот начал смотреть NTQueryDirectoryFile уже в проводнике видно,
что иногда к ней обращаются, ток как с помощью нее скрыть ?  smile 

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

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

Автор: Fishtel 7.6.2010, 20:27
объявил стурктуру
Код


#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 не хранит имя файла а какую то ерунду...

Автор: xvr 7.6.2010, 22:39
Цитата(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 длинной



Автор: Fishtel 8.6.2010, 14:45
а вообще реально ли мне на уровне пользователя вроде ring 3, перехватить и обработать ZwQueryDirectoryFile  ?
она ведь используется драйвером...

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


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)