1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
program RealName;
{$APPTYPE CONSOLE}
uses
Classes,SysUtils;
type
IMAGE_DOS_HEADER=packed record { DOS .EXE header }
magic : word; { Magic number }
cblp : word; { Bytes on last page of file }
cp : word; { Pages in file }
crlc : word; { Relocations }
cparhdr : word; { Size of header in paragraphs }
minalloc: word; { Minimum extra paragraphs needed }
maxalloc: word; { Maximum extra paragraphs needed }
ss : word; { Initial (relative) SS value }
sp : word; { Initial SP value }
csum : word; { Checksum }
ip : word; { Initial IP value }
cs : word; { Initial (relative) CS value }
lfarlc : word; { File address of relocation table }
ovno : word; { Overlay number }
res : array[0..3] of word; { Reserved words }
oemid : word; { OEM identifier }
oeminfo : word; { OEM information }
res2 : array[0..9] of word; { Reserved words }
lfanew : longint; { File address of new exe header }
end;
IMAGE_FILE_HEADER=packed record
Machine : word; { Intel 386 = $014C }
NumberOfSections : word;
TimeDateStamp : longint;
PointerToSymbolTable : longint;
NumberOfSymbols : longint;
SizeOfOptionalHeader : word;
Characteristics : word;
end;
IMAGE_OPTIONAL_HEADER=packed record
Magic : word;
MajorLinkerVersion : byte;
MinorLinkerVersion : byte;
SizeOfCode : longint;
SizeOfInitializedData : longint;
SizeOfUninitializedData : longint;
AddressOfEntryPoint : longint;
BaseOfCode : longint;
BaseOfData : longint;
ImageBase : longint;
SectionAlignment : longint;
FileAlignment : longint;
MajorOperatingSystemVersion : word;
MinorOperatingSystemVersion : word;
MajorImageVersion : word;
MinorImageVersion : word;
MajorSubsystemVersion : word;
MinorSubsystemVersion : word;
Win32VersionValue : longint;
SizeOfImage : longint;
SizeOfHeaders : longint;
Checksum : longint;
Subsystem : word;
DllCharacteristics : word;
SizeOfStackReserve : longint;
SizeOfStackCommit : longint;
SizeOfHeapReserve : longint;
SizeOfHeapCommit : longint;
LoaderFlags : longint;
NumberOfRvaAndSizes : longint;
end;
IMAGE_NT_HEADERS=packed record
Signature : array[0..3] of char; { 'PE'00 }
FileHeader : IMAGE_FILE_HEADER;
OptionalHeader: IMAGE_OPTIONAL_HEADER;
end;
IMAGE_DATA_DIRECTORY=packed record
VirtualAddress:longint;
Size :longint;
end;
IMAGE_SECTION_HEADER=packed record
Name : array[0..7] of char;
VirtualSize : longint; { PhysicalAddress }
VirtualAddress : cardinal;
SizeOfRawData : longint;
PointerToRawData : longint;
PointerToRelocations: longint;
PointerToLinenumbers: longint;
NumberOfRelocations : word;
NumberOfLinenumbers : word;
Characteristics : cardinal;
end;
IMAGE_EXPORT_DESCRIPTOR=packed record
Characteristics : cardinal;
TimeDateStamp : cardinal;
MajorVersion : word;
MinorVersion : word;
Name : cardinal;
Base : cardinal;
NumberOfFunctions : cardinal;
NumberOfNames : cardinal;
AddressOfFunctions : cardinal;
AddressOfNames : cardinal;
AddressOfNameOrdinals : cardinal;
end;
const
sign:array[0..3] of char='PE'#0#0;
var
dllname:string;
name :string;
stream :TFileStream;
dos :IMAGE_DOS_HEADER;
pe :IMAGE_NT_HEADERS;
dd :IMAGE_DATA_DIRECTORY;
va :integer;
i :integer;
sh :IMAGE_SECTION_HEADER;
ed :IMAGE_EXPORT_DESCRIPTOR;
begin
dllname:=ParamStr(1);
name:='unknown';
if dllname='' then exit;
stream:=TFileStream.Create(dllname,fmOpenRead);
try
// entête DOS
stream.ReadBuffer(dos,SizeOf(dos));
if dos.magic<>$5A4D then exit;
stream.Position:=dos.lfanew;
// entête Windows
WriteLn('@PE=',IntToHex(stream.Position,4));
stream.ReadBuffer(pe,SizeOf(pe));
if cardinal(pe.Signature)<>cardinal(sign) then exit;
// adresse de la section d'import
WriteLn('@DD',i,'=',IntToHex(stream.Position,4));
stream.ReadBuffer(dd,SizeOf(dd));
va:=dd.VirtualAddress;
WriteLn('@header=$',IntToHex(va,8));
// on saute les 15 autres entrées (import,Resource, Exception, Security,...)
stream.Seek(15*SizeOf(dd),soFromCurrent);
// on cherche dans les entêtes qui suivent
for i:=1 to pe.FileHeader.NumberOfSections do begin
stream.ReadBuffer(sh,SizeOf(sh));
// celle qui a la bonne adresse virtuelle
if sh.VirtualAddress=va then begin
WriteLn('@data=$',IntToHex(sh.PointerToRawData,8));
// à sa position réelle dans le fichier
stream.Position:=sh.PointerToRawData;
// on lit l'entête d'exportation
stream.ReadBuffer(ed,SizeOf(ed));
WriteLn('@name=$',IntToHex(ed.Name,8));
// qui contient l'adresse du nom qu'on cherche
stream.Position:=sh.PointerToRawData+ed.Name-va;
// qui voici :D
SetLength(name,80);
stream.ReadBuffer(name[1],80);
name:=pchar(name);
break;
end;
end;
WriteLn('RealName=',name);
ReadLn;
finally
stream.Free
end;
end. |