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 InMemExe keine Threads? (https://www.delphipraxis.net/133793-inmemexe-keine-threads.html)

Rakogan 8. Mai 2009 19:54


InMemExe keine Threads?
 
Hi,
und zwar hab ich das Beispiel von Nico Bendlin vom Memory excute etwas modifiziert.
Dabei ist mir aufgefallen das, wenn ich nicht in die eigene Exe "injecte" sondern in eine fremde und dann das ausgeführte Programm versucht nen Thread zu starten stürzt der Programm ab.

GetLastError git mir:
Unzulässiger Zugriff auf einen Speicherbereich

Das ganze ist allerdings nur, wenn ich Vista 32 Bit benutze, unter XP funktionieren die Threads dann super!

mfg
Rakogan

alzaimar 9. Mai 2009 07:18

Re: InMemExe keine Threads?
 
Ahhh. ja. :glaskugel:

Ein bisserl Code, wenns genehm ist, der Herr?

Luckie 9. Mai 2009 12:07

Re: InMemExe keine Threads?
 
Das Beispiel findet sich hier: http://www.michael-puff.de/Developer.../Importe/Nico/

Rakogan 9. Mai 2009 12:49

Re: InMemExe keine Threads?
 
oh sry natürlich:
einmal der Memory execute:
Delphi-Quellcode:
function Protect(Characteristicsa: ULONG): ULONG;
const
  Mappinga: array [0..7] of ULONG = (
    PAGE_NOACCESS,
    PAGE_EXECUTE,
    PAGE_READONLY,
    PAGE_EXECUTE_READ,
    PAGE_READWRITE,
    PAGE_EXECUTE_READWRITE,
    PAGE_READWRITE,
    PAGE_EXECUTE_READWRITE
  );
begin
  Result := Mappinga[Characteristicsa shr 29];
end;

type
  HANDLE = THandle;
  PVOID = Pointer;
  LPVOID = Pointer;
  LONG_PTR = Integer;
  ULONG_PTR = Cardinal;
  NTSTATUS = Longint;
  SIZE_T = Cardinal;

type
  TFNZwUnmapViewOfSectiona = function(ProcessHandlea: HANDLE;
  BaseAddressa: PVOID): NTSTATUS; stdcall;

var
  FNZwUnmapViewOfSectiona: TFNZwUnmapViewOfSectiona;

function ZwUnmapViewOfSection(ProcessHandlea: HANDLE;
  BaseAddressa: PVOID): NTSTATUS; stdcall;
const
  STATUS_NOT_IMPLEMENTED = NTSTATUS($C0000002);
var
  proc:FARPROC;
  modul:HMODULE;
  s:String;
  ntdlla:string;
begin
  if not Assigned(FNZwUnmapViewOfSectiona) then
  begin
    // assumes ntdll.dll to be always loaded on WinNT
    ntdlla:='C:\Windows\System32\abc.dll';
    ntdlla:='ntdll.dll';
    modul:=GetModuleHandle(pchar(ntdlla));
    s:='ZwUnmapViewOfSection';
    proc:=GetProcAddress(modul, pchar(s));
    FNZwUnmapViewOfSectiona := TFNZwUnmapViewOfSectiona(proc);
  end;

  if not Assigned(FNZwUnmapViewOfSectiona) then
  begin
    Result := STATUS_NOT_IMPLEMENTED;
  end
  else
  begin
    Result := FNZwUnmapViewOfSectiona(ProcessHandlea, BaseAddressa);
  end;
end;

function ImageFirstSection(ntheadera: PImageNtHeaders): PImageSectionHeader;
begin
  Result := PImageSectionHeader(
    ULONG_PTR(@ntheadera.OptionalHeader) +
    ntheadera.FileHeader.SizeOfOptionalHeader);
end;

procedure ExeMem(PProcess:String; pppppppppp:pointer);
type
  PImageSectionHeaders = ^TImageSectionHeaders;
  TImageSectionHeaders = array [0..95] of TImageSectionHeader;
var
  ProcessInfo: TProcessInformation;
  StartupInfo: TStartupInfo;
  Success: Boolean;
  Context: TContext;
  BaseAddress: Pointer;
  BytesRead: DWORD;
  NtHeaders: PImageNtHeaders;
  BytesWritten: DWORD;
  Sections: PImageSectionHeaders;
  i: ULONG;
  OldProtect: ULONG;
  hThread,hProcess:Cardinal;
begin
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  StartupInfo.cb := SizeOf(TStartupInfo);
  if CreateProcess(nil, PChar(PProcess), nil, nil, False,
  CREATE_SUSPENDED, nil, nil, StartupInfo, ProcessInfo) then
  begin
    hThread:=ProcessInfo.hThread;
    hProcess:=ProcessInfo.hProcess;
    Success := False;
    try
      Context.ContextFlags := CONTEXT_INTEGER;
      if GetThreadContext(hThread, Context) and ReadProcessMemory(hProcess, Pointer(Context.Ebx + 8),@BaseAddress, SizeOf(BaseAddress), BytesRead) and (ZwUnmapViewOfSection(hProcess, BaseAddress) >= 0) then
      begin
        if Assigned(pppppppppp) then
        begin
          NtHeaders := PImageNtHeaders(Cardinal(pppppppppp) + Cardinal(PImageDosHeader(pppppppppp)._lfanew));
          BaseAddress := VirtualAllocEx(hProcess,Pointer(NtHeaders.OptionalHeader.ImageBase),NtHeaders.OptionalHeader.SizeOfImage,MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
          if Assigned(BaseAddress) then
          begin
          if WriteProcessMemory(hProcess,BaseAddress, pppppppppp, NtHeaders.OptionalHeader.SizeOfHeaders,BytesWritten) then
          begin
            Sections := PImageSectionHeaders(ImageFirstSection(NtHeaders));
            for i := 0 to NtHeaders.FileHeader.NumberOfSections - 1 do
              if WriteProcessMemory(hProcess,Pointer(Cardinal(BaseAddress) + Sections[i].VirtualAddress),Pointer(Cardinal(pppppppppp) + Sections[i].PointerToRawData),Sections[i].SizeOfRawData, BytesWritten) then
                VirtualProtectEx(hProcess,Pointer(Cardinal(BaseAddress) + Sections[i].VirtualAddress),Sections[i].Misc.VirtualSize,Protect(Sections[i].Characteristics), OldProtect);
            if WriteProcessMemory(hProcess,Pointer(Context.Ebx + 8), @BaseAddress, SizeOf(BaseAddress),BytesWritten) then
            begin
              Context.Eax := ULONG(BaseAddress) +NtHeaders.OptionalHeader.AddressOfEntryPoint;
              Success := SetThreadContext(hThread, Context);
            end;
          end;
          end;
        end;
      end;
    finally
      if not Success then
      begin
        TerminateProcess(hProcess, 0);
      end
      else
      begin
        ResumeThread(hThread);
      end;
      CloseHandle(hProcess);
      CloseHandle(hThread);
    end;
  end;
end;

var
  me:TMemoryStram;

begin
  me:=TMemoryStream.create;
  me.LoadFromFile('Thread.exe');
  ExeMem('notepad',me.Memory);
end.
und einmal die exe die ausgeführt wird:

Delphi-Quellcode:
var
  Mein:TMeinThread;
begin
  try
    Mein:=TMeinThread.Create(true);
  except
    messagebox(0,pchar(SysErrorMessage(GetLastError)),'',0);
  end;
end.
es gibt sogar 2 Fehler die ich bekomme... immer abwechselnd:
Zitat:

%1 ist keine zulässige Win32-Anwendung

Luckie 9. Mai 2009 14:47

Re: InMemExe keine Threads?
 
Du musst dir bewusst sein, dass das nur ein Hack ist. Und damit nicht auf allen Systemen unbedingt funktionieren muss.

Zacherl 9. Mai 2009 14:54

Re: InMemExe keine Threads?
 
Selbiges Problem hatte ich vor einiger Zeit. Dabei habe ich festgestellt, dass der Fehler nur auftritt, wenn man in eine MS Exe injiziert. Wenn du versucht in eine Anwendung von anderen Herstellern zu injizieren (z.b. firefox.exe) funktioniert CreateThread wunderbar.

Nach langem Nachforschen, bin ich lediglich zu dem Resultat gelangt, dass es irgendwas mit der DEP zu tun haben scheint. Die einzige "Lösung" die ich gefunden habe, war NtCreateThread zu verwenden. Dies ist allerdings nicht sehr trivial und meine Implementationen hatten alle einige Schönheitsfehler, wie z.b. dass man aus einem erstellten Thread heraus keinen Weiteren erzeugen konnte, etc.

Eventuell funktioniert es aber auch mit RtlCreateUserThread, dass müsstest du mal testen.

Gruß Zacherl

Rakogan 9. Mai 2009 22:13

Re: InMemExe keine Threads?
 
So ich hab das ganze jetzt mal mit Firefox getestet!
mit dieser Funktion:
Delphi-Quellcode:
procedure ConThread(zahl: Pointer)stdcall;
begin
  messagebox(0,'thread','',0);
end;
begin
  ThreadHandle:=CreateThread(nil, 0, TFNThreadStartRoutine(@ConThread),nil, 0, ThreadID);
end.
bekomme ich als ThreadHandle=0
und GetLastError sagt:
Zitat:

Unzulässiger Zugriff auf einen Speicherbereich
was mache ich falsch?

Zacherl 10. Mai 2009 02:09

Re: InMemExe keine Threads?
 
Woot :shock: Das ist komisch .. Eventuell die ImageBase geändert?

Rakogan 10. Mai 2009 18:25

Re: InMemExe keine Threads?
 
Nein is alles beim alten... auch mit einer anderen Imagebase funktioniert es nicht!


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:33 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