Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

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

Re: DLL-EntryPoint mit Funktion tauschen?

  Alt 4. Jul 2009, 14:05
Nein, das ist nicht schneller.

Denn wie ich grad mitbekommen habe, stehen die Adressen in diesem Directory als RVA drin
und demnach muß ich dennoch die Sektionen durchgehn und schauen wo es denn nun wirklich drin ist.

Aber da ich nun eine RVA2Pointer-Funktion hab und über das Directory vom Namen unabhängig bin, hab ich das Directory jetzt verwendet.

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) = '.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;
            {}ExportDirectory := RVA2RealPointer(NTHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
            If Cardinal(ExportDirectory) > 1 Then Begin
              WriteLn('search the init procedure');
              Names := RVA2RealPointer(LongWord(ExportDirectory.AddressOfNames));
              InitProcedure := -1;
              i := 0;
              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.
Aber jetzt muß ich dennoch testen, ob der EntryPoint ebenfalls als RVA definiert ist,
aber bei einem Wert von 213956 ( $000343C4 ) geh ich mal stark davon auß und müßte jetzt also nur noch die beiden Werte austauschen
$2B or not $2B
  Mit Zitat antworten Zitat