Сейчас на форуме: bartolomeo, -Sanchez- (+4 невидимых) |
eXeL@B —› Вопросы новичков —› И снова о добавлении новой секции |
Посл.ответ | Сообщение |
|
Создано: 12 февраля 2006 11:09 · Личное сообщение · #1 Ничего не понимаю: добавляю новую секцию в файл (к примеру в calc.exe), после чего файл не запускается. Использую такой вот код (добавляется секция размером 1000h): procedure TForm1.Button1Click(Sender: TObject); type PCardinal = ^Cardinal; TSectName = packed array[0..IMAGE_SIZEOF_SHORT_NAME-1] of char; TSectionsArray = packed array [0..0] of _IMAGE_SECTION_HEADER; PSectionsArray = ^TSectionsArray; var i : cardinal; f : THandle; FileSize, BytesRead, BytesWritten : cardinal; Buf : pointer; BufAdr : cardinal absolute Buf; MaxRVA, MaxRVAIndex : cardinal; ObjectEntry : PImageSectionHeader; idh : PImageDosHeader absolute Buf; ifh : PImageFileHeader; ioh : PImageOptionalHeader; ish : PSectionsArray; begin // Открытие файла if not OpenDialog1.Execute then Exit; f := CreateFile (PChar(Form1.OpenDialog1.FileName), GENERIC_READ + GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0); if f = INVALID_HANDLE_VALUE then Exit; FileSize := GetFileSize (f, nil); FileSize := (FileSize and $fffff000) + $1000; // BufAdr := GlobalAlloc (0, FileSize + AttachDataSize); BufAdr := GlobalAlloc (0, FileSize + $1000); ReadFile (f, Buf^, FileSize, BytesRead, nil); // Адреса заголовков ifh := PImageFileHeader (BufAdr + idh._lfanew + 4); ioh := PImageOptionalHeader (cardinal(ifh) + IMAGE_SIZEOF_FILE_HEADER); // Указатель на массив секций ish := PSectionsArray (cardinal(ioh) + IMAGE_SIZEOF_NT_OPTIONAL_HEADER); // Поиск максимального RVA MaxRVA := ish[0].VirtualAddress; MaxRVAIndex := 0; for i := 1 to ifh.NumberOfSections-1 do if ish[i].VirtualAddress > MaxRVA then begin MaxRVA := ish[i].VirtualAddress; MaxRVAIndex := i; end; // Заполнение новой секции ObjectEntry := @(ish[ifh.NumberOfSections]); FillChar (ObjectEntry^, SizeOf(ObjectEntry^), 0); TSectName(ObjectEntry.Name) := 'CODE'#0#0#0; ObjectEntry.Misc.VirtualSize := $00001000; ObjectEntry.SizeOfRawData := $00001000; ObjectEntry.Characteristics := $c0000040; // Read+Write, Initialized data //Выравниваем VirtualAddress ObjectEntry.VirtualAddress := ((MaxRVA + ish[MaxRVAIndex].Misc.VirtualSize) and $FFFFF000) + $1000; ioh.SizeOfImage := ObjectEntry.VirtualAddress + $00001000; ObjectEntry.PointerToRawData := ish[ifh.NumberOfSections-1].PointerToRawData + ish[ifh.NumberOfSections-1].SizeOfRawData; // Увеличение числа секций Inc (ifh.NumberOfSections); // Запись измененного файла SetFilePointer (f, 0, nil, FILE_BEGIN); WriteFile (f, Buf^, ObjectEntry.PointerToRawData + ObjectEntry.SizeOfRawData, BytesWritten, nil); // Конец GlobalFree (BufAdr); CloseHandle (f); end; В теории вроде все правильно. В чем тут может быть дело? |
|
Создано: 12 февраля 2006 12:23 · Личное сообщение · #2 |
|
Создано: 12 февраля 2006 13:04 · Личное сообщение · #3 |
|
Создано: 12 февраля 2006 13:31 · Поправил: Klajnor · Личное сообщение · #4 Этот файл не работает скорее всего из-за того, что файл ты увеличиваешь на 1024 байта, а размер секции 1000$ Лучше вынеси все $1000 в константу или переменную ЗЫ. Забыл сказать. Из десятка файлов( проги написанные мной на delphi, strannik, FASM, calc и notepad) после твоей проги не запускаются только последние два(calc и notepad). На моих прогах всё нормально работает |
|
Создано: 12 февраля 2006 13:39 · Личное сообщение · #5 |
|
Создано: 12 февраля 2006 15:29 · Личное сообщение · #6 |
|
Создано: 12 февраля 2006 18:17 · Личное сообщение · #7 Может кому потом еще понадобится - для затирки bound import в вышеприведенный код нужно добавить: type _IMAGE_OPTIONAL_HEADER = packed record DataDirectory : packed array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of TImageDataDirectory; end; begin ... if ioh.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress<> 0 then begin ioh.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress := 0; ioh.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size :=0 ; end; ... |
eXeL@B —› Вопросы новичков —› И снова о добавлении новой секции |