пытаюсь перенести таблицу импорта в область заголовка, файл становится невалидным. неужели таблица импорта обязательно должна быть в какой-то секции?
т.е. таблица импорта может быть в заголовке? код: Код (Text): int AddDllToPE2(char *szTargetFile,char *szDllName) { HANDLE hFile,hFileMap; char *pBase,*pPE; IMAGE_OPTIONAL_HEADER *pOptHeader; DWORD nSections; int i; IMAGE_SECTION_HEADER *pSection; DWORD dwImportRVA,dwImportSize; IMAGE_IMPORT_DESCRIPTOR *pImport; hFile=CreateFile( szTargetFile,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0); if(INVALID_HANDLE_VALUE==hFile)return 0; hFileMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE|SEC_COMMIT,0,0,NULL); if(0==hFileMap)return 0; CloseHandle(hFile); pBase=(char*)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,0,0,0); if(0==pBase)return 0; __try { //analysing pPE=pBase+*(LPDWORD)(pBase+0x3C); nSections=*(LPWORD)(pPE+0x06); pOptHeader=(IMAGE_OPTIONAL_HEADER*)(pPE+0x18); dwImportRVA=pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; dwImportSize=pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size; pSection=(IMAGE_SECTION_HEADER*)(pPE+0x18+0xE0); for(i=0;i<nSections;i++){ pImport=(IMAGE_IMPORT_DESCRIPTOR*)(pBase+dwImportRVA-pSection->VirtualAddress+pSection->PointerToRawData); if( (dwImportRVA>=pSection->VirtualAddress) && (dwImportRVA<pSection->VirtualAddress+pSection->SizeOfRawData) ) break; pSection++; } //============== patching ================== //redirecting import pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress=0xE00; pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size=dwImportSize+20; //copying import table CopyMemory(pBase+0xE00,pImport,dwImportSize); //adding new item pImport=(IMAGE_IMPORT_DESCRIPTOR*)(pBase+0xE00+dwImportSize-20); pImport->Name = 0xE00 + 0x1E0; pImport->FirstThunk = 0xE00 + 0x1F0; //writing name and function ordinal CopyMemory(pBase+0xFE0,szDllName,strlen(szDllName)); *(LPDWORD)(pBase+0xFF0)=0x80000001; } __except(EXCEPTION_EXECUTE_HANDLER) {return 0;} UnmapViewOfFile(pBase); CloseHandle(hFileMap); return 1; }
GoldFinch за место строк: (pBase+0x3C рекомдую макрос FIELD_OFFSET(IMAGE_DOS_HEADER,e_lfanew); он поставит тоже самое, токо читать проще, если не проще, то еще один упрощающий макрос ! просто мне в лом ща щитать чему 0x18 или 0x06, а было бы описательно, я бы посидел подольше Да и другие названиям полей больше порадуются чем циферкам!
когда я буду пбликовать этот тру код, я кнешно сделаю его читаемым) за FIELD_OFFSET спасибо, не знал о таком но хотелось бы услышать чтонить по теме - можно ли разместить таблицу импорта в заголовке
GoldFinch Блин, ты не врубаешься! )) приходит чувак после бухла(праздник же или с работы(ктото втыкает) или просто есть время и видит твою тему, ты действительно веришь что кто-то не врубившись за пару сек в вопрос будет упорно пытаться тебе помочь ? Не знаю как другие, но если я не втыкаю в в попрос с первого прочтения, то просто забиваю! А у тебя вопрос специфичный, с пояснением в виде кода! Так что если я его сразу не понял, то наверное забью, ибо влом
Дворды, в которые записываются адреса функций должны быть в секции, остальное можно разместить в заголовке.
Фигасе у вас спор насчет PE офсета, а то что в реализации нет ни одного правильного момента - ерунда? IAT никак не может быть в заголовке ибо он ReadOnly, а загрузчик патчит Thunks. IAT нильзя никак переносить ибо код настроен на уже существующие Thunks. Нильзя использовать DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size для CopyMemory т.к. это значение можно хоть в 1 установить - импорт всё равно нормально сработает. борланд забивает его вообще размером всего, что относится к импорту, а мс только размер IID. А вообще в хэдере можно размещать только данные не нуждающиеся в патчинге, IIDs, sz's, ... Даже мс размещает там Bound Import
Так... еще раз... я хочу перенести структуру IMAGE_IMPORT_DESCRIPTOR в заголовок. Пишу хелловорлд: Код (Text): ? equ 0xAA ?? equ ((? shl 8)+?) ???? equ ((?? shl 16)+??) ;========== MZ header =============== dd "MZ" db 0x3c-$ dup 0 dd 0x40 ;========== PE header =============== dd "PE" dw 14ch, 1 db 12 dup (?) dw 0xE0,103h,10bh db 14 dup (?) dd EntryPoint db 8 dup (?) dd 400000h,0x1000,0x200 db 8 dup (?) dw 4 db 6 dup (?) dd 0x2000,SizeOfHeaders db 4 dup (?) dw 2 db ?,? dd 0,0,0,0 db 4 dup (?) dd 2 ;NumberOfRvaAndSizes ;======== Data Directory ============== db 8 dup (?) dd idata,20*1 db 36 dup (?) dd 0 ;debug directory size db 72 dup (?) ;========= Section Table =============== dq "section1" dd 0x1000,0x1000,0x1000,0x1000 dd 0,0,0,0xE0000040 ;======================================= ;idata dd 0,0,0,aUSER32,vUSER32, 5 dup 0 ;NOT WORKING HERE ;======================================= db 0x1000-$ dup 0 ;align SizeOfHeaders: ;======== Section 1 Begin ======================= EntryPoint: use32 push 0 call @f ;"PE",0 db "O_o",0 @@: call @f db "Hello world",0 @@: push 0 call @f vUSER32 dd aMessageBoxA,0 @@: pop eax call dword[eax] ret ;------- imports ----------- idata dd 0,0,0,aUSER32,vUSER32, 5 dup 0 ;WORKS HERE aUSER32 db "USER32.DLL",0 aMessageBoxA db 0,0,"MessageBoxA",0 ;============= section 1 end ======================= db 0x2000-$ dup 0 ;align в нем есть строчки: ;idata dd 0,0,0,aUSER32,vUSER32, 5 dup 0 ;NOT WORKING HERE - это если импорт в заголовке, и idata dd 0,0,0,aUSER32,vUSER32, 5 dup 0 ;WORKS HERE - это импорт в секции. С 1й строчкой прога не работает. Кто-нибудь объяснит этот феномен?
неее, ты мне такой же файл, только с VirtualAlign=0x1000 и FileAlign = 0x200 покажи, с выравниванием 4 я и сам сделать могу.
мне-то надо готовые файлы править, а не новые собирать, этот я так, для примера привел. а у нормальных файлов align=4 не бывает) а если и бывает, так там импорт перемещать некуда %)
ну пока что сабж получился только с добавлением новой секции в заголовок, т.е. был заголовок 0x1000 стал 0x800 и новая секция с raw offset 0x800 и в памяти после всех секций.
GoldFinch В ПМ положил ссылку - там есть пример переноса импорта в хидер и добавления еще одной записи
Да... Твой код работает. Переписал свой такой же, тоже работает... Пробовал переносить в hex-редакторе, и тоже как ни странно работает. Но почему тогда когда я вручную собираю файл с импортом в заголовке, он не работает? И старый Сишный исходник тоже не работает. Мистика, мля =\ upd: ооо я нашел причину. Если заполнить IMAGE_DIRECTORY_ENTRY_IAT, то прога работает нормально. Нашел методом тыка. Хз как IAT связана с дескрипторами %)