Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi import / export tables zweier .dlls vergleichen (https://www.delphipraxis.net/47760-import-export-tables-zweier-dlls-vergleichen.html)

Arnulf 15. Jun 2005 22:16


import / export tables zweier .dlls vergleichen
 
Hi
Ich kämpf mich gerade durch data directorys und wie ein kleines kind spiel ich damit herum :)
Ich wollte vor allem fragen, ob ich da völligen unsinn gemacht hab, oder ob das im prinzip richtig ist:

INH1 und INH2 sind bereits die pointer zu den ntheaders.

Delphi-Quellcode:
           ////////////////////////
           /// import tables

           ImpTableSize1 := INH1^.OptionalHeader.DataDirectory[1].Size;
           ImpTableSize2 := INH2^.OptionalHeader.DataDirectory[1].Size;

           ImpTable1 := pointer(pointer(integer(INH1)+integer(sizeof(TIMAGEDATADIRECTORY))*sizeof(IMAGE_DIRECTORY_ENTRY_IMPORT)));
           ImpTable2 := pointer(pointer(integer(INH2)+integer(sizeof(TIMAGEDATADIRECTORY))*sizeof(IMAGE_DIRECTORY_ENTRY_IMPORT)));

           if ImpTableSize1 <> ImpTableSize2 then
              MessageBox(0,'imptable size wrong',nil,0)//result := false;
           else if not comparemem(ImpTable1,ImpTable2,ImpTableSize1) then
                              MessageBox(0,'imptable not same',nil,0);//result := false;;

            ///////////////////////
            ///// export table
           ExpTableSize1 := INH1^.OptionalHeader.DataDirectory[0].Size;
           ExpTableSize2 := INH2^.OptionalHeader.DataDirectory[0].Size;

           pExportDirectory1 := pointer(pointer(integer(INH1)+integer(sizeof(TIMAGEDATADIRECTORY))*sizeof(IMAGE_DIRECTORY_ENTRY_EXPORT)));
           pExportDirectory2 := pointer(pointer(integer(INH2)+integer(sizeof(TIMAGEDATADIRECTORY))*sizeof(IMAGE_DIRECTORY_ENTRY_EXPORT)));

           if ExpTableSize1 <> ExpTableSize2 then
              MessageBox(0,'imptable size wrong',nil,0)//result := false;
           else if not comparemem(pExportDirectory1,pExportDirectory2,ExpTableSize1) then
                              MessageBox(0,'exptable not same',nil,0);//result := false;;
Da ich wirklich kompletter Anfänger bin, hoffe ich es sagt mir jemand ob das kompletter unsinn ist oder es nur reines glück ist, daß mir das nicht abstürtzt :).

Danke
Arnulf
Edit: bezugnehmend auf diesen thread: http://www.delphipraxis.net/internal...ll+vergleichen

brechi 10. Jul 2005 18:01

Re: import / export tables zweier .dlls vergleichen
 
naja ganz falsch ist es nicht
ABER:
du weißt denk ich noch nicht ganz was es mit der ImportTabelle/ExportTabelle auf sich hat.

Die Exporttabelle liegt in einer DLL (in deinem fall opengl32.dll) und wenn nun eine andere dll bzw die programmexe versucht GetProcAddress(oglhandle,'exportiertefunktion') aufruft dann ist das ergebniss de adresse die die opengl32.dll exportiert

d.h. du kannst das ohne probleme checken ob es stimmt -> die in dem spiel und bei dir im spiecher muss die selbe sein WENN beide dlls die selbe basis haben.

die ImportTabelle lädt statsich eine funktion von einer anderen dll, d.h. jede DLL kann in ihrer ImportTabelle eine funktion von der opengl32.dll importieren, nur die opengl32.dll nicht sich selber.

d.h. du musst ALLE dlls durchschaun ob eine funktion von der opengl32.dll importiert wird und wenn JA ob sie mit der ExportTabelle übereinstimmt.

d.h. dein beispiel wäre nur für die ExportTabelle korrekt nicht aber dür die ImportTabelle da musst du das für die anderen dlls, bzw die programmexe machen

Arnulf 10. Jul 2005 21:26

Re: import / export tables zweier .dlls vergleichen
 
Ahaaa... glaub ich :)
wenn ichs richtig verstehe muß ich einfach mal alle geladenen .dlls nach dem import von glbegin durchsuchen.
Da ich die game .dlls ja kenne weiß ich ja welche das importieren darf.
Dann überprüfe ich die import tabelle von der game.exe und den game.dlls die ogl benutzen und gleiche die mit der export tabelle meiner opengl32.dll library ab.

klingt für mich logisch, daß die funktion glbegin in der import table gleich ist wie die function glbegin in der export table der .dll selbst.

Wenn das stimmt verstehe ich das prinzip.
Was allerdings relocation ist ist mir dann immer noch schleierhaft :)

Arnulf

Edit: etwas interessantes hab ich noch gefunden - das programm nennt sich dependiant walker oder so.
Damit sieht man welche librarys ein programm oder eine .dll benutzt.
Wäre das einfacher, als die import table nach einer bestimmten funktion zu durchsuchen?

brechi 10. Jul 2005 21:40

Re: import / export tables zweier .dlls vergleichen
 
die ImportTabelle ist ne tabelle von mehreren dlls die importiert werden

| | | | addrn | addrf |


die ||symbolisieren dabei einen cardinal

addrn zeigt auf den namen der dll als pchar
addrf zeigt auf ne 2 tabelle mit adressen zu den pchars der einzelnen funktionen

hier mal nen auszug aus meinem crypter:

Delphi-Quellcode:
type TImportStruct = packed record
    res1,res2,res3,dllnameaddr,firstthunkaddr,
    res4,res5,res6,res7,res8: integer;
    f1,f2,f3,f4, f5: integer;
    s1: string[14];
    w1: word;
    s2: string[15];
    w2: word;
    s3: string[13];
    w3: word;
    s4: string[15];
    w4: word;
    s5: string[17];
  end;

function AddImport(p: pointer; mymem: integer): integer;
var ImportStruct: TImportStruct;
begin
  ZeroMemory(@ImportStruct,sizeof(TImportStruct));
  with ImportStruct do
  begin
    s1 := 'kernel32.dll';
    s2 := 'GetProcAddress';
    s3 := 'LoadLibraryA';
    s4 := 'VirtualProtect';
    s5 := 'GetModuleHandleA';
    dllnameaddr := MyVirtualMem+integer(@s1[1])-integer(@ImportStruct);
    firstthunkaddr := MyVirtualMem+integer(@f1)-integer(@ImportStruct);
    f1 := MyVirtualMem+integer(@w1)-integer(@ImportStruct)+1;
    f2 := MyVirtualMem+integer(@w2)-integer(@ImportStruct)+1;
    f3 := MyVirtualMem+integer(@w3)-integer(@ImportStruct)+1;
    f4 := MyVirtualMem+integer(@w4)-integer(@ImportStruct)+1;
  end;
  CopyMemory(p,@ImportStruct,sizeof(TImportStruct));
  result := sizeOf(TImportStruct);
end
vielleicht erkennst daraus den aufbau
ist ahlt nur für die paar funktionen die ich importiere

meine uallCollection hat auch nen "ImportWalker", da kannst sdir ja anschaun wie du da durchegehn musst um die importtabelle zu überprüfen

Arnulf 11. Jul 2005 21:31

Re: import / export tables zweier .dlls vergleichen
 
Hi
Die Source oben ist mir nur bedingt verständlich :)
Import Walker hab ich nicht wirklich gefunden dafür aber
Zitat:

function HookApiIAT
was vermutlich das selbe ist - das verstehe ich... - ist nett so bekomm ich auf jeden fall mal die adresse der funktion.
ist die import table für eine function immer 4 bytes lang?
Delphi-Quellcode:
thunks := pointer(integer(thunks)+4);
Arnulf

Arnulf 13. Jul 2005 14:03

Re: import / export tables zweier .dlls vergleichen
 
hallo nochmal .... - ich glaub nicht, daß ich damit klar komme :(.

Ich wollte den gameprozess mal öffnen und mir die import tabelle mal anschauen - damit ich sie nachher vergleichen kann.
mein kläglicher Versuch schaut so aus:

Delphi-Quellcode:
processname := 'spearhead.exe';
glfunction := 'glbegin';
  pr := FindProcess(processname);
  if pr = 0 then
    exit
    else
    pr := OpenProcess(PROCESS_ALL_ACCESS,false,pr);
    IDH := pointer(pr);
    if IDH^.e_magic = IMAGE_DOS_SIGNATURE then
Das geht natürlich nicht ... leider.
ich hab auch probiert erstmal mit virtual protect zuzugreifen - aber hab auch versagt.

Delphi-Quellcode:
VirtualProtect(pointer(pr),sizeof(TImageDosHeader),PAGE_EXECUTE_READWRITE,old)
Die theorie hab ich zwar halbwegs begriffen, aber ich versag völlig bei dem herumhantieren mit pointern und behalte meißtens auch nicht den überblick wo ich mich gerade befinde ..... leider.

Arnulf

Arnulf 14. Jul 2005 12:16

Re: import / export tables zweier .dlls vergleichen
 
Also ich versteh den import struct einfach nicht..
Irgendwie verstehe ich die struktur dahinter nicht.

Ich denk mal so komm ich sicher nicht an den namen der importierten function?...

Delphi-Quellcode:
function CheckImports (phandle : pointer): boolean;
  type timportblock = record
                        Characteristics: cardinal;
                        TimeDateStamp: cardinal;
                        ForwarderChain: cardinal;
                        Name: pchar;
                        FirstThunk: pointer;
                      end;
       pimportblock = ^timportblock;
var IDH1 : PImageDosHeader;
    INH1 : PImageNtHeaders;
    ImpTable1 : pimportblock;
    thunks: ^pointer;
    funcname : pchar;
    old : cardinal;
begin
IDH1 := phandle;
if (IDH1^.e_magic = IMAGE_DOS_SIGNATURE) then
begin
Form1.Memo1.Lines.Add('dll found');
INH1 := pointer(integer(idh1)+integer(IDH1^._lfanew));
impTable1 := pointer(integer(idh1)+integer(inh1^.OptionalHeader.DataDirectory[1].VirtualAddress));

    while (impTable1^.FirstThunk <> nil) do
    begin
      thunks := pointer(integer(impTable1^.FirstThunk)+integer(IDH1));
      while thunks^ <> nil do
      begin
        if VirtualProtect(thunks,4,PAGE_EXECUTE_READWRITE, old) then
        begin
            if impTable1^.Name = pchar('glBegin') then Form1.Memo1.Lines.Add('glbegin import');
            result := true;
          VirtualProtect(thunks,4,old, old);
        end;
        thunks := pointer(integer(thunks)+4);
      end;
      impTable1 := pointer(integer(impTable1)+sizeof(TImportBlock));
    end;
end;
end;
Der teil ist vermutlich völliger unsinn:

Delphi-Quellcode:
if impTable1^.Name = pchar('glBegin') then Form1.Memo1.Lines.Add('glbegin import');
Aber ich hab auch keine idee wie ich da ran kommen soll.
Ich dachte ich mach mal was einfacheres und versuche .dlls nach importierten funktionen zu durchsuchen.
Das ergebnis sieht man :(

Arnulf

Arnulf 18. Jul 2005 11:35

Re: import / export tables zweier .dlls vergleichen
 
Also die Lösung hab ich wenigstens - ich hab mich einfach in der Datenstruktur geirrt.
Es handelt sich hier um datenblöcke, man muß also immer einen ganzen Block weitergehen um den namen der Module zu bekommen.

Allerdings steh ich jetzt ganz an.
Ich hab verzweifelt versucht rauszufinden welche .dll oder .exe in meinem spielchen die opengl32.dll ladet und wollte dann eben die import tabelle mal anschauen.
Das Spiel importiert die .dll aber garnicht - zumindestens laut dependiance Walker.

Da glaubt man man etwas zu vertehen und schon ists wieder vorbei :(.
Kann sich darauf jemand einen Reim machen?.

Arnulf

Arnulf 20. Jul 2005 23:30

Re: import / export tables zweier .dlls vergleichen
 
Auch wenn ich mit mir selber rede :) - wenigstens versteh ich was brechi gemeint hat mit den import tables aller .dlls zu überprüfen.

Das ist exakt das was uallprotect.ishooked macht.
zwar steh ich bei der source genau hier an:
Delphi-Quellcode:
        if (integer(addr) < moduleh) or (integer(addr) > moduleh+integer(INH^.OptionalHeader.SizeOfImage)) then
           if GetRealModuleHandle(addr) <> GetModuleHandle('ntdll.dll') then
              result := false;
speziell hier bin ich ausgestiegen:
Delphi-Quellcode:
GetRealModuleHandle(addr)
wieso und wie das dann mit
Delphi-Quellcode:
GetModuleHandle('ntdll.dll')
verglichen wird ist mir ein rätsel - oder was überhaupt das ergebnis von getrealmodulehandle ist.

Jedenfalls seh ich bei dem ganzen ein problem - hab ich früher schon mal erwähnt, wenn jemand findmodulefirst, findmodulenext gehookt hat steht der check an :(.
Egal ich wills ja eh nur verstehen - wenn jemand mir erklären will was getrealmodulehandle macht, dann würd ich mich freuen.
cu
Arnulf

brechi 21. Jul 2005 11:21

Re: import / export tables zweier .dlls vergleichen
 
GetRealModuleHandle gibt von einer Adresse die Imagebase von der dll zurück in der diese liegt.
das mit der ntdll hab ich so gemacht da die kernel32.dll einige exporte auf funktionen der ntdll weiterleitet.
d.h. es würde immer "Hooked" zurückgeben. kann man aber noch verbessern, musst dir selbst mal anschaun.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:49 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz