home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vp21beta.zip
/
LRTLSRC.RAR
/
PE2ELF
/
PE2ELF.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
2000-08-15
|
41KB
|
1,167 lines
{█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█}
{█ █}
{█ Virtual Pascal for Linux █}
{█ PE to ELF conversion utility █}
{█ ─────────────────────────────────────────────────█}
{█ Copyright (C) 1999 Veit Kannegieser █}
{█ █}
{▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀}
(*$Use32+,I+,Delphi+,X+*)
(* $D+,L+,Locinfo+*)
(*$M 1000000*)
program pe2elf;
// 1999.07.28 Veit Kannegieser
// ... VK/JP
// 1999.10.22 Version mit funkionierendem .so-Import an J.P. verschickt
// 2000.05.10 -v für Sektionenliste und word->smallword für PE2LETY.PAS
uses
pe2lety,
reskonv,
ELFDef,
dbwrite,
Strings;
type
PCharArray = ^TCharArray;
TCharArray = array[0..512*1024*1024 ] of Char;
PByteArray = ^TByteArray;
TByteArray = array[0..512*1024*1024 ] of Byte;
PLongArray = ^TLongArray;
TLongArray = array[0..512*1024*1024 div 4] of Longint;
dynamic_tabelle_typ =array[0..20000] of Elf32_Dyn_type;
dynamic_tabelle_z_typ =^dynamic_tabelle_typ;
symboltabelle_typ =array[0..200000] of Elf32_Sym_type;
rel_plt_typ =array[0..200000] of Elf32_Rel_type;
rel_plt_z_typ =^rel_plt_typ;
var
d1,d2 :file;
pe_kopf :pe_kopf_typ;
pe_obj_tab :array[pe_obj_typen] of pe_obj_typ;
code_puffer,
bss_puffer,
data_puffer,
import_puffer,
relo_puffer,
reso_temp_puffer,
reso_puffer :speicherfeld_z_typ;
plt_speicher :PByteArray;
got_speicher :PLongArray;
hash_tabelle :PLongArray;
symboltabelle :^symboltabelle_typ;
symbolstringtabelle :PCharArray;
rel_plt_speicher :rel_plt_z_typ;
importe_vorhanden,
resourcen_vorhanden,
bss_vorhanden :boolean;
programm_kopf :array[0..40] of program_header_type;
sektionen_kopf :array[0..40] of section_header_type;
speicher_tabelle :array[0..40] of pointer;
pk2 :array[0..40] of program_header_type;
string_puffer :speicherfeld_z_typ;
string_puffer_laenge :longint;
reso_temp_laenge :longint;
resource_anker_gefunden :boolean;
anzahl_importe :longint;
InFile, OutFile : string;
type
sektionen=(sekt_null, // reserviert
sekt_interpreter, // Programmlader
sekt_text, // Code
sekt_bss, // wenn vorhanden
sekt_data_a, // \ Konstanten, / alle initialisierten Seiten
sekt_data_b, // / Variablen \ alle Nullseiten
sekt_dynamic, // Informationen/Zeiger für den Programmlader
sekt_got, // Adressen importierter Funktionen
sekt_dynsym, // Tabelle importierte Symbole
sekt_dynsymstr, // Namen für sekt_dynsym
sekt_dynsymstrhash,// Hash-Tabelle für sekt_dynsymstr
sekt_rel_plt, // Verbindung von plt zu dynsym
sekt_resource, // Resourcen
sekt_plt, // Aufrufe von importierten Funktionen
sekt_strings); // Namen von Sektionen
var
sektionen_uebersicht:
array[low(sektionen)..high(sektionen)] of
record
vorhanden :boolean;
index_ :longint;
end;
anzahl_dynamic_eintraege :longint;
dynamic_speicher :dynamic_tabelle_z_typ;
const
sektionen_namen:array[low(sektionen)..high(sektionen)] {of array[1..2]} of string[25]=
(('null,reserved' ),
('interpreter' ),
('.text (program code)' ),
('"_bss"' ),
('data_a (.data)' ),
('data_b (.bss)' ),
('.dynamic' ),
('.got' ),
('.dynsym' ),
('.dynsymstr' ),
('.dynsymstrhash' ),
('.rel.plt' ),
('resource' ),
('.plt' ),
('sektion header strings' ));
elf_kopf:Elf32_Ehdr_type=
(magic0123 :magic0123_elf;
file_class :file_class__32bit;
data_encoding :ELFDATA2LSB;
file_version :e_version__current;
padding :(0,0,0,0,0,0,0,0,0);
e_type :e_type__exec;
e_machine :e_machine__intel386;
e_version :e_version__current;
e_entry :0; // entrypoint
e_phoff :0; // program header offset
e_shoff :0; // sections header offset
e_flags :0; // keine
e_ehsize :SizeOf(Elf32_Ehdr_type);
e_phentsize :SizeOf(program_header_type);
e_phnum :0; // 0..e_phnum-1 of entrys
e_shentsize :SizeOf(section_header_type);
e_shnum :0; // 0..e_shnum-1 of entrys
e_shstrndx :0);
delta=0;
alignment=4;//1024; //{4096}1024;
// die Doku sagt '/usr/lib/libc.so.1'#0
programmlader0 ='/lib/ld-linux.so.1'#0;
programmlader :array[0..Length(programmlader0)-1] of char=programmlader0;
type // Kopie aus resource.pas
linux_resource_anker_typ=
packed record
zeiger :pointer;
laenge :longint;
signatur :array[0..3] of char;
end;
{ Return hexadecimal equivalent of parameter Number as a string }
Function Int2Hex( Number : Longint; N : Byte ) : String;
Const
HexDigit : Array[0..$f] of char = '0123456789ABCDEF';
Var
s : String;
i : Integer;
begin
SetLength(s, N);
For i := N downto 1 do
begin
s[i] := HexDigit[Number and $F];
Number := Number shr 4;
end;
Int2Hex := s;
end;
{ Return hexadecimal equivalent of Pointer }
Function Ptr2Hex( p : Pointer ) : String;
begin
Ptr2Hex := Int2Hex( Word(p), 8 );
end;
{ Return string representation of Number }
Function Int2Str( Number : Longint ) : String;
Var
s : String;
begin
Str( Number, s );
Int2Str := s;
end;
procedure Abbruch(const zk:string);
begin
WriteLn(zk);
Halt(255);
end;
procedure Aufrunden(var a:longint;const m:longint);
var
rest:longint;
begin
rest:=a mod m;
if rest<>0 then
a:=a+m-rest;
end;
//███████████████████████████████████████████████████████████████████████
procedure lade_pe;
var
pe_start :longint;
puffer :array[0..$3f] of char;
procedure lies(var p:speicherfeld_z_typ;var obj:pe_obj_typ);
begin
GetMem(p,obj.physical_size);
Seek(d1,obj.physical_offset);
BlockRead(d1,p^,obj.physical_size);
end;
procedure lies_obj_hdr(var h:pe_obj_typ);
begin
blockread(d1,h,SizeOf(h));
(* kann nicht mehr aus Datei laden als SPeicher reserviert ist *)
if h.physical_size>h.virtual_size then
h.physical_size:=h.virtual_size;
end;
begin
Assign(d1,InFile);
Reset(d1,1);
pe_start:=0;
repeat
BlockRead(d1,puffer,SizeOf(puffer));
if (puffer[0]='P')
and (puffer[1]='E')
and (puffer[2]=#0 )
and (puffer[3]=#0 )
then
break;
if ((puffer[0]='M') and (puffer[1]='Z'))
or ((puffer[0]='Z') and (puffer[1]='M'))
then
begin
pe_start:=longint_z(@puffer[$3c])^;
Seek(d1,pe_start);
Continue;
end;
if (puffer[0]='L')
and (puffer[1]='X')
and (puffer[2]=#0 )
and (puffer[3]=#0 )
then
abbruch('Error: source is LX');
if (puffer[0]='L')
and (puffer[1]='E')
and (puffer[2]=#0 )
and (puffer[3]=#0 )
then
abbruch('Error: source is LE');
if (puffer[0]=#$7f)
and (puffer[1]='E' )
and (puffer[2]='L' )
and (puffer[3]='F' )
then
abbruch('Error: source is ELF');
abbruch('Error: unknown invalid source executable format.');
until false;
Seek(d1,pe_start);
BlockRead(d1,pe_kopf,sizeof(pe_kopf));
(* obj-Tabelle laden
expected object names:
CODE32
_BSS (optional)
CONST32
.idata
.edata (optional)
.reloc
.rsrc (optional) *)
if not (pe_kopf.num_obj in [4,5,6,7]) then
abbruch('Error: not created with VP 2.0');
seek(d1,pe_start+pe_kopf.nthdrsize+$18);
lies_obj_hdr(pe_obj_tab[code32 ]);
lies_obj_hdr(pe_obj_tab[_bss ]);
bss_vorhanden:=(pe_obj_tab[_bss].name='_BSS'#0#0#0#0) or (pe_obj_tab[_bss].name='DATA32'#0#0);
if not bss_vorhanden then
begin
pe_obj_tab[const32]:=pe_obj_tab[_bss];
fillchar(pe_obj_tab[_bss],SizeOf(pe_obj_tab[_bss]),0);
end
else
lies_obj_hdr(pe_obj_tab[const32]);
lies_obj_hdr(pe_obj_tab[idata ]);
lies_obj_hdr(pe_obj_tab[reloc ]);
if pe_obj_tab[reloc ].name<>'.reloc'#0#0 then (* .edata ? *)
lies_obj_hdr(pe_obj_tab[reloc ]);
lies_obj_hdr(pe_obj_tab[res ]);
resourcen_vorhanden:=(pe_obj_tab[res ].name='.rsrc'#0#0#0);
if not resourcen_vorhanden then
fillchar(pe_obj_tab[res ],sizeof(pe_obj_typ),0);
if (pe_obj_tab[code32 ].name<>'CODE32'#0#0 )
or ((pe_obj_tab[_bss ].name<>'_BSS'#0#0#0#0) and (pe_obj_tab[_bss ].name<>'DATA32'#0#0) and bss_vorhanden)
or (pe_obj_tab[const32].name<>'CONST32'#0 )
or (pe_obj_tab[idata ].name<>'.idata'#0#0 )
or (pe_obj_tab[reloc ].name<>'.reloc'#0#0 )
or ((pe_obj_tab[res ].name<>'.rsrc'#0#0#0 ) and resourcen_vorhanden)
then
abbruch('Error: not created with VP 2.0');
importe_vorhanden:={(pe_obj_tab[idata ].physical_size>$14)}true;
lies(code_puffer,pe_obj_tab[code32 ]);
if bss_vorhanden then
lies(bss_puffer,pe_obj_tab[_bss]);
lies(data_puffer,pe_obj_tab[const32]);
lies(import_puffer,pe_obj_tab[idata]);
lies(relo_puffer,pe_obj_tab[reloc]);
if resourcen_vorhanden then
lies(reso_puffer,pe_obj_tab[res]);
Close(d1);
end;
//███████████████████████████████████████████████████████████████████████
procedure rechne;
var
dateiposition,adressposition:longint;
sekt_z:sektionen;
index_:longint;
z1:longint;
function name_speichern(const zk:string):longint;
begin
Result:=string_puffer_laenge;
ReallocMem(string_puffer,string_puffer_laenge+Length(zk)+1);
Move(zk[1],string_puffer^[string_puffer_laenge],Length(zk));
Inc(string_puffer_laenge,Length(zk));
string_puffer^[string_puffer_laenge]:=0; // #0
Inc(string_puffer_laenge);
end;
procedure suche_naechste_passende_dateipostion;
begin
// mod 4096 = and $fff
if (dateiposition and $fff)<>(adressposition and $fff) then
begin
dateiposition:=(dateiposition and $fffff000)+$1000+(adressposition and $fff);
end;
end;
procedure suche_naechste_passende_adressposition;
begin
// mod 4096 = and $fff
if (dateiposition and $fff)<>(adressposition and $fff) then
begin
adressposition:=(adressposition and $fffff000)+$1000+(dateiposition and $fff);
end;
end;
(*$I impconve.pas*)
(*$I proghead.pas*)
begin
string_puffer_laenge:=0;
string_puffer:=nil;
name_speichern('');
anzahl_dynamic_eintraege:=0;
dynamic_speicher:=nil;
// Länge eines Symboltabelleneintrages
Speichere_in_der_DYNAMIC_Tabelle(DT_SYMENT,SizeOf(Elf32_Sym_type));
// das von VP im Datenbereich angelegte Stacksegment kann gelöscht werden
z1:=Meml[Ofs(code_puffer^[pe_kopf.entrypoint-pe_obj_tab[code32].rva])+5+1];
Dec(pe_obj_tab[const32].virtual_size,z1);
// Nullen am Ende des Datenbereiches kommen in den virtuellen Teil
z1:=pe_obj_tab[const32].physical_size;
while data_puffer^[z1-1-1]=0 do
dec(z1);
// auf 32-Bit-Länge bringen
Aufrunden(z1,4);
pe_obj_tab[const32].physical_size:=z1;
// welche Sektionen werden benötigt ?
FillChar(sektionen_uebersicht,SizeOf(sektionen_uebersicht),0); // 0,false,..
sektionen_uebersicht[sekt_null].vorhanden:=true;
sektionen_uebersicht[sekt_text].vorhanden:=true;
// >>>>!!!sekt_bss
sektionen_uebersicht[sekt_data_a].vorhanden:=true;
if pe_obj_tab[const32].virtual_size>pe_obj_tab[const32].physical_size then
sektionen_uebersicht[sekt_data_b].vorhanden:=true;
if importe_vorhanden then
begin
sektionen_uebersicht[sekt_interpreter ].vorhanden:=true;
sektionen_uebersicht[sekt_plt ].vorhanden:=true;
sektionen_uebersicht[sekt_rel_plt ].vorhanden:=true;
sektionen_uebersicht[sekt_got ].vorhanden:=true;
sektionen_uebersicht[sekt_dynamic ].vorhanden:=true;
sektionen_uebersicht[sekt_dynsym ].vorhanden:=true;
sektionen_uebersicht[sekt_dynsymstr ].vorhanden:=true;
sektionen_uebersicht[sekt_dynsymstrhash ].vorhanden:=true;
end;
// Resourceumwandlung
if resourcen_vorhanden then
begin
// sekt_resource
sektionen_uebersicht[sekt_resource].vorhanden:=true;
(* Annahme: viel weniger Platz wird benötigt *)
getmem(reso_temp_puffer,(pe_obj_tab[res].physical_size*3) div 2);
reso_temp_laenge:=0;
konvertiere_resourcen(reso_puffer,pe_obj_tab[res].physical_size,pe_obj_tab[res].rva,
reso_temp_puffer,reso_temp_laenge);
//!!wirr
(* neu in richtiger Größe anfordern *)
ReAllocMem(reso_puffer,reso_temp_laenge);
(* Daten Kopieren *)
Move(reso_temp_puffer^,reso_puffer^,reso_temp_laenge);
(* temporären Speicher freigeben *)
Dispose(reso_temp_puffer);
(* neue Länge merken *)
pe_obj_tab[res].virtual_size :=reso_temp_laenge;
pe_obj_tab[res].physical_size:=reso_temp_laenge;
end;
sektionen_uebersicht[sekt_strings].vorhanden:=true;
// Nummern verteilen und zählen
for sekt_z:=low(sektionen) to high(sektionen) do
if sektionen_uebersicht[sekt_z].vorhanden then
begin
sektionen_uebersicht[sekt_z].index_:=elf_kopf.e_shnum;
Inc(elf_kopf.e_shnum);
end
else
sektionen_uebersicht[sekt_z].index_:=-1;
elf_kopf.e_phnum:=elf_kopf.e_shnum;
//*********************************************************************
// Sektionen füllen und Dateipostionen vergeben
dateiposition:=SizeOf(elf_kopf);
elf_kopf.e_shoff:=dateiposition;
Inc(dateiposition,elf_kopf.e_shentsize*elf_kopf.e_shnum);
FillChar(sektionen_kopf[0],SizeOf(sektionen_kopf),0); // SHT_NULL
FillChar(programm_kopf [0],SizeOf(programm_kopf ),0); // PT_NULL
adressposition:=$00401000-$1000+dateiposition;
//***********************************************************************
// Programmlader
if sektionen_uebersicht[sekt_interpreter].vorhanden then
begin
index_:=sektionen_uebersicht[sekt_interpreter].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.interp');
sh_type :=SHT_PROGBITS;
sh_flags :=SHF_ALLOC;
sh_addr :=adressposition;
sh_offset :=dateiposition;
sh_size :=Length(programmlader);
sh_link :=0;
sh_info :=0;
sh_addralign :=1;
sh_entsize :=0;
end;
with programm_kopf [index_] do
begin
p_type :=PT_INTERP;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
Inc(adressposition,sektionen_kopf[index_].sh_size);
Inc(dateiposition ,sektionen_kopf[index_].sh_size);
Aufrunden(adressposition,4);
Aufrunden(dateiposition ,4);
end;
//***********************************************************************
// CODE bearbeiten
// $00401000 damit der VP-debugger funktioniert
adressposition:=pe_obj_tab[code32].rva+pe_kopf.image_base+delta;
suche_naechste_passende_dateipostion;
index_:=sektionen_uebersicht[sekt_text].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.text');
sh_type :=SHT_PROGBITS;
sh_flags :=SHF_ALLOC+SHF_EXECINSTR;
sh_addr :=adressposition;
sh_offset :=dateiposition;
sh_size :=pe_obj_tab[code32].physical_size;
sh_link :=0;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=0;
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_X+PF_R;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
// Eintrittspunkt
elf_kopf.e_entry:=pe_kopf.entrypoint+pe_kopf.image_base+delta;
Inc(adressposition,sektionen_kopf[index_].sh_size);
Inc(dateiposition ,sektionen_kopf[index_].sh_size);
Aufrunden(adressposition,4);
Aufrunden(dateiposition ,4);
//***********************************************************************
// BSS
if sektionen_uebersicht[sekt_bss].vorhanden then
begin
adressposition:=pe_obj_tab[_bss].rva+pe_kopf.image_base+delta;
index_:=sektionen_uebersicht[sekt_bss].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.bss');
sh_type :=SHT_NOBITS;
sh_flags :=SHF_ALLOC+SHF_WRITE;
sh_addr :=adressposition;
sh_offset :=0;
sh_size :=pe_obj_tab[_bss].virtual_size;
sh_link :=0;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=0;
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=0;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R+PF_W;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
Inc(adressposition,sektionen_kopf[index_].sh_size);
Aufrunden(adressposition,4);
end;
//***********************************************************************
// Konstanten und Daten - Teil 1
adressposition:=pe_obj_tab[const32].rva+pe_kopf.image_base+delta;
suche_naechste_passende_dateipostion;
index_:=sektionen_uebersicht[sekt_data_a].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.data');
sh_type :=SHT_PROGBITS;
sh_flags :=SHF_ALLOC+SHF_WRITE;
sh_addr :=adressposition;
sh_offset :=dateiposition;
sh_size :=pe_obj_tab[const32].physical_size;
sh_link :=0;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=0;
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R+PF_W;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
Inc(adressposition,sektionen_kopf[index_].sh_size);
Inc(dateiposition ,sektionen_kopf[index_].sh_size);
//***********************************************************************
// Konstanten und Daten - Teil 2
if sektionen_uebersicht[sekt_data_b].vorhanden then
begin
index_:=sektionen_uebersicht[sekt_data_b].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.bss');
sh_type :=SHT_NOBITS;
sh_flags :=SHF_ALLOC+SHF_WRITE;
sh_addr :=adressposition;
sh_offset :=dateiposition;
sh_size :=pe_obj_tab[const32].virtual_size-pe_obj_tab[const32].physical_size;
sh_link :=0;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=0;
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=0;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R+PF_W;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
Inc(adressposition,sektionen_kopf[index_].sh_size);
Aufrunden(adressposition,4);
suche_naechste_passende_adressposition;
end;
resource_adressposition:=0;
if importe_vorhanden then
import_umrechnung;
//***********************************************************************
// ".dynamic"
if sektionen_uebersicht[sekt_dynamic].vorhanden then
begin
index_:=sektionen_uebersicht[sekt_dynamic].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.dynamic');
sh_type :=SHT_DYNAMIC;
sh_flags :=SHF_WRITE+SHF_ALLOC;
sh_addr :=_dynamic_adressposition;
sh_offset :=_dynamic_dateiposition ;
sh_size :=_dynamic_laenge;
sh_link :=sektionen_uebersicht[sekt_dynsymstr].index_;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=SizeOf(Elf32_Dyn_type);
end;
with programm_kopf [index_] do
begin
p_type :=PT_DYNAMIC;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R+PF_W;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
end;
//***********************************************************************
// ".got"
if sektionen_uebersicht[sekt_got].vorhanden then
begin
index_:=sektionen_uebersicht[sekt_got].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.got');
sh_type :=SHT_PROGBITS;
sh_flags :=SHF_WRITE+SHF_ALLOC;
sh_addr :=_got_adressposition;
sh_offset :=_got_dateiposition ;
sh_size :=_got_laenge;
sh_link :=0;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=4;
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R+PF_W;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
end;
//***********************************************************************
// ".dynsym"
if sektionen_uebersicht[sekt_dynsym].vorhanden then
begin
index_:=sektionen_uebersicht[sekt_dynsym].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.dynsym');
sh_type :=SHT_DYNSYM;
sh_flags :=SHF_ALLOC;
sh_addr :=_dynsym_adressposition;
sh_offset :=_dynsym_dateiposition ;
sh_size :=_dynsym_laenge;
sh_link :=sektionen_uebersicht[sekt_dynsymstr].index_;
sh_info :=sektionen_uebersicht[sekt_interpreter].index_;
sh_addralign :=4;
sh_entsize :=SizeOf(Elf32_Sym_type);
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
end;
//***********************************************************************
// ".dynstr"
if sektionen_uebersicht[sekt_dynsymstr].vorhanden then
begin
index_:=sektionen_uebersicht[sekt_dynsymstr].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.dynstr');
sh_type :=SHT_STRTAB;
sh_flags :=SHF_ALLOC;
sh_addr :=_dynsymstr_adressposition;
sh_offset :=_dynsymstr_dateiposition;
sh_size :=symbolstringtabelle_laenge;
sh_link :=0;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=0;
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
end;
//***********************************************************************
// ".hash"
if sektionen_uebersicht[sekt_dynsymstrhash].vorhanden then
begin
index_:=sektionen_uebersicht[sekt_dynsymstrhash].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.hash');
sh_type :=SHT_HASH;
sh_flags :=SHF_ALLOC;
sh_addr :=_dynsymstrhash_adressposition;
sh_offset :=_dynsymstrhash_dateiposition;
sh_size :=hash_tabelle_laenge;
sh_link :=sektionen_uebersicht[sekt_dynsym].index_;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=4;
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
end;
//***********************************************************************
// Resourcen
if sektionen_uebersicht[sekt_resource].vorhanden then
begin
if resource_adressposition=0 then
begin
// Adresse und Dateipostion kongruent modulo Seitengröße
// wenn die Resourcen auf einer beschreibbaren Seite
// anfangen wuerden, muß eine neue Seite gewählt werden
if (adressposition mod 4096)>0 then
Inc(adressposition,4096);
runerror(99); // prüfen,dateiposition...!!!!!!!!!!!!
resource_laenge:=pe_obj_tab[res].physical_size;
Inc(adressposition,sektionen_kopf[index_].sh_size);
Inc(dateiposition ,sektionen_kopf[index_].sh_size);
Aufrunden(adressposition,4);
Aufrunden(dateiposition ,4);
end;
index_:=sektionen_uebersicht[sekt_resource].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('resource');
sh_type :=SHT_PROGBITS;
sh_flags :=SHF_ALLOC;
sh_addr :=resource_adressposition;
sh_offset :=resource_dateiposition;
sh_size :=resource_laenge;
sh_link :=0;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=0;
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R;
p_align :=4;
end;
end;
//***********************************************************************
// ".rel.plt"
if sektionen_uebersicht[sekt_rel_plt].vorhanden then
begin
index_:=sektionen_uebersicht[sekt_rel_plt].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.rel.plt');
sh_type :=SHT_REL;
sh_flags :=SHF_ALLOC;
sh_addr :=_rel_plt_adressposition;
sh_offset :=_rel_plt_dateiposition;
sh_size :=_rel_plt_laenge;
sh_link :=sektionen_uebersicht[sekt_dynsym].index_;
sh_info :=sektionen_uebersicht[sekt_plt ].index_;
sh_addralign :=4;
sh_entsize :=SizeOf(Elf32_Rel_type);
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
end;
//***********************************************************************
// ".plt"
if sektionen_uebersicht[sekt_plt].vorhanden then
begin
index_:=sektionen_uebersicht[sekt_plt].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.plt');
sh_type :=SHT_PROGBITS;
sh_flags :=SHF_ALLOC+SHF_EXECINSTR;
sh_addr :=_plt_adressposition;
sh_offset :=_plt_dateiposition;
sh_size :=_plt_laenge;
sh_link :=0;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=0;
end;
with programm_kopf [index_] do
begin
p_type :=PT_LOAD;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=sektionen_kopf[index_].sh_size;
p_memsz :=sektionen_kopf[index_].sh_size;
p_flags :=PF_R+PF_X;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
end;
//***********************************************************************
// Sektionsnamensektion
index_:=sektionen_uebersicht[sekt_strings].index_;
with sektionen_kopf[index_] do
begin
sh_name :=name_speichern('.shstrtab');
sh_type :=SHT_STRTAB;
sh_flags :=0;
sh_addr :=0;
sh_offset :=dateiposition;
sh_size :=string_puffer_laenge;
sh_link :=0;
sh_info :=0;
sh_addralign :=4;
sh_entsize :=0;
end;
with programm_kopf [index_] do
begin
p_type :=PT_NULL;
p_offset :=sektionen_kopf[index_].sh_offset;
p_vaddr :=sektionen_kopf[index_].sh_addr;
p_paddr :=0;
p_filesz :=string_puffer_laenge;
p_memsz :=string_puffer_laenge;
p_flags :=0;
p_align :=sektionen_kopf[index_].sh_addralign;
end;
Inc(dateiposition ,string_puffer_laenge);
Inc(adressposition,string_puffer_laenge);
elf_kopf.e_shstrndx:=sektionen_uebersicht[sekt_strings].index_;
//**********************************************************************
// wenn Resourcen vorhanden sind, muß der Anker in Resource.pas
// gefunden und angepaßt werden
if sektionen_uebersicht[sekt_resource].vorhanden then
begin
resource_anker_gefunden:=false;
for z1:=0 to programm_kopf[sektionen_uebersicht[sekt_data_a].index_].
p_filesz-Sizeof(linux_resource_anker_typ) do
// vielleicht zu langsam ..
with linux_resource_anker_typ(data_puffer^[z1]) do
if (zeiger =Ptr($b582cc18))
and (laenge = $467a1d0e )
and (signatur= 'RES?' ) then
begin
zeiger :=pointer(sektionen_kopf[sektionen_uebersicht[sekt_resource].index_].sh_addr);
laenge :=sektionen_kopf[sektionen_uebersicht[sekt_resource].index_].sh_size;
signatur:='RESO';
resource_anker_gefunden:=true;
break;
end;
if not resource_anker_gefunden then
WriteLn('Warning: resource anchor not found !');
end;
bearbeite_programmheader;
end;
//███████████████████████████████████████████████████████████████████████
procedure schreibe_elf;
procedure Fuellen(const anzahl:longint);
var
null_feld:array[0..4096-1] of byte;
begin
if anzahl<=0 then exit;
DWriteLn('***'+' '+
Int2Hex(FilePos(d2),8)+' '+
Int2Hex(anzahl,8)
{'********'+' ',});
FillChar(null_feld,anzahl,0);
BlockWrite(d2,null_feld,anzahl);
end;
var
sekt_z:sektionen;
laenge:longint;
begin
Assign(d2,OutFile);
FileMode:=$41;
Rewrite(d2,1);
BlockWrite(d2,elf_kopf,SizeOf(elf_kopf));
BlockWrite(d2,sektionen_kopf,elf_kopf.e_shentsize*elf_kopf.e_shnum);
DWriteLn('sec'+' '+
'filepos '+' '+
'len '+' '+
'addr '+' '+
'len '+' '+
'attr '+
{'Name der Sektion'}'name of section');
for sekt_z:=sekt_interpreter to high(sektionen) do
if sektionen_uebersicht[sekt_z].vorhanden then
begin
laenge:=programm_kopf[sektionen_uebersicht[sekt_z].index_].p_filesz;
Seek(d2,FileSize(d2));
if (laenge>0) and (sektionen_kopf[sektionen_uebersicht[sekt_z].index_].sh_offset>0) then
Fuellen(sektionen_kopf[sektionen_uebersicht[sekt_z].index_].sh_offset-FilePos(d2));
DWrite (Int2Hex(Ord(sektionen_uebersicht[sekt_z].index_),3)+' '+
{Int2Hex(FilePos(d2),8),' ',}
Int2Hex(sektionen_kopf[sektionen_uebersicht[sekt_z].index_].sh_offset,8)+' '+
Int2Hex(laenge,8)+' '+
Int2Hex(sektionen_kopf[sektionen_uebersicht[sekt_z].index_].sh_addr,8)+' '+
Int2Hex(programm_kopf[sektionen_uebersicht[sekt_z].index_].p_memsz,8)+' ');
with programm_kopf[sektionen_uebersicht[sekt_z].index_] do
begin
if (p_flags and PF_R)=PF_R then
DWrite('R')
else
DWrite('-');
if (p_flags and PF_W)=PF_W then
DWrite('W')
else
DWrite('-');
if (p_flags and PF_X)=PF_X then
DWrite('X')
else
DWrite('-');
DWrite(' ');
end;
DWriteLn(sektionen_namen[sekt_z{,1}]);
if laenge>0 then
Seek(d2,programm_kopf[sektionen_uebersicht[sekt_z].index_].p_offset);
if (laenge>0) and (programm_kopf[sektionen_uebersicht[sekt_z].index_].p_vaddr>0) then
if (FilePos(d2) mod 4096)<>(programm_kopf[sektionen_uebersicht[sekt_z].index_].p_vaddr mod 4096) then
begin
WriteLn('internal bug: filepos=$',
Int2Hex(programm_kopf[sektionen_uebersicht[sekt_z].index_].p_offset,8),
' alignement mismatch to v_addr=$',
Int2Hex(programm_kopf[sektionen_uebersicht[sekt_z].index_].p_vaddr ,8));
RunError(1);
end;
BlockWrite(d2,speicher_tabelle[sektionen_uebersicht[sekt_z].index_]^,laenge);
end;
BlockWrite(d2,pk2,elf_kopf.e_phentsize*elf_kopf.e_phnum);
Close(d2);
// Writeln('Success.');
// memleaks...
end;
//███████████████████████████████████████████████████████████████████████
function RPos(C: Char; const S: string): LongInt;
begin
Result := Length(S);
while (Result > 0) and (S[Result] <> C) do Dec(Result);
end;
procedure show_usage;
begin
WriteLn;
WriteLn('Usage: PE2ELF [-v] <infile>[.exe] [<outfile>]');
Halt(1);
end;
var
param :word;
begin
WriteLn('PE2ELF * Veit Kannegieser * 1999.07.28..2000.05.10');
param:=1;
while Pos('-',ParamStr(param))<>0 do
begin
case UpCase(ParamStr(param)[2]) of
'V':verbose:=true;
else
show_usage;
end;
Inc(param);
end;
InFile := ParamStr(param);
if InFile = '' then
show_usage;
Inc(param);
if RPos('.', InFile) = 0 then InFile := InFile + '.exe';
OutFile := ParamStr(param);
if OutFile = '' then OutFile := InFile;
Delete(Outfile, RPos('.', OutFile), 255);
WriteLn('Converting PE file ''', InFile, ''' to ELF...');
lade_pe;
rechne;
schreibe_elf;
end.