纯代码,你懂的

1. dump.h

#ifndef __SPIDER_DUMP_H_
#define __SPIDER_DUMP_H_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

typedef struct _CARDINFO{
	DWORD dwIndex;		// 牌的序号
	_CARDINFO *pPrev;	// 前一张指针(NULL为第一张)
	_CARDINFO *pNext;	// 下一张指针(NULL最后一张)
} CARDINFO, *PCARDINFO;

typedef struct _CARDPROP{
	DWORD Class;	// 花色: 梅花=0, 方块=1, 红桃=2, 黑桃=3
	DWORD Order;	// 序列: A-K, A=0
	DWORD Opened;	// 状态: 未翻开=0
} CARDPROP, *PCARDPROP;

typedef struct _GAMEPROP{
	LPVOID lpCardList[10];	// 链表指针数组
	DWORD dwCardCount[10];	// 每列牌数数组
	DWORD dwHideCount[10];	// 未翻牌数数组
} GAMEPROP, *PGAMEPROP;

typedef struct _GAMEDATA{
	HWND hWnd;
	LPVOID lpDifficulty;
	LPVOID lppTrainList;
} GAMEDATA, *PGAMEDATA;

#endif


2.dump.cpp

#include 
#include "dump.h"
#include 

const char *szClass[] = {
	"梅花",
	"方块",
	"红桃",
	"黑桃"
};
const char *szOrder[] = {
	"A",
	"2",
	"3",
	"4",
	"5",
	"6",
	"7",
	"8",
	"9",
	"10",
	"J",
	"Q",
	"K"
};
const char *szOpened[] = {
	"未翻开",
	"已翻开"
};

LPVOID lpBaseAddress = (LPVOID)0x01012008;	// 全局指针
//LPVOID lpPropAddress = (LPVOID)0x01012008;
//LPVOID lpViewAddress = (LPVOID)0x01012008;
//LPVOID lpShowAddress = (LPVOID)0x01012008;
//LPVOID lpHideAddress = (LPVOID)0x01012008;

GAMEDATA g_Data;
GAMEPROP g_Prop;
CARDPROP lpCards[104];
CARDINFO ci;

int fnDump()
{
	HWND hWnd;
	DWORD dwProcessId;
	HANDLE hProcess;
	LPVOID lpAddress;
	DWORD dwValue;
	DWORD dwLoop;
	DWORD dwOrder;	// 12-0循环
	DWORD dwClass;	//  7-0黑桃*2, 红桃*2, 梅花*2, 方块*2

	int dwRet;

	hWnd = FindWindow(NULL, "蜘蛛");
	if(hWnd == NULL)
	{
		printf("Can not find the spider window!\n");
		return 0;
	}
	GetWindowThreadProcessId(hWnd, &dwProcessId);	// return thread id
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
	if(hProcess == NULL)
	{
		printf("Can not open process! code: %d.\n", GetLastError());
		return 0;
	}

	dwRet = ReadProcessMemory(hProcess, lpBaseAddress, &g_Data, sizeof(GAMEDATA), NULL);
	if(dwRet == 0)
	{
		printf("Can not read global data! code: %d.\n", GetLastError());
		CloseHandle(hProcess);
		return 0;
	}
	if(g_Data.hWnd != hWnd)
	{
		printf("Global data mismatch!\n");
		CloseHandle(hProcess);
		return 0;
	}
	lpAddress = (LPVOID)((DWORD)lpBaseAddress + 0xF1C);
	dwRet = ReadProcessMemory(hProcess, lpAddress, &dwValue, sizeof(DWORD), NULL);
	if(dwRet == 0)
	{
		printf("Can not determine whether partially completed or not! code: %d.\n", GetLastError());
		CloseHandle(hProcess);
		return 0;
	}
	if(dwValue != 0)
	{
		printf("Game is partially completed!\n");
		CloseHandle(hProcess);
		return 0;
	}
	lpAddress = (LPVOID)((DWORD)lpBaseAddress + 0x58);
	dwRet = ReadProcessMemory(hProcess, lpAddress, &dwValue, sizeof(DWORD), NULL);
	if(dwRet == 0)
	{
		printf("Can not read remaining card count! code: %d.\n", GetLastError());
		CloseHandle(hProcess);
		return 0;
	}
	dwValue = 5 - dwValue;	// 发完是5次
	printf("There are(is) %d time(s) remaining.\n", dwValue);
	if(dwValue > 0)
	{
		SetForegroundWindow(hWnd);
		for(dwLoop = 0; dwLoop < dwValue; dwLoop++)
		{	// 把所有的牌发完 -> 发送点击发牌菜单的命令
			dwRet = SendMessage(hWnd, WM_COMMAND, 40016, 0);
		}
	}
	dwRet = ReadProcessMemory(hProcess, g_Data.lpDifficulty, &dwValue, sizeof(DWORD), NULL);
	if(dwRet == 0)
	{
		printf("Can not read difficulty data! code: %d.\n", GetLastError());
		CloseHandle(hProcess);
		return 0;
	}
	if((dwValue != 1) && (dwValue != 2) && (dwValue != 4))
	{
		printf("Difficulty data mismatch!\n");
		CloseHandle(hProcess);
		return 0;
	}
	dwValue = (DWORD)g_Data.lpDifficulty;
	dwValue += 0xC;
	lpAddress = (LPVOID)dwValue;	// 牌属性指针地址
	dwRet = ReadProcessMemory(hProcess, lpAddress, &dwValue, sizeof(DWORD), NULL);
	if(dwRet == 0)
	{
		printf("Can not read card property pointer! code: %d.\n", GetLastError());
		CloseHandle(hProcess);
		return 0;
	}
	lpAddress = (LPVOID)dwValue;	// 牌属性指针
	dwRet = ReadProcessMemory(hProcess, lpAddress, lpCards, sizeof(CARDPROP) * 104, NULL);
	if(dwRet == 0)
	{
		printf("Can not read card property array! code: %d.\n", GetLastError());
		CloseHandle(hProcess);
		return 0;
	}
	dwRet = ReadProcessMemory(hProcess, g_Data.lppTrainList, &g_Prop, sizeof(GAMEPROP), NULL);
	if(dwRet == 0)
	{
		printf("Can not read train list data! code: %d.\n", GetLastError());
		CloseHandle(hProcess);
		return 0;
	}
	printf("======== begin dumping card data ========\n");
	dwOrder = 12;	// ..
	dwClass = 7;	// ..
	for(dwLoop = 0; dwLoop < 10; dwLoop++)
	{	// 遍历每一列
		dwRet = ReadProcessMemory(hProcess, g_Prop.lpCardList[dwLoop], &dwValue, sizeof(DWORD), NULL);
		if(dwRet == 0)
		{	// 此次是根据元素(链表指针读取链表地址)
			printf("Can not read train %d pointer! code: %d.\n", dwLoop, GetLastError());
			CloseHandle(hProcess);
			return 0;
		}
		//lpAddress = (LPVOID)dwValue;
		//dwRet = ReadProcessMemory(hProcess, lpAddress, &dwValue, sizeof(DWORD), NULL);
		//if(dwRet == 0)
		//{
		//	printf("Can not read train %d data! code: %d.\n", dwLoop, GetLastError());
		//	CloseHandle(hProcess);
		//	return 0;
		//}
		lpAddress = (LPVOID)dwValue;
		dwRet = ReadProcessMemory(hProcess, lpAddress, &ci, sizeof(CARDINFO), NULL);
		if(dwRet == 0)
		{	// 此次读取链表第一个元素(要求游戏一行都没有收起, 也没有空行)
			printf("Can not read train %d data! code: %d.\n", dwLoop, GetLastError());
			CloseHandle(hProcess);
			return 0;
		}
		dwValue = 0;
		// 显示当前实际的卡片属性
		printf("第 %d 张牌序号为: %d(%s 的 %s%s).\n",
				dwValue,
				ci.dwIndex,
				szOpened[lpCards[ci.dwIndex].Opened],
				szClass[lpCards[ci.dwIndex].Class],
				szOrder[lpCards[ci.dwIndex].Order]);
		// 修改为我们想要的属性值
		lpCards[ci.dwIndex].Opened = 1;				// 已经翻开
		lpCards[ci.dwIndex].Class = dwClass / 2;	// 花色
		lpCards[ci.dwIndex].Order = dwOrder;		// 序号
		if(dwOrder == 0)
		{	// 已经排到A了
			if(dwClass == 0) break;	// 尽头了
			dwOrder = 12;
			dwClass--;
		}else dwOrder--;
		while(ci.pNext != 0)
		{
			lpAddress = (LPVOID)ci.pNext;
			dwRet = ReadProcessMemory(hProcess, lpAddress, &ci, sizeof(CARDINFO), NULL);
			if(dwRet == 0)
			{
				printf("Can not read train %d data!! code: %d.\n", dwLoop, GetLastError());
				CloseHandle(hProcess);
				return 0;
			}
			dwValue++;
			// 显示当前实际的卡片属性
			printf("第 %d 张牌序号为: %d(%s 的 %s%s).\n",
					dwValue,
					ci.dwIndex,
					szOpened[lpCards[ci.dwIndex].Opened],
					szClass[lpCards[ci.dwIndex].Class],
					szOrder[lpCards[ci.dwIndex].Order]);
			// 修改为我们想要的属性值
			lpCards[ci.dwIndex].Opened = 1;				// 已经翻开
			lpCards[ci.dwIndex].Class = dwClass / 2;	// 花色
			lpCards[ci.dwIndex].Order = dwOrder;		// 序号
			if(dwOrder == 0)
			{	// 已经排到A了
				if(dwClass == 0) break;	// 尽头了
				dwOrder = 12;
				dwClass--;
			}else dwOrder--;
		}
		if(ci.pNext) break;	// 中断跳出的while循环
		if(dwLoop < 9) printf("\n");
	}
	if(dwLoop < 10)
	{
		printf("Card count mismatch.\n");
		CloseHandle(hProcess);
		return 0;
	}
	printf("======== Cracking game memory ========\n");
	dwValue = (DWORD)g_Data.lpDifficulty;
	dwValue += 0xC;
	lpAddress = (LPVOID)dwValue;	// 牌属性指针地址
	dwRet = ReadProcessMemory(hProcess, lpAddress, &dwValue, sizeof(DWORD), NULL);
	lpAddress = (LPVOID)dwValue;	// 牌属性指针
	dwRet = WriteProcessMemory(hProcess, lpAddress, lpCards, sizeof(CARDPROP) * 104, NULL);
	// 修改已翻开的牌数
	for(dwLoop = 0; dwLoop < 10; dwLoop++)
	{
		g_Prop.dwHideCount[dwLoop] = 0;
	}
	dwValue = (DWORD)g_Data.lppTrainList;
	dwValue += (sizeof(DWORD) * 20);
	lpAddress = (LPVOID)dwValue;
	dwRet = WriteProcessMemory(hProcess, lpAddress, g_Prop.dwHideCount, sizeof(DWORD) * 10, NULL);
	if(dwRet == 0)
	{
		printf("Can not crack card view property! code: %d.\n", GetLastError());
		CloseHandle(hProcess);
		return 0;
	}
	InvalidateRect(hWnd, NULL, TRUE);
	printf("======== finish dumping card data ========\n");
	CloseHandle(hProcess);
	return 1;
}

int main(int argc, char* argv[])
{
	printf("============================================\n");
	printf("======== 游侠技术研究,请勿非法使用 ========\n");
	printf("============================================\n");
	return fnDump();
}


至于是干嘛的,看得懂就懂,不懂也就这样了,至于你懂不懂,反正我懂了.

无图有真相...

你可能感兴趣的:(Visual,C++,黑客技术)