проблема с генерацией кода. часть кода идёт с рва, что позволяет потом настраивать через релоки, а часть (хз почему) - через статические адреса. сам код Код (Text): #include "stdafx.h" #include <windows.h> void test_func() { char msg[] = "iamhere"; MessageBox (NULL, test, test, MB_YESNO); } int _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { test_func(); return 0; } /fixed:no включено. но...часть кода всё равно компилится со стат адресами. в чём причина? как можно оттучить комплиятор от такого поведения?)
loginrl_103 Ты не правильно понимаешь что такое релоки, если код идет с RVA (что не бывает), то релоки никакие не нужны, т.к. надо просто прибавить базу образа. В твоем случае единственный оффсет, для которого нужны релоки это строка, да и к ней можно обратиться базонезависимо.
Еще косвенный вызов апи call dword ptr [__imp_MessageBox@16] и куча других вызовов и переменных в CRT зашитых, взять тот же (Win)mainCRTStartup
IMAGE_SCN_LNK_NRELOC_OVFL ? "Расширенная" секция релоков? Нету. Код (Text): int FixReloc(PVOID Image, DWORD dwDelta) { ... PIMAGE_DOS_HEADER dosI; PIMAGE_NT_HEADERS peI; PIMAGE_BASE_RELOCATION reloc; dosI = (PIMAGE_DOS_HEADER)Image; peI = (PIMAGE_NT_HEADERS) ((DWORD)dosI->e_lfanew + (DWORD)dosI); reloc = (PIMAGE_BASE_RELOCATION)((DWORD)peI->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + (DWORD)Image); DWORD dwOffset, SmallOffset; printf ("Image in our proc: %x\n", Image); printf ("reloc: %x\n", reloc); printf ("VirtualAddress: %x\n", reloc->VirtualAddress); .... } Image - буффер с экзешником (createfile/virtualalloc/readfile). При работе показывает, что Image = reloc, те peI->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = ...0 ! Но релоки в тестовом экзешнике есть (тулза их видит)...Откуда там 0 ??? ...
Смотрел) Выше писал)...Проблема решилась...Я для теста пытался запихнуть блокнот в блокнот...в блокноте релоков НЕТУ )) Убрать забыл( Время потрачено "с толком"...)
Код (Text): ... int main() { HANDLE insF = CreateFileA ("E:\\test.exe", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if (insF == INVALID_HANDLE_VALUE) return -1; DWORD size_low = GetFileSize (insF, NULL); PVOID prcobuff = VirtualAlloc (NULL, size, MEM_COMMIT, PAGE_READWRITE); DWORD read; if (ReadFile (insF, prcobuff , size, &read, 0) == FALSE) { printf ("error reading file: %d\n", GetLastError()); return 0; } Ins ("notepad.exe", 0, (PTHREAD_START_ROUTINE)((DWORD)prcobuff + 0x1000), (DWORD)prcobuff); return 0; } Код (Text): int Ins(PCHAR ProcName, DWORD PID, PTHREAD_START_ROUTINE RemoteProc, DWORD Base) { GetDebug(); IMAGE_DOS_HEADER * dos; IMAGE_NT_HEADERS *pe; DWORD RetVal = 0, SizeOfImage, tmp; PVOID NewBase, NewImage; HANDLE Proc; PID = FindProcess(ProcName); dos = (IMAGE_DOS_HEADER *) Base; pe = (IMAGE_NT_HEADERS *) ((DWORD) dos->e_lfanew + (DWORD) dos); SizeOfImage = pe->OptionalHeader.SizeOfImage; Proc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, 0, PID); NewBase = VirtualAllocEx(Proc, NULL, SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (Proc && NewBase) { NewImage = VirtualAlloc(NULL, SizeOfImage, MEM_COMMIT, PAGE_READWRITE); memcpy (NewImage, Base, SizeOfImage); //NewImage = (PVOID)Base; FixReloc(NewImage, (DWORD)NewBase - Base); WriteProcessMemory(Proc, NewBase, NewImage, SizeOfImage, &tmp); RemoteProc = (PTHREAD_START_ROUTINE) ((DWORD) RemoteProc - Base + (DWORD) NewBase); printf ("RemoteProc: %x\n", RemoteProc); CreateRemoteThread(Proc, NULL, NULL, RemoteProc, (PVOID)NewBase, NULL, &tmp); Sleep (-1); VirtualFree(NewImage, 0, MEM_RELEASE); RetVal = -1; } CloseHandle(Proc); return RetVal; } // ------------------------------------------------------ void FixReloc(PVOID Image, UINT dwDelta) { PIMAGE_NT_HEADERS pe; PIMAGE_BASE_RELOCATION reloc; DWORD dwOffset, SmallOffset; int i; pe = (PIMAGE_NT_HEADERS) ((DWORD)(((PIMAGE_DOS_HEADER)Image)->e_lfanew) + (DWORD)Image); DWORD delta = (DWORD)Image - (DWORD)pe->OptionalHeader.ImageBase; PIMAGE_FIXUP_BLOCK pfb; pfb = (PIMAGE_FIXUP_BLOCK)RVATOVA(Image, pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); PIMAGE_FIXUP_BLOCK startpfb = pfb; if((delta == 0) || (pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size == 0)) return; while(((DWORD)(((char *)pfb)-((char *)startpfb))) < pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size) { PIMAGE_FIXUP_ENTRY pfe; int count; count = 0; printf ("dwBlockSize: %x\n", pfb->dwBlockSize); printf ("dwPageRVA: %x\n", pfb->dwPageRVA); if(pfb->dwBlockSize > 0) { count = (pfb->dwBlockSize - sizeof(IMAGE_FIXUP_BLOCK)) / sizeof(IMAGE_FIXUP_ENTRY); pfe = (PIMAGE_FIXUP_ENTRY)(((char *)pfb) + sizeof(IMAGE_FIXUP_BLOCK)); } else { pfb= (PIMAGE_FIXUP_BLOCK)(((char *)pfb) + sizeof(IMAGE_FIXUP_BLOCK)); continue; } for(i=0; i < count; i++) { printf ("change reloc\n"); void *fixaddr; fixaddr= (void *)RVATOVA(Image, pfb->dwPageRVA + pfe->offset); switch(pfe->type) { case IMAGE_REL_BASED_ABSOLUTE: break; case IMAGE_REL_BASED_HIGH: *((WORD *)fixaddr) += HIWORD(delta); break; case IMAGE_REL_BASED_LOW: *((WORD *)fixaddr) += LOWORD(delta); break; case IMAGE_REL_BASED_HIGHLOW: *((DWORD *)fixaddr) += delta; break; case IMAGE_REL_BASED_HIGHADJ: // This one's really fucked up. { DWORD adjust; adjust=((*((WORD *)fixaddr)) << 16) | (*(WORD *)(pfe+1)); adjust += delta; adjust += 0x00008000; *((WORD *)fixaddr) = HIWORD(adjust); } pfe++; break; default: return; } pfe++; } pfb=(PIMAGE_FIXUP_BLOCK)((char *)pfb + pfb->dwBlockSize); } } test.exe - скомпиляный код в самом первом посте. С релоками. Сначала грешил на кривой код FixReloc - потому взял этот из BO...Если в код программы, впихивающей ехе, определить простой messagebox и попробовать внедрить её прямо из памяти - всё проходит отлично. Но если брать образ с диска и его пытаться..то чорти что.
Хм...Считать надо с файловым оффсетом...Теперь все релоки видятся и отображаются правильно)...Жду следующих проблем)