Модераторы: 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   Вверх
Страницы: (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.0677 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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