Program himXML_DLL_Modifizierer;
{$APPTYPE CONSOLE}
Uses Windows, SysUtils;
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;
Type TSectionName =
packed Array[0..IMAGE_SIZEOF_SHORT_NAME-1]
of AnsiChar;
Var N:
String;
H, M: THandle;
DOSHeader: ^IMAGE_DOS_HEADER;
NTHeaders: ^IMAGE_NT_HEADERS;
SectionHeader: ^IMAGE_SECTION_HEADER;
ImageSection: PAnsiChar;
ExportDirectory: ^IMAGE_EXPORT_DIRECTORY;
Names: PCardinal;
InitProcedure, i: Integer;
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');
NTHeaders := Pointer(Integer(DOSHeader) + DOSHeader._lfanew);
If NTHeaders.Signature = IMAGE_NT_SIGNATURE
Then Begin
WriteLn('
search image and export section');
SectionHeader := Pointer(Integer(NTHeaders) + SizeOf(IMAGE_NT_HEADERS));
ImageSection :=
nil;
ExportDirectory :=
nil;
i := 0;
While i < NTHeaders.FileHeader.NumberOfSections
do Begin
WriteLn('
section "' + TSectionName(SectionHeader.
Name) + '
" found');
If TSectionName(SectionHeader.
Name) = '
.data'
Then
If ImageSection <>
nil Then Begin
ImageSection := Pointer(1);
WriteLn('
found more than one .data sections');
End Else ImageSection := Pointer(Integer(DOSHeader) + SectionHeader.PointerToRawData);
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(ImageSection) > 1
Then Begin
If Cardinal(ExportDirectory) > 1
Then Begin
asm int 3
end;
WriteLn('
search the init procedure');
InitProcedure := 0;
Names := Pointer(ImageSection + Integer(ExportDirectory.AddressOfNames));
i := -1;
While i < ExportDirectory.NumberOfNames
do Begin
WriteLn('
procedure/function "' + PAnsiChar(Integer(ImageSection) + Names^) + '
" found');
If PAnsiChar(Integer(ImageSection) + 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 NTHeaders.OptionalHeader.AddressOfEntryPoint <> 0
Then ;
WriteLn('
OK');
End Else WriteError('
not found');
End Else WriteLn('
export section not found');
End Else WriteLn('
image section 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.