Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#12

Re: DLL-EntryPoint mit Funktion tauschen?

  Alt 4. Jul 2009, 13:49
@Apollonius: uffff, na dann mal sehn ob ich das mit dem IMAGE_DATA_DIRECTORY auch noch hinbekomm
(aber aktuell geht es ja erstmal)

Was ich mich dann aber noch frage ist, gibt es dann 2 Exporttabellen, welche ich ändern muß, oder sind Beides die "Selben" (also die in .edata und IMAGE_DATA_DIRECTORY)



Ohhh, na dann hi MrEmbreD

Nja, cryptisch war's ja nicht ... nur etwas "eigenartig" berechnet.
Aber hatte ja dennoch durch deinen Code den Weg gefunden und dank dem Hinweis von Apollonius wird nun auch die Prozedurliste ausgelesen.

jetzt muß ich nur noch rausbekommen, ob IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoin t auch als RVA definiert ist,
oder ob ich mir das auch noch umrechnen muß.

Delphi-Quellcode:
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) = '.edataThen
                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^)) = 'initDLLThen
                  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.
$2B or not $2B
  Mit Zitat antworten Zitat