Program himXML_DLL_Modifizierer;
{$APPTYPE CONSOLE}
Uses Windows, SysUtils;
Type TSectionName =
packed Array[0..IMAGE_SIZEOF_SHORT_NAME-1]
of AnsiChar;
Var N:
String;
H, M: THandle;
DOSHeader: ^IMAGE_DOS_HEADER;
NTHeader: ^IMAGE_NT_HEADERS;
SectionHeader: ^IMAGE_SECTION_HEADER;
ExportDirectory: ^IMAGE_EXPORT_DIRECTORY;
Names: PCardinal;
InitProcedure, i: Integer;
Procedure WriteLn(
Const S:
String);
Var OEMBuffer:
Array[0..2047]
of AnsiChar;
Begin
CharToOem(PChar(S), @OEMBuffer);
System.WriteLn(OEMBuffer);
End;
Procedure WriteError(
Const S:
String);
Var S2:
String;
Begin
S2 := SysErrorMessage(GetLastError);
WriteLn(S + '
>> ' + S2);
End;
Function RVA2RealPointer(RVA: LongWord): Pointer;
Var
SectionHeader2: ^IMAGE_SECTION_HEADER;
i2: Integer;
Begin
Result :=
nil;
SectionHeader := Pointer(Integer(NTHeader) + SizeOf(IMAGE_NT_HEADERS));
i2 := 0;
While i2 < NTHeader.FileHeader.NumberOfSections
do Begin
If (RVA < SectionHeader.VirtualAddress + SectionHeader.SizeOfRawData)
and (RVA >= SectionHeader.VirtualAddress)
Then
If Result <>
nil Then Begin
Result := Pointer(1);
WriteLn('
found more than one sections that includet this RVA');
End Else Result := Pointer(Integer(DOSHeader) + SectionHeader.PointerToRawData
- SectionHeader.VirtualAddress + RVA);
Inc(SectionHeader);
Inc(i2);
End;
If Cardinal(Result) = 1
Then Result :=
nil;
End;
Begin
Try
N := ExtractFilePath(ParamStr(0)) + '
himXML_DLL.dll';
WriteLn('
open "' + N + '
"');
H := CreateFile(PChar(N), GENERIC_READ
or GENERIC_WRITE, FILE_SHARE_READ,
nil, OPEN_EXISTING, 0, 0);
If H <> INVALID_HANDLE_VALUE
Then Begin
WriteLn('
load file data');
M := CreateFileMapping(H,
nil, PAGE_READWRITE, 0, 0,
nil);
DOSHeader := MapViewOfFile(M, FILE_MAP_READ
or FILE_MAP_WRITE, 0, 0, 0);
If (M <> 0)
and Assigned(DOSHeader)
Then Begin
WriteLn('
check IMAGE_DOS_HEADER');
If DOSHeader.e_magic = IMAGE_DOS_SIGNATURE
Then Begin
WriteLn('
search and check IMAGE_NT_HEADERS');
NTHeader := Pointer(Integer(DOSHeader) + DOSHeader._lfanew);
If NTHeader.Signature = IMAGE_NT_SIGNATURE
Then Begin
WriteLn('
search export section');
SectionHeader := Pointer(Integer(NTHeader) + SizeOf(IMAGE_NT_HEADERS));
ExportDirectory :=
nil;
i := 0;
While i < NTHeader.FileHeader.NumberOfSections
do Begin
WriteLn('
section "' + TSectionName(SectionHeader.
Name) + '
" found');
If TSectionName(SectionHeader.
Name) = '
.edata'
Then
If ExportDirectory <>
nil Then Begin
ExportDirectory := Pointer(1);
WriteLn('
found more than one .edata sections');
End Else ExportDirectory := Pointer(Integer(DOSHeader) + SectionHeader.PointerToRawData);
Inc(SectionHeader);
Inc(i);
End;
If Cardinal(ExportDirectory) > 1
Then Begin
WriteLn('
search the init procedure');
Names := RVA2RealPointer(LongWord(ExportDirectory.AddressOfNames));
InitProcedure := 0;
i := -1;
While i < ExportDirectory.NumberOfNames
do Begin
WriteLn('
procedure "' + PAnsiChar(RVA2RealPointer(Names^)) + '
" found');
If PAnsiChar(RVA2RealPointer(Names^)) = '
initDLL'
Then
If InitProcedure <> -1
Then Begin
InitProcedure := -2;
WriteLn('
found more than one init procedures');
End Else InitProcedure := i;
Inc(Names);
Inc(i);
End;
If InitProcedure >= 0
Then Begin
If NTHeader.OptionalHeader.AddressOfEntryPoint <> 0
Then ;
WriteLn('
OK');
End Else WriteError('
not found');
End Else WriteLn('
not found');
End Else WriteError('
not found');
End Else WriteError('
not found');
UnmapViewOfFile(DOSHeader);
End Else WriteError('
can''
t load');
CloseHandle(M);
End Else WriteError('
no access to file or not exists');
CloseHandle(H);
Except
On E:
Exception do WriteLn(E.Classname + '
: ' + E.
Message);
End;
ReadLn;
End.