Сейчас на форуме: hgdagon, asfa, bartolomeo (+6 невидимых) |
![]() |
eXeL@B —› Программирование —› Добавление секции в PE |
. 1 . 2 . >> |
Посл.ответ | Сообщение |
|
Создано: 23 июля 2006 13:37 · Личное сообщение · #1 Не получается добавись секцию в PE unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; OD: TOpenDialog; Button2: TButton; procedure Button1Click(Sender: TObject); procedure AddSection(sname: string); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; dos: TImageDosHeader; nt: TImageNTHeaders; sh:array[0..15] of TImageSectionHeader; f, f_new :file; //исходный и новый файл implementation {$R *.dfm} procedure TForm1.AddSection(sname: string); Var n:byte; begin for n:=0 to 7 do sh[nt.FileHeader.NumberOfSections+1].Name[n]:=ord(sname[n]); sh[nt.FileHeader.NumberOfSections+1].VirtualAddress:= sh[nt.FileHeader.NumberOfSections].VirtualAddress+ sh[nt.FileHeader.NumberOfSections].SizeOfRawData; sh[nt.FileHeader.NumberOfSections+1].SizeOfRawData:=0; sh[nt.FileHeader.NumberOfSections+1].PointerToRawData:= sh[nt.FileHeader.NumberOfSections].PointerToRawData+ sh[nt.FileHeader.NumberOfSections].SizeOfRawData; sh[nt.FileHeader.NumberOfSections+1].Characteristics:=$40000000; end; procedure TForm1.Button1Click(Sender: TObject); begin if OD.Execute then Edit1.Text:=OD.FileName; end; procedure TForm1.Button2Click(Sender: TObject); Var i:byte; buf:array[0..250000] of char; begin AssignFile(f,edit1.Text); AssignFile(f_new,ExtractFileDir(Edit1.Text)+'\new.exe'); ReWrite(f_new,1); Reset(f,1); BlockRead(f,dos,SizeOf(TImageDosHeader)); Seek(f,dos._lfanew); BlockRead(f,nt,SizeOf(nt)); for i:=0 to (nt.FileHeader.NumberOfSections-1) do BlockRead(f,sh[i],SizeOf(TImageSectionHeader)); Seek(f,0); BlockRead(f,buf,dos._lfanew); BlockWrite(f_new,buf,dos._lfanew); BlockWrite(f_new,nt,SizeOf(nt)); AddSection('LOH'); for i:=0 to nt.FileHeader.NumberOfSections do BlockWrite(f_new,sh[i],SizeOf(TImageSectionHeader)); Seek(f,sh[0].PointerToRawData); BlockRead(f,buf,FileSize(f)-sh[0].PointerToRawData); BlockWrite(f_new,buf,FileSize(f)-sh[0].PointerToRawData); CloseFile(f_new); CloseFile(f); end; end. В чём ошибка? ![]() ![]() |
|
Создано: 23 июля 2006 14:32 · Личное сообщение · #2 sniperZ В ломы смотреть не зная оЧибки! Но почему-то мои глаза не наблюдают увеличения кол-ва секций в файле, это поле тако NumberOfSection. P.S.: Пиши на си, он классикой является, люди быстрее врубятся в си, а не в дельфи, т.к. на си больше народу пишет. А алгоритм, он и в африке алгоритм ----- My love is very cool girl. ![]() |
|
Создано: 23 июля 2006 15:06 · Личное сообщение · #3 |
|
Создано: 23 июля 2006 15:11 · Поправил: theCollision · Личное сообщение · #4 sniperZ Если ты пишешь на си, то плиз напиши класс для работы с PE-форматом. Че даст: Не будешь изобретать велосипед, достаточно будет: PPEFORMAT pefile = new PPEFORMAT; pefile->open("starforce.exe"); int count = pefile->GetCountSection(); DWORD EntryPoint = pefile->GetEntryPoint(); etc. че задашь ----- My love is very cool girl. ![]() |
|
Создано: 23 июля 2006 15:14 · Личное сообщение · #5 Я пишу на DELPHI! ![]() Исправил увеличение секций в файле. Все равно не получается. ![]() ![]() ![]() ![]() unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; OD: TOpenDialog; Button2: TButton; procedure Button1Click(Sender: TObject); procedure AddSection(sname: string); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; dos: TImageDosHeader; nt: TImageNTHeaders; sh:array[0..15] of TImageSectionHeader; f, f_new :file; //исходный и новый файл implementation {$R *.dfm} procedure TForm1.AddSection(sname: string); Var n:byte; begin for n:=0 to 7 do sh[nt.FileHeader.NumberOfSections].Name[n]:=ord(sname[n]); sh[nt.FileHeader.NumberOfSections].VirtualAddress:= sh[nt.FileHeader.NumberOfSections].VirtualAddress+ sh[nt.FileHeader.NumberOfSections].SizeOfRawData; sh[nt.FileHeader.NumberOfSections].SizeOfRawData:=0; sh[nt.FileHeader.NumberOfSections].PointerToRawData:= sh[nt.FileHeader.NumberOfSections].PointerToRawData+ sh[nt.FileHeader.NumberOfSections].SizeOfRawData; sh[nt.FileHeader.NumberOfSections].Characteristics:=$40000000; end; procedure TForm1.Button1Click(Sender: TObject); begin if OD.Execute then Edit1.Text:=OD.FileName; end; procedure TForm1.Button2Click(Sender: TObject); Var i:byte; buf:array[0..250000] of char; begin AssignFile(f,edit1.Text); AssignFile(f_new,ExtractFileDir(Edit1.Text)+'\new.exe'); ReWrite(f_new,1); Reset(f,1); BlockRead(f,dos,SizeOf(TImageDosHeader)); Seek(f,dos._lfanew); BlockRead(f,nt,SizeOf(nt)); for i:=0 to (nt.FileHeader.NumberOfSections-1) do BlockRead(f,sh[i],SizeOf(TImageSectionHeader)); Seek(f,0); BlockRead(f,buf,dos._lfanew); BlockWrite(f_new,buf,dos._lfanew); BlockWrite(f_new,nt,SizeOf(nt)); AddSection('LOH'); for i:=0 to nt.FileHeader.NumberOfSections do BlockWrite(f_new,sh[i],SizeOf(TImageSectionHeader)); Seek(f,sh[0].PointerToRawData); BlockRead(f,buf,FileSize(f)-sh[0].PointerToRawData); BlockWrite(f_new,buf,FileSize(f)-sh[0].PointerToRawData); CloseFile(f_new); CloseFile(f); end; end. ![]() |
|
Создано: 23 июля 2006 16:03 · Личное сообщение · #6 sniperZ берёшь myPEFile.pas от Guru.eXe и внимательно изучаешь функцию AddSection. function AddSection(filname: string; SecName:string): boolean; const Ziro: Byte = $00; var I,ImSz,N,VirAddr,PhyAddr: DWORD; begin result:=false; if not openpe(filname) then exit; if length(SecName) > 8 then exit; SetFilePointer(FHandle, PEHeaderOffset + $50, nil, 0); ReadFile(FHandle, SizeOfImage, SizeOf(SizeOfImage), BytesRead, nil); SetFilePointer(FHandle, PEHeaderOffset + $38, nil, 0); ReadFile(FHandle, Sect_Align, SizeOf(Sect_Align), BytesRead, nil); SetFilePointer(FHandle, PEHeaderOffset + $06, nil, 0); ReadFile(FHandle, NumOfSections, SizeOf(NumOfSections), BytesRead, nil); SetFilePointer(FHandle, PEHeaderOffset + $F8, nil, 0); for I:= 1 to NumOfSections do begin ReadFile(FHandle, Section, SizeOf(Section), BytesRead, nil); end; VirAddr:=((section.VirtualAddress+section.VirtualSize+Sect_Align-1) div Sect_Align) * Sect_Align; PhyAddr:=section.PhysicalOffset+section.PhysicalSize; SetFilePointer(FHandle, PEHeaderOffset + $F8 + NumOfSections * $28 - $28, nil, 0); ReadFile(FHandle, Section, SizeOf(Section), BytesRead, nil); with Section do begin VirtualAddress:=VirAddr; PhysicalOffset:=PhyAddr; VirtualSize:= $1000; PhysicalSize:= $200; Characteristics:= $E00000E0; StrPCopy(name,SecName); end; SetFilePointer(FHandle, PEHeaderOffset + $50, nil, 0); ImSZ:=SizeOfImage+Section.VirtualSize; WriteFile(FHandle, ImSz, SizeOf(ImSz), BytesRead, nil); SetFilePointer(FHandle, PEHeaderOffset + $F8 + NumOfSections * $28, nil, 0); WriteFile(FHandle, Section, SizeOf(Section), BytesRead, nil); Inc(NumOfSections); SetFilePointer(FHandle, PEHeaderOffset + $06, nil, 0); WriteFile(FHandle, NumOfSections, SizeOf(NumOfSections), BytesRead, nil); SetFilePointer(FHandle, Section.PhysicalOffset + Section.PhysicalSize - $200, nil, 0); for N:=1 to Section.PhysicalSize do WriteFile(FHandle, Ziro, SizeOf(Ziro), BytesRead, nil); CloseHandle(FHandle); result:=true; end; Приаттачил сам myPEFile.pas. ![]() ![]() |
|
Создано: 23 июля 2006 23:26 · Личное сообщение · #7 А на асме кто-нибудь подскажет как это делается ? Пытаюсь писать криптор-шифратор .exe-шников(основное направление - обход AV) ![]() ----- все багрепорты - в личные сообщения ![]() |
|
Создано: 23 июля 2006 23:38 · Личное сообщение · #8 HandMill А ты вот спроси себя, сколько секций в файле calc.exe ? И почему их столько? А что если какое либо сво-во файла занулить, сделать большим, маленьким что будет? Ведь стоит только написать на бумажке, распечать экзампл, такое понятие как добавление секции становится не таким уж и сложынм. Попробуй. ЗЫ: Я такой же задачей примерно занимаюсь с некоторой оговоркой ----- My love is very cool girl. ![]() |
|
Создано: 24 июля 2006 00:27 · Личное сообщение · #9 Не забываем про поле ImageSize PS: народ, выбросите вы этот делфи. Если уж хочется вам париться с процедурным программированием, возьмите с++, там хоть в хидерах полно предопределений, а то код типа SetFilePointer(FHandle, PEHeaderOffset + $50, nil, 0); Этож маразм ----- Недостаточно только получить знания:надо найти им приложение ![]() |
|
Создано: 24 июля 2006 14:09 · Поправил: sniperZ · Личное сообщение · #10 Написал по анологии с myPEFile.pas. В некоторые проги(Winrar.exe, FASMW.exe) секция добавляется и файл работает. А вот в calc.exe и Дельфовские проги не работает.(Пишен, что не найдена какая-то DLL), но если в PEiD сделать RebuiltPE, то ЕКЗЕШНИК заново работает. ![]() В чём ошибка? unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; OD: TOpenDialog; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; dos: TImageDosHeader; nt: TImageNTHeaders; sh:array[0..15] of TImageSectionHeader; f :file; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin if OD.Execute then Edit1.Text:=OD.FileName; end; procedure TForm1.Button2Click(Sender: TObject); Var n: integer; SecName:string; Num:byte; NOP:array[0..0] of byte; begin SecName:='.aspack'; AssignFile(f,edit1.Text); {$I-} Reset(f,1); If IOResult<>0 then exit; {$I+} BlockRead(f,dos,SizeOf(dos)); Seek(f,dos._lfanew); BlockRead(f,nt,SizeOf(nt)); for n:=0 to (nt.FileHeader.NumberOfSections-1) do BlockRead(f,sh[n],SizeOf(TImageSectionHeader)); Num:=nt.FileHeader.NumberOfSections; for n:=0 to 7 do sh[num].Name[n]:=ord(SecName[n-1]); sh[num].VirtualAddress:=((sh[num-1].VirtualAddress+sh[num-1].Misc.Virt ualSize+nt.OptionalHeader.SectionAlignment-1) div nt.OptionalHeader.SectionAlignment)*nt.OptionalHeader.SectionAlignment ; sh[num].PointerToRawData:=sh[num-1].PointerToRawData+sh[num-1].SizeOfR awData; sh[num].Misc.VirtualSize:=$1000; sh[num].SizeOfRawData:=$200; sh[num].Characteristics:=$E00000E0; nt.OptionalHeader.SizeOfImage:=nt.OptionalHeader.SizeOfImage+sh[num].M isc.VirtualSize; inc(nt.FileHeader.NumberOfSections); Seek(f,dos._lfanew); BlockWrite(f,nt,SizeOf(nt)); Seek(f,dos._lfanew+SizeOf(TImageNTHeaders)); BlockWrite(f,sh,SizeOf(sh)); Seek(f,sh[num].PointerToRawData); NOP[0]:=$90; for n:=1 to $200 do BlockWrite(f,NOP,SizeOf(NOP)); CloseFile(f); end; end. ![]() |
|
Создано: 24 июля 2006 14:45 · Поправил: BaGiE · Личное сообщение · #11 sniperZ пишет: nt.OptionalHeader.SizeOfImage:=nt.OptionalHeader.SizeOfImage+sh[num].M isc.VirtualSize; ошибка может быть тут. не стоит просто увеличивать размер образа. его надо высчитать заного, т.е. пробежаться по всем сециям, и сложить их выровненный виртуальный размер+размер заголовков. Дело в том что иногда компилятор, например дельфовский может не совсем корректно установить SizeOfImage (несколько больше настоящего, т.е. максимум до разницы выровненного и невыровненнго ImageBase) я когда-то столкнулся с такой херней. может быть здесь именно в этом проблема. а еще при добавлении секции могут возникнуть проблемы с BoundImport (у calc.exe он есть), т.е. непоняной лично для меня вещью, которая находится в PE-заголовке после заголовков секций. В этом случае надо просто затереть описание каталога BoundImport'а в PE-хеадере. ![]() |
|
Создано: 24 июля 2006 15:16 · Личное сообщение · #12 Rascal пишет: народ, выбросите вы этот делфи. Если уж хочется вам париться с процедурным программированием, возьмите с++, там хоть в хидерах полно предопределений, а то код типа SetFilePointer(FHandle, PEHeaderOffset + $50, nil, 0); Этож маразм Вот именно. В Делфи дохрена предопределений ;) ----- Yann Tiersen best and do not fuck ![]() |
|
Создано: 24 июля 2006 15:16 · Личное сообщение · #13 |
|
Создано: 24 июля 2006 15:52 · Личное сообщение · #14 Сделал: nt.OptionalHeader.SizeOfImage:=nt.OptionalHeader.SizeOfHeaders; for n:=0 to Num do nt.OptionalHeader.SizeOfImage:=nt.OptionalHeader.SizeOfImage+sh[n].Mis c.VirtualSize; Всё равно WinRaR.exe работает,а calc.exe и Project.exe(Delphi) не являются приложениями Win32. ![]() BaGiE пишет: а еще при добавлении секции могут возникнуть проблемы с BoundImport (у calc.exe он есть), т.е. непоняной лично для меня вещью, которая находится в PE-заголовке после заголовков секций. В этом случае надо просто затереть описание каталога BoundImport'а в PE-хеадере. Ну ка расскажи про BoundImport'а в PE-хеадере. ![]() ![]() |
|
Создано: 24 июля 2006 15:56 · Личное сообщение · #15 sniperZ пишет: Всё равно WinRaR.exe работает,а calc.exe и Project.exe(Delphi) не являются приложениями Win32. sniperZ пишет: но если в PEiD сделать RebuiltPE, то ЕКЗЕШНИК заново работает. посмотри че изменяется в экзешнике после ребилда. может поймешь где ошибка. sniperZ пишет: Ну ка расскажи про BoundImport'а в PE-хеадере. че тут рассказывать,то ---------------------------------- IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[DataDirectoryBoundImport ].VirtualAddress := 0 IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[DataDirectoryBoundImport ].Size := 0 ![]() |
|
Создано: 24 июля 2006 16:13 · Личное сообщение · #16 sniperZ пишет: nt.OptionalHeader.SizeOfImage:=nt.OptionalHeader.SizeOfHeaders; for n:=0 to Num do nt.OptionalHeader.SizeOfImage:=nt.OptionalHeader.SizeOfImage+sh[n].Mis c.VirtualSize; че это такое! вот так. nt.OptionalHeader.SizeOfImage := nt.OptionalHeader.SizeOfHeaders; for n:=0 to Num do nt.OptionalHeader.SizeOfImage := nt.OptionalHeader.SizeOfImage + AlignSize(sh[n].Mis c.VirtualSize, $1000); $1000 - это по умолчанию, а так должно быть значение из IMAGE_NT_HEADERS.OptionalHeader.SectionAlignment а функцию AlignSize(Value, Factor) напиши сам для выравниввния значений до значения указанного в Factor ![]() |
|
Создано: 24 июля 2006 17:04 · Личное сообщение · #17 |
|
Создано: 24 июля 2006 17:13 · Поправил: BaGiE · Личное сообщение · #18 sniperZ пишет: BaGiE, я новичек. бррр. а я нет? чем я лучше тебя? почитал бы тогда статьи что-ли... ну да ладно. вот хотя бы так. edit: //ступил и неправильно написал function Bit(B: DWORD): DWORD; begin if B <> 0 then Result:= 1 else Result:= 0; end; function Align(Value, Factor: DWORD): DWORD; begin Result := (Value div Factor) * Factor + Factor * Bit(Value mod Factor); end; ![]() |
|
Создано: 24 июля 2006 17:28 · Личное сообщение · #19 вот, вроде всегда работает, правда есть несколько недороботок, но это мелочи...
----- [nice coder and reverser] ![]() |
|
Создано: 24 июля 2006 17:43 · Личное сообщение · #20 PE_Kill Да ну, скоко не пробовал я в делфи писать - сакс. IDE убогая-убогая, чтоб узнать, какой тип переменной или класса юзаю AVSearch ![]() Вообще можно и в yc и yp глнуть - и на асме и на сях ----- Недостаточно только получить знания:надо найти им приложение ![]() |
|
Создано: 24 июля 2006 22:13 · Личное сообщение · #21 BaGiE, всё равно calc.exe и Project.exe падают, а WinRaR.exe на высоте. ![]() ![]() unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; OD: TOpenDialog; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; dos: TImageDosHeader; nt: TImageNTHeaders; sh:array[0..15] of TImageSectionHeader; f :file; implementation {$R *.dfm} function Bit(B: DWORD): DWORD; asm shl eax,31 shr eax,31 end; function AlignSize(Value, Factor: DWORD): DWORD; begin Result := (Value div Factor) * Factor + Factor * Bit(Value mod Factor); end; procedure TForm1.Button1Click(Sender: TObject); begin if OD.Execute then Edit1.Text:=OD.FileName; end; procedure TForm1.Button2Click(Sender: TObject); Var n: integer; SecName:string; Num:byte; NOP:array[0..0] of byte; begin SecName:='.aspack'; AssignFile(f,edit1.Text); {$I-} Reset(f,1); If IOResult<>0 then exit; {$I+} BlockRead(f,dos,SizeOf(dos)); Seek(f,dos._lfanew); BlockRead(f,nt,SizeOf(nt)); for n:=0 to (nt.FileHeader.NumberOfSections-1) do BlockRead(f,sh[n],SizeOf(TImageSectionHeader)); Num:=nt.FileHeader.NumberOfSections; for n:=0 to 7 do sh[num].Name[n]:=ord(SecName[n+1]); sh[num].VirtualAddress:=((sh[num-1].VirtualAddress+sh[num-1].Misc.Virt ualSize+nt.OptionalHeader.SectionAlignment-1) div nt.OptionalHeader.SectionAlignment)*nt.OptionalHeader.SectionAlignment ; sh[num].PointerToRawData:=sh[num-1].PointerToRawData+sh[num-1].SizeOfR awData; sh[num].Misc.VirtualSize:=$1000; sh[num].SizeOfRawData:=$200; sh[num].Characteristics:=$E00000E0; nt.OptionalHeader.SizeOfImage:=nt.OptionalHeader.SizeOfImage+sh[num].M isc.VirtualSize; nt.OptionalHeader.SizeOfImage:=nt.OptionalHeader.SizeOfHeaders; for n:=0 to Num do nt.OptionalHeader.SizeOfImage:=nt.OptionalHeader.SizeOfImage+ AlignSize(sh[n].Misc.VirtualSize, nt.OptionalHeader.FileAlignment); //nt.OptionalHeader.DataDirectory[11].VirtualAddress:=0; //nt.OptionalHeader.DataDirectory[11].Size:=0; inc(nt.FileHeader.NumberOfSections); Seek(f,dos._lfanew); BlockWrite(f,nt,SizeOf(nt)); Seek(f,dos._lfanew+SizeOf(TImageNTHeaders)); BlockWrite(f,sh,SizeOf(sh)); Seek(f,sh[num].PointerToRawData); NOP[0]:=$90; for n:=1 to $200 do BlockWrite(f,NOP,SizeOf(NOP)); CloseFile(f); end; end. ![]() |
|
Создано: 25 июля 2006 01:26 · Личное сообщение · #22 |
|
Создано: 25 июля 2006 08:29 · Поправил: BaGiE · Личное сообщение · #23 sniperZ пишет: //nt.OptionalHeader.DataDirectory[11].VirtualAddress:=0; //nt.OptionalHeader.DataDirectory[11].Size:=0; а че это закомментировал? и Align работает неправильно. вобщем не муди. у меня голова уже пухнет от кода на паскале. лучше асм. и проще будет. а если уж решил что на Delphi обязательно, то лучше работай через файл-маппинг, удобнее полюбому получается. а если очень приспичит то пиши в личку, помогу чем смогу, а то нафлудил уже тут. ![]() |
|
Создано: 25 июля 2006 11:36 · Личное сообщение · #24 |
|
Создано: 25 июля 2006 12:31 · Личное сообщение · #25 |
|
Создано: 25 июля 2006 12:36 · Личное сообщение · #26 |
|
Создано: 25 июля 2006 12:45 · Личное сообщение · #27 |
|
Создано: 25 июля 2006 13:18 · Личное сообщение · #28 |
|
Создано: 25 июля 2006 13:22 · Личное сообщение · #29 Кстати, в myPEFile от GuGu.Exe AddSection тоже неправильно работает в calc.exe. А всё из-за BoundImport. Надо ещё добавить,как советовал Bagie: IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[11 ].VirtualAddress := 0 IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[11].Size := 0 Так что GuGu.exe лови баг и исправляй. ![]() ![]() ![]() В моей функции где-то вкралась небольшая ошибка. Ща переделаю и исправлю. ![]() |
|
Создано: 25 июля 2006 13:42 · Личное сообщение · #30 Вот исправленый myPEFile от Guru.EXE Теперь AddSection работает корректно. ![]() ![]() |
. 1 . 2 . >> |
![]() |
eXeL@B —› Программирование —› Добавление секции в PE |