Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > PE-Exe: Добавление новой секции


Автор: p0s0l 20.12.2003, 19:11
Кто-нибудь скажите, в чем тут трабл...
Мне нужно добавить новую секцию в PE-файл (секция размером примерно 400-500 байт), но это не работает...
Что я сделал не так ?

Код
procedure TForm1.btnAttachClick(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
// Открытие файла
 f := CreateFile (PChar('c:\project2.exe'),
                  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);

 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)  := 'CODE2'#0#0#0;
 ObjectEntry.Misc.VirtualSize := $00001000;
 ObjectEntry.SizeOfRawData    := $00001000;
 ObjectEntry.Characteristics  := $c0000040; // Read+Write, Initialized data

 ObjectEntry.VirtualAddress := ((MaxRVA + ish[MaxRVAIndex].Misc.VirtualSize) and $FFFFF000) + $1000;

 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;


Автор: p0s0l 20.12.2003, 19:18
При запуске пишет "Error Executing Program" - т.е. ошибка в структуре файла.
Действия таковы:
В разделе секций дописываю одну секцию (параметры высчитываю вроде правильно)
Увеличиваю количество секций в заголовке IMAGE_FILE_HEADER.
В конец файла дописываю кусочек данных

Параметры у секции высчитываются так:
физич. адрес = физ. адрес последней секции + физ. размер последней секции
вирт. адрес = макс. вирт. адрес из всех секций + вирт. размер этой секции (у которой найден макс. виртуальный адрес), выравненный по границе страницы.
размер и физический и виртуальный = 4096 байт (1000h), если ставлю реальный размер (456 байт), то непомогает...

Автор: stab 21.12.2003, 16:35
Попробуй поменять ioh.SizeOfImage, значение должно быть кратно Object Align. И еще понять не могу зачем это:

Код

FileSize := GetFileSize (f, nil);
FileSize := (FileSize and $fffff000) + $1000


выравнивание что ли?

Автор: p0s0l 21.12.2003, 22:02
cully, спасибо, помогло.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)