Dateiname von einem fremden Programm "abfangen"?

Anfängerfragen zum Programmieren mit PureBasic.
pebo
Beiträge: 66
Registriert: 01.12.2006 21:08
Wohnort: 66450 Bexbach

Dateiname von einem fremden Programm "abfangen"?

Beitrag von pebo »

Hallo zusammen,

ich bräuchte für ein Tool eine bestimmte Funktion, weiss aber nicht ob das überhaupt möglich ist und wenn ja, hab ich keine Ahnung wie ich das angehen soll:

Mein Tool soll im Systray abgelegt werden und dort warten, bis in einem anderen Programm eine Datei mittels Fileselectbox eingeladen wird. Sobald in dieser Fileselectbox eine Datei mittels "OK-Button" geladen wird, soll der Dateiname von meinem Tool "abgefangen" werden damit ich darauf reagieren kann.

Mein Tool soll nur unter Windows laufen, deshalb kann auch die WINAPI benutzt werden (ohne eine API-Funktion geht es eh nicht nehme ich mal an)
Wäre prima wenn ihr mir da weiterhelfen könntet!

Viele Grüsse
Peter
Alle sagten "das geht nicht!" .... und dann kam einer der nichts davon wusste und machte es einfach.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Soll jedes Programm auf dem Rechner überwacht werden oder nur ein bestimmtes?

Letzteres ist einfacher.
Du musst die API-Funktion GetOpenFileName hooken. Dann kannst du den Dateinamen abfangen und ändern.

Schau dir mal RemoteAPI - Hook an.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
pebo
Beiträge: 66
Registriert: 01.12.2006 21:08
Wohnort: 66450 Bexbach

Beitrag von pebo »

Hi Thorium,
Thorium hat geschrieben:Soll jedes Programm auf dem Rechner überwacht werden oder nur ein bestimmtes?

Letzteres ist einfacher.
Du musst die API-Funktion GetOpenFileName hooken. Dann kannst du den Dateinamen abfangen und ändern.

Schau dir mal RemoteAPI - Hook an.
vielen Dank für den Tipp :allright:

Es soll nur ein bestimmtes Programm überwacht werden.
Ich werde mir mal das "RemoteAPI - Hook"-Paket anschauen und hoffe das ich mit meinen "Programmierkünsten "damit zurecht komme :wink:


Gruss
Peter
Alle sagten "das geht nicht!" .... und dann kam einer der nichts davon wusste und machte es einfach.
pebo
Beiträge: 66
Registriert: 01.12.2006 21:08
Wohnort: 66450 Bexbach

Beitrag von pebo »

Ich muss zugestehen das ich mit dem RemoteHook Beispiel und auch allgemein mit dem Hooken der Funktion GetOpenFileName nicht zurechtkomme :oops:
Kann mir keiner hier mit einem kleinen Beispiel weiterhelfen? Ich würde auch als Entlohnung z.B. ein Päckchen DVD-Rohlinge oder sowas in der Art springen lassen (ich weis nicht wieviel Arbeit so ein Beispiel erfordert, deshalb bitte keine Anmache von wegen "... viel zu wenig für den Job ...". Man kann über alles reden)

Gruss
Peter
Alle sagten "das geht nicht!" .... und dann kam einer der nichts davon wusste und machte es einfach.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Sorry.
Aber das scheint mir noch ein wenig zu komplex zu sein.

Ich kann dir zwar nen Code liefern, aber da musst du auch durchsteigen, weil sauber laufen tut der net und ich hab keine Lust da jetzt ewig drann zu hocken.

Das muss als DLL mit Unicode-Unterstützung kompiliert werden und dann in die zu überwachende Anwendung injiziert werden:

Code: Alles auswählen

;/---------------------------------------------------\
;| Beispiel zur Überwachung von "Open File Dialogen" |
;| by Thorium                                        |
;|                                                   |
;| Stand: 30.09.2008                                 |
;|                                                   |
;| PureBasic 4.20                                    |
;\---------------------------------------------------/

EnableExplicit

;OrigProcAddr = Funktion, die gehookt werden soll
;HookProcAddr = Hook-Prozedur
;OrigCodePatchAddr = Adresse in der Hook-Prozedur, wo der Originalcode eingepatcht werden kann
Procedure InstallInlineHook(OrigProcAddr.l,HookProcAddr,OrigCodePatchAddr.l)

  Define.l StartPos,EndPos,Length,OldProtect,Dummy
  
  ;Ermitteln der Länge des zu patchenden Codes und Einsprungpunkt
  StartPos = OrigProcAddr
  Repeat
    EndPos = DisASMCommand(StartPos)
    Length = Length + (EndPos - StartPos)
    StartPos = EndPos
  Until Length >= 7
  
  ;Schreibrechte in Hook-Prozedur setzen
  VirtualProtect_(OrigCodePatchAddr,Length + 6,#PAGE_EXECUTE_READWRITE,@OldProtect)
  
  ;Patchen der Hook-Prozedur mit dem Code, der in der Original-Funktion überschrieben wird.
  CopyMemory(OrigProcAddr,OrigCodePatchAddr,Length)
  
  ;Rücksprungcode in Hook-Funktion einpatchen
  PokeB(OrigCodePatchAddr + Length,$68) ;push const
  PokeL(OrigCodePatchAddr + Length + 1,OrigProcAddr + Length) ;const
  PokeB(OrigCodePatchAddr + Length + 5,$C3) ;ret
  
  ;Zugriffsrechte in Hook-Prozedur wiederherstellen
  VirtualProtect_(OrigCodePatchAddr,Length + 6,OldProtect,@Dummy)
  
  ;Schreibrechte in Original-Prozedur setzen
  VirtualProtect_(OrigProcAddr,Length + 6,#PAGE_EXECUTE_READWRITE,@OldProtect)

  ;patchen der Original-Prozedur
  PokeB(OrigProcAddr,$68) ;push const
  PokeL(OrigProcAddr + 1,HookProcAddr) ;const
  PokeB(OrigProcAddr + 5,$C3) ;ret
  
  ;Zugriffsrechte in Original-Prozedur wiederherstellen
  VirtualProtect_(OrigProcAddr,Length + 6,OldProtect,@Dummy)
  
EndProcedure

Procedure UninstallInlineHook(OrigProcAddr.l,OrigCodePatchAddr.l)

  Define.l StartPos,EndPos,Length,OldProtect,Dummy
  
  ;Ermitteln der Länge des überschriebenen Originalcodes
  StartPos = OrigProcAddr
  Repeat
    EndPos = DisASMCommand(StartPos)
    Length = Length + (EndPos - StartPos)
    StartPos = EndPos
  Until Length >= 7

  ;Patchen der Original-Prozedur mit dem Code, der in der Original-Funktion überschrieben wurde.

  ;Schreibrechte in Original-Prozedur setzen
  VirtualProtect_(OrigProcAddr,Length + 6,#PAGE_EXECUTE_READWRITE,@OldProtect)
  
  ;Patchen der Original-Prozedur mit dem Code, der in der Original-Funktion überschrieben wurde.
  CopyMemory(OrigCodePatchAddr,OrigProcAddr,Length)

  ;Zugriffsrechte in Original-Prozedur wiederherstellen
  VirtualProtect_(OrigProcAddr,Length + 6,OldProtect,@Dummy)

EndProcedure

Procedure GetOpenFileName_Hook(*lpofn.OPENFILENAME)

  If MessageRequester("GetOpenFileName Hook","Anwendung möchte einen OpenFile-Dialog öffnen." + Chr(10) + "Möchten sie dies zulassen?",#PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes

    ;Aufrufen der Originalprozedur
    CallFunctionFast(?GetOpenFileName_OrigCode,*lpofn)
    
    If MessageRequester("GetOpenFileName Hook","Ausgewählte Datei: " + PeekS(*lpofn\lpstrFile,#PB_Ignore,#PB_Unicode) + Chr(10) + "Möchten sie das öffnen dieser Datei unterbinden?",#PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
      PokeW(*lpofn\lpstrFile,0)
    EndIf

  EndIf

  ProcedureReturn
  
  ;in Originalprozedur überschriebenen Code ausführen und Rücksprung
  ;wird während der Laufzeit gepatcht
  GetOpenFileName_OrigCode:
  
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop
  !nop

EndProcedure

Procedure InstallOpenFileNameHook()

  Define.l hModule,ProcAddr

  hModule = OpenLibrary(#PB_Any,"comdlg32.dll")
  ProcAddr = GetFunction(hModule,"GetOpenFileNameW")
  InstallInlineHook(ProcAddr,@GetOpenFileName_Hook(),?GetOpenFileName_OrigCode)

EndProcedure

Procedure UninstallOpenFileNameHook()

  Define.l hModule,ProcAddr

  hModule = OpenLibrary(#PB_Any,"comdlg32.dll")
  ProcAddr = GetFunction(hModule,"GetOpenFileNameW")
  UnInstallInlineHook(ProcAddr,?GetOpenFileName_OrigCode)

EndProcedure

ProcedureDLL AttachProcess(Instance)
  
  InstallOpenFileNameHook()
  
EndProcedure

ProcedureDLL DetachProcess(Instance)
  
  UninstallOpenFileNameHook()

EndProcedure
Zum Test kann einfach ein universeller DLL-Injector, wie dieser verwendet werden.

2 große Probleme hat der Code:
Erstens wird der Dateiname nicht richtig ausgelesen oder angezeigt, keine Ahnung warum. Der ist Unicode und sollte eigentlich ausgelesen und angezeigt werden können. Tut aber net.
Zweitens knippst sich die Testanwendung (Notepad) manchmal einfach aus, wenn der Hook installiert ist und man sich im OpenFile-Dialog befindet.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
pebo
Beiträge: 66
Registriert: 01.12.2006 21:08
Wohnort: 66450 Bexbach

Beitrag von pebo »

Hi Thorium,

vielen Dank für deine Mühe :allright:
Aber um ehrlich zu sein: da blick ich nie und nimmer durch, bin halt ein "Hobbyprogrammierer" dessen Kenntnisse für so einen Code nicht ausreichen /:->
Habe heute auf der Arbeit auch festgestellt, dass ich das geplante Tool nicht unbedingt brauche da ich das Problem auf einem anderen Weg lösen kann :wink:

Viele Grüsse
Peter
Alle sagten "das geht nicht!" .... und dann kam einer der nichts davon wusste und machte es einfach.
Antworten