📄 dedeclasses.pas
字号:
Function TFieldData.GetFieldIdx(ID : DWORD) : Integer;
var Field : TFieldRec;
i : Integer;
begin
Result:=-1;
For i:=0 to Fields.Count-1 Do
begin
Field:=TFieldRec(Fields[i]);
if Field.dwID=ID then
begin
Result:=i;
Break;
end;
end;
end;
procedure TFieldData.ClearFields;
var i : Integer;
begin
For i:=Fields.Count-1 downto 0 Do
TFieldRec(Fields[i]).Free;
end;
constructor TFieldData.Create;
begin
Inherited Create;
Fields:=TList.Create;
end;
destructor TFieldData.Destroy;
begin
ClearFields;
Fields.Free;
Inherited Destroy;
end;
{ TMethodData }
procedure TMethodData.AddMethod(Name: String; RVA: DWORD; Flag: Word);
var Field : TMethodRec;
begin
Field:=TMethodRec.Create;
Field.sName:=Name;
Field.dwRVA:=RVA;
Field.wFlag:=Flag;
Methods.Add(Field);
end;
procedure TMethodData.ClearMethods;
var i : Integer;
begin
For i:=Methods.Count-1 downto 0 Do
TMethodRec(Methods[i]).Free;
end;
constructor TMethodData.Create;
begin
Inherited Create;
Methods:=TList.Create;
end;
destructor TMethodData.Destroy;
begin
ClearMethods;
Methods.Free;
Inherited Destroy;
end;
function TMethodData.MethodIndexByRVA(RVA: DWORD): Integer;
var i : Integer;
begin
For i:=0 To Methods.Count-1 Do
If TMethodRec(Methods[i]).dwRVA=RVA Then
Begin
Result:=i;
Exit;
End;
Result:=-1;
end;
Function _Chr(Ab : Byte) : Char;
Begin
If Ab=0 Then Result:='.'
Else Result:=Chr(Ab);
End;
Function Chr1(Ab : Byte) : String;
Begin
If Ab=0 Then Result:=''
Else Result:=Chr(Ab);
End;
Function HexChar(Ab : Byte) : Char;
Begin
If Ab in [32..ORD('z')]
Then Result:=Chr(Ab)
Else Result:='.';
End;
function TMethodData.ProcEntryPossible(RVA: DWORD): Boolean;
var i : Integer;
dw : DWORD;
begin
Result:=False;
For i:=0 To Methods.Count-1 Do
Begin
dw:=TMethodRec(Methods[i]).dwRVA;
If dw=RVA then
begin
Result:=True;
Exit;
end;
End;
end;
{ TPEObject }
function TPEObject.DecodeFlags(AdwFlags: DWORD): String;
var TmpStr : String;
begin
Result:='';
If AdwFlags and $8>0 Then Result:=Result+txt_sect8;
If AdwFlags and $20>0 Then Result:=Result+txt_sect20;
If AdwFlags and $40>0 Then Result:=Result+txt_sect40;
If AdwFlags and $80>0 Then Result:=Result+txt_sect80;
If AdwFlags and $200>0 Then Result:=Result+txt_sect200;
If AdwFlags and $800>0 Then Result:=Result+txt_sect800;
If AdwFlags and $1000>0 Then Result:=Result+txt_sect1000;
TmpStr:=DWord2Hex(AdwFlags);
While Length(TmpStr)<8 Do TmpStr:='0'+TmpStr;
Case TmpStr[3] of
'1': Result:=Result+txt_align_on_a+'1-byte'+txt_boundary;
'2': Result:=Result+txt_align_on_a+'2-byte'+txt_boundary;
'3': Result:=Result+txt_align_on_a+'4-byte'+txt_boundary;
'4': Result:=Result+txt_align_on_a+'8-byte'+txt_boundary;
'5': Result:=Result+txt_align_on_a+'16-byte'+txt_boundary;
'6': Result:=Result+txt_align_on_a+'32-byte'+txt_boundary;
'7': Result:=Result+txt_align_on_a+'64-byte'+txt_boundary;
'8': Result:=Result+txt_align_on_a+'128-byte'+txt_boundary;
'9': Result:=Result+txt_align_on_a+'256-byte'+txt_boundary;
'A': Result:=Result+txt_align_on_a+'512-byte'+txt_boundary;
'B': Result:=Result+txt_align_on_a+'1024-byte'+txt_boundary;
'C': Result:=Result+txt_align_on_a+'2048-byte'+txt_boundary;
'D': Result:=Result+txt_align_on_a+'4096-byte'+txt_boundary;
'E': Result:=Result+txt_align_on_a+'8192-byte'+txt_boundary;
End;
If AdwFlags and $1000000>0 Then Result:=Result+txt_sect1000000;
If AdwFlags and $2000000>0 Then Result:=Result+txt_sect2000000;
If AdwFlags and $4000000>0 Then Result:=Result+txt_sect4000000;
If AdwFlags and $8000000>0 Then Result:=Result+txt_sect8000000;
If AdwFlags and $10000000>0 Then Result:=Result+txt_sect10000000;
If AdwFlags and $20000000>0 Then Result:=Result+txt_sect20000000;
If AdwFlags and $40000000>0 Then Result:=Result+txt_sect40000000;
If AdwFlags and $80000000>0 Then Result:=Result+txt_sect80000000;
end;
procedure TPEObject.MakeBuffer;
Var i : Integer;
val : DWORD;
begin
// adding object name
For i:=1 To Length(OBJECT_NAME) Do
DATA[i]:=ORD(OBJECT_NAME[i]);
For i:=Length(OBJECT_NAME)+1 To 8 Do
DATA[i]:=0;
Val:=VIRTUAL_SIZE;
DATA[9]:=Val mod 256;Val:=Val div 256;
DATA[10]:=Val mod 256;Val:=Val div 256;
DATA[11]:=Val mod 256;Val:=Val div 256;
DATA[12]:=Val mod 256;
Val:=RVA;
DATA[13]:=Val mod 256;Val:=Val div 256;
DATA[14]:=Val mod 256;Val:=Val div 256;
DATA[15]:=Val mod 256;Val:=Val div 256;
DATA[16]:=Val mod 256;
Val:=PHYSICAL_SIZE;
DATA[17]:=Val mod 256;Val:=Val div 256;
DATA[18]:=Val mod 256;Val:=Val div 256;
DATA[19]:=Val mod 256;Val:=Val div 256;
DATA[20]:=Val mod 256;
Val:=PHYSICAL_OFFSET;
DATA[21]:=Val mod 256;Val:=Val div 256;
DATA[22]:=Val mod 256;Val:=Val div 256;
DATA[23]:=Val mod 256;Val:=Val div 256;
DATA[24]:=Val mod 256;
Val:=PointerToRelocations;
DATA[25]:=Val mod 256;Val:=Val div 256;
DATA[26]:=Val mod 256;Val:=Val div 256;
DATA[27]:=Val mod 256;Val:=Val div 256;
DATA[28]:=Val mod 256;
Val:=PointerToLinenumbers;
DATA[29]:=Val mod 256;Val:=Val div 256;
DATA[30]:=Val mod 256;Val:=Val div 256;
DATA[31]:=Val mod 256;Val:=Val div 256;
DATA[32]:=Val mod 256;
Val:= NumberOfRelocations;
DATA[33]:=Val mod 256;Val:=Val div 256;
DATA[34]:=Val mod 256;
Val:=NumberOfLinenumbers;
DATA[35]:=Val mod 256;Val:=Val div 256;
DATA[36]:=Val mod 256;
Val:=FLAGS;
DATA[37]:=Val mod 256;Val:=Val div 256;
DATA[38]:=Val mod 256;Val:=Val div 256;
DATA[39]:=Val mod 256;Val:=Val div 256;
DATA[40]:=Val mod 256;
end;
procedure TPEObject.Process;
begin
// Object Table: begins from 1F8h, 40 bytes as follows:
//*1..8 - object name
//*12..9 - virtual size (when loaded into memory)
//*16..13 - RVA (virtual address);
//*20..17 - size (of raw data);
//*24..21 - offset (pointer to raw data);
// 28..25 - PointerToRelocations
// 32..29 - PointerToLinenumbers
// 34..33 - NumberOfRelocations
// 36..35 - NumberOfLinenumbers
//*40..37 - flags (Characteristics);
// [ name ]
// [virtual size ] [RVA ] [ Size ] [ Offset]
// [ PtrToRelocs.] [ PtrToLinNum. ] [NOR][NOL] [ Flags ]
OBJECT_NAME:=Chr1(DATA[1])+Chr1(DATA[2])+Chr1(DATA[3])+Chr1(DATA[4])
+Chr1(DATA[5])+Chr1(DATA[6])+Chr1(DATA[7])+Chr1(DATA[8]);
RVA:=(DATA[16]*256+DATA[15])*256*256+DATA[14]*256+DATA[13];
PHYSICAL_OFFSET:=(DATA[24]*256+DATA[23])*256*256+DATA[22]*256+DATA[21];
PHYSICAL_SIZE:=(DATA[20]*256+DATA[19])*256*256+DATA[18]*256+DATA[17];
VIRTUAL_SIZE:=(DATA[12]*256+DATA[11])*256*256+DATA[10]*256+DATA[9];
FLAGS:=(DATA[40]*256+DATA[39])*256*256+DATA[38]*256+DATA[37];
PointerToRelocations:=(DATA[28]*256+DATA[27])*256*256+DATA[26]*256+DATA[25];
PointerToLinenumbers:=(DATA[32]*256+DATA[31])*256*256+DATA[30]*256+DATA[29];
NumberOfRelocations:=DATA[34]*256+DATA[33];
NumberOfLinenumbers:=DATA[36]*256+DATA[35];
end;
{ TPEHeader }
destructor TPEHeader.Destroy;
begin
inherited;
end;
procedure TPEHeader.Dump(PFile : ThePEFile);
var lPEHOffset : DWORD;
b1,b2 : Byte;
j,k : Integer;
begin
if bELF then begin
DumpElfFile(PFile);
ELFDumped:=True;
Exit;
end;
ELFDumped:=False;
PEFile:=PFile;
PEFile.PEStream.Seek(0,SoFromBeginning);
PEFile.Seek(DATA_FOR_PE_HEADER_OFFSET);
PEFile.Read(b1,b2);
lPEHOffset:=b1+b2*256;
PEHeaderOffset:=lPEHOffset;
Process;
PEFile.Seek(PE_HEADER_SIZE+lPEHOffset+PEPlusDelta);
For j:=1 To ObjectNum Do
Begin
//Objects[j]:=TPEObject.Create;
Objects[j].InfoAddress:=PEFile.FilePos;
SetLength(Objects[j].OBJECT_NAME,8);
PEFile.Stream.ReadBuffer(Objects[j].OBJECT_NAME[1],8);
For k:=1 to 8 do
if Objects[j].OBJECT_NAME[k]=#0 then
begin
Objects[j].OBJECT_NAME:=Copy(Objects[j].OBJECT_NAME,1,k-1);
Break;
end;
PEFile.Stream.ReadBuffer(Objects[j].VIRTUAL_SIZE,4);
PEFile.Stream.ReadBuffer(Objects[j].RVA,4);
PEFile.Stream.ReadBuffer(Objects[j].PHYSICAL_SIZE,4);
PEFile.Stream.ReadBuffer(Objects[j].PHYSICAL_OFFSET,4);
PEFile.Stream.ReadBuffer(Objects[j].PointerToRelocations,4);
PEFile.Stream.ReadBuffer(Objects[j].PointerToLinenumbers,4);
PEFile.Stream.ReadBuffer(Objects[j].NumberOfRelocations,2);
PEFile.Stream.ReadBuffer(Objects[j].NumberOfLinenumbers,2);
PEFile.Stream.ReadBuffer(Objects[j].FLAGS,4);
End;
//ProcessObjects;
end;
procedure TPEHeader.DumpELFFile(PFile : ThePEFile);
var ElfFile : TELFFile;
i,idx : Integer;
tmp : TPEObject;
begin
ElfFile:=TELFFile.Create(PFile.sFileName);
try
ElfFile.Dump;
PEHeader.ELFDumped:=True;
PEHeader.Signature:='ELF';
PEHeader.ObjectNum:=ElfFile.ELFHeader.SectionsCount;
if PEHeader.ObjectNum>High(PEHeader.Objects) then Raise Exception.Create('Too many ELF sections!');
//First Section is NULL
for i:=1 to PEHeader.ObjectNum-1 do
begin
PEHeader.Objects[i].OBJECT_NAME:=ElfFile.ELFHeader.Sections[i].SectionName;
PEHeader.Objects[i].VIRTUAL_SIZE:=ElfFile.ELFHeader.Sections[i].SHDR.sh_size;
PEHeader.Objects[i].RVA:=ElfFile.ELFHeader.Sections[i].SHDR.sh_addr;
PEHeader.Objects[i].PHYSICAL_OFFSET:=ElfFile.ELFHeader.Sections[i].SHDR.sh_offset;
PEHeader.Objects[i].PHYSICAL_SIZE:=ElfFile.ELFHeader.Sections[i].SHDR.sh_size;;
PEHeader.Objects[i].FLAGS:=ElfFile.ELFHeader.Sections[i].SHDR.sh_flags;
end;
PEHeader.RVA_ENTRYPOINT:=ElfFile.ELFHeader.ELF32HDR.e_entry;
PEHeader.BaseOfCode:=PEHeader.GetSectionIndex('.text');
idx:=PEHeader.GetSectionIndex('.rodata');
//Move the class data section first
if idx>1 then begin
tmp:=PEHeader.Objects[idx];
PEHeader.Objects[idx]:=PEHeader.Objects[1];
PEHeader.Objects[1]:=tmp;
end;
PEHeader.IMAGE_BASE:=0;
finally
ElfFile.Free;
end;
end;
function TPEHeader.GetPEObjectData(AsRVA: String; Var AiOffset,
AiSize: Integer): Boolean;
Var i : Integer;
begin
For i:=1 To ObjectNum Do
Begin
If Objects[i].RVA=Hex2DWord(AsRVA) Then Break;
End;
If Objects[i].RVA=Hex2DWord(AsRVA)
Then Begin
Result:=True;
AiOffset:=Objects[i].PHYSICAL_OFFSET;
AiSize:=Objects[i].PHYSICAL_SIZE;
End
Else Begin
For i:=1 To ObjectNum Do
Begin
If Objects[i].RVA>Hex2DWord(AsRVA) Then Break;
End;
AiOffset:=Objects[i-1].PHYSICAL_OFFSET+(Hex2DWord(AsRVA)-Objects[i-1].RVA);
AiSize:=-1;
If Hex2DWORD(AsRVA)=0
Then Result:=False
Else Result:=True;
End;
end;
function TPEHeader.GetSectionIndex(AsSect: String): Integer;
Var i : Integer;
begin
// Result:=GetSectionIndexEx(AsSect);
Result:=-1;
If ObjectNum=0 Then Exit;
For i:=1 To ObjectNum Do
If Objects[i].OBJECT_NAME=AsSect Then Break;
If Objects[i].OBJECT_NAME=AsSect Then Result:=i;
end;
function TPEHeader.GetSectionIndexByRVA(RVA: DWORD): Integer;
Var i : Integer;
begin
Result:=-1;
If ObjectNum=0 Then Exit;
{ for i:=1 to PEHeader.ObjectNum Do
If ABS(PEHeader.Objects[i].RVA-RVA)<$10 then break;
If ABS(PEHeader.Objects[i].RVA-RVA)<$10 then Result:=i;}
for i:=1 to PEHeader.ObjectNum Do
If PEHeader.Objects[i].RVA=RVA then break;
If PEHeader.Objects[i].RVA=RVA then Result:=i;
end;
function TPEHeader.GetSectionIndexEx(AsSect: String): Integer;
var i : Integer;
RVA : DWORD;
begin
Result:=-1;
//Elf file support. The mapping is not exactly 100% :(
if bELF then begin
if AsSect='CODE' then AsSect:='.text';
if AsSect='DATA' then AsSect:='.data';
if AsSect='.idata' then AsSect:='.dynsym';
if AsSect='.rsrc' then AsSect:='borland.resdata';
if AsSect='BSS' then AsSect:='.bss';
Result:=GetSectionIndex(AsSect);
end
else begin
if AsSect='CODE' then Result:=GetSectionIndexByRVA(self.BaseOfCode);
if AsSect='DATA' then Result:=GetSectionIndexByRVA(self.BaseOfData);
if AsSect='.idata' then Result:=GetSectionIndexByRVA(self.IMPORT_TABLE_RVA);
if AsSect='.rsrc' then Result:=GetSectionIndexByRVA(self.RESOURCE_TABLE_RVA);
if AsSect='BSS' then
begin
Result:=-1;
RVA:=self.BaseOfData;
If ObjectNum=0 Then Exit;
// Try to find the BSS section as the first section after the data section
// that has zero phisical length. This will not be 0 length if the file is
// memory mirror
for i:=1 to PEHeader.ObjectNum Do
If (PEHeader.Objects[i].RVA>RVA) and (PEHeader.Objects[i].PHYSICAL_SIZE=0) then break;
If (PEHeader.Objects[i].RVA>RVA) and (PEHeader.Objects[i].PHYSICAL_SIZE=0) then Result:=i;
if Result<>-1 then exit;
//now return it as the 3-th section
Result:=3;
end;
end;
end;
procedure TPEHeader.Process;
var wCPU,wSubSys, wDLL, wOptionalPEType : Word;
bIsPEPlus : Boolean;
// PlusDelta : Integer;
lPEHOffset : Word;
b1,b2 : Byte;
begin
// PE Header:
PEFile.PEStream.Seek(DATA_FOR_PE_HEADER_OFFSET,soFromBeginning);
PEFile.PEStream.ReadBuffer(lPEHOffset,2);
PEFile.PEStream.Seek(lPEHOffset,soFromBeginning);
{REAL PE HEADER}
SetLength(Signature,4);
PEFile.PEStream.ReadBuffer(Signature[1],4);
If Copy(Signature,1,2)<>'PE' Then
Raise Exception.Create(err_bad_signature+Copy(Signature,1,2)+#13#10+err_d1_not_supported);
PEFile.PEStream.ReadBuffer(wCPU,2);
Case wCPU of
0: CPU:='unknown';
$184: CPU:='Alpha AXP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -