Благодарен всем заранее за ответы.
Встала задача об отлове копирования файлов. Решений конечно много: хуки, журнал файловой системы, замена самой функции копированя. Вот я и решил выбрать последний вариант... В 2005 году была опубликована статья Перехват API-функций в Windows NT_2000_XP, вот в ней расказывался метод внедрения DLL в процесс с последующей заменой почти любой функции на свою(храняшуюся в той же dll). Как бы с этим проблем нет, dll внедряется, функции заменяются(Замена нужна бля того, чтобы перед началом копированя показать диалог с запросом пароля, и если пароль верен продолжить копирование), всё как бы работает, если учесть что внедрение происходит в процесс мной написаной программы

. Но появилась проблема внедрения в процесс explorer.exe(ибо как я понимаю, за копирование файлов в Windows отвечает именно этот процесс) т.к. этот процесс не содержит .idata.
Вопросы:
1) Что я делаю нетак?
2) Есть ли какие нибудь другие методы отлова и замены копированя файлов?
Код Dll
//------------DLL----------------------
#define _WIN32_WINNT 0x4000
// Dll_for_hook.cpp : Defines the entry point for the DLL application.
//
#define RASSWORD "111"
#include "StdAfx.h"
#include "resource.h"
char szPass[MAX_PATH]; //Буфер для пароля
DWORD adr_i_CopyFileExA;
HINSTANCE hInstance = NULL;
BOOL CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL WINAPI i_CopyFileExA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
LPVOID lpData OPTIONAL, LPBOOL pbCancel OPTIONAL, DWORD dwCopyFlags );
void InterceptFunctions(void);
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
hInstance = (HINSTANCE)hModule;
if(ul_reason_for_call == DLL_PROCESS_ATTACH)
InterceptFunctions();
return TRUE;
}
// Эта функция ищет в таблице импорта - .idata нужный адрес и меняет на
// адрес процедуры-двойника
void InterceptFunctions(void)
{
// Начало отображения в памяти процесса
BYTE *pimage = (BYTE*)GetModuleHandle(NULL);
BYTE *pidata;
// Стандартные структуры описания PE заголовка
IMAGE_DOS_HEADER *idh;
IMAGE_OPTIONAL_HEADER *ioh;
IMAGE_SECTION_HEADER *ish;
IMAGE_IMPORT_DESCRIPTOR *iid;
DWORD *isd; //image_thunk_data dword
// Получаем указатели на стандартные структуры данных PE заголовка
idh = (IMAGE_DOS_HEADER*)pimage;
ioh = (IMAGE_OPTIONAL_HEADER*)(pimage + idh->e_lfanew
+ 4 + sizeof(IMAGE_FILE_HEADER));
ish = (IMAGE_SECTION_HEADER*)((BYTE*)ioh + sizeof(IMAGE_OPTIONAL_HEADER));
//если не обнаружен магический код, то у этой программы нет PE заголовка
if (idh->e_magic != 0x5A4D)
{
MessageBox(NULL, "Not exe hdr", "Error!", 0);
return;
}
//ищем секцию .idata
for(int i=0; i<16; i++)
if(strcmp((char*)((ish+ i)->Name) , ".idata") == 0) break;
if(i==16)
{
MessageBox(NULL, "Unable to find .idata section", "Error!", 0);
return;
}
// Получаем адрес секции .idata(первого элемента IMAGE_IMPORT_DESCRIPTOR)
iid = (IMAGE_IMPORT_DESCRIPTOR*)(pimage + (ish +i)->VirtualAddress );
// Получаем абсолютный адрес функции для перехвата
adr_i_CopyFileExA = (DWORD)GetProcAddress(
GetModuleHandle("KERNEL32.dll"), "CopyFileExA");
if(adr_i_CopyFileExA == 0)
{
MessageBox(NULL, "Can`t get adr_i_CopyFileExA", "Error!", 0);
return;
}
// В таблице импорта ищем соответствующий элемент для
// библиотеки user32.dll
while(iid->Name) //до тех пор пока поле структуры не содержит 0
{
if(strcmp((char*)(pimage + iid->Name), "KERNEL32.dll") ==0 ) break;
iid++;
}
// Ищем в IMAGE_THUNK_DATA нужный адрес
isd = (DWORD*)(pimage + iid->FirstThunk);
while(*isd!=adr_i_CopyFileExA && *isd!=0) isd++;
if(*isd == 0)
{
MessageBox(NULL, "CopyFileExA not found in .idata", "Error!", 0);
return;
}
// Заменяем адрес на свою функцию
DWORD buf = (DWORD)&i_CopyFileExA;
DWORD op, writen;
// Обычно страницы в этой области недоступны для записи
// поэтому принудительно разрешаем запись
VirtualProtect((void*)(isd),4,PAGE_READWRITE, &op);
// Пишем новый адрес
WriteProcessMemory(GetCurrentProcess(), (void*)(isd),
(void*)&buf,4,&writen);
//восстанавливаем первоначальную защиту области по записи
VirtualProtect((void*)(isd),4,op, &op);
//если записать не удалось – увы, все пошло прахом…
if(writen!=4)
{
MessageBox(NULL, "Unable rewrite address", "Error!", 0);
return;
}
}
BOOL CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg){
case WM_INITDIALOG:
SetDlgItemText(hDlg, IDC_EDIT1, "Enter_Pass");
case WM_COMMAND:
switch(LOWORD(wParam)){
case IDC_BUTTON1:
GetDlgItemText(hDlg, IDC_EDIT1, szPass, MAX_PATH);
if(szPass != "111"){ // Знаю что эта стока в данном случае не несёт никакого смысла
MessageBox(hDlg, "Пароль не верен, копирование прекращёно", "Error", MB_OK);
EndDialog(hDlg, TRUE);
return false;
}
else return true;
}
}
return 0;
}
BOOL WINAPI i_CopyFileExA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
LPVOID lpData OPTIONAL, LPBOOL pbCancel OPTIONAL, DWORD dwCopyFlags)
{
//здесь вы выполняете любые свои действия
//-----------------------------------------------------------------------------------------------
// if( !DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc) ) return TRUE;
//-----------------------------------------------------------------------------------------------
// вызываем оригинальную функцию через указатель
MessageBox(NULL, "Пароль не верен, копирование прекращёно", "Error", MB_OK);
((BOOL (__stdcall*)(LPCSTR, LPCSTR, LPPROGRESS_ROUTINE, LPVOID, LPBOOL, DWORD))adr_i_CopyFileExA)(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, pbCancel, dwCopyFlags);
return TRUE;
}
Я и не спорю... Но всётаки как найти выход из положения подмены функции?
Здравствуйте, Strann1k, Вы писали:
[]
S>появилась проблема внедрения в процесс explorer.exe(ибо как я понимаю, за копирование файлов в Windows отвечает именно этот процесс) т.к. этот процесс не содержит .idata.
Вам нужен
каталог импорта, значит следует смотреть в IMAGE_OPTIONAL_HEADER (например, используя ImageDirectoryEntryToData). Закладываться на имена
секций нельзя, поскольку секции могут быть объеденены, да и нигде не написано, в каком месте секции должен быть расположен каталог.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
А может быть кто-нибудь сталкивался с такой проблемой? Хотелось бы послушать иные решения этой проблемы.