Inel Опубликовано 7 сентября, 2007 Жалоба Share Опубликовано 7 сентября, 2007 У кого нибудь проверенный рабочий исходник есть? А то, я уже запарился. Ссылка на комментарий Поделиться на другие сайты More sharing options...
Marik Опубликовано 8 сентября, 2007 Жалоба Share Опубликовано 8 сентября, 2007 Inel А конкретнее? Какую фукнцию перехватить нужно? Ссылка на комментарий Поделиться на другие сайты More sharing options...
NiCrome Опубликовано 9 сентября, 2007 Жалоба Share Опубликовано 9 сентября, 2007 Да хотябы уточни о каком АПИ речь. Их знаешь ли тысячи. Ссылка на комментарий Поделиться на другие сайты More sharing options...
Inel Опубликовано 10 сентября, 2007 Автор Жалоба Share Опубликовано 10 сентября, 2007 Да какая разница какую API функцию перехватывать,принцип-то один и тот-же. Собственно разобрался как перехватить API с помощью таблицы импорта. Пробовал в своем проекте(то-есть в своем процессе).все работает. Написал DLL.А вот как внедрить в чужой процесс,незнаю. Подскажите плиз! Ссылка на комментарий Поделиться на другие сайты More sharing options...
Inel Опубликовано 10 сентября, 2007 Автор Жалоба Share Опубликовано 10 сентября, 2007 Вот DLL: #include "stdafx.h" DWORD adr_MessageBoxA; unsigned long written; void InterceptFunctions(void); BOOL WINAPI Intercept_MessageBoxA(HWND hwnd, char *text, char *hdr, UINT utype); BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { 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_MessageBoxA = (DWORD)GetProcAddress( GetModuleHandle("user32.dll"), "MessageBoxA"); if(adr_MessageBoxA == 0) { MessageBox(NULL, "Can`t get addr_MessageBoxA", "Error!", 0); return; } // В таблице импорта ищем соответствующий элемент для // библиотеки user32.dll while(iid->Name) //до тех пор пока поле структуры не содержит 0 { if(strcmp((char*)(pimage + iid->Name), "USER32.dll") ==0 ) break; iid++; } // Ищем в IMAGE_THUNK_DATA нужный адрес isd = (DWORD*)(pimage + iid->FirstThunk); while(*isd!=adr_MessageBoxA && *isd!=0) isd++; if(*isd == 0) { MessageBox(NULL, "adr_MessageBoxA not found in .idata", "Error!", 0); return; } // Заменяем адрес на свою функцию DWORD buf = (DWORD)&Intercept_MessageBoxA; DWORD op; // Обычно страницы в этой области недоступны для записи // поэтому принудительно разрешаем запись VirtualProtect((void*)(isd),4,PAGE_READWRITE, &op); // Пишем новый адрес WriteProcessMemory(GetCurrentProcess(), (void*)(isd), (void*)&buf,4,&written); //восстанавливаем первоначальную защиту области по записи VirtualProtect((void*)(isd),4,op, &op); //если записать не удалось – увы, все пошло прахом… if(written!=4) { MessageBox(NULL, "Unable rewrite address", "Error!", 0); return; } } BOOL WINAPI Intercept_MessageBoxA(HWND hwnd, char *text, char *hdr, UINT utype) { //здесь вы выполняете любые свои действия char *str = "Hi From MessageBOX!!!!"; // вызываем оригинальную функцию через указатель ((BOOL (__stdcall*)(HWND, char*, char*, UINT))adr_MessageBoxA)(hwnd, str, hdr, utype); return TRUE; } А вот функция внедрения: //структура описывает поля, в которых содержится код внедрения struct INJECTORCODE { BYTE instr_push_loadlibrary_arg; //инструкция push DWORD loadlibrary_arg; //аргумент push WORD instr_call_loadlibrary; //инструкция call [] DWORD adr_from_call_loadlibrary; BYTE instr_push_exitthread_arg; DWORD exitthread_arg; WORD instr_call_exitthread; DWORD adr_from_call_exitthread; DWORD addr_loadlibrary; DWORD addr_exitthread; //адрес функции ExitTHread BYTE libraryname[100]; //имя и путь к загружаемой библиотеке }; BOOL InjectDll(DWORD pid, char *lpszDllName) { HANDLE hProcess; BYTE *p_code; INJECTORCODE cmds; DWORD wr, id; //открыть процесс с нужным доступом hProcess=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE| PROCESS_VM_OPERATION, FALSE, pid); if(hProcess == NULL) { MessageBoxA(NULL, "You have not enough rights to attach dlls", "Error!", 0); return FALSE; } //зарезервировать память в процессе p_code = (BYTE*)VirtualAllocEx(hProcess, 0, sizeof(INJECTORCODE), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(p_code==NULL) { MessageBox(NULL, "Unable to alloc memory in remote process", "Error!", 0); return FALSE; } //инициализировать машинный код cmds.instr_push_loadlibrary_arg = 0x68; //машинный код инструкции push cmds.loadlibrary_arg = (DWORD)((BYTE*)p_code + offsetof(INJECTORCODE, libraryname)); cmds.instr_call_loadlibrary = 0x15ff; //машинный код инструкции call cmds.adr_from_call_loadlibrary = (DWORD)(p_code + offsetof(INJECTORCODE, addr_loadlibrary)); cmds.instr_push_exitthread_arg = 0x68; cmds.exitthread_arg = 0; cmds.instr_call_exitthread = 0x15ff; cmds.adr_from_call_exitthread = (DWORD)(p_code + offsetof(INJECTORCODE, addr_exitthread)); cmds.addr_loadlibrary = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); cmds.addr_exitthread = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"ExitThread"); if(strlen(lpszDllName)>99) { MessageBox(NULL, "Dll Name too long", "Error!", 0); return FALSE; } strcpy((char*)cmds.libraryname, lpszDllName ); /*После инициализации cmds в мнемонике ассемблера выглядит следующим образом: push adr_library_name ;аргумент ф-ции loadlibrary call dword ptr [loadlibrary_adr] ; вызвать LoadLibrary push exit_thread_arg ;аргумент для ExitThread call dword ptr [exit_thread_adr] ;вызвать ExitThread */ //записать машинный код по зарезервированному адресу WriteProcessMemory(hProcess, p_code, &cmds, sizeof(cmds), &wr); //выполнить машинный код HANDLE z = CreateRemoteThread(hProcess, NULL, 0, (unsigned long (__stdcall *)(void *))p_code, 0, 0, &id); //ожидать завершения удаленного потока WaitForSingleObject(z, INFINITE); //освободить память VirtualFreeEx(hProcess, (void*)p_code, sizeof(cmds), MEM_RELEASE); return TRUE; } При выполнии машинного кода HANDLE z = CreateRemoteThread(hProcess, NULL, 0, (unsigned long (__stdcall *)(void *))p_code, 0, 0, &id); Прога (в которую я внедряю DLL)вылетает с ошибкой. Кстати описано ,что при компиляции ,надо указать компилятору ,что-бы он выравнивал структуры побайтово. Где это указывается в Visual Studio 6. Может в этом вся проблема? Ссылка на комментарий Поделиться на другие сайты More sharing options...
Romses Опубликовано 10 сентября, 2007 Жалоба Share Опубликовано 10 сентября, 2007 Фуууу... Сии.... ну ты и Садист Ссылка на комментарий Поделиться на другие сайты More sharing options...
Inel Опубликовано 11 сентября, 2007 Автор Жалоба Share Опубликовано 11 сентября, 2007 Romses ,обоснуй. Ссылка на комментарий Поделиться на другие сайты More sharing options...
Marik Опубликовано 11 сентября, 2007 Жалоба Share Опубликовано 11 сентября, 2007 Inel По субжу вечером посмотрю код, подумаю. Но в целом, умные люди на RSDN встречаются и задачи подобные уже рассмотрены там. Про выравнивание побайтное: Project->Properties->C/C++->Code Generation->Struct Member Alignment->1 Byte (или просто параметр компилятору /Zp1) Romses Флудер Ссылка на комментарий Поделиться на другие сайты More sharing options...
Marik Опубликовано 11 сентября, 2007 Жалоба Share Опубликовано 11 сентября, 2007 Inel Еще вспомнил с лету. Для внедрения в адресное пространство чужого процесса кажется надо изменять права доступа к этой памяти, иначе не получится изменить таблицу импорта. Ссылка на комментарий Поделиться на другие сайты More sharing options...
Inel Опубликовано 14 сентября, 2007 Автор Жалоба Share Опубликовано 14 сентября, 2007 Marik,СПАСИБО! Решил проблему методом сплайсинга и жестким внедрением. Ссылка на комментарий Поделиться на другие сайты More sharing options...
Рекомендуемые сообщения
Заархивировано
Эта тема находится в архиве и закрыта для дальнейших ответов.