Нашел в инете пример: Код (Text): BOOL Inject(HANDLE hProc,DWORD(WINAPI* func)(LPVOID)) { DWORD id; DWORD ByteOfWriten; HMODULE hModule = GetModuleHandle(NULL); DWORD size=((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE*)(hModule)+((PIMAGE_DOS_HEADER)(hModule))->e_lfanew+sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER))))->SizeOfImage; char* hNewModule = (char*)VirtualAllocEx(hProc,hModule,size, MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); if(hNewModule==NULL) return false; WriteProcessMemory(hProc,hNewModule,hModule,size,&ByteOfWriten); if(ByteOfWriten!=size){return false;} HANDLE hThread=CreateRemoteThread(hProc,NULL,0,func,(LPVOID)hNewModule,0,&id); if(hThread==0) return false; return true; } вообщем вызов этой функции возвращает false ... может кто предположить может почему?
Код (Text): hModule = GetModuleHandle(NULL); Афигеть, никодна не понимал такого, ведь двух инструкций достаточно: Код (Text): mov eax,fs:[0x30] mov eax,dword ptr [eax + 0x8] Хотя заюзать GetProcAddress("GetModuleHandle") будет вобще чудесно..
Clerk 1) Стиль программирования. Если среди чистого WinApi-кода будут asm-вставки с константами, то 1) красоты коду это не сделает 2) его сложнее поддерживать 3) его сложнее редактировать. По этому пункту все-таки советую тебе почитать что-нибудь по эффективному программированию. Ведь программы люди не только для себя пишут, и не только в одиночку. 2) Кроссплаформенность. Для переноса хорошо написанной С-программы достаточно перекомпила, твою же прогу с асм-вставками надо будет переписывать. 3) Недокументированность. Если что-то не указывается в документации, то есть возможность, что вскоре, в следующей версии операционной системы программа работать не будет. А ведь есть проги, которые работают и через 10 лет! А все из-за того, что они юзали только документированные структуры и функции. Документированные - означает, что описаны в официальной документации по интерфейсу.
Да! спасибо! Теперь функция выполняется, но выскакивает ошибка ... то памят не может быть READ, то WRITE ... видимо ссылаемся на занятую область памяти. Как сместить? Ну или как найти пустое место для размещения моего кода? Может статью какую подскажете, где для дураков расписана методика ...
Код (Text): char* hNewModule = (char*)VirtualAllocEx(hProc, /*hModule*//*NULL*/"/BASE:0x13140000", size, MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); Как я тока не изголялся уже над этой строчкой ... в таком варианте снова не выполняется, с NULL ошибка, но хоть функция выполняется
BadLogin Если хочешь домучить этот "дурной пример", то нужно посмотреть распределение памяти в подопытном процессе (например, через OllyDbg) и затем изменить ImageBase своей проги так, чтобы он приходился на незанятую область памяти в целевом процессе. А лучше ес-но делать код внедряемой функции базонезависимым (тогда под нее можно будет выделять память в любом месте) и при необходимости подгружать свою dll к целевому процессу
подключить dll у меня уже получилось! Мне для диплома нужно именно ПЗ в машинном коде, чтобы она была видна в дампе памяти, как часть кода =)) я вообщем то понимал это и ранее,leo, у меня это не получается =( Есть ли где статья про поиск места в машинном коде, и как сместить базу? я пытался ... выше в примере видно Код (Text): "/BASE:0x13140000" функция возвращает False (
Инструкция по адресу "0x004013f8" обратилась к памяти по адресу "0x00000000". Память не может быть "writen". ________________________ Зато функция выполняется =)
BadLogin Чудак-человек, ImageBase нужно задавать в опциях своего компилятора. Тогда в твоем экзешнике значение hModule будет равно значению этой заданной базы и если этот адрес не будет занят в подопытном процессе, то VirtualAllocEx(hProc,hModule,..) отработает нормально
PS: Все равно код дурной и работать не будет, т.к. CreateRemouteThread передает управление на адрес hModule, по которому расположен не исполняемый код, а PE заголовок. Если тупо сместить адрес на какую-нибудь функцию, то наверняка возникнут проблемы с вызовом импортируемых функций и т.д. и т.п. Поэтому проще выкинуть этот пример на помойку и сделать по человечески
Код (Text): #pragma comment (linker,"/BASE:0xFFFFFF00") пробывал ещё разные значения, всё равно не работает.
Код (Text): #include < windows.h> #include < tlhelp32.h> #pragma comment(linker,"/BASE:0x13140000") // сдвигаем базу нашего процесса // ------- тут как обычно описываем прототипы функций -------- DWORD GetProcessID(char*); BOOL Inject(HANDLE,DWORD(WINAPI* func)(LPVOID)); DWORD WINAPI func(LPVOID); //-------- главная функция.... вопросов возникнуть не должно :-) --------- int WINAPI WinMain(HINSTANCE,HINSTANCE,LPTSTR,int) { if(!Inject(OpenProcess(PROCESS_ALL_ACCESS,false,GetProcessID("explorer.exe")),&func)) return false; return true; } //-------- а вот это та самая функция, которая будет выполнять наши, ------- //-------- конечно же, доброжелательные действия в --------------------- //-------- чужом адресном пространстве :-)) --------------------------- DWORD WINAPI func(LPVOID) { LoadLibrary("kernel32.dll"); // нам необходимо подгрузить жертве в процесс LoadLibrary("user32.dll"); // требуемые нам библиотеки (их может и не быть изначально) SYSTEMTIME SysTime; GetSystemTime(&SysTime); WORD time=SysTime.wSecond+30; while(time!=SysTime.wSecond){GetSystemTime(&SysTime);} MessageBox(0,"Hello from addres area of explorer","title",0); return true; } //-------- в поисках нашей жертвы --------- DWORD GetProcessID(char* lpNameProcess) // в параметрах передаем имя процесса жертвы { HANDLE snap; PROCESSENTRY32 pentry32; snap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if(snap==INVALID_HANDLE_VALUE) return 0; pentry32.dwSize=sizeof(PROCESSENTRY32); if(!Process32First(snap,&pentry32)) {CloseHandle(snap);return 0;} do { if(!lstrcmpi(lpNameProcess,&pentry32.szExeFile[0])) { CloseHandle(snap); return pentry32.th32ProcessID; // вот наша жертва для внедрения кода;-) } }while(Process32Next(snap,&pentry32)); CloseHandle(snap); return 0; } //-------- функция внедрения в пространство жертвы ------------------- BOOL Inject(HANDLE hProc,DWORD(WINAPI* func)(LPVOID)) { DWORD id; DWORD ByteOfWriten; HMODULE hModule = GetModuleHandle(NULL); DWORD size=((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE*)(hModule)+((PIMAGE_DOS_HEADER)(hM odule))->e_lfanew+sizeof(DWORD)+ sizeof(IMAGE_FILE_HEADER))))->SizeOfImage; char* hNewModule = (char*)VirtualAllocEx(hProc,hModule,size,MEM_COMMIT|MEM_RESERVE,PAGE _EXECUTE_REA DWRITE); if(hNewModule==NULL) return false; WriteProcessMemory(hProc,hNewModule,hModule,size,&ByteOfWriten); if(ByteOfWriten!=size){return false;} HANDLE hThread=CreateRemoteThread(hProc,NULL,0,func,(LPVOID)hNewModule,0,&id); if(hThread==0) return false; return true; } Вот собственно весь код! если внести изменения: То всё выполняется, но эксплорер выдаёт ошибку: Мне всего то нужно сделать прогу изменяющую машинный код запущенного процесса (произвольные изменения - просто символы может какие вписать) и чтобы это было видно из IDA или чего-нить подобного, ну вообщем, чтобы в дампе были видны эти изменения, а статике не было никаких изменений. Что в этом коде не так? Есть ли ещё примеры для изучения?