Entwickler-Ecke
Windows API - hook problem...
mtin - Fr 27.05.05 19:03
Titel: hook problem...
ich hoffe mal das ist hier so halbwegs richtig...
also ich hatte vor sowas wie einen leetspeak-converter zu schreiben, den man anmachen kann und dann normal mit der tastatur in jedem programm schreibt und das wird in echtzeit übersetzt(h gedrückt->schreibe |-|).
Dazu hab ich mir zuerst mal nen paar hook tutorials angeschaut, und mir das von
http://delphi.about.com/library/bluc/text/uc063001a.htm
runtergeladen. Nachdem ich das dann in Delphi importiert und Compiliert hatte, ging der LocalHook erstmal gut, nur der Global Hook lieferte mir jeden Tastendruck als 4 Buchstaben (TTTTEEEESSSSTTTT), außerdem ging er scheinbar nur wenn das Programm angewählt war. So wie ich das aber verstanden habe müsste ein Global Hook IMMER funktionieren und nicht nur wenn das Programm im Vordergrund ist. :roll:
Ich bin jetzt also so weit das meine Buchstaben in einer log.txt gespeichert werden, allerdings nur wenn das prog angewählt ist.
Wie komm ich jetzt weiter?
(erstmal das das wirklich global funktioniert, dann das nich der buchstabe den ich drücke ankommt sondern meine 1337 übersetzung)
hoffentlich frag ich nich zuviel :oops:
hier noch der code der dll:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67:
| library HookDll;
uses SysUtils, Classes,windows;
var CurrentHook: HHook; KeyArray: array[0..19] of byte; KeyArrayPtr: integer; CurFile: file of byte;
function GlobalKeyBoardHook(code: integer; wParam: word; lParam: longword): longword; stdcall; begin if code<0 then begin GlobalKeyBoardHook:=CallNextHookEx(CurrentHook,code,wParam,lparam); Exit; end; if ((lParam and KF_UP)=0) and (wParam>=65) and (wParam<=90) then begin KeyArray[KeyArrayPtr]:=wParam; KeyArrayPtr:=KeyArrayPtr+1; if KeyArrayPtr>19 then begin assignfile(CurFile,'log.txt'); if fileexists('log.txt')=false then rewrite(CurFile) else reset(CurFile); blockwrite(CurFile,KeyArray[0],20); closefile(CurFile); KeyArrayPtr:=0; end; end; CallNextHookEx(CurrentHook,code,wParam,lparam); GlobalKeyBoardHook:=0; Exit; end;
procedure SetHookHandle(HookHandle: HHook); stdcall; begin CurrentHook:=HookHandle; KeyArrayPtr:=0; end;
exports GlobalKeyBoardHook index 1, SetHookHandle index 2; begin
end. |
Moderiert von
raziel: Topic aus Sonstiges verschoben am Fr 27.05.2005 um 19:20
mtin - Fr 27.05.05 21:48
der Link geht bei mir nicht...
maps - Sa 28.05.05 01:24
Hallo,
Ich würde den Hook mit "WH_JOURNALRECORD" realisieren, da du dann keine externe DLL brauchst.
mtin - Sa 28.05.05 11:12
wenn ich jetzt noch wüsste was das is...
eine suche hier im Forum bringt gar keinen Treffer(nicht mal diesen thread :?: :?: ?
ahja un uall@ogc der link ist für mich immer noch down....könntest du mir irgendwie mal nen alternativlink geben oder so?
EDIT: arg hab da wohl was falsch gelesen..."diese Frage ist zu allumfassend" :oops:
aber wär trotzdem nett wenn mir ma jemand nen gutes tutorial zeigen könnte!
mtin - Sa 28.05.05 11:43
hmmm....wenn ich versuche das zu compilen kommt gleich in der Zeile
uses windows, uallDisasm, uallProcess, uallKernel, tlhelp32;
in uallhook.pas nen fehler
"cannot resolve Unit name 'uallDisasm' at line 5"
"cannot resolve Unit name 'uallProcess' at line 5"
"cannot resolve Unit name 'uallKernel' at line 5"
was mach ich jetzt schon wieder falsch?
uall@ogc - Sa 28.05.05 11:49
kopier alle units in del projekt ordner oder in den delphi7\lib ordner
mtin - Sa 28.05.05 13:05
ok, danke erstmal!
hab jetzt von dem 1337 example die exe compiliert un die dll mit exemain.exe als Host Application compiliert...
dann hab ich ne verknüpfung zu exemain.exe gemacht und -load bzw. -unload an den Pfad angehägt.
Wenn ich die jetzt starte, passiert erstma nix(was ja nen gutes Zeichen ist)
aber es scheint auch nich zu funktionieren, diesen gesamten post hab ich jetzt geschrieben und ich seh nich das da irgendwas im 1337-style is.....
uall@ogc - Sa 28.05.05 13:09
du musst erst die hook.dpr kompilieen (dann bekommste ne dll) und dann die exemain.dpr
die startest dann mit dem parameter -load
mtin - Sa 28.05.05 13:56
hä?
wenn ich noch keine exemain.exe hab, wie will ich da die dll kompilieren?
da sagt er mir halt immer ich soll unter Run->Paramters ne Host Application festlegen...
also kompiliere ich die .exe ZUERST und wähl die dann bei der dll aus, kompilier die dll un dann start ich das programm...
hab mir grad ma den exemain source angeschaut, is das nich etwas komisch?
Delphi-Quelltext
1: 2: 3: 4: 5:
| if uppercase(paramstr(1)) = uppercase('-load') then GlobalInjectLibrary(pchar(uallUtil.GetExeDirectory+'hook3.dll')) else
if uppercase(paramstr(1)) = uppercase('-unload') then GlobalUnloadLibrary(pchar('hook.dll')) |
soweit ich weiß hab ich keine hook3.dll???
EDIT:LOL hab jetzt den gehighlighteten text mit
'hook.dll' ersetzt und unter Run->Paramteser -load eingetragen, nach dem compilieren warn alle menüs und der ganze sourcecode im 1337-style^^
is das programm so gedacht?
ich meinte eigentlich eins was erstmal gar nix umändert, sondern nur wenn ich z.b. in meinem messenger bin und z.b. hallo schreibe sollte dort |-|4110 stehen oder so....
uall@ogc - Sa 28.05.05 13:59
ähm jo änders mal ab und teste es dann, hab einfach nur meine aktuelle version mal gezippt, kann sein das ich da was getestet hatte
mtin - Sa 28.05.05 14:09
tja also irgendwie is das SEHR komisch, ich hab mir wieder die beiden verknüpfungen gemacht, klick doppelt auf load und dann auf nen Editor-fenster mit nem bissl text drin und der komplette editor text auch mit den menüs und der titelleiste wird im 1337 style angezeigt. Jetzt kann ich auch da drin schreiben, und es klappt
dann speicher ich das, klick doppelt auf unload und dann auf das Editor fenster, jetzt sieht alles normal wieder aus und gespeichert hat der auch nur das normale!
und mit meinem messenger funktionierts gleich gar nich(trillian), habs genauso probiert, load bverknüpfung gestartet, messenger angeklickt aber nix is passiert un ich konnte auch normal weiterschreiben:(
irgendwie is das alles seeeehr merkwürdig :wink:
uall@ogc - Sa 28.05.05 14:18
naja du kannst die dll in jeden prozess laden wie du es machen wolltest (keyboard hook) dann wirds immer in 1337 schrift angezeigt
mtin - Sa 28.05.05 14:37
ich will aber nich das das irgendwie umgeändert wird, ich will das alles ganz normal aussieht, und sobald ich irgendwo egal in welchem programm nen e auf der tastatur drücke, soll in dem Programm ne 3 ankommen.
also einfach nur das Signal umändern...geht das damit auch ?
noNeed 4 aNick - Mo 30.05.05 14:47
Hi mtin, das geht auch.
Ich würde dir empfehlen einen anderen Hook zu nehemen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| function msg_Hook(code: integer; wParam: word; lParam: longword): longword; stdcall; type PMsg = ^TMsg; var msg: PMsg; f: TextFile;
begin if code < HC_ACTION then begin Result := CallNextHookEx(CurrentHook, code, wParam, lParam); exit; end;
msg := PMsg(lParam);
Result := CallNextHookEx(CurrentHook, code, wParam, lParam); end; |
Beim Hook installieren musst dann mit WH_GETMESSAGE speichern
Delphi-Quelltext
1:
| setwindowshookex(WH_GETMESSAGE, HookProcAdd, LibHandle, 0); |
Der Vorteil dieses Hooks liegt auf der Hand:
Er fängt nicht nur so ziemlich alle Systemmessages ab, sondern man kann über diese Prozedur die Messages auch killen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| if (msg^.message = WM_KEYUP) and (msg^.lParam in ['A'..'Z']) then if msg^.lParam = 'E' then begin msg^.message = WM_NULL; end; end; |
Wenn du Hilfe brauchst das einzuarbeiten oder das mit dem SendInput nicht hinkriegst dann kann ich ja mal nen Beispielcode basteln...
Ansonsten wird google auch gerne dein Freund sein ;)
Moderiert von
raziel: Code- durch Delphi-Tags ersetzt.
mtin - Mo 30.05.05 17:11
also wenns dir nich zuviel is....nen beispielcode wär EXTREM nett :D
am besten einfach nen ganz simplen hook der meinetwegen aus jedem "m" nen t macht oder so 8)
ich versuch derweil mal mich noch nen bissl weiter reinzulesen, vielleicht kapier ichs ja irgendwann mal alles :roll:
noNeed 4 aNick - Mo 30.05.05 19:58
Also gut, dann wolln wa ma ;)
Die DLL:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70:
| library HookDll;
uses SysUtils, Classes, Windows, Messages;
var GlobalHookHandle: HHook;
procedure fakeInput(s: string); var i: integer; send: Array of TInput; begin if Length(s) < 1 then exit;
SetLength(send, Length(s)*2); for i := 0 to Length(s)-1 do begin send[i*2].Itype := INPUT_KEYBOARD; send[i*2].ki.wVk := ord(s[i+1]); send[i*2].ki.dwFlags := 0; send[(i*2) + 1].Itype := INPUT_KEYBOARD; send[(i*2) + 1].ki.wVk := ord(s[i+1]); send[(i*2) + 1].ki.dwFlags := KEYEVENTF_KEYUP; end; SendInput(Length(send),send[0],SizeOf(send[0])); end;
function msg_Hook(code: integer; wParam: word; lParam: longword): longword; stdcall; type PMsg = ^TMsg; var msg: PMsg;
begin
if code < HC_ACTION then begin Result := CallNextHookEx(GlobalHookHandle, code, wParam, lParam); exit; end;
msg := PMsg(lParam); if msg^.message = WM_KEYDOWN then case char(msg^.wParam) of 'E': begin fakeInput('3'); msg^.message := WM_NULL; end; 'A': begin fakeInput('4'); msg^.message := WM_NULL; end; end; Result := CallNextHookEx(GlobalHookHandle, code, wParam, lParam); end;
procedure SetHookHandle(HookHandle: HHook); stdcall; begin GlobalHookHandle := HookHandle; end;
exports msg_Hook index 1, SetHookHandle index 2; begin
end. |
Und das ist der Code der Unit, die den Hook kontrolliert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62:
| unit Global;
interface
uses windows;
type TSetHookHandle = procedure(HookHandle: HHook); stdcall;
var LibLoaded: boolean; LibHandle: HInst; HookProcAdd: pointer; SetHookHandle: TSetHookHandle; GlobalHookHandle: HHook; function LoadGlobalHook(DLL: string): boolean; function InstallGlobalHook(Handle: HWND): boolean; function UninstallGlobalHook: Boolean; stdcall; implementation
function LoadGlobalHook(DLL: string): boolean; begin LibHandle := LoadLibrary(PChar(DLL)); if LibHandle = 0 then begin Result := false; exit; end;
HookProcAdd := GetProcAddress(LibHandle,'msg_Hook');
@SetHookHandle:=GetProcAddress(LibHandle,'SetHookHandle');
if (HookProcAdd = nil)or(@SetHookHandle = nil) then begin FreeLibrary(LibHandle); Result := false; exit; end;
LibLoaded := true; Result := true; end;
function InstallGlobalHook(Handle: HWND): boolean; begin Result := false; if LibLoaded = false then exit; CurrentHook := setwindowshookex(WH_GETMESSAGE, HookProcAdd, LibHandle, Handle); SetHookHandle(GlobalHookHandle); if GlobalHookHandle<>0 then Result := true; end;
function UninstallGlobalHook: Boolean; stdcall; begin Result := UnhookWindowsHookEx(CurrentHook); GlobalHookHandle := 0; end;
end. |
So und nun einfach in deiner Form:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| uses , Global;
procedure TMainForm.Button1Click(Sender: TObject) begin LoadGlobalHook('C:\bla\HookDLL.dll'); InstallGlobalHook(0); end;
procedure TMainForm.Button2Click(Sender: TObject) begin UninstallGlobalHook; end; |
Getestet hab ich das jetzt nur so halbwegs, sollte jedoch funktionieren...
Du wirst jedoch merken, dass die fakeInput() Prozedur nicht so klappen wird wie du es dir wünscht.
Denn Sonderzeichen kannst du damit nicht simulieren.
Wenn es an Sachen wie | geht, wofür du ja [STRG]+[ALT]+[<] drücken musst, musst erst STRG dann ALT runterdrücken mit SendInput. Danach < drücken lassen und zum Schluss die Modifkatortasten wieder loslassen...
Da kannse noch hübsch rumbasteln
Viel Spass ;)
mtin - Mo 30.05.05 20:51
habs erst versucht gleich nen bissl umzuschreiben--->UNDECLARED IDENTIFIER "CurrentHook"
fast so wie in deinem beispiel gemacht-->UNDECLARED IDENTIFIER "CurrentHook"
EXAKT so wie du es aufgeschrieben hast gemacht(nur eben is die "gloabl" unit bei mir gleich der unit in der die 2 buttons sind)
-->UNDECLARED IDENTIFIER "CurrentHook"
:cry: :cry: :cry: :cry:
Ich glaub die DLL geht, kann sie halt nur nich compilen weil ich ja die "host Application2 dafür brauch...(welche ich nich compilen kann)
noNeed 4 aNick - Mo 30.05.05 21:17
Sry mein Fehler...
Ich hab die Prozeduren aus nem alten Programm rausgenommen, dort hab ich ne andere Variable verwendet...
Such einfach mal alle 'CurrentHook' und ersetzte sie mit 'GlobalHookHandle'
mtin - Mo 30.05.05 21:38
DANKE
das is echt PERFEKT!!!!!
echt nett von dir :D
noNeed 4 aNick - Mo 30.05.05 22:23
Bitte, immer gerne doch :)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!