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 vergleichen von zwei librarys im speicher (https://www.delphipraxis.net/46886-vergleichen-von-zwei-librarys-im-speicher.html)

Arnulf 2. Jun 2005 12:27


vergleichen von zwei librarys im speicher
 
Hallo
Ich würde gerne überprüfen ob eine geladene library in einem fremden prozess anders ist als diejenige die im system32 ordner liegt.

Ich denke mal man wird die beiden mit comparemem vergleichen.
Die erste frage dazu ist wie bekomm ich die .dll in einem fremden prozess eingelesen.
Genauer wie finde ich die speicheradresse - einlesen wird man wohl mit ReadProcessMemory?

Arnulf

barf00s 2. Jun 2005 12:36

Re: vergleichen von zwei librarys im speicher
 
könnte man sich nicht viel einfacher einfach alle geladenen module (dlls) eines prozesses holen, sowie deren pfade, und diese dann sparat mitnem memorystream laden und dann so mit

if CompareMem(MemStreamFuerDll1.Memory, MemStreamFuerDll2.Memory) <> 0 then
...

prüfen?
:gruebel:

Robert Marquardt 2. Jun 2005 12:50

Re: vergleichen von zwei librarys im speicher
 
Wenn man die Pfade hat, dann muss man doch nur noch diese vergleichen.

Arnulf 2. Jun 2005 13:36

Re: vergleichen von zwei librarys im speicher
 
also irgendwer versteht hier irgendwen nicht :)

ich will eine .dll die ein prozess geladen hat - in dem fall mein spiel das die opengl32.dll library geladen hat mit derjenigen vergleichen die vom spiel geladen wurde.
also einmal die im speicher und einmal die auf der festplatte - und die dürfen sich einfach nicht unterscheiden.
auch die eisprungtabellen sollten überprüft werden ...

und ich hab einfach keinen dunst wie man das machen soll.

Arnulf

Robert Marquardt 2. Jun 2005 13:51

Re: vergleichen von zwei librarys im speicher
 
Wenn du den Pfad der geladenen DLLs herausbekommen hast, dann kaeme nur noch In-Memory Patching in Frage fuer Veraenderungen.
Das lohnt aber nicht wirklich. Da ist es einfacher die Funktionen gleich ins Programm einzubauen.
Die Datensegmente der DLLs unterscheiden sich sowieso, da es zwar die gleichen DLLs sind (Codesegment gleich), aber die Zustaende sind unterschiedlich.

Sag mal was du erreichen willst. Anti-Cheating-Tool?

Arnulf 2. Jun 2005 14:10

Re: vergleichen von zwei librarys im speicher
 
Zitat:

Sag mal was du erreichen willst. Anti-Cheating-Tool?
ganz genau - ein anticheat tool :)

klar unterscheiden sich die datensegmente.
aber ich denke das codesegment zu überprüfen reicht ja wohl.
wenn hier irgendwer eine funktion hookt dann muß er doch mindestens einen jump machen und da reichts mir wenn ich das codesegment überprüfen kann.
nur wie ist die gretchenfrage :)

Arnulf

barf00s 2. Jun 2005 14:12

Re: vergleichen von zwei librarys im speicher
 
warum lädst du nicht die module und vergleichst deren inhalt?
oder muss es >unbegingt< so kompliziert sein? </dummfrag>

brechi 2. Jun 2005 14:27

Re: vergleichen von zwei librarys im speicher
 
zusäzlich zu

http://www.delphipraxis.net/internal...ct.php?t=55308

noch nen bisl code
wenn ich gleich noch zeit habe kann ich dir noch die CompareExecuteSection machen aber da haste jedenfalls schonmal die beiden dll im speicher (die originale und die von dem spiel)

Delphi-Quellcode:
procedure IsCorrectExecuteSection(dlln,processname: string);
  function CompareExecuteSections(p1,p2: pointer): boolean;
  begin
    result := true;
  end;
var h1,h2, pr, dllprocsize: integer;
    read: cardinal;
    buf, buf2: pointer;
begin
  pr := uallProcess.FindProcess(processname);
  if pr = 0 then
    messagebox(0,'process not loaded',nil,0) else
  begin
    h1 := LoadLibrary(pchar(dlln));
    if h1 = 0 then
      messagebox(0,'cant load dll',nil,0) else
    begin
      h2 := uallProcess.GetModuleOffset(dlln,pr);
      if h2 = 0 then
        MessageBox(0,'dll in process not found',nil,0) else
      begin
        buf := VirtualAlloc(nil,$1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
        pr := OpenProcess(PROCESS_ALL_ACCESS,false,pr);
        ReadProcessMemory(pr,pointer(h2),buf,$1000,read);
        dllprocsize := uallUtil.GetModuleVirtualSize(integer(buf));
        if uallUtil.GetModuleVirtualSize(h1) <> dllprocsize then
          MessageBox(0,'other dll loaded',nil,0) else
        begin
          buf2 := VirtualAlloc(nil,dllprocsize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
          if CompareExecuteSections(pointer(h1),buf2) then
            MessageBox(0,'ok',nil,0) else
            MessageBox(0,'execute sections not same',nil,0);
          VirtualFree(buf2,dllprocsize,MEM_DECOMMIT);
        end;
        VirtualFree(buf,$1000,MEM_DECOMMIT);
      end;
    end;
    FreeLibrary(h1);
  end;
end;

brechi 2. Jun 2005 14:58

Re: vergleichen von zwei librarys im speicher
 
Delphi-Quellcode:

procedure IsCorrectExecuteSection(dlln,processname: string);
  function CompareSection(p1,p2: pointer; orig1, orig2: integer; size: integer): boolean;
  var i, err: integer;
  begin
    result := true;
    for i := 0 to size-1 do
      pbyte(integer(p2)+i)^ := pbyte(integer(p2)+i)^-pbyte(integer(p1)+i)^;
    err := 0;

    for i := 0 to size-1 do
      if pbyte(integer(p2)+i)^ <> 0 then
        inc(err);
    if err > 4 then  // error konstante, 4 bytes sind immer unterschiedlich in der openglcode section
      result := false;
                      // einbau unterschiedlichen dllbasen noch nicht eingebaut
                      // aber durch orig1,orig2 möglich
  end;

  function CompareExecuteSections(p1,p2: pointer; orig1,orig2: integer): boolean;
  var IDH1, IDH2: PImageDosHeader;
      INH1, INH2: PImageNtHeaders;
      sectionh1, sectionh2: PImageSectionHeader;
      seca1, seca2, i: integer;
  begin
    result := true;
    IDH1 := p1;
    IDH2 := p2;
    if (IDH1^.e_magic = IMAGE_DOS_SIGNATURE) and (IDH2^.e_magic = IMAGE_DOS_SIGNATURE) then
    begin
      INH1 := pointer(integer(p1)+integer(IDH1^._lfanew));
      INH2 := pointer(integer(p2)+integer(IDH2^._lfanew));
      if (INH1^.Signature = IMAGE_NT_SIGNATURE) and (INH2^.Signature = IMAGE_NT_SIGNATURE) then
      begin
        seca1 := INH1^.FileHeader.NumberOfSections;
        seca2 := INH2^.FileHeader.NumberOfSections;
        if (seca1 <> seca2) then
          MessageBox(0,'sectioncount is not correct',nil,0) else
        begin
          for i := 0 to seca1-1 do
          begin
            sectionh1 := pointer(pointer(integer(INH1)+integer(sizeof(TImageNtHeaders))+i*sizeof(TImageSectionHeader)));
            sectionh2 := pointer(pointer(integer(INH2)+integer(sizeof(TImageNtHeaders))+i*sizeof(TImageSectionHeader)));
            if (sectionh1^.VirtualAddress <> sectionh2^.VirtualAddress) then
              MessageBox(0,'section pointer is not correct',nil,0) else
            if (sectionh2^.Misc.VirtualSize <> sectionh2^.Misc.VirtualSize) then
              MessageBox(0,'section size is not correct',nil,0) else
            begin
              if (sectionh1^.Characteristics and $20000000) = $20000000 then
              if CompareSection(pointer(integer(p1)+integer(sectionh1^.VirtualAddress)),
                               pointer(integer(p2)+integer(sectionh2^.VirtualAddress)),
                               orig1,orig2,
                               sectionh1^.Misc.VirtualSize) = false then
                MessageBox(0,'not same section',nil,0);
            end;
          end;
        end;
      end;
    end;

  end;
var h1,h2, pr, dllprocsize: integer;
    read: cardinal;
    buf, buf2: pointer;
begin
  pr := uallProcess.FindProcess(processname);
  if pr = 0 then
    messagebox(0,'process not loaded',nil,0) else
  begin
    h1 := LoadLibrary(pchar(dlln));
    if h1 = 0 then
      messagebox(0,'cant load dll',nil,0) else
    begin
      h2 := uallProcess.GetModuleOffset(dlln,pr);
      if h2 = 0 then
        MessageBox(0,'dll in process not found',nil,0) else
      begin
        buf := VirtualAlloc(nil,$1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
        pr := OpenProcess(PROCESS_ALL_ACCESS,false,pr);
        ReadProcessMemory(pr,pointer(h2),buf,$1000,read);
        dllprocsize := uallUtil.GetModuleVirtualSize(integer(buf));
        if uallUtil.GetModuleVirtualSize(h1) <> dllprocsize then
          MessageBox(0,'other dll loaded',nil,0) else
        begin
          buf2 := VirtualAlloc(nil,dllprocsize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
          ReadProcessMemory(pr,pointer(h2),buf2,dllprocsize,read);
          if CompareExecuteSections(pointer(h1),buf2,h1,h2) then
            MessageBox(0,'ok',nil,0) else
            MessageBox(0,'execute sections not same',nil,0);
          VirtualFree(buf2,dllprocsize,MEM_DECOMMIT);
        end;
        VirtualFree(buf,$1000,MEM_DECOMMIT);
      end;
    end;
    FreeLibrary(h1);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  IsCorrectExecuteSection('opengl32.dll','hl.exe');
end;
rest mussu selbst coden ;>

Arnulf 2. Jun 2005 22:47

Re: vergleichen von zwei librarys im speicher
 
wow - muß mich da erstmal durchackern :)
leider ist es schon spät und ich komm vor montag nicht dazu das wirklich durchzunehmen.

aber das ist mal unglaublich - leider hab ich immer den anspruch solche sachen zu verstehen...

naja kurz ausprobiert hab ichs - er stürtzt hin und wieder ab - gleich mitsamt ide .. aber ich schaus mir nochmal genauer an wenn ich zeit hab.
aber unglaublich - das prinzip funktioniert schon mal - danke vielmals mit so einer code flut hab ich nicht gerechnet :)
hab ich schon danke gesagt? ... nein - danke nochmal..
Ich lass den thread aber noch offen, weil ich sicher noch theoretische fragen hab :) - aber eigentlich ist er beantwortet ..

Delphi-Quellcode:
          if CompareExecuteSections(pointer(h1),buf2,h1,h2) then
            MessageBox(0,'ok',nil,0) else
            MessageBox(0,'execute sections not same',nil,0);
liefert übrigens immer true zurück
ich hab mal statt den messageboxen fals zurückgeben lassen und dann funktionierts eigentlich schon - bis auf das abstürzen der gesamten ide natürlich - hin und wieder lol....

Arnulf

brechi 2. Jun 2005 22:52

Re: vergleichen von zwei librarys im speicher
 
warum die IDE abstürzt ist mir ein rätsel
so viel mach ich gar net im speicher rum oO

jo hab nich false zurückgegeben, kannst ja schaun was deiner meinung nach nen cheat ist, alles was net funzt wird ja inner msg box ausgegeben

Arnulf 5. Jun 2005 21:07

Re: vergleichen von zwei librarys im speicher
 
Hi
leider bin ich immer noch nicht dazu gekommen das wirklich durchzuschauen :(
aber ich denke dein code funktioniert ziemliche gut - du weißt was du tust :).

die ide ist immer dann abgestürtzt, wenn ich den cheat ins spiel injiziert hab und danach wieder entfernt - wenn er dann nochmal überprüft hat ist mir das delphi abgekackt.
Hab nur leider noch nicht mehr herumprobieren können ...
Ansonsten denk ich ist das genial - ich werd schon dazu kommen dir zu berichten wo das problem lag..

Arnulf

Arnulf 7. Jun 2005 14:24

Re: vergleichen von zwei librarys im speicher
 
Also ich hab mich mal kurz durchgeschaut und ein bisschen herumprobiert.

Abstürtzen tut er hier:
Delphi-Quellcode:
    for i := 0 to size-1 do
      pbyte(integer(p2)+i)^ := pbyte(integer(p2)+i)^-pbyte(integer(p1)+i)^;
    err := 0;
und zwar mit range check error.
Allerdings nur, wenn ein cheat installiert ist.

Was ich allerdings seltsam finde ist, daß er wenn ich die ganze funktion in einem eigenen programm laufen hab eigentlich funktioniert.
Wenn ich es allerdings in mein Programm einbaue dann stürtzt er ab.
Der code ist aber garantiert der gleiche und ich hatte den absturtz auch schon im separaten programm allerdings momentan gehts seltsamer weise.

der code ist deshalb sicher der gleiche, weil ichs mit copy und paste eingefügt hab.

Ich hab mich auch schon versucht ein bisschen durchzuwurschteln durch den code.
Ist im prinzip recht verständlich - wusste ja nicht, daß man einfach so den handle einer lib in einem anderen prozess bekommen kann :).

wo ich allerdings aussteige ist dann bei der funktion: compareExecuteSections
vor allem deshalb, weil ich den datentyp PImageDosHeader nicht kenne und mir auch nicht klar ist was letzten endes in der struktur steht auf den der pointer zeigt.

Hoffe damit ist dir klar warum das programm nicht mehr funktioniert :) mir nämlich nicht.

Danke
Arnulf

Edit: Ich hab mal ein bischen nachgeschlagen - jetzt verstehe ich die source ganz - gott sei dank :) - wusste ja nicht, daß solche header für .exe oder .dlls existieren - sag ja ich bin etwas ab vom schuß des programmierens...
Auch interessant für mich ist wohl IMAGE_EXPORT_DIRECTORY damit wäre es doch relativ einfach simple wrapper zu entdecken - ich müsste nur alle vom spiel geladene .dlls kontrollieren.
oder lieg ich damit falsch? - Das ist ein extrem interessantes kapitel.

Arnulf

Arnulf 5. Jul 2005 20:29

Re: vergleichen von zwei librarys im speicher
 
Hallo nochmal.
Leider hab ich ziemlich viel stress mit dem check :(

Delphi-Quellcode:
for i := 0 to size-1 do
      pbyte(integer(p2)+i)^ := pbyte(integer(p2)+i)^-pbyte(integer(p1)+i)^;
       err := 0;
das stürtzt leider mit range check error ab :(.

funktionieren tut es so:
Delphi-Quellcode:
    while (k < size-1) do
    begin
         if pbyte(integer(p1)+k)^ <> pbyte(integer(p2)+k)^ then inc (err);
         inc(k);
    end;
ich hab es auch mit comparemem probiert, aber brechi hat vermutlich recht und es kommt vor, daß 4 bytes unterschiedlich sind manchmal ( bei mir hat comparemem gut funktioniert ).

Jedenfalls hab ich mit der 2. ten methode das problem, daß leute mit dem neuen nvidia treiber plötzlich eine seltsame Auflösung am Bildschirm angezeigt bekommen.
Bei einem Screenshot ist die das bild aber normal.

Kann mir hier irgendjemand helfen? - wäre nett, wenn du mir noch ein paar tips dazu geben könntest Brechi :)

Arnulf

NicoDE 5. Jul 2005 21:46

Re: vergleichen von zwei librarys im speicher
 
Bei Pointern sollte immer mit Cardinal-Cast gearbeitet werden (nicht Integer).

Arnulf 5. Jul 2005 22:16

Re: vergleichen von zwei librarys im speicher
 
hi
was meinst du mit cardinal-cast?
ich mein ich kann natürlich integer gegen cardinal austauschen was aber vermutlich nicht viel unterschied macht.
Wenn doch, dann würde es mich interessieren welchen :).
Arnulf

Olli 5. Jul 2005 22:17

Re: vergleichen von zwei librarys im speicher
 
Cardinal ist vorzeichenlos. Deswegen!

NicoDE 5. Jul 2005 22:18

Re: vergleichen von zwei librarys im speicher
 
Pointer haben kein Vorzeichen. Deswegen kann es bei einem Cast auf Integer auch zu Range-Check-Fehlern kommen...

Arnulf 5. Jul 2005 22:23

Re: vergleichen von zwei librarys im speicher
 
Ja das ergibt sinn.
allerdings in dem zusammenhang nicht wirklich.
Hier geh ich ja nur den ganzen speicherbereich durch und zähle nach oben - wie sollte ich da eine negative zahl rausbekommen.
so groß ist der bereich nicht.
integer ist ja signed 32 bit also –2147483648..2147483647.

ich will echt nicht blöd fragen :) aber ich versuche immer etwas zu verstehen bevor ich es abschreibe hehe

Arnulf

NicoDE 5. Jul 2005 22:28

Re: vergleichen von zwei librarys im speicher
 
Zitat:

Zitat von Arnulf
Delphi-Quellcode:
pbyte(integer(p2)+i)^-pbyte(integer(p1)+i)^;

Das Byte in P1+i könnte größer sein als das in P2+i -> Range-Check.
Folgendes könnte trotz Range-Check funktionieren (habe gerade keine Delphi zur Hand):
Delphi-Quellcode:
Byte(PByteArray(p2)[i] - PByteArray(p1)[i]);

Arnulf 5. Jul 2005 22:42

Re: vergleichen von zwei librarys im speicher
 
Hm ich habs jetzt so ausprobiert:
Delphi-Quellcode:
       pbytearray(p2)[i] := Byte(PByteArray(p2)[i] - PByteArray(p1)[i]);
hier gibts gleich range check error - ohne cheat.

Damit gibts nur mit cheat range check error
Delphi-Quellcode:
pbyte(cardinal(p2)+i)^ := pbyte(cardinal(p2)+i)^-pbyte(cardinal(p1)+i)^;
seltsam das alles :) - ich könnte das natürlich wieder mit IF machen, aber das subtrahieren ist vermutlich einfach schneller als das vergleichen.
Arnulf

NicoDE 5. Jul 2005 22:47

Re: vergleichen von zwei librarys im speicher
 
Wenn es keinen anderen Weg gibt, dann deaktiviere es mit
Delphi-Quellcode:
{$RANGECHECK OFF}
//...
{$IFDEF DEBUG}
  {$RANGECHECK ON}
{$ENDIF DEBUG}

Arnulf 5. Jul 2005 22:57

Re: vergleichen von zwei librarys im speicher
 
Nagut ich hab es jetzt mal so gemacht.

Delphi-Quellcode:
{$RANGECHECKS OFF}
   for i := 0 to size-1 do
      pbyte(cardinal(p2)+i)^ := pbyte(cardinal(p2)+i)^-pbyte(cardinal(p1)+i)^;
        //pbytearray(p2)[i] := Byte(PByteArray(p2)[i] - PByteArray(p1)[i]);
{$IFDEF DEBUG}
  {$RANGECHECKS ON}
{$ENDIF DEBUG}
Mal sehen was die grafikkarten treiber dazu sagen :) - warum es damit probleme gab ist mir immer noch schleierhaft.
Aber so geht es jetzt wenigstens - lustige idee range checks auszuschalten lol.
Danke jedenfalls.
Arnulf

brechi 6. Jul 2005 11:59

Re: vergleichen von zwei librarys im speicher
 
hau einfach nen VirtualProtect auf beide adressen bevor du die schleife ausführst
oder teste vorher mit IsReadPtr ob du überhaupt den speicher lesen kannst bzw IsBadWritePtr scheirben kannst (das aber nur wichtig für die dll die du mit LoadLibraryA vorher lädst)

Arnulf 6. Jul 2005 21:38

Re: vergleichen von zwei librarys im speicher
 
Hi
Also ich hab mal beides probiert :) aber es gibt immer noch range check errors.
LoadlibraryA verwende ich übrigens garnicht, kenn den befehl nichtmal.

Delphi-Quellcode:
virtualprotect(p1,size,PAGE_READONLY, oldprotect1);
virtualprotect(p2,size,PAGE_READWRITE, oldprotect2);
if not IsbadReadPtr(p2,size) or not isbadwritePtr(p2,size) then
   for i := 0 to size-1 do
       pbyte(cardinal(p2)+i)^ := pbyte(cardinal(p2)+i)^-pbyte(cardinal(p1)+i)^;
Auch VirtualProtect oder IsbadReadPtr hab ich noch nie verwendet :) - vielleicht ist es ja so einfach falsch.
Übrigens wollte ich dich, da du ja die source geschrieben hast zu den credits dazu schreiben.
Allerdings wollte ich dich vorher fragen, will ja deinen ruf als hacker nicht ruinieren :).

Arnulf

brechi 6. Jul 2005 21:45

Re: vergleichen von zwei librarys im speicher
 
das mir bob bin eh nur bei CS bekannt

Delphi-Quellcode:
virtualprotect(p1,size,PAGE_EXECUTE_READWRITE, oldprotect1);
   for i := 0 to size-1 do
       pbyte(cardinal(p2)+i)^ := pbyte(cardinal(p2)+i)^-pbyte(cardinal(p1)+i)^;
virtualprotect(p1,size,oldprotect1, oldprotect1);

Arnulf 6. Jul 2005 22:10

Re: vergleichen von zwei librarys im speicher
 
brrr... das geht auch nicht lol.
jedenfalls geb ich dir mal ein paar links vielleicht wird dann einiges klar.

screenshot von rangecheck error:
http://212.112.224.207/toe/rangecheck.jpg
der eigentliche cheat den ich damit checke:
http://212.112.224.207/toe/glpatc.exe
und die unit die ich aus deiner source gebastelt hab:
http://212.112.224.207/toe/uMemScanner.pas

Naja wenn das läuft und ich das veröffentlichen kann, schreib ich dich dazu :)

Arnulf

brechi 6. Jul 2005 23:06

Re: vergleichen von zwei librarys im speicher
 
ich schua mir das morgen mal an, aber guck mal nach ob size überhaupt stimmt oder ob das negativ ist

NicoDE 7. Jul 2005 14:42

Re: vergleichen von zwei librarys im speicher
 
Ich habe einen kleinen Detection-Code für den Target geschrieben, die darauf basiert, dass die Protection einer Speicherseite der Exporte (glBegin) PAGE_EXECUTE_READWRITE ist...
Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// GetOpenGL32Infos

type
  POpenGL32Infos = ^TOpenGL32Infos;
  TOpenGL32Infos = record
    BaseOfCode: Longword;
    SizeOfCode: Longword;
  end;

function GetOpenGL32Infos(var Info: TOpenGL32Infos): Boolean;
const
  INVALID_FILE_SIZE = DWORD(-1);
  INVALID_SET_FILE_POINTER = DWORD(-1);
  opengl32lib = '\opengl32.dll';
var
  FileName: array [0..MAX_PATH + Length(opengl32lib)] of Char;
  FileHandle: THandle;
  DosHeader: TImageDosHeader;
  BytesRead: DWORD;
  NtHeaders: TImageNtHeaders;
begin
  Result := False;
  GetSystemDirectory(FileName, MAX_PATH);
  StrCat(FileName, opengl32lib);
  FileHandle := CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, nil,
    OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, THandle(nil));
  if INVALID_HANDLE_VALUE = FileHandle then
    Exit;
  try
    with DosHeader, NtHeaders, NtHeaders.FileHeader, NtHeaders.OptionalHeader do
    begin
      // Get Headers
      if not ReadFile(FileHandle, DosHeader, SizeOf(TImageDosHeader), BytesRead,
          nil) or (BytesRead <> SizeOf(TImageDosHeader)) or
        (e_magic <> IMAGE_DOS_SIGNATURE) or
        (_lfanew < SizeOf(TImageDosHeader)) or
        (INVALID_SET_FILE_POINTER = SetFilePointer(FileHandle,
          _lfanew - SizeOf(TImageDosHeader), nil, FILE_CURRENT)) or
        not ReadFile(FileHandle, NtHeaders, SizeOf(TImageNtHeaders), BytesRead,
          nil) or (BytesRead <> SizeOf(TImageNtHeaders)) or
        (Signature <> IMAGE_NT_SIGNATURE) or (NumberOfSections <= 0) or
        (SizeOfOptionalHeader < SizeOf(TImageOptionalHeader)) then
        Exit;
      // Write Infos
      Info.BaseOfCode := ImageBase + BaseOfCode;
      Info.SizeOfCode := SizeOfCode;
      Result := True;
    end;
  finally
    CloseHandle(FileHandle);
  end;
end;

////////////////////////////////////////////////////////////////////////////////
// DetectOpenGL32Patch

var
  OpenGL32InfosValid: Boolean;
  OpenGL32Infos: TOpenGL32Infos;
  OpenGL32Modul: HMODULE;
  OpenGL32Begin: Pointer;

function DetectOpenGL32Patch: Boolean;
var
  Adr: Cardinal;
  Mbi: TMemoryBasicInformation;
begin
  Result := False;
  if not OpenGL32InfosValid or
    (HMODULE(nil) = OpenGL32Modul) or
    (nil = OpenGL32Begin) then
    Exit;
  Adr := Cardinal(OpenGL32Begin);
  Result :=
    // check if opengl32!glBegin is outside of the code section...
    (Adr < OpenGL32Infos.BaseOfCode) or
    (Adr > OpenGL32Infos.BaseOfCode + OpenGL32Infos.SizeOfCode) or
    // check if the memory page of opengl32!glBegin is writable...
    (
      (VirtualQuery(Pointer(Adr), Mbi, SizeOf(Mbi)) = SizeOf(Mbi)) and
      (Mbi.Protect = PAGE_EXECUTE_READWRITE)
    );
end;

function DetectOpenGL32PatchEx(ProcessId: DWORD): Boolean;
var
  Prc: THandle;
  Mbi: TMemoryBasicInformation;
begin
  Result := False;
  if not OpenGL32InfosValid or
    (HMODULE(nil) = OpenGL32Modul) or
    (nil = OpenGL32Begin) then
    Exit;
  Prc := OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessId);
  if THandle(nil) = Prc then
    Exit;
  try
    Result :=
      // check if the memory page of opengl32!glBegin is writable...
      (VirtualQueryEx(Prc, OpenGL32Begin, Mbi, SizeOf(Mbi)) = SizeOf(Mbi)) and
      (Mbi.Protect = PAGE_EXECUTE_READWRITE);
  finally
    CloseHandle(Prc);
  end;
end;

////////////////////////////////////////////////////////////////////////////////
// Check

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(BoolToStr(DetectOpenGL32Patch, True));
end;

////////////////////////////////////////////////////////////////////////////////
// Init

initialization

  OpenGL32InfosValid := GetOpenGL32Infos(OpenGL32Infos);
  OpenGL32Modul := LoadLibrary('opengl32.dll');
  OpenGL32Begin := GetProcAddress(OpenGL32Modul, 'glBegin');
Mögliches Problem: die Seite könnte absichtlich PAGE_EXECUTE_READWRITE sein (unwahrscheinlich ohne Manipulation).


Gruß Nico

brechi 7. Jul 2005 14:55

Re: vergleichen von zwei librarys im speicher
 
Liste der Anhänge anzeigen (Anzahl: 1)
das bringt fast agr nichts.

jeder normale cheatcoder setzt nachdem er die daten überschriebn hat die page wieder auf den alten status

wie z.b. hier:

Delphi-Quellcode:
  virtualprotect(p1,size,PAGE_EXECUTE_READWRITE, oldprotect1);
   for i := 0 to size-1 do
       pbyte(cardinal(p2)+i)^ := pbyte(cardinal(p2)+i)^-pbyte(cardinal(p1)+i)^;
  virtualprotect(p1,size,oldprotect1, oldprotect1);
desweiteren ändern jeder neuere cheat nichst mehr an der opengl32.dll sondern direkt im treiber

brechi 7. Jul 2005 15:15

Re: vergleichen von zwei librarys im speicher
 
generell würd ich mir überlegen wie du am besten einen opengl cheat erkennst.
hier mal nen paar tips dazu was eigentlich ziemlich gut ist


(1) GetProcAdderss hooken und schaun ob eine andere dll eine opengl funktion importieren will -> cheat
(2) GetAsyncKeyState / GetKeyboardState hooken, wirds benutzt -> Cheat (normal machen das die spiele über directX)
(3) änderungen an der importtabelle von der spiel enigne schauen -> nicht in der opengl32.dll -> cheat
(4) schauen on eine dll später nachgeladen wird
(5) schaun ob die opengl funktionen überschrieben werden (sehen eigentlich immer gleich aus, gibt 3 arten)
(6) Privileg von OpenProcess wegnehmen -> dll kann nicht mehr extern geladen werden
(7) schauen ob 2 opengl32.dll im speicher -> wenn mehr als eine dann cheat
(8) schaun ob opengl32.dll im system ordner liegt -> wenn nicht cheat
(9) schaun ob an der treiber funktion nen jmp gesetzt wurde
(10) schaun ob opengl32.dll funktionen benutzt werden die normal nicht benutzt werden

das sind erstmal die wichtigsten, obwohl ich selber jede davon schon umgangen habe
wenn es schaffst den OGCi (treiber hack) bei HL zu erkennen dann bist schon ganz gut :)

barf00s 7. Jul 2005 15:19

Re: vergleichen von zwei librarys im speicher
 
hmm um nen wallhack für OpenGL engines zu schreiben muss mans nicht SO verkomplizieren ^^
aber wers brauch </senf>

brechi 7. Jul 2005 15:41

Re: vergleichen von zwei librarys im speicher
 
ntürlich sonst werden die ja von nem anti cheat tool erkannt :)

Arnulf 7. Jul 2005 17:33

Re: vergleichen von zwei librarys im speicher
 
phuu .. das klingt nach 3 jahren arbeit :).
Zitat:

(1) GetProcAdderss hooken und schaun ob eine andere dll eine opengl funktion importieren will -> cheat
Darüber hab ich schon nachgedacht - ist mit madcodehook oder uallhook einfach zu machen:
Zitat:

(2) GetAsyncKeyState / GetKeyboardState hooken, wirds benutzt -> Cheat (normal machen das die spiele über directX)
Daran hab ich noch nicht gedacht, aber ich hab ziemlich schlechte erfahrungen mit so allgemeinen checks - es gibt so viele programme die so viele dinge machen - ich denk nur an TSO oder Gamevoice, das hier sicherlich probleme macht:
Zitat:

(3) änderungen an der importtabelle von der spiel enigne schauen -> nicht in der opengl32.dll -> cheat
Ich hab schon probiert import tables zu checken (opengl32.dll) - den code hab ich im forum gepostet - weiß nicht ob das gestimmt hat.
Hab ja das erste mal in deiner source pe headers gesehen :). Für das spiel dürfte das ähnlich gehen...
Zitat:

(4) schauen on eine dll später nachgeladen wird
Der Anticheat funktioniert ja schon und das ist eines der dinge die ich schon mache.
Allerdings muß man hier etwas aufpassen, weil es ziemlich viele programme gibt die .dlls nachladen - Norton, TSO, Incredimail (die Spyware sachen), logitec maus treiber usw... - wie gesagt hab ich damit erfahrung :)
Zitat:

(5) schaun ob die opengl funktionen überschrieben werden (sehen eigentlich immer gleich aus, gibt 3 arten)
Genau darum gehts in dem thread und in brechis source denk ich oder irr ich mich da?
Zitat:

(6) Privileg von OpenProcess wegnehmen -> dll kann nicht mehr extern geladen werden
Du meinst dem Spiel openprocess wegnehmen? - naja bei jedem mapchange wird im prinzip gleich ein vid_restart gemacht und damit auch gleich eine game dll entladen und neu geladen - damit würde es vermutlich stress geben - oder irr ich mich da?
Zitat:

(7) schauen ob 2 opengl32.dll im speicher -> wenn mehr als eine dann cheat
Das mach ich bereits - ist die einfachste art einen wrapper zu erkennen. Allerdings gibts probleme mit process hide programmen.
Hier brauch ich denk ich noch eine bessere methode um .dlls zu listen. findnext und enum sind ja meißtens gehookt bei diesen process hide programmen.
Zitat:

(Cool schaun ob opengl32.dll im system ordner liegt -> wenn nicht cheat
Das wäre seltsam, wozu sollte man opengl32.dll aus dem win ordner rausgeben - wrapper haben ja meißtens den gleichen namen:
Zitat:

(9) schaun ob an der treiber funktion nen jmp gesetzt wurde
Also das ist was für spezialisten :) - noch nie gehört sowas ...
Zitat:

(10) schaun ob opengl32.dll funktionen benutzt werden die normal nicht benutzt werden
Das ist wieder für spezialisten - ich könnte höchstens schauen, welche ogl funktionen das spiel benutzt - aber ob ich dazu die zeit finde :)

@NicoDE
Zitat:

// check if opengl32!glBegin is outside of the code section...
Das ist interessant denk ich, aber brechi hat recht die meißten cheats setzen nach dem patchen einfach page execute wieder zurück.

Also ich hab jetzt 20 fragen da oben stehen und bei den meißten keine ahnung wie ich das machen soll :)
Die warheit ist, das Projekt ist mir schon lange über den Kopf gewachsen aber ich kann einfach nicht mehr aufhören.
Wenn jemand mitarbeiten will, dann gerne - Die Basis funktioniert ja schon und es wird auch benutzt in einigen ligen.

Ich hab mir auch schon überlegt das open source zu machen :) - aber das wär dann auch wieder idiotisch für einen Anticheat der vielleicht doch ernst genommen werden will lol.

Naja würde mich freuen wenn jemand mitmachen will bzw. mir weiterhin hilft ... fragen gibts ja genug!

Arnulf

NicoDE 7. Jul 2005 21:18

Re: vergleichen von zwei librarys im speicher
 
Zitat:

Zitat von brechi
wenn es schaffst den OGCi (treiber hack) bei HL zu erkennen dann bist schon ganz gut :)

Lokal ist es nicht schwer. Eine generische Erkennung (der Hack selbst ist alles andere als generisch) würde eine Menge Arbeit kosten.
Wenn ich zuviel Zeit hätte... deine Vorschläge sind gut, aber sprengen meinen Zeitrahmen fürs Forum *g*

Mir gefallen die vielen Hooks nicht wirklich, vieles würde man auch ohne erkennen können.

brechi 7. Jul 2005 21:22

Re: vergleichen von zwei librarys im speicher
 
problem ist nur das der OGCi nen treiber patched und das polymorph.

alle die erkennugnen hat CD (cheatings-death, www.uniedadmins.com) schon
und ohen hook bzw dll injection bekommt man das meiste nicht sicher hin, da du gewungendermaßen auf ReadProcessMemory angewiesen bist

bigg 7. Jul 2005 21:25

Re: vergleichen von zwei librarys im speicher
 
Bilde von beiden Dateien einen Hash z. B. MD5 und vergleiche beide miteinander. ;)
(macht Punk Buster auch so)

Arnulf 7. Jul 2005 23:18

Re: vergleichen von zwei librarys im speicher
 
Zitat:

Bilde von beiden Dateien einen Hash z. B. MD5 und vergleiche beide miteinander. Wink
(macht Punk Buster auch so)
ja ich könnte statt brechis vergleich code natürlich mit readprocessmemory durchgehen und md5 machen.
ob das allerdings besser geht ist fraglich. mir stürtzt das ding ja leider immer ab - und ich weiß nicht warum.

Ausserdem hat brechi ja beim posten der source schon erwähnt, das in der code section 4 bytes oftmals unterschiedlich sind.
Ich kann das nicht bestätigen oder dementieren aber ich weiß, daß einige leute probleme hatten als ich einfach comparemem verwendet hab.
Die meißten haben hald irgendwelche win xp skins oder teamspeak overlay verwendet und damit sind sie dann auch schon gekickt worden.

Arnulf

brechi 8. Jul 2005 09:41

Re: vergleichen von zwei librarys im speicher
 
du musst aj gar nicht die ganze codesection der opegl32.dll prüfen, es reicht ja wenn du die für den cheat benutzen export (glBegin / glDrawElements etc) auf richtigkeit prüfst (20 bytes);

wenn du die dll aus dem speiche von dem game in deinen geladen hast geht das ja einfach über:


Delphi-Quellcode:
h2 := //memory von der opengl32 aus dem spiel die in deine speicher geladne wurde
h1 := LoadLibrary('opengl32.dll');
p := GetProcAddress(h,'glBegin');
if CompareMem(p,cardinal(h1)-h1+h2,20) then
begin

end;
bei den opengl funktionen musst du dir da noch ent mal wegen der relcation tabelle sorgen machen -> die ersten 20 bytes müssen gleich sein da diese nur nen wrapper sind zum treiber in der art

mov eax, fs:[18h]
jmp [eax+7cch]

davon gibt es 3 verschiedene arten, keine braucht dafür die relocation tabelle, demnachmüssten die die gleichen sein (im spiel und selbst geladen)

NicoDE 8. Jul 2005 10:21

Re: vergleichen von zwei librarys im speicher
 
Zitat:

Zitat von brechi
mov eax, fs:[18h]
jmp [eax+7cch]

Randnotiz: in einigen Versionen der OpenGL32.dll (Win9x) steht der Offset in einer Variablen:
Code:
mov    eax, large fs:[00000018h]
add    eax, [g_glTableOffset] ; set in DllInitialize on DLL_PROCESS_ATTACH
mov    eax, [eax]
jmp    dword ptr [__]
wobei es beim Jump drei Arten gibt
Code:
jmp    dword ptr [eax]
; oder
jmp    dword ptr [eax+__h]
; oder
jmp    dword ptr [eax+________h]
Um zu überprüfen ob der Funktionszeiger umgeleitet wurde (wie im Dll-Beispiel von brechi), müsste man den Wrapper-Code analysieren um die Adresse zu berechnen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:27 Uhr.
Seite 1 von 2  1 2      

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