Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  Kindlate klahvide intercept/forwarding (hook)? märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale.  :: Teata moderaatorile teata moderaatorile
otsing:  
neros
HV Guru
neros

liitunud: 26.11.2003




sõnum 31.12.2008 22:15:18 Kindlate klahvide intercept/forwarding (hook)? vasta tsitaadiga

Nii, põhimõtteliselt olen ma (taaskord) veebi läbi sirvinud kuid teemakohast ei osanud küll olemasolevast materjalist kokku panna.

Tarvis oleks siis vihjeid kuidas teha sellist asja:
Taustal lahti olev programm, mis kontrollib kas üks kindel programm on avatud, ning kui on, siis interceptib sealt ainult teatud klahve ning saadab muud klahvid programmile edasi.

A la, internet explorer on "aktiivne", ma vajutan klaviatuuril "A", programm näeb seda, aga saadab internet explorerile hoopis "B". Aga kui ma vajutan "C", siis programm ignoreeriks seda ning "C" läheks otse IE'le, ning kui ma vajutan nt "Esc" siis programm pausiks oma töö seniks kuni vajutan "Enter". Lisaks, kui internet explorer ei ole aktiivne, programm jällegi kord ignoreeriks kõiki klahve.

Ma isegi kunagi kirjutasin midagi mis programmile keysid saadab, aga vat seda kuidas saada programmile saadetud keyse interceptida.... mitte ei suuda leida, ehk keegi juhendaks õigele teele?
Kommentaarid: 48 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum
mark11
HV vaatleja

liitunud: 28.01.2006




sõnum 31.12.2008 23:44:36 Re: Kindlate klahvide intercept/forwarding (hook)? vasta tsitaadiga

madedog kirjutas:
Nii, põhimõtteliselt olen ma (taaskord) veebi läbi sirvinud kuid teemakohast ei osanud küll olemasolevast materjalist kokku panna.

Tarvis oleks siis vihjeid kuidas teha sellist asja:
Taustal lahti olev programm, mis kontrollib kas üks kindel programm on avatud, ning kui on, siis interceptib sealt ainult teatud klahve ning saadab muud klahvid programmile edasi.

A la, internet explorer on "aktiivne", ma vajutan klaviatuuril "A", programm näeb seda, aga saadab internet explorerile hoopis "B". Aga kui ma vajutan "C", siis programm ignoreeriks seda ning "C" läheks otse IE'le, ning kui ma vajutan nt "Esc" siis programm pausiks oma töö seniks kuni vajutan "Enter". Lisaks, kui internet explorer ei ole aktiivne, programm jällegi kord ignoreeriks kõiki klahve.

Ma isegi kunagi kirjutasin midagi mis programmile keysid saadab, aga vat seda kuidas saada programmile saadetud keyse interceptida.... mitte ei suuda leida, ehk keegi juhendaks õigele teele?

millega proged? või noh vahet pole, winapi funktsioone saab tänapäeval igas keeles enamasti kasutada(python, ruby, midaiganes..)

põhimõtteliselt ma ei kujuta ette kui raske/lihtne see on aga kindlasti tehtav(pole ise kunagi teinud) aga võin sulle juhtnööre anda millega arvatavasti saab selle asja ära tehtud(võimalik,et viiruse tõrjele selline asi ei meeldi):

SetWindowsHookEx() - selle abil saad sa siis näiteks teatud programmi asju nn jälgida enne kui nad päriselt programmini jõuavad
CallNextHook() - et anda klahvi väärtus edasi
// kindlasti on vaja veel kasutada funktsioone millega määrata ära mis programmi sa hookida tahad

aga nii see peaks olema..


kui hätta jääd koodiga siis küsi, proovin aidata, aga kui ei suuda lihtsalt ise ära teha siis võta minuga ühendust ja väikese tasu eest teen ära

icon_wink.gif
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
neros
HV Guru
neros

liitunud: 26.11.2003




sõnum 01.01.2009 03:21:46 vasta tsitaadiga

Ahjaa, unustasin täitsa mainimata, eriti vahet pole millega teen, ilmselt .NET'iga tuleb proge ise natuke kiirem. Tahan lihtsalt harjutamise pärast teha kuna endal oleks sellist proge vaja, ning ise tehtud on ikka hea icon_razz1.gif

Aga, CallNextHook... hmm, ma tõesti sellesarnast teemat ei leidnud, SetWindowsHookEx oli olemas aga midagi peale hakata ei osanud, na vat! Eks proovin!

_________________
GitHub
.NET Core & Azure baasil lahendused ja arhitektuur - kontakt.
Kommentaarid: 48 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum
neros
HV Guru
neros

liitunud: 26.11.2003




sõnum 01.01.2009 09:56:11 vasta tsitaadiga

Okei, ma olen öö otsa nüid sellega tegelenud. Akna leiab üles. Hookida ka NAGU õnnestuks.

Aga... miskipärast ei kutsuta kunagi vastavat hooki proci välja..

Kood siis selline

c#:
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Drawing;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Windows.Forms;
  10. using System.Diagnostics;
  11. using System.Runtime.InteropServices;
  12.  
  13. namespace WindowsFormsApplication1
  14. {
  15.     public partial class Form1 : Form
  16.     {
  17.         // DLL imports...
  18.         [DllImport("user32.dll")]
  19.         static extern int GetForegroundWindow();
  20.         [DllImport("user32.dll")]
  21.         static extern int GetWindowThreadProcessId(int hWnd, ref int ProcessId);
  22.         [DllImport("user32.dll")]
  23.         static extern int GetWindowText(int hWnd, StringBuilder text, int count);
  24.         [DllImport("user32.dll")]
  25.         static extern int SetWindowsHookEx(int idHook, HookProc lpfn, int hInstance, int threadId);
  26.         [DllImport("user32.dll")]
  27.         static extern bool UnhookWindowsHookEx(int idHook);
  28.         [DllImport("user32.dll")]
  29.         static extern int CallNextHookEx(int idHook, int nCode, int wParam, int lParam);
  30.  
  31.         // Delegate doh.gif
  32.         public delegate int HookProc(int nCode, int wParam, int lParam);
  33.  
  34.         // Declare hookprocedure
  35.         HookProc KbHookProc = null;
  36.  
  37.         // Some variables and constants
  38.         int hHook = 0;
  39.         public const int WH_KEYBOARD = 2;
  40.         public const int HC_ACTION = 0;
  41.         public const int VK_LSHIFT = 0xA0;
  42.         public const int VK_RSHIFT = 0xA1;
  43.  
  44.         // To get process' thread ID
  45.         private int GetProcessThreadFromHandle(int hWnd)
  46.         {
  47.             int processId = 0;
  48.             int threadId = GetWindowThreadProcessId(hWnd, ref processId);
  49.             return processId;
  50.         }
  51.  
  52.         // Check if the active window is what we want it to be, if so, return true
  53.         private bool ActiveWindow()
  54.         {
  55.             const int nChars = 256;
  56.             int handle = 0;
  57.             // Trying out some stuff here
  58.             StringBuilder WindowTitle = new StringBuilder(nChars);
  59.  
  60.             handle = GetForegroundWindow();
  61.  
  62.             // Check if it even has a title
  63.             if (GetWindowText(handle, WindowTitle, nChars) > 0)
  64.             {
  65.                 this.textBox1.Text = WindowTitle.ToString();
  66.                 // Compare to what we want
  67.                 if (WindowTitle.ToString() == "karri.txt - Notepad")
  68.                     return true;
  69.                 else
  70.                     return false;
  71.             }
  72.             else
  73.                 return false;
  74.  
  75.         }
  76.  
  77.         ////////////////////////////////
  78.         // Initialize ze form
  79.         ////////////////////////////////
  80.         public Form1()
  81.         {
  82.             InitializeComponent();
  83.         }
  84.  
  85.         //< Keyboard hook procedure
  86.         public int Proc(int nCode, int wParam, int lParam)
  87.         {
  88.             //For some reason, this whole function never seems to get called out??
  89.  
  90.  
  91.             // Check if an action was performed
  92.             if (nCode == HC_ACTION)
  93.             {
  94.                 // And start switching...
  95.                 switch (wParam)
  96.                 {
  97.                     case VK_LSHIFT:
  98.                         MessageBox.Show("Left shift");
  99.                         Form1.ActiveForm.Text = "Left shift pressed!";
  100.                         break;
  101.                     case VK_RSHIFT:
  102.                         Form1.ActiveForm.Text = "Right shift pressed!";
  103.                         break;
  104.                 }
  105.             }
  106.             return (CallNextHookEx(hHook, nCode, wParam, lParam));
  107.         } // Keyboard hook function >
  108.  
  109.  
  110.         // Timer ticks every millisecond (prolly too fast?) to check
  111.         // Whether foreground window is what we want it to be
  112.         private void timer1_Tick(object sender, EventArgs e)
  113.         {
  114.             if (ActiveWindow())
  115.             {
  116.                 // Get process ID
  117.                 int PID = GetProcessThreadFromHandle(GetForegroundWindow());
  118.                 // Check if hook isn't already set
  119.                 if (hHook == 0)
  120.                 {
  121.                         // If not, create a new procedure
  122.                         KbHookProc = new HookProc(Proc);
  123.                         // And create the hook
  124.                         hHook = SetWindowsHookEx(WH_KEYBOARD, KbHookProc, 0, AppDomain.GetCurrentThreadId());
  125.                        
  126.                         // If creating hook failed, let the user know!
  127.                         if (hHook == 0)
  128.                         {
  129.                             textBox1.Text = "SetWindowsHookEx Failed";
  130.                             return;
  131.                         }
  132.                         richTextBox1.Text += "\nHooked";
  133.                 }
  134.                 // Process ID into textbox
  135.                 textBox1.Text = Convert.ToString(hHook)+" "+Convert.ToString(PID);
  136.             }
  137.             else // And if it's not, unhook!
  138.             {
  139.                 if (hHook != 0)
  140.                 {
  141.                     bool ret = UnhookWindowsHookEx(hHook);
  142.                     if (ret == false)
  143.                     {
  144.                         textBox1.Text = "UnhookWindowsHookEx failed";
  145.                         return;
  146.                     }
  147.                     richTextBox1.Text += "\nUnhooked";
  148.                     hHook = 0;
  149.                 }
  150.                 textBox1.Text = "Not the right window.";
  151.             } // If (ActiveWindow()) else
  152.         }
  153.  
  154.     }
  155. }
  156.  
  157.  



Ehk siis funktsioon Proc ei tööta millegipärast. Või pigem, teda ei kutsuta kunagi välja.

Natuke oli abiks järgmine leht: http://codeidol.com/csharp/csharpckbk2/Delegates,-Events,-and-Anonymous-Methods/Using-the-Windows-Keyboard-Hook/#csharpckbk2-CHP-9-EX-13

Kuigi jällegi, kui ma selle näite kopeerisin uude projekti ja käima lasin... ei tuvastatud ühtegi klahvi ära. Ehk siis... Vista probleem? Nagu oleks adminnina käima lasknud selle proge...
Kommentaarid: 48 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum
mark11
HV vaatleja

liitunud: 28.01.2006




sõnum 01.01.2009 16:58:12 vasta tsitaadiga


lpfn
[in] Pointer to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL). Otherwise, lpfn can point to a hook procedure in the code associated with the current process.


see asi veits raskem, nimelt SetWindowsHookEx() tahab,et funktsioon oleks samas kohas kus protsess, seega kui sa ütled windowsile umbes,et "vaata notepad.exe't ja kui midagi näed siis kutsu funktsioon aadressil #<sinu .net application HookProc() funktsiooni aadress> siis selline asi ei lähe mitte kuidagi läbi, miks ei lähe, sellele kahjuks vastust anda ei oska aga kindlasti on seal mingi lihtne seletus, mis siis teha saad on see,et teed omale DLL faili kus sees on Proc() funktsioon mis sul hetkel on ning kindlasti vaata,et see funktsioon ei muutuks kompileerimise ajal(mul oli nii,et kui .def faili funktsiooni nimesi DLL kohta ei kirjutanud siis DLL'ile pandi suvalised funktsiooni nimed ja pärast ei saanudki neile ligi)..


et siis umbes midagi sellist:
hHook = SetWindowsHookEx(WH_KEYBOARD, KbHookProc, 0, AppDomain.GetCurrentThreadId());

peaks olema
hHook = SetWindowsHookEx(WH_KEYBOARD, (void *)GetProcAddress(LoadLibrary("SInu dll"), "Hook"), 0, AppDomain.GetCurrentThreadId());
(See kood ei ole valideeruv .net'iga kohe kindlasti nii,et sa pead seda tsipa muutma siis..)





//edit räme süntaks sellel .net'il,
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
neros
HV Guru
neros

liitunud: 26.11.2003




sõnum 01.01.2009 19:02:33 vasta tsitaadiga

Kas teeki ei peaks kasutama ainult siis kui globalhookida? Tho eks ma proovin.
Kommentaarid: 48 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum
inzinz
HV kasutaja

liitunud: 26.01.2005




sõnum 01.01.2009 21:02:13 vasta tsitaadiga

Soovitan uurida näidist aadressilt http://www.codeproject.com/KB/cs/globalhook.aspx
Seal ongi tehtud spetsiaalne dll, mida siis põhiprojekt kasutab. Too küll hookib ennast global keypresside külge mitte ainult antud programmi keypresside külge, aga põhiline töötav loogika on olemas, sealt edasi saad juba ise edasi aretada.
Ma ise proovisin ja ei saanud mitte kuidagi teisest programmist key evente kätte, kui siis ainult global hookimist kasutades.

Proovisin ka ise järgi, põhiline võtmepunkt ongi see, et seal dll's olevas klassis peab tegema:
//WH_KEYBOARD_LL = 13
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KbHookProc, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);

Siis peaksid ilusti saama oma eventid kätte ja sealt saad juba edasi aretada, edu uurimisel siis icon_wink.gif

_________________
Upload.ee - eestimaine failiupload
Kommentaarid: 4 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  Kindlate klahvide intercept/forwarding (hook)?
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.