Где я косячу с форматом PE ? Ахтунг !!!

Тема в разделе "WASM.BEGINNERS", создана пользователем Shooshpanchik, 26 июл 2010.

  1. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    Код (Text):
    1. const
    2.     MaxObjects = 32;
    3.  
    4. type
    5. TPE = class
    6.      FMemStr : TMemoryStream;
    7.      MZ_Header : IMAGE_DOS_HEADER;
    8.      MZData : Pointer;
    9.      PE_Header : IMAGE_NT_HEADERS;
    10.      FSize : Cardinal;
    11.      Sections : packed array[1..MaxObjects] of TImageSectionHeader;
    12.      Objects :  packed array[1..MaxObjects] of PByteArray;
    13.      Procedure AddSection(Siz : Cardinal);
    14.      Procedure Load(FName : String);
    15.      Procedure Save(FName : String);
    16. end;
    17.  
    18.  
    19. Procedure TPE.AddSection(Siz : Cardinal);
    20. var n : Integer;
    21.     sz : Cardinal;
    22. begin
    23.   Inc(PE_Header.FileHeader.NumberOfSections);
    24.   n :=PE_Header.FileHeader.NumberOfSections;
    25.   inc(PE_Header.OptionalHeader.SizeOfImage, Siz);
    26.   inc(PE_Header.OptionalHeader.SizeOfHeaders, SizeOf(TImageSectionHeader));
    27.   ZeroMemory(@Sections[n], SizeOf(TImageSectionHeader));
    28.   with Sections[n] do
    29.     begin
    30.       Name[0] :=Byte('.');
    31.       Name[1] :=Byte('d');
    32.       PointerToRawData := (FSize div PE_Header.OptionalHeader.FileAlignment + 1) * PE_Header.OptionalHeader.FileAlignment;
    33.       Misc.VirtualSize :=Siz;
    34.       SizeOfRawData := Siz;
    35.       VirtualAddress:=$20000;
    36.       Characteristics := $c0000040;
    37.     end;
    38.   GetMem(Objects[n], Siz);
    39.   sz :=SizeOf(TImageSectionHeader) + PE_Header.OptionalHeader.FileAlignment;
    40.   sz := (sz div PE_Header.OptionalHeader.FileAlignment) * PE_Header.OptionalHeader.FileAlignment;
    41.   for n := 1 to PE_Header.FileHeader.NumberOfSections do
    42.     inc(Sections[n].PointerToRawData, sz);
    43. end;
    44.  
    45. Procedure TPE.Save(FName : String);
    46. Var tmp1 : Word;
    47.   begin
    48.     FMemStr := TMemoryStream.Create;
    49.     FMemStr.WriteBuffer(MZData^, MZ_Header._lfanew);
    50.     FMemStr.Seek(0, soFromBeginning);
    51.     FMemStr.WriteBuffer(MZ_Header, sizeof(MZ_Header));
    52.     FMemStr.Seek(MZ_Header._lfanew, soFromBeginning);
    53.     FMemStr.WriteBuffer(PE_Header, SizeOf(PE_Header));
    54.     FMemStr.WriteBuffer(Sections, SizeOf(TImageSectionHeader)*PE_Header.FileHeader.NumberOfSections);
    55.     for tmp1 := 1 to PE_Header.FileHeader.NumberOfSections do
    56.       begin
    57.         FMemStr.Seek(Sections[tmp1].PointerToRawData, soFromBeginning);
    58.         FMemStr.WriteBuffer(Objects[tmp1]^, Sections[tmp1].SizeOfRawData);
    59.       end;
    60.     FMemStr.SaveToFile(FName);
    61.     FMemStr.Free;
    62.   end;
    63.  
    64. Procedure TPE.Load(FName : String);
    65. Var tmp1 : Word;
    66.   begin
    67.     FMemStr := TMemoryStream.Create;
    68.     FMemStr.LoadFromFile(FName);
    69.     FSize := FMemStr.Size;
    70.     FMemStr.Seek(0, soFromBeginning);
    71.     FMemStr.ReadBuffer(MZ_Header, sizeof(MZ_Header));
    72.     GetMem(MZData, MZ_Header._lfanew);
    73.     FMemStr.Seek(0, soFromBeginning);
    74.     FMemStr.ReadBuffer(MZData^, MZ_Header._lfanew);
    75.     FMemStr.Seek(MZ_Header._lfanew, soFromBeginning);
    76.     FMemStr.ReadBuffer(PE_Header, SizeOf(PE_Header));
    77.     FMemStr.ReadBuffer(Sections, SizeOf(TImageSectionHeader)*PE_Header.FileHeader.NumberOfSections);
    78.     for tmp1 := 1 to PE_Header.FileHeader.NumberOfSections do
    79.       begin
    80.         GetMem(Objects[tmp1], Max(Sections[tmp1].Misc.VirtualSize, Sections[tmp1].SizeOfRawData));
    81.         FMemStr.Seek(Sections[tmp1].PointerToRawData, soFromBeginning);
    82.         FMemStr.ReadBuffer(Objects[tmp1]^, Min(Sections[tmp1].Misc.VirtualSize, Sections[tmp1].SizeOfRawData));
    83.       end;
    84.     FMemStr.Free;
    85.   end;
    86.  
    87. procedure TForm3.Button1Click(Sender: TObject);
    88. var PE : TPE;
    89. begin
    90.   PE := TPE.Create;
    91.   PE.Load(FileNameEdit1.Text);
    92.   PE.AddSection($200);
    93.   PE.Save(FileNameEdit1.Text + '.exe');
    94. end;
    95.  
    96.  
    97. end.
    В результате получаю нерабочий PE, который LordPE влекую фиксит, но где я г-ню, я чет не пойму.
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    А про SectionAlignment/FileAlignment не забыли? Или именно в этом PE эти значения равны? Потому что к SizeOfImage нужно прибавлять не тоже самое, что и писать в SizeOfRawData.
    Да и заполнение поля VirtualAddress смущает. Прям таки такое фиксированное число?
     
  3. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    Насчет VirtualAddress стоит вычислять:

    // Поиск максимального RVA
    MaxRVA := ish[0].VirtualAddress;
    MaxRVAIndex := 0;
    for i := 1 to ifh.NumberOfSections-1 do
    if ish.VirtualAddress > MaxRVA then
    begin
    MaxRVA := ish.VirtualAddress;
    MaxRVAIndex := i;
    end;
    В эксперименте я пробую с FASM.EXE, давая знаения чтоб ничего там в оригинале не попортить.
     
  4. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    Great
    Вроде как $200 и под то и под то канает как бы.
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Shooshpanchik
    Это вопрос или утверждение? Вам виднее, какие там значения SectionAlignment/FileAlignment. Лучше бинарник выложите, хотя бы дамп заголовков.
     
  6. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    Shooshpanchik
    Кто вам мешает сравнить исходный и исправленный. И посмотреть в чем же разница?
     
  7. fsd

    fsd New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    353
    обычно не нужно, если секция 1(заголовок соответственно тоже 1) то добавить еще одну просто обычно не выйдет, т к придется двигать в файле все остальные секции, если секций больше 1й, то править размер не нужно, т к SizeOfHeaders будет выровнен линкером на FileAlignment и его размер обычно покрывает заголовок новой секции, что не мешало бы? так это добавить проверку есть ли достаточное место, чтобы добавить еще один заголовок секции
    это что? По идее должно быть что-то вроде PE_Header.OptionalHeader.SizeOfImage, а не $20000
    выравнивать необязательно, если у файла нет оверлея (либо подписи) он всегда будет выровнен, а если есть то секцию просто так не добавить
    новый размер должен быть выровнен на FileAlignment(Section Table (Section Headers))
    Код (Text):
    1. #define IMAGE_SCN_CNT_INITIALIZED_DATA       0x00000040  // Section contains initialized data.
    OptionalHeader.SizeOfInitializedData должен быть изменен на вирт размер секции
    размер образа должен быть выровнен на SectionAlignment (Optional Header Windows-Specific Fields (Image Only))
     
  8. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    Вообщето и сдвигаю все:
    for n := 1 to PE_Header.FileHeader.NumberOfSections do
    inc(Sections[n].PointerToRawData, sz);

    Сейчас чуток изменил с учетом
    и даже
    И вроде весь Alignment выровнял,не ну вот все что у меня есть считают подкорректированный файл нормальным, и вот токо винда грит:
    C:\FASM.EXE.exe не является приложением Win32.


    Вот до и после:
    http://file.qb.by/8fdef0deb52e18cc95c6c6965d6fd5aa
    (66 кб)

    Разница видна, и вроде все корректно, но токо не запускается он :)
     
  9. izl3sa

    izl3sa New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2010
    Сообщения:
    164
    Адрес:
    Spb
    у вас rva добавленной секции не выровнен.
    4 .d 00000200 00018162 <- (должно быть 18000) 00000200 00010600 00000040
    остальное у файла в пределах нормы
     
  10. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    Это ж
    VirtualAddress := PE_Header.OptionalHeader.SizeOfImage;
    Ранее я просто ставил его в $20000, счас, по формуле, с учетом Alignment он становится $19000
    Но винда всеравно бракует файл, а остальные утилиты нормально открывают.
     
  11. fsd

    fsd New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    353
    Shooshpanchik
    https://www.wasm.ru/forum/viewtopic.php?pid=389800#p389800
    как минимум неверны SizeOfImage образа и VirtualAddress новой секции

    add
    вот ваш, исправленный вручную, файл http://www.sendspace.com/file/swt0d6
    перечитывайте пост внимательнее, ни одной ошибки вами не исправлено,

    - выравнивания абсолютно нигде нет (там где заголовок изменен, все поля испорчены)
    - размер данных в файле расчитан неверно, у вас 0x200, должно быть - 0x400
    - размер заголовка с правильного испорчен на неизвестно что
    - чексумма левая
    - размер образа левый
    - вирт адрес секции левый
    - физ адрес секции левый

    грубо говоря правильно только то, что NumberOfSections увеличен на 1
    вобщем разбирайтесь еще