⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dedeclasses.pas

📁 dede 的源代码 3.10b
💻 PAS
📖 第 1 页 / 共 3 页
字号:

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 + -