📄 elfutils.pas
字号:
function TELFSection.Name: string;
begin
Result := FParent.ReadString(FHeader^.sh_name);
end;
//////////////////////////////////////////////////////////////////////
procedure TELFSection.ProcessSymtab(q: integer);
{const
types: array[0..15] of string = ('N/A', 'Object', 'Function',
'Section', 'File', '','','','','','','','','Lo Proc','','Hi Proc');
type
TSymbolTable = array[0..0] of TElf32SymbolEntry;
PSymbolTable = ^TSymbolTable;
var
section: TElfSection;
sym: PSymbolTable;
i: integer;}
begin
{ section := FParent.Sections[FHeader^.sh_link];
sym := @(data^);
if FHeader^.sh_type = SECTION_TYPE_SYMTAB then
for i := 0 to (FHeader^.sh_size div FHeader^.sh_entsize) - 1 do if sym^[i].sectionIndex < SECTION_LORESERVE then begin
printf(Format('%-33s is at $%8.8x, of type %-8s and size %-4d]', [section.ReadString(sym^[i].st_name), sym^[i].st_value, types[sym^[i].st_info and $F], sym^[i].st_size]));
end;}
end;
//////////////////////////////////////////////////////////////////////
function TELFSection.ReadElfString(index: integer): string;
begin
if (index < $FF00) and (FHeader^.sh_type = SECTION_TYPE_STRTAB) then
Result := PChar(@(data^[index]))
else
Result := '';
end;
//////////////////////////////////////////////////////////////////////
// TReadableResource /////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadUint8: uint32;
begin
Result := Puint8(dataPointer)^;
dataPointer := pointer(integer(dataPointer) + 1);
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadInt8: int32;
begin
Result := Pint8(dataPointer)^;
dataPointer := pointer(integer(dataPointer) + 1);
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadUint16: uint32;
begin
Result := Puint16(dataPointer)^;
dataPointer := pointer(integer(dataPointer) + 2);
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadInt16: int32;
begin
Result := Pint16(dataPointer)^;
dataPointer := pointer(integer(dataPointer) + 2);
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadUint32: uint32;
begin
Result := Puint32(dataPointer)^;
dataPointer := pointer(integer(dataPointer) + 4);
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadInt32: int32;
begin
Result := Pint32(dataPointer)^;
dataPointer := pointer(integer(dataPointer) + 4);
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadUint64: uint32;
begin
// fixme!
ReadUint32;
Result := ReadUint32;
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadInt64: int32;
begin
ReadInt32;
Result := ReadInt32;
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadLEB128: uint32;
var
shift: integer;
b: byte;
begin
Result := 0;
shift := 0;
repeat
b := ReadUint8;
Result := Result or ((b and $7F) shl shift);
shift := shift + 7;
until b and (1 shl 7) = 0;
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadSLEB128: int32;
var
shift: integer;
b: byte;
begin
Result := 0;
shift := 0;
repeat
b := ReadUint8;
Result := Result or ((b and $7F) shl shift);
shift := shift + 7;
until b and (1 shl 7) = 0;
if (shift < 32) and (b and (1 shl 6) <> 0) then
Result := Result or (-(1 shl shift));
end;
//////////////////////////////////////////////////////////////////////
procedure TReadableResource.ReadBlock(var block; size: uint32);
begin
Move((dataPointer)^, block, size);
dataPointer := pointer(uint32(dataPointer) + size);
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadString: PChar;
begin
Result := dataPointer;
dataPointer := pointer(integer(dataPointer) + Length(Result) + 1);
end;
//////////////////////////////////////////////////////////////////////
function TReadableResource.ReadAddress: uint32;
begin
Result := ReadUint32;
end;
//////////////////////////////////////////////////////////////////////
procedure TReadableResource.SeekRelAddress(offset: integer);
begin
dataPointer := pointer(integer(dataPointer) + offset);
end;
//////////////////////////////////////////////////////////////////////
procedure TReadableResource.Seek(absOffset: integer);
begin
dataPointer := pointer(integer(data) + absOffset);
end;
//////////////////////////////////////////////////////////////////////
// TElfFile //////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
procedure TELFFile.Build;
var
i: uint32;
section: TElfSection;
begin
// Load the sections into their own classes
FSections := TObjectList.Create;
for i := 0 to header^.numSectionEntries - 1 do begin
section := TElfSection.Create(self, @(data^[header^.sectionTableOffset + i * SizeOf(TElf32SectionHeader)]));
FSections.Add(section);
end;
end;
//////////////////////////////////////////////////////////////////////
constructor TELFFile.Create(stream: TStream);
begin
// Read in the data from the stream
size := stream.Size;
GetMem(data, size);
stream.Read(data^, size);
// Access the header
header := PElf32Header(data);
// Verify its a valid version 1 little-endian executable 32-bit ARM ELF file
if (header.ident[ELF_INDEX_MAGIC0] = ELF_MAGIC0) and
(header.ident[ELF_INDEX_MAGIC1] = ELF_MAGIC1) and
(header.ident[ELF_INDEX_MAGIC2] = ELF_MAGIC2) and
(header.ident[ELF_INDEX_MAGIC3] = ELF_MAGIC3) and
(header.ident[ELF_INDEX_CLASS] = ELF_CLASS_32) and
(header.ident[ELF_INDEX_DATA] = ELF_DATA_LSB) and
(header.ident[ELF_INDEX_VERSION] = ELF_VERSION_CURRENT) and
(header.elfType = ELF_TYPE_EXEC) and
(header.machine = ELF_MACHINE_ARM) and
(header.version = ELF_VERSION_CURRENT) then else Free;
end;
//////////////////////////////////////////////////////////////////////
destructor TELFFile.Destroy;
begin
FreeMem(data, size);
FSections.Free;
inherited;
end;
//////////////////////////////////////////////////////////////////////
function TELFFile.FindSectionByName(name: string): TElfSection;
var
index: integer;
begin
for index := 0 to NumSections - 1 do begin
Result := Sections[index];
if Result.name = name then Exit;
end;
Result := nil;
end;
//////////////////////////////////////////////////////////////////////
function RoundUpToPow2(num: uint32): uint32;
begin
Result := 1;
while Result < num do Result := Result shl 1;
end;
//////////////////////////////////////////////////////////////////////
// Flattens any run-time active segments into a linear image, stored
// in data, and returns the size of this image
function TELFFile.Flatten(var data: Puint8array): integer;
var
acc, size: longword;
i: integer;
section: TElfSection;
begin
size := 0;
for i := 0 to NumSections - 1 do begin
section := Sections[i];
if section.HasSubstance then Inc(size, section.FHeader.sh_size);
end;
// Spew the segments into a memory buffer
Result := RoundUpToPow2(size);
GetMem(data, Result);
acc := 0;
for i := 0 to NumSections - 1 do begin
section := Sections[i];
if section.HasSubstance then begin
Move(section.data^, data^[acc], section.FHeader.sh_size);
acc := acc + section.FHeader.sh_size;
end;
end;
end;
//////////////////////////////////////////////////////////////////////
function TELFFile.GetSection(index: integer): TElfSection;
begin
Result := TElfSection(FSections.Items[index]);
end;
//////////////////////////////////////////////////////////////////////
function TELFFile.NumSections: integer;
begin
Result := FSections.Count;
end;
//////////////////////////////////////////////////////////////////////
function TELFFile.ReadString(index: integer): string;
begin
if (header^.stringTableIndex > 0) and (header^.stringTableIndex < SECTION_LORESERVE) then
Result := Sections[header^.stringTableIndex].ReadElfString(index)
else
Result := '';
end;
//////////////////////////////////////////////////////////////////////
end.
//////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -