VC黑防日记(四):部分黑防代码分享
代码1:自动空格键(可用于某些游戏)
关键字:自动连跳、兔子跳、模拟按键
start: //循环标签
while (true)
{
Sleep(200);
if (GetAsyncKeyState(VK_F8))
{
while (true)
{
Sleep(600);
keybd_event(VK_SPACE, 0x20, KEYEVENTF_EXTENDEDKEY | 0, 0);
if (GetAsyncKeyState(VK_ESCAPE))
{
goto start; //start hating
}
if (GetAsyncKeyState(VK_F9))
{
MessageBox(NULL, "Bye", "", MB_ICONEXCLAMATION);
return 0;
}
}
}
}
代码2:低级键盘挂钩( 使用SetWindowsHookEx设置低级键盘挂钩以用于热键 )
关键字: SetWindowsHookEx、挂钩、热键、HOOK
#include <windows.h>
#include <iostream>
using namespace std;
HHOOK keybdhook;
LRESULT CALLBACK KeyboardHook(int nCode, WPARAM wParam, LPARAM lParam); // declaration of the callback
int main()
{
keybdhook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHook, GetModuleHandle(0), 0);
if (keybdhook == 0)
{
cout << "创建hook失败" << endl;
}
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK KeyboardHook(int nCode, WPARAM wParam, LPARAM lParam)
{
KBDLLHOOKSTRUCT* key;
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
{
key = (KBDLLHOOKSTRUCT*)lParam;
//hotkey example
if (key->vkCode == VkKeyScan('a'))
{
cout << "您按下了'a'" << endl;
}
if (key->vkCode == VK_F1)
{
cout << "您按下了F1" << endl;
}
}
return CallNextHookEx(keybdhook, nCode, wParam, lParam);
}
代码3:记录鼠标坐标(有很多用法)
关键字:鼠标坐标、轨迹记录
#include <Windows.h>
#include "iostream"
using namespace std;
main()
{
while (true)
{
POINT mousePos;
GetCursorPos(&mousePos);
cout << "(" << mousePos.x << "," << mousePos.y << ")";
Sleep(20);
system("cls");
}
}
代码4:SMTP发信(有很多用法)
关键字:发信、SMTP、电子邮件、轰炸
#include <iostream>
#include <string>
#include <WinSock2.h> //适用平台 Windows
using namespace std;
#pragma comment(lib, "ws2_32.lib") /*链接ws2_32.lib动态链接库*/
int main()
{
char buff[500]; //recv函数返回的结果
string message;
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 1);
//WSAStarup,即WSA(Windows SocKNDs Asynchronous,Windows套接字异步)的启动命令
int err = WSAStartup(wVersionRequested, &wsaData);
cout << "WSAStartup:" << err << endl;
SOCKET sockClient; //客户端的套接字
sockClient = socket(AF_INET, SOCK_STREAM, 0); //建立socket对象
HOSTENT* pHostent;
pHostent = gethostbyname("smtp.126.com"); //得到有关于域名的信息
SOCKADDR_IN addrServer; //服务端地址
addrServer.sin_addr.S_un.S_addr = *((DWORD *)pHostent->h_addr_list[0]); //得到smtp服务器的网络字节序的ip地址
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(25); //连接端口25
//int connect (SOCKET s , const struct sockaddr FAR *name , int namelen ); //函数原型
err = connect(sockClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); //向服务器发送请求
cout << "connect:" << err << endl;
buff[recv(sockClient, buff, 500, 0)] = '\0';
cout << "connect:" << buff << endl;
/*
登录邮件服务器
*/
message = "ehlo 126.com\r\n";
send(sockClient, message.c_str(), message.length(), 0); //发送ehlo命令
buff[recv(sockClient, buff, 500, 0)] = '\0'; //接收返回值
cout << "helo:" << buff << endl; //输出返回值
message = "auth login \r\n";
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
cout << "auth login:" << buff << endl;
/*
发送base64加密的用户名、密码
*/
message = "xxxx\r\n"; //base64 编码的用户名
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
cout << "usrname:" << buff << endl;
message = "xxxx\r\n";//base64 编码的密码
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
cout << "password:" << buff << endl;
/*
使用 MAIL 命令指定发送者
使用 RCPT 命令指定接收者,可以重复使用RCPT指定多个接收者
*/
message = "MAIL FROM:<xxxx@126.com> \r\nRCPT TO:<xxxx@126.com> \r\n";
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
cout << "mail from: " << buff << endl;
buff[recv(sockClient, buff, 500, 0)] = '\0';
cout << "rcpt to: " << buff << endl;
/*
使用 DATA 命令告诉服务器要发送邮件内容
*/
message = "DATA\r\n";
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
cout << "data: " << buff << endl;
message = "From: Bob@example.com\r\n\
To: Alice@example.com\r\n\
Cc: theboss@example.com\r\n\
subject: subject\r\n\r\n\
Hello Alice\r\n\
This is a test message with 4 header fields and 4 lines in the message body\r\n\
your friend\r\n\
Bob\r\n.\r\n"; //注意subject关键字与正文之间要有一个空行
send(sockClient, message.c_str(), message.length(), 0);
message = "QUIT\r\n";
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
cout << "QUIT:" << buff << endl;
system("pause");
}
代码5:特征码搜索(定位特征码之类、造轮子)
关键字:造轮子、特征码
bool isHex(char c)
{
return (c >= 48 && c <= 57) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122);
}
bool createPattern(const std::string& pattern, std::string& pattern_result, std::string& mask_result)
{
bool result = false;
size_t l = pattern.size();
if (l-- > 0)
{
std::stringstream pattern_s;
std::stringstream mask_s;
for (size_t i = 0; i < l; i++)
{
if (!isHex(pattern[i]))
{
if (pattern[i] == 63)
{
pattern_s << "\x90";
mask_s << '?';
}
}
else
{
char buffer[2];
buffer[0] = pattern[i];
buffer[1] = (l >= i + 1 && isHex(pattern[i + 1])) ? pattern[++i] : 0;
pattern_s << (char)strtol(buffer, nullptr, 16);
mask_s << 'x';
}
}
result = true;
pattern_result = pattern_s.str();
mask_result = mask_s.str();
}
return result;
}
uint64_t getImageSize(uint64_t moduleBase)
{
const IMAGE_DOS_HEADER* headerDos = (const IMAGE_DOS_HEADER*)moduleBase;
const IMAGE_NT_HEADERS* headerNt = (const IMAGE_NT_HEADERS64*)((const unsigned char*)headerDos + headerDos->e_lfanew);
return (uint64_t)moduleBase + headerNt->OptionalHeader.SizeOfCode;
}
char* ptrScan(const std::string& pattern, const std::string& mask, int find)
{
uint64_t base = (uint64_t)GetModuleHandleA(nullptr);
char* ptr = (char*)base;
char* end = (char*)getImageSize(base);
size_t matchlen = mask.size();
for (int i = 0, found = 0; ptr != end; ptr++)
{
if (*ptr == pattern[i] || mask[i] == 63)
{
if (++i == matchlen)
{
if (find != found)
{
i = 0;
found++;
}
else
{
ptr -= matchlen - 1;
break;
}
}
}
}
else if (i > 0 && (*ptr == pattern[0] || *ptr == mask[0]))
{
i = 1;
}
else
{
i = 0;
}
}
if (ptr == end)
return nullptr;
return ptr;
}
char* ptrScan(const std::string& pattern, int find)
{
std::string sub_ptr;
std::string sub_mask;
createPattern(pattern, sub_ptr, sub_mask);
return ptrScan(sub_ptr, sub_mask, find);
}
const char* = ptrScan("? ? ? ? ? ? ? ? ? ? ? ? ? ? 0E 40 1F 85 EB 51 B8 9E 16 40? ? ? ? ? ? 39 40 9A 99 99 99 99 99 E9 3F");
代码6:变速齿轮(软件变速之类)
关键字:变速、hook、detours库
#include <Windows.h>
#include "detours.h" // Version 3.0 use for this hook. Be sure to include the library and includes to your project in visual studio
// Detours: https://www.microsoft.com/en-us/research/project/detours/
#pragma comment(lib,"detours.lib") // Need to include this so we can use Detours
#pragma comment(lib,"Kernel32.lib") // Need to include this since we're hooking QueryPerformanceCounter and GetTickCount which reside inside the Kernel32 library
#pragma comment(lib,"Winmm.lib") // Neet to include this since we're hooking timeGetTime which resides inside the Winmm library
extern"C" {
static BOOL(WINAPI *originalQueryPerformanceCounter)(LARGE_INTEGER *performanceCounter) = QueryPerformanceCounter;
static DWORD(WINAPI *originalGetTickCount)() = GetTickCount;
static DWORD(WINAPI *originalTimeGetTime)() = timeGetTime;
}
HMODULE hModule;
float multiplier = 2; // Game speed multiplier
LARGE_INTEGER prevLi;
LARGE_INTEGER currentLi;
LARGE_INTEGER falseLi;
// QueryPerformanceCounter is generally what is used to calculate how much time has passed between frames. It will set the performanceCounter to the amount of micro seconds the machine has been running
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx
BOOL WINAPI newQueryPerformanceCounter(LARGE_INTEGER *counter) {
originalQueryPerformanceCounter(¤tLi); // Get real current performance counter
falseLi.QuadPart += ((currentLi.QuadPart - prevLi.QuadPart) * multiplier); // Add the difference between this frame and the pervious * our multiplier to our false counter variable
prevLi = currentLi; // Set the previous to our current we just calculated
*counter = falseLi; // Make sure the caller gets our fake counter value
return true; // Return true
}
DWORD prevTickCount;
DWORD currentTickCount;
DWORD falseTickCount;
// GetTickCount can also be used to calculate time between frames, but is used less since it's less accurate than QueryPerformanceCounter
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724408%28v=vs.85%29.aspx
DWORD WINAPI newGetTickCount() {
currentTickCount = originalGetTickCount(); // Get the real current tick count
falseTickCount += ((currentTickCount - prevTickCount) * multiplier); // Add the difference between this frame and the pervious * our multiplier to our false tick count variable
prevTickCount = currentTickCount; // Set the previous to our current we just calculated
return falseTickCount; // Return false tick count
}
DWORD prevTime;
DWORD currentTime;
DWORD falseTime;
// timeGetTime can also be used to caluclate time between frames, as with GetTickCount it isn't as accurate as QueryPerformanceCounter
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd757629(v=vs.85).aspx
DWORD WINAPI newTimeGetTime() {
currentTime = originalTimeGetTime(); // Get real current time
falseTime += ((currentTime - prevTime) * multiplier); // Add the difference between this frame and the pervious * our multiplier to our false tick count variable
prevTime = currentTime; // Set the previous to our current we just calculated
return falseTime; // Return false time
}
void enable() { // Enable speedhack by hooking the 3 functions games use to keep track of time between frames
// Set initial values for hooked calculations
originalQueryPerformanceCounter(&prevLi); // Set previous frame QueryPerformanceCounter since it hasn't been hooked yet
falseLi = prevLi; // Set false value which we use to keep track of the returned value each frame
prevTickCount = originalGetTickCount(); // Set previous frame GetTickCount since it hasn't been hooked yet
falseTickCount = prevTickCount; // Set false value which we use to keep track of the returned value each frame
prevTime = originalTimeGetTime(); // Set previous frame timeGetTime since it hasn't been hooked yet
falseTime = prevTime; // Set false value which we use to keep track of the returned value each frame
// Basic detours
DisableThreadLibraryCalls(hModule);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)originalQueryPerformanceCounter, newQueryPerformanceCounter);
DetourAttach(&(PVOID&)originalGetTickCount, newGetTickCount);
DetourAttach(&(PVOID&)originalTimeGetTime, newTimeGetTime);
DetourTransactionCommit();
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)enable, NULL, 0, NULL); // Detours the 3 functions, enabling the speed hack
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}