Code Injection

Für allgemeine Fragen zur Programmierung mit PureBasic.
myself
Beiträge: 67
Registriert: 18.03.2006 12:48

Code Injection

Beitrag von myself »

Hi, ich hab diesen code im englischen pb forum gefunden:

Code: Alles auswählen

;whole idea to use create process as suspended is by DarkDragon
;thanks for everyone who have helped with this
DisableDebugger ;DISABLES DEBUGGER! This is needed.
Procedure RemoteThread()
   MessageRequester("Success", "Injection successed!")
EndProcedure
Procedure InjectCode(Process.s, *lpCodeToInject)
   CreateProcess_(0,Process.s,0,0,0,#CREATE_SUSPENDED,0,0,@sinfo.STARTUPINFO,@pinfo.PROCESS_INFORMATION)
   dwPID = pinfo\dwProcessId
   hProcess = pinfo\hProcess
   dwWritten.l = #Null : pbModule.l = GetModuleHandle_(0) : DwSize.l = PeekL(pbmodule+PeekW(pbmodule+$3c)+$50)
   VirtualFreeEx_(hProcess, pbModule, 0, #MEM_RELEASE)
   lpBuffer.l = VirtualAllocEx_(hProcess, pbModule, dwSize, #MEM_COMMIT | #MEM_RESERVE, #PAGE_EXECUTE_READWRITE)
   If lpBuffer = #Null : While ResumeThread_(pinfo\hThread)>1 : Wend : CloseHandle_(hProcess)  :   ProcedureReturn #False : EndIf
   If WriteProcessMemory_(hProcess, lpBuffer, pbModule, dwSize, dwWritten) = 0
      While ResumeThread_(pinfo\hThread)>1 : Wend : CloseHandle_(hProcess)
      ProcedureReturn #False
   EndIf
   hThread.l = CreateRemoteThread_(hProcess, #Null, 0, *lpCodeToInject, pbModule, #Null, #Null)
 
   If hThread=#Null : CloseHandle_(hProcess) : ProcedureReturn #False : EndIf
   While ResumeThread_(pinfo\hThread)>1 : Wend
   CloseHandle_(hThread)
   ProcedureReturn #True
EndProcedure
 
If InjectCode("notepad.exe", @RemoteThread()) = #False
   MessageRequester("Error!", "Injection failed!")
EndIf
End
Funktioniert auch prima, mein problem ist jetzt nur das geht seltsamerweise nur in manchen prozessen.. hier mal ein paar von den wenigen bei denen es geht:
geht:
notepad.exe
calc.exe
explorer.exe

und nicht gehen tut's z.B. bei firefox, internet explorer und eigentlich allen "komplexeren" oder nicht von windows mitgelieferten programmen.
Weis jemand wie man das ändert bzw. woran das liegt? Bin für jede hilfe dankebar!

mfg MySelf
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Beitrag von real »

Ich denke das sind Schutzmechanismen, um eine DLL Injection zu verhindern. Es gab zum Beispiel mit dem Internet Explorer mal Probleme mit Trojanern, die per Code Injection eingeschleust werden. Viele kommerzielle Programme unterbinden so etwas, um Manipulation zu vermeiden.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Ich hab mal versucht, das ganze so umzuschreiben, das man Code auch in einen laufenden Prozess injizieren kann. Funzt bis jetzt, habs aber nochnicht großartig getestet.

Code: Alles auswählen

EnableExplicit

DisableDebugger

Procedure RemoteThread()

  !xor eax,eax
  
EndProcedure

Procedure.l GetPIDfromWndTitle(WndTitle.s)
  Define.l PID, hWnd

  hWnd = FindWindow_(WndTitle,0)
  GetWindowThreadProcessId_ (hWnd, @PID)
  ProcedureReturn PID
EndProcedure

Procedure InjectCode(hProcess, *CodeToInject)
  Define.l WrittenBytes, CodeSize, hThread, BaseAddr
  
  CodeSize = 1024
  BaseAddr = VirtualAllocEx_(hProcess, 0, CodeSize, #MEM_COMMIT | #MEM_RESERVE, #PAGE_EXECUTE)
  
  If BaseAddr = 0
    CloseHandle_(hProcess)
    ProcedureReturn #False
  EndIf
    If WriteProcessMemory_(hProcess, BaseAddr, *CodeToInject, CodeSize, WrittenBytes) = 0
    CloseHandle_(hProcess)
    ProcedureReturn #False
  EndIf
  hThread.l = CreateRemoteThread_(hProcess, 0, 0, BaseAddr, 0, #Null, #Null)
  If hThread = 0
    CloseHandle_(hProcess)
    ProcedureReturn #False
  EndIf

  ProcedureReturn #True
EndProcedure

If InjectCode(OpenProcess_(#PROCESS_ALL_ACCESS,0,GetPIDfromWndTitle("Notepad")), @RemoteThread()) = #False
  MessageRequester("Error!", "Injection failed!")
EndIf
Edit: Für alle die gelesen haben, das der Code net funzt, habs grad gesehen und gefixt. :mrgreen:
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
myself
Beiträge: 67
Registriert: 18.03.2006 12:48

Beitrag von myself »

hWnd = FindWindow_(WndTitle,0) -> hWnd = FindWindow_(0,WndTitle)
Funktioniert übrigends, aber kann ich da auch noch was anderes machen als
!xor eax,eax ?? :)
Hellhound66
Beiträge: 476
Registriert: 23.03.2005 23:19

Beitrag von Hellhound66 »

Ja
!mov eax,0
Optimismus ist ein Mangel an Information.
Benutzeravatar
mk-soft
Beiträge: 3700
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

!xor eax,eax wird aber lieber genommen weil es weniger prozessortakte benötigt um eax zu löschen
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

ist aber langsamer als
!and eax, 0

da xor eine bescheuerte logik als and hat.
Bild
myself
Beiträge: 67
Registriert: 18.03.2006 12:48

Beitrag von myself »

ich rede von sachen wie z.B. messagebox mit titel und text im remoteprozess
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

myself hat geschrieben:ich rede von sachen wie z.B. messagebox mit titel und text im remoteprozess
Das ist nicht so einfach. Der Code den du gepostet hast ist sehr rafiniert und läd das komplette PureBasic-Modul in den fremden Prozess, dadurch hat man Zugriff auf sämtliche Prozeduren und kann ganz normal Programmieren. Injiziert man den Code aber zur Laufzeit, kann man nicht das komplette PureBasic-Modul injizieren, dass heißt man kann schon, allerdings sind dann alle Adressen falsch, da das Modul nun an einer anderen Basisadresse liegt, als es glaubt.

Wenn du Code wie in meinem Beispiel injizierst, dann unterliegt dein Programmieren gewissen Regeln:

-Du kannst keine Strings verwenden, da diese nicht in der Prozedur, sondern im Datensegment liegen.

-Du kannst keine Prozeduren aus deinem Programm aufrufen. Das schließt viele PureBasic-Befehle mit ein!

-Du kannst die API nur eingeschränkt nutzen, am sichersten ist es, wenn du alle DLL's, die du brauchst selbst lädst, mittels LoadLibrary_.

Deshalb arbeite ich da auch nur mit Assembler. :wink:
Ich nutze es um Code in ein Spiel zu injizieren und eine spielinterne Prozedur aufzurufen.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
DarkDragon
Beiträge: 6267
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Um sowas zu machen gibt es remoteAPI(schon oft genug hier gepostet, such dir den Link selbst heraus oder such im PureArea.Net Showcase).
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Antworten