Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Dll Injection nur von Konsolenanwendung möglich (https://www.delphipraxis.net/156364-dll-injection-nur-von-konsolenanwendung-moeglich.html)

schlagzu 29. Nov 2010 16:43

Dll Injection nur von Konsolenanwendung möglich
 
Hallo,

folgender Sachverhalt:

Ich habe vor einigen Wochen (hier im Forum) meine Idee zu einem Anti-Cheat-Tool geschildert.
Nun habe ich mich mit API Hooks beschäftigt. Eine funktionierende DLL habe ich, die creatprocess (A,W und normal), openprocess, Readprocessmemory und Writeprocessmemory mit meine Funktionen überschreibt.
Der Globale Injektion (uall,magicapihook) funktioniert in einer Konsolenanwendung.

1. Problem) Mit meine DLL injizierten Programme können von ihnen erstellte Programme nicht injizieren.
Lösung: Per SendMessage zum eigentlichen Programm eine Melden, das dies zu injizieren ist.
2. Prob) Meldung kommt an, aber die Anwendung kann es nicht injizieren. Auch der globale funktioniert in der Anwendung mit Oberfläche nicht (Eigentliche) und 3. Anwendung mit 2 Buttons die einfach den global Befehl ausführen funktioniert nicht. Hat das was mit der Oberfläche zu tun? Hat eine Konsolenanwendung besondere Rechte oder etwas in dieser Art?

Delphi 2010 Schülerversion

MfG schlagzu

Aphton 29. Nov 2010 17:04

AW: Dll Injection nur von Konsolenanwendung möglich
 
Etwas genauer - Wie injizierst du genau? Sind erforderliche Rechte vorhanden? Wird der Code richtig "verwendet"? Usw. usf.

Hau rein

schlagzu 29. Nov 2010 19:45

AW: Dll Injection nur von Konsolenanwendung möglich
 
Konsolenanwendung:
Delphi-Quellcode:
program Loader;

uses
  Windows,
  Sysutils,
  MagicApiHook in 'C:\Users\*snipp*\Desktop\MagicApiHook\MagicApiHook.pas';

var
 Dllname:string='anticheat.dll';

begin
 if not IsWinNt then begin
  MessageBox(0,'Sorry...just for WinNT...','Error...',MB_ICONERROR);
  Exit;
 end;
 if not IsFileExist(DllName) then begin
  MessageBox(0,Pchar('File not found : '+DllName),'Error...',MB_ICONERROR);
  Exit;
 end;
 DebugPrivilege(True);

 if uppercase(paramstr(1)) = uppercase('-load') then
 begin
 InjectAllProc(GetPath(ParamStr(0))+DllName);
 end
 else
 if uppercase(paramstr(1)) = uppercase('-unload') then
 begin
 UnInjectAllProc(GetPath(ParamStr(0))+DllName);
 end
 else
 MessageBox(0,Pchar('Hab ich gesagt du sollt verwenden Parameter'),'Error...',MB_ICONERROR);
end.
Ausschnitt aus Client.exe

Delphi-Quellcode:
procedure TForm8.Button1Click(Sender: TObject);
begin
Button1.Enabled:=false;
Edit1.Enabled:=false;
Edit2.Enabled:=false;
Combobox1.Enabled:=false;
DebugPrivilege(True);
if(IsWindows64) then
begin
  GlobalInjectLibrary(pchar(GetPath(ParamStr(0))+'anticheat.dll'));
end
else
begin
  GlobalInjectLibrary(pchar(GetPath(ParamStr(0))+'anticheat.dll'));
end;
port:=strtoint(Combobox1.Items[ComboBox1.ItemIndex]);
ClientSocket1.Port := port; //Festlegung des Ports
ClientSocket1.Host := Edit1.Text; //IP des Zielrechners
ClientSocket1.active := true; //Aufbau der Verbindung
Label4.Caption:='Verbunden mit '+Edit1.Text+':'+inttostr(port)+'...';
sentdata(Edit2);
end;
DLL

Delphi-Quellcode:
library anticheat;

uses
  Windows,
  SysUtils,
  Messages,
  MagicApiHook in '..\MagicApiHook.pas',
  uallHook in '..\uallHook.pas',
  uallDisasm in '..\uallDisasm.pas',
  uallDisasmEx in '..\uallDisasmEx.pas',
  uallKernel in '..\uallKernel.pas',
  uallProcess in '..\uallProcess.pas',
  uallProtect in '..\uallProtect.pas',
  uallUtil in '..\uallUtil.pas';

var
 DllName: string='anticheat.dll';
 DllPath: array[0..255] of Char;
 lastw,lastr:word;
 protectedid:integer;

 oldWriteProcessMemory,newWriteProcessMemory: function (hProcess:integer;lpBaseAddress:Pointer;lpBuffer:PChar;nSize:integer;var write:cardinal): Boolean; stdcall;
 oldReadProcessMemory,newReadProcessMemory: function (hProcess:integer;lpBaseAddress:Pointer;var lpBuffer:PChar;nSize:integer;var write:cardinal): Boolean; stdcall;
 oldOpenProcess,newOpenProcess: function (dwDesiredAccess:DWord;bInheritHandle:LOngbool;dwProcessId:Dword):integer; stdcall;



 VNewCreateProcessA,VOldCreateProcessA : function (lpApplicationName: PChar; lpCommandLine: PChar;
                         lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
                         bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
                         lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
                         var lpProcessInformation: TProcessInformation): BOOL; stdcall;

 VNewCreateProcess,VOldCreateProcess : function (lpApplicationName: PChar; lpCommandLine: PChar;
    lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
    bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
    lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
    var lpProcessInformation: TProcessInformation): BOOL; stdcall;


 VOldCreateProcessW,VNewCreateProcessW : function (lpApplicationName: PWideChar; lpCommandLine: PWideChar;
                         lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
                         bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
                         lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
                         var lpProcessInformation: TProcessInformation): BOOL; stdcall;


 function HookWriteProcessMemory(hProcess:integer;lpBaseAddress:Pointer;lpBuffer:PChar;nSize:integer;var write:cardinal): Boolean; stdcall; forward;
 function HookReadProcessMemory(hProcess:integer;lpBaseAddress:Pointer;var lpBuffer:PChar;nSize:integer;var write:cardinal): Boolean; stdcall; forward;
 function HookOpenProcess(dwDesiredAccess:DWord;bInheritHandle:LOngbool;dwProcessId:Dword):integer; stdcall; forward;

 function CatchCreateProcessA(lpApplicationName: PChar; lpCommandLine: PChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall; forward;
 function CatchCreateProcess(lpApplicationName: PChar; lpCommandLine: PChar;
    lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
    bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
    lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
    var lpProcessInformation: TProcessInformation): BOOL; stdcall; forward;
function CatchCreateProcessW(lpApplicationName: PWideChar; lpCommandLine: PWideChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall; forward;


procedure logg(s:string);
var
  f: textfile;
  m:string;
begin
  m:=GetPath(DllPath)+'log.txt';
  if IsFileInUse(m) then
    sleep(2);
  AssignFile(f,m);
  try
    if IsFileExist(m) then
      Append(f)
    else
      Rewrite(f);
    writeln(f,FormatDateTime('hh:nn:ss,', time)+s);
  finally
    CloseFile(f);
  end;
end;

procedure SendCopyData(hTargetWnd: HWND; ACopyDataStruct:TCopyDataStruct);
begin
  if hTargetWnd <> 0 then
  SendMessage(hTargetWnd, WM_COPYDATA, Longint(hTargetWnd), Longint(@ACopyDataStruct))
  else
  logg('Error: Kein Client gefunden!');
end;

procedure sendid(id:string);
var
  MyCopyDataStruct: TCopyDataStruct;
  hTargetWnd: HWND;
begin
  // TCopyDataStruct mit den Sende-Daten Infos ausfüllen
  with MyCopyDataStruct do
  begin
    dwData := 0; // may use a value do identify content of message
    cbData := StrLen(PChar(id)) + 1; //Need to transfer terminating #0 as well
    lpData := PChar(id)
  end;
  // Empfänger Fenster anhand des Titelzeilentextes suchen
  hTargetWnd := FindWindow(nil,PChar('Anti-Cheat-Client'));
  // Die Struktur an den Empfänger schicken
  SendCopyData(hTargetWnd, MyCopyDataStruct);
end;

function protect(i:integer):boolean;
begin
  if(i = protectedid) then
  result:=true
  else
  result:=false;
end;

function protect2(p:integer):boolean;
var f: textfile;
     m:string;
     b:boolean;
begin
  b:=false;
  m:=GetPath(DllPath)+'w.txt';
  if IsFileInUse(m) then
    sleep(2);
  AssignFile(f,m);
  try
      Reset(f);
      while not (eof(f)) do
      begin
      readln(f,m);
      if(strtoint(m)=p) then b:=true;
      end;
  finally
    CloseFile(f);
  end;
  result:=b;
end;

procedure addtolist(s:string);
var
  f: textfile;
  m:string;
begin
  m:=GetPath(DllPath)+'list.txt';
  if IsFileInUse(m) then
    sleep(2);
  AssignFile(f,m);
  try
    if IsFileExist(m) then
      Append(f)
    else
      Rewrite(f);
      writeln(f,s);
  finally
    CloseFile(f);
  end;
end;

 procedure waitforprocess(h:DWord);
 var i:integer;
 begin
 i:=0;
 while (Pos('KERNEL32', UpCaseStr(FindModulesInProcess(h))) = 0) and (i<2000) do
 begin
   inc(i);
   sleep(10);
 end;
 end;


 function HookOpenProcess(dwDesiredAccess:cardinal;bInheritHandle:LOngbool;dwProcessId:cardinal):integer; stdcall;
 var i:cardinal;
 begin
  i:=newOpenProcess(dwDesiredAccess,bInheritHandle,dwProcessId);
  if (protect2(dwProcessId)) then
  begin
  SetLastError(ERROR_ACCESS_DENIED);
  protectedid:=i;
  i:=0;
  end;
  result:=i;
 end;

(******************************************************************************)
function HookWriteProcessMemory(hProcess:integer;lpBaseAddress:Pointer;lpBuffer:PChar;nSize:integer;var write:cardinal): Boolean; stdcall;
begin
if(protect(hProcess)) then
  begin
  logg(paramstr(0)+',write,'+inttostr(PHandleToPID(hProcess))+',prot');
  result:=false;
  end
else
  begin
  if(lastw<>PHandleToPID(hProcess)) then
  logg(paramstr(0)+',write,'+inttostr(PHandleToPID(hProcess))+',free');
  result := newWriteProcessMemory(hProcess,lpBaseAddress,lpBuffer,nSize,write);
  end;
  lastw:=PHandleToPID(hProcess);
end;
(******************************************************************************)
function HookReadProcessMemory(hProcess:integer;lpBaseAddress:Pointer;var lpBuffer:PChar;nSize:integer;var write:cardinal): Boolean; stdcall;
begin

if(protect(hProcess)) then
  begin
  logg(paramstr(0)+',write,'+inttostr(PHandleToPID(hProcess))+',prot');
  result:=false;
  end
else
  begin
  if(lastr<>PHandleToPID(hProcess)) then
  logg(paramstr(0)+',read,'+inttostr(PHandleToPID(hProcess))+',free');
  result := newReadProcessMemory(hProcess,lpBaseAddress,lpBuffer,nSize,write);
  end;
  lastr:=PHandleToPID(hProcess);
end;

function CatchCreateProcessA(lpApplicationName: PChar; lpCommandLine: PChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall;
begin
   result:=VNewCreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes,
                               lpThreadAttributes, bInheritHandles, dwCreationFlags,
                               lpEnvironment, lpCurrentDirectory, lpStartupInfo,
                               lpProcessInformation);
   waitforprocess(lpProcessInformation.dwProcessId);
   sendid(inttostr(lpProcessInformation.dwProcessId));
   logg(paramstr(0)+',creat(A),'+inttostr(lpProcessInformation.dwProcessId)+',free')
end;

function CatchCreateProcess(lpApplicationName: PChar; lpCommandLine: PChar;
    lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
    bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
    lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
    var lpProcessInformation: TProcessInformation): BOOL; stdcall;
var b:boolean;
begin
   result:=VNewCreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes,
                               lpThreadAttributes, bInheritHandles, dwCreationFlags,
                               lpEnvironment, lpCurrentDirectory, lpStartupInfo,
                               lpProcessInformation);
  waitforprocess(lpProcessInformation.dwProcessId);
  sendid(inttostr(lpProcessInformation.dwProcessId));
  logg(paramstr(0)+',creat(N),'+inttostr(lpProcessInformation.dwProcessId)+',free')
end;

function CatchCreateProcessW(lpApplicationName: PWideChar; lpCommandLine: PWideChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall;
begin
    result:=VNewCreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes,
                               lpThreadAttributes, bInheritHandles, dwCreationFlags,
                               lpEnvironment, lpCurrentDirectory, lpStartupInfo,
                               lpProcessInformation);
   waitforprocess(lpProcessInformation.dwProcessId);
   sendid(inttostr(lpProcessInformation.dwProcessId));
   logg(paramstr(0)+',creat(W),'+inttostr(lpProcessInformation.dwProcessId)+',free')
end;
(******************************************************************************)
procedure DLLEntryPoint(dwReason:DWORD);
var h:integer;
begin
 case dwReason of
   DLL_PROCESS_ATTACH: begin
     h := GetModuleHandle('kernel32.dll');
     if h > 0 then
     begin
       @oldWriteProcessMemory := GetProcAddress(h,'WriteProcessMemory');
       if @oldWriteProcessMemory <> nil then
         HookCode(@oldWriteProcessMemory,@HookWriteProcessMemory,@newWriteProcessMemory);

       @oldReadProcessMemory := GetProcAddress(h,'ReadProcessMemory');
       if @oldReadProcessMemory <> nil then
         HookCode(@oldReadProcessMemory,@HookReadProcessMemory,@newReadProcessMemory);

       @oldOpenProcess := GetProcAddress(h,'OpenProcess');
       if @oldOpenProcess <> nil then
         HookCode(@oldOpenProcess,@HookOpenProcess,@newOpenProcess);

      @VOldCreateProcess:= GetProcAddress(h, 'CreateProcess');
      if @VOldCreateProcess <> nil then
      HookCode(@VOldCreateProcess, @CatchCreateProcess, @VNewCreateProcess);

      @VOldCreateProcessA:= GetProcAddress(h, 'CreateProcessA');
      if @VOldCreateProcessA <> nil then
      HookCode(@VOldCreateProcessA, @CatchCreateProcessA, @VNewCreateProcessA);

      @VOldCreateProcessW := GetProcAddress(h, 'CreateProcessW');
      if @VOldCreateProcessW <> nil then
      HookCode(@VOldCreateProcessW, @CatchCreateProcessW, @VNewCreateProcessW);
      end;
      GetModuleFileName(GetModuleHandle(Pchar(DllName)),DllPath,SizeOf(DllPath));
   end;
   DLL_PROCESS_DETACH:
   begin
     UnHookCode(@NewWriteProcessMemory);
     UnHookCode(@NewReadProcessMemory);
     UnHookCode(@NewOpenProcess);
     UnhookCode(@VNewCreateProcess);
     UnhookCode(@VNewCreateProcessA);
     UnhookCode(@VNewCreateProcessW);
   end;
 end;
end;
(******************************************************************************)
begin
 DllProc:=@DLLEntryPoint;
 DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Probiert unter Vista 32bit , XP 32 und Seven 64 immer das gleiche, die Konsolenanwendung funzt, aber sonst nicht. Ohne Antivirus etc.

Sir Rufo 30. Nov 2010 00:01

AW: Dll Injection nur von Konsolenanwendung möglich
 
Wenn du jetzt noch anstatt der Code-Tags die Delphi-Tags benutzen würdest, könnte man das auch besser lesen

Code:
procedure CodeTag;
begin
  // doof zu lesen
end;
Delphi-Quellcode:
procedure DelphiTag;
begin
  // Das kann man schön lesen
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:40 Uhr.

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