Сейчас на форуме: bartolomeo, -Sanchez- (+4 невидимых)

 eXeL@B —› Вопросы новичков —› И снова о добавлении новой секции
Посл.ответ Сообщение


Ранг: 199.9 (ветеран), 4thx
Активность: 0.120.02
Статус: Участник

Создано: 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;

В теории вроде все правильно. В чем тут может быть дело?



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 12 февраля 2006 12:23
· Личное сообщение · #2

Очень лениво всё это рассматривать (видимо не только мне =), ты бы PE-файлик прикрепил тот, что на выходе получается.
И тебе сразу скажут, что не так. Только файлик поменьше возьми.

-----
Всем привет, я вернулся





Ранг: 199.9 (ветеран), 4thx
Активность: 0.120.02
Статус: Участник

Создано: 12 февраля 2006 13:04
· Личное сообщение · #3

Прикрепил

e690_notepad.rar.zip



Ранг: 50.7 (постоянный)
Активность: 0.060
Статус: Участник

Создано: 12 февраля 2006 13:31 · Поправил: Klajnor
· Личное сообщение · #4

Этот файл не работает скорее всего из-за того, что файл ты увеличиваешь на 1024 байта, а размер секции 1000$
Лучше вынеси все $1000 в константу или переменную

ЗЫ. Забыл сказать. Из десятка файлов( проги написанные мной на delphi, strannik, FASM, calc и notepad) после твоей проги не запускаются только последние два(calc и notepad). На моих прогах всё нормально работает



Ранг: 162.2 (ветеран)
Активность: 0.090
Статус: Участник

Создано: 12 февраля 2006 13:39
· Личное сообщение · #5

Ты bound import зарезал.
Перед вставкой новой секции нужно проверять есть ли они, и если есть, то обнулять их. Запись о них находится в DIrectoryTable по смещению 88h, по-моему.




Ранг: 199.9 (ветеран), 4thx
Активность: 0.120.02
Статус: Участник

Создано: 12 февраля 2006 15:29
· Личное сообщение · #6

asd пишет:
Ты bound import зарезал.


Respect! Точно, дело было в нем.




Ранг: 199.9 (ветеран), 4thx
Активность: 0.120.02
Статус: Участник

Создано: 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 —› Вопросы новичков —› И снова о добавлении новой секции
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати