DLL Inject / Eject

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Re: DLL Inject / Eject

Beitrag von uweb »

Mein Hook läuft immer noch nicht.
Ich habe nun verschiedene DLL's und Target-Test-EXE (um sicher zu sein, dass genau DER API-Aufruf auch vorhanden ist).
Da mir das Handling damit zu nervig wurde habe ich für Josh's Inject / Eject eine alternative Öberfläche gebastelt.
Es ist zwar nur ein bescheidener Beitrag, aber vielleicht kann es jemand gebrauchen.

Code: Alles auswählen

DisableDebugger

;- Variablen und Konstanten
Global Window_0, G_Target_Text, G_Target, G_Inject, G_Eject, G_DLL, G_EXE
Global Target.s ; Text der Titelzeile eines Fensters
Global Target_valid, Dll_valid
Global Dll_Url.s

Define Dll_Path.s    = GetCurrentDirectory()
;Define msg    .s

;-
Procedure.i CodeInject   (WndName.s, DllName.s)
;  kann unverändert übernommen werden
EndProcedure

Procedure.i CodeEject    (WndName.s, DllName.s)
;  kann unverändert übernommen werden
EndProcedure

Procedure.s GetTargetWindowTitle(hwnd)
  Protected Length
  Protected *Buffer
  Length = GetWindowTextLength_(hwnd)+1
  *Buffer = AllocateMemory(Length)
  GetWindowText_(hwnd,*Buffer,Length)
  ProcedureReturn PeekS(*Buffer)
EndProcedure

;-

Procedure G_TargetEvent(Event) ; später richtige Prüfung - Hotpatch möglich ?
  If EventType() = #PB_EventType_Change
    Target = GetGadgetText(G_Target)
    If Target <> ""
      Target_valid = #True
    Else
      Target_valid = #False
    EndIf
    Debug "G_Target Change"
  EndIf
EndProcedure

Procedure G_ClearEvent(Event)
  SetGadgetText(G_Target, "")
  Target_valid = #False
  DisableGadget(G_Inject, #True)
  DisableGadget(G_Eject,  #True)  
EndProcedure
Procedure G_InjectEvent(Event)
  CodeInject   (Target.s, Dll_Url.s)
  Debug "G_Inject Event"
EndProcedure

Procedure G_EjectEvent(Event)
  CodeEject    (Target.s, Dll_Url.s)
  Debug "G_Eject Event"
EndProcedure

Procedure G_DLLEvent(Event) ; später richtige Prüfung - Hook-Dll oder nur Dll ?
  If EventType() = #PB_EventType_LeftClick Or EventType() = #PB_EventType_RightClick
    entry = GetGadgetState(G_DLL)
    If entry <> -1
      Dll_Url = GetGadgetText(G_DLL) + GetGadgetItemText(G_DLL, entry, 0)
      Dll_valid = #True
      Debug "G_DLL Click - " + Dll_Url
    Else
      Dll_valid = #False
      Debug "G_DLL Click - " + "keine verwertbare Auswahl"
    EndIf
  EndIf
EndProcedure

Procedure G_EXEEvent(Event) 
  If EventType() = #PB_EventType_LeftClick Or EventType() = #PB_EventType_RightClick
    entry = GetGadgetState(G_EXE)
    If entry <> -1
      EXE_Url.s = GetGadgetText(G_EXE) + GetGadgetItemText(G_EXE, entry, 0)
      Injector.s = GetWindowTitle(Window_0) 
      i = 0
      If RunProgram(EXE_Url)
        Repeat
          Delay(50)
          i = i + 1
          hwnd = GetForegroundWindow_()
          Target = GetTargetWindowTitle(hwnd)
        Until Target <> Injector Or i = 25
        If i < 26
          SetGadgetText(G_Target, GetTargetWindowTitle(hwnd))
          Target_valid = #True
        EndIf
      EndIf
      Debug "G_EXE Click - " + EXE_Url
    Else
      Debug "G_EXE Click - " + "keine verwertbare Auswahl"
      Target_valid = #False
    EndIf
  EndIf
EndProcedure




;- Main

;Prüfen ob Programm nicht in Unicode compiliert
If #PB_Compiler_Unicode
  MessageRequester ("Inject / Eject", "Das Programm darf nicht in Unicode compiliert werden", #MB_ICONERROR)
  End
EndIf



Window_0      = OpenWindow(#PB_Any, 0, 0, 600, 600, "", #PB_Window_SystemMenu)
G_Target_Text = TextGadget(#PB_Any, 10, 10, 100, 20, "Target Title")
G_Target      = StringGadget(#PB_Any, 10, 30, 555, 25, "")
G_Clear       = ButtonGadget(#PB_Any, 565, 30, 25, 25, "X")
G_Inject      = ButtonGadget(#PB_Any, 10, 65, 100, 25, "Inject")
G_Eject       = ButtonGadget(#PB_Any, 490, 65, 100, 25, "Eject")
G_DLL         = ExplorerListGadget(#PB_Any, 10, 100, 580, 240, Dll_Path + "*.dll", #PB_Explorer_AutoSort|#PB_Explorer_AlwaysShowSelection|#PB_Explorer_FullRowSelect)
G_EXE         = ExplorerListGadget(#PB_Any, 10, 350, 580, 240, Dll_Path + "*.exe", #PB_Explorer_AutoSort|#PB_Explorer_AlwaysShowSelection|#PB_Explorer_FullRowSelect)

DisableGadget(G_Clear,  #True)
DisableGadget(G_Inject, #True)
DisableGadget(G_Eject,  #True)
SetGadgetItemAttribute(G_DLL, 0, #PB_Explorer_ColumnWidth, 259)
SetGadgetItemAttribute(G_EXE, 0, #PB_Explorer_ColumnWidth, 259)

Repeat
 Event = WaitWindowEvent()
 Select Event
   Case #PB_Event_Gadget
     Select EventGadget()
       Case G_Target : G_TargetEvent(Event)
       Case G_Clear  : G_ClearEvent(Event)
       Case G_Inject : G_InjectEvent(Event)
       Case G_Eject  : G_EjectEvent(Event)
       Case G_DLL    : G_DLLEvent(Event)
       Case G_EXE    : G_EXEEvent(Event)
     EndSelect
   
     If Target_valid 
       DisableGadget(G_Clear,  #False)
       If Dll_valid
         DisableGadget(G_Inject, #False)
         DisableGadget(G_Eject,  #False)
       Else
         DisableGadget(G_Inject, #True)
         DisableGadget(G_Eject,  #True)
       EndIf
     Else
       DisableGadget(G_Clear,  #True)
     EndIf
     
   EndSelect
Until event = #PB_Event_CloseWindow
Das Eine oder andere habe ich mir hier aus dem Forum geholt.
Danke an alle !

Im Idealfall liegt das kompilierte Test-Tool mit allen DLL's und Target-Test-EXE in einem Verzeichnis.
Die Target-Test-EXE muss übrigens nicht unbedingt darüber aufgerufen werden. Man kann den Fenstertitel auch direkt eingeben.

Beispiel für eine Target-Test-EXE um zu verdeutlichen, dass es oft mehrere API-Wege zum Ziel gibt :

Code: Alles auswählen

Import "User32.lib"
  MessageBoxA(Window.l, Body$, Title$, Flags.l = 0)
  MsgBox(Window.l, Body$, Title$, Flags.l) As "_MessageBoxA@16"
EndImport

  
If OpenWindow(0, 200, 200, 200, 100, "Test")
  
  ButtonGadget(0, 10, 10, 180, 20, "MessageRequester")
  ButtonGadget(1, 10, 40, 180, 20, "MessageBoxA")
  ButtonGadget(2, 10, 70, 180, 20, "MsgBox")
  
  Repeat
   Event = WaitWindowEvent()
   Select Event
     Case #PB_Event_Gadget
       Select EventGadget()
         Case 0 : MessageRequester ("Test-Message", "MessageRequesterText", #PB_MessageRequester_Ok)
         Case 1 : MessageBoxA(0, "MessageBoxAText", "Test-Message")
         Case 2 : MsgBox(0, "MsgBoxText", "Test-Message", 0)
       EndSelect
     EndSelect
  Until event = #PB_Event_CloseWindow    
    
EndIf
End 
Antworten