黑客编程
0x01 初识windows消息
发送消息可以用来打开记事本的进程、关闭笔记本的进程、获取窗口的标题和设置窗口的标题。程序的具体代码为:
void CMsgTestDlg::OnClose()
{
HWND hWnd = ::FindWindow("Notepad",NULL);
if(hand == NULL)
{
AfxmessageBox("没有找到记事本");
return;
}
::SendMessage(hWnd,WM_CLOSE,NULL,NULL);
}
void CMsgTestDlg::ONExec()
{
winexec("notepad.exe",SW_SHOW);
}
void CMsgTestDlg::OnEditWnd()
{
HWND hWnd=::FindWindow(NULL,"无标题 - 记事本");
if(hand == NULL)
{
AfxMessageBox("没有找到记事本");
return;
}
char *pCaptionText = "消息测试";
::SendMessage(hWnd,VM_SETTEXT,(WPARAM)0,(LPARAM)pCaptionText);
}
void CMsgTestDlg::OnGetWnd()
{
HWND hWnd=::FindWindow("Notepad",NULL);
if(hand == NULL)
{
AfxMessageBox("没有找到记事本");
return;
}
char pCaptionText[MAXBYTE]={0};
::SendMessage(hWnd,VM_SETTEXT,(WPARAM)0,(LPARAM)pCaptionText);
AfxMessageBox(pCaptionText);
}
FindWindow()功能是通过指定的窗口名返回窗口句柄,其有两个参数,lpClassName为窗口类名,通常使用第二个长处lpWindowName指定窗口的名称。当函数找到该窗口时,会返回它的窗口句柄。
SendMessage()函数根据指定窗口句柄将消息发送给指定的窗口。三个参数分别是HWND对象要接受消息的窗口的窗口句柄、UINT对象要发送消息的消息类型,第三个参数WPARAM对象和第四个参数LPARAM对象是消息的两个附加参数。第二个参数分别是:
使用FindWindow()函数时,通常使用第二个参数,获取窗口的类名称常用Spy++。
0x02 Windows消息机制的处理
Windows应用程序执行流程非常复杂,可以看到主程序和窗口过程没有直接的调用关系,它们之间使用系统程序模块进行连接。主程序是用来注册窗口类、获取消息和分发消息的,窗口过程中定义了需要处理的消息,会根据不同的消息执行不同的动作,而不需要程序处理的消息则会交给默认的系统进程进行处理。
这里学习到一个比较简单的例子:
WinMain()函数的定义如下:
int WINAPI WinMain(
Hinstance hInstance, //应用程序的实例句柄,即为程序装入内存后的起始地址
HINSTANCE hPrevInstance, //同一文件创建的上一个实例的实例句柄
LPSTR lpCmdLine, //主函数的参数,用于程序启动时给进程传递参数
int nCmdShow //进程显示的方式,可以使最大化显示、最小化显示或者隐藏等
);
因为主函数要完成的任务是注册一个窗口类,创建一个窗口并显示创建的窗口,然后不停的获取属于自己的消息并分发给自己的窗口过程,直到收到WM_QUIT消息后推出消息循环结束进程:
使用了MyRegisterClass函数,传递实例句柄作为参数,首先填充WNDCLASSEX结构体,然后调用RegisterClassEx函数进行注册。见下:
其中,lpfnWndProc是最重要的字段,保存窗口过程的地址。注册窗口类的重点是在后面的代码中可以根据该窗口类创建该种类型的窗口。代码中,在定义窗口类时指定了背景色、鼠标指针和窗口图表等,则使用该窗口类创建的窗口都具有相同的窗口类型。
创建主窗口并显示更新的代码为:
窗口函数是由操作系统进行调用的,代码如下:
WinMain()函数收到消息后,使用DispatchMessage()函数将消息派发给了窗口过程,从而由窗口过程对消息进行处理。
0x03 模拟鼠标键盘按键的操作
鼠标、键盘常用的信息中, WM_MOUSEMOVE对应移动鼠标光标,按下鼠标左键为WM_LBUTTONDOWN,释放鼠标左键为WM_LBUTTONUP,鼠标消息如下:
键盘的按下与抬起消息也有定义,分别是WM_KEYDOWN和WM_KEYUP。常用的为:
postmessage()函数可以对键盘按键进行模拟,目标编程界面为:
开始按钮事件的代码如下:
在按钮事件中添加定时器,按照指定的时间间隔进行相应的处理:
获取标题可以通过Spy++获得。通过PostMessage()发送按F5就可以完成键盘按键模拟的程序,此函数的好处是目标程序可以在后台,不需要窗口处于激活状态。
通过API函数也可以模拟鼠标键盘按键的操作。keybd_event()、mouse_enevt()可以分别模拟键盘和鼠标的输入,定义如下:
模拟界面为:
首先将目标窗口设置到最前面并处于激活状态的部分,代码如下:
在代码的使用中,SetForegroundWindow()函数将指定的窗口设置到最前面并处于激活状态,唯一的参数是目标窗口的窗口句柄。
模拟键盘按钮:
模拟鼠标:
其中用到的ClientToScreen()函数的作用时得到指定窗口在屏幕中的坐标位置,SetCursorPos()将鼠标移动到指定的坐标位置。
0x04 通过消息实现进程间的通信
系统消息分为两种,已经定义的消息是由0到0x3ff,用户自定义的消息可以从0x400开始,系统提供了一个宏WM_USER,在进行自定义消息是,在其基础上加一个值就可以。
进程间通信需要有发送端和接受端:
通过WM_COPYDATA消息也可进行进程通信:
消息机制在计算机中得到了充分的利用,是黑客编程的基础。
虽因初涉,致云里雾里,小生只得继续努力,以待醍醐灌顶之时。