植物大战僵尸作弊器源代码(控制台版)

从之前的文章中,可以知道如何找到植物大战僵尸的游戏基址,以及其全部内存地址。。

下面将其实现出来。。

说明:通过游戏基址,再加上偏移量,修改游戏在内存中的值。实现无限阳光‘、无限金币、免CD、免暂停的功能。。。。,本例子的游戏是植物大战僵尸-----英文原版。

注意:不同版本的游戏的游戏基址不一定相同。’

 

思路:

1.打开进程,并获取进程句柄。

  方式:1.可以遍历当前所有的进程。

    CreateToolhelp32Snapshot(),Process32First(),Process32Next(),OpenProcess()。

     2.直接利用VS的SPY++,得到进程的句柄。(或者得到进程的标题、类名,再通过标题得到窗口句柄,再得到进程ID,再得到进程句柄)

    FindWindow(),GetWindowThreadProcessId(),OpenProcess().

2.根据游戏基址+偏移量,得到修改地址。将值修改成自定义值。(具体偏移多少次,看之前的文章----游戏内存地址)

 

主要用到函数:

ReadProcessMemory(),读取内存
WriteProcessMemory(),修改内存

修改内存权限后,在写入。。。。。
VirtualProtectEx(g_hProcess, pCode, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect);
WriteProcessMemory(g_hProcess, pCode, opCode, 4, NULL);
VirtualProtectEx(g_hProcess, pCode, 4, dwOldProtect, NULL);

// jsConsole.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include <Windows.h>

//游戏基址
int g_nBaseAddr = 0x006A9EC0;
//游戏句柄
HANDLE g_hProcess;

//根据基址计算出两次偏移后的地址
int *get2Point(int g_nBaseAddr, int p1, int p2)
{
    int iBase, iP1, *iP2;

    if (!ReadProcessMemory(g_hProcess, (LPVOID)g_nBaseAddr, &iBase, 4, NULL))
    {
        return NULL;
    }

    if (!ReadProcessMemory(g_hProcess, (LPVOID)(iBase + p1), &iP1, 4, NULL))
    {
        return NULL;
    }

    //返回最终地址
    iP2 = (int *)(iP1 + p2);
    return iP2;
}

//根据基址计算出三次偏移后的地址
int *get3Point(int g_nBaseAddr, int p1, int p2, int p3)
{
    int iBase, iP1, iP2, *iP3;

    if (!ReadProcessMemory(g_hProcess, (LPVOID)g_nBaseAddr, &iBase, 4, NULL))
    {
        return NULL;
    }

    if (!ReadProcessMemory(g_hProcess, (LPVOID)(iBase + p1), &iP1, 4, NULL))
    {
        return NULL;
    }

    if (!ReadProcessMemory(g_hProcess, (LPVOID)(iP1 + p2), &iP2, 4, NULL))
    {
        return NULL;
    }
    iP3 = (int *)(iP2 + p3);
    return iP3;
}

//改变阳光值
void ModifySun()
{
    //获取阳光所在地址
    int *pSun = get2Point(g_nBaseAddr, 0x768, 0x5560);
    //将阳光改为多少
    int nSunValue = 999999;
    //修改
    WriteProcessMemory(g_hProcess, pSun, &nSunValue, 4, NULL);
}

//修改关卡
void ModifyGuanka()
{
    int *pGuanka = get2Point(g_nBaseAddr, 0x82C, 0x24);
    int guankaValue = 58;
    WriteProcessMemory(g_hProcess, pGuanka, &guankaValue, 4, NULL);
}

//修改金币
void ModifyMoney()
{
    int *pMoney = get2Point(g_nBaseAddr, 0x82C, 0x28);
    int moneyValue = 999999;
    WriteProcessMemory(g_hProcess, pMoney, &moneyValue, 4, NULL);
}

//点击其他程序,游戏不会暂停。免暂停
void ModifyPause()
{
    unsigned char *pCode = (unsigned char *)0x4502C0;

    //修改内存读写权限
    DWORD dwOldProtect;
    VirtualProtectEx(g_hProcess, pCode, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    unsigned char opCode[] = "\xC3\x04\x00";
    WriteProcessMemory(g_hProcess, pCode, opCode, 4, NULL);

    VirtualProtectEx(g_hProcess, pCode, 4, dwOldProtect, NULL);
}

//利用线程不断更新阳光和金币、免CD。实现无限金币
DWORD WINAPI ModifyCDThread(
    LPVOID lpParameter   // thread data
    )
{
    while (1)
    {
        //修改阳光
        ModifySun();

        //获取卡槽数目地址
        int *pCount = get3Point(g_nBaseAddr, 0x768, 0x144, 0x24);
        if (pCount == NULL)
            continue;

        //获取第一个卡槽地址
        int *pFirst = get3Point(g_nBaseAddr, 0x768, 0x144, 0x4C);
        if (pFirst == NULL)
            continue;

        //获取卡槽数目
        int nCount = 0;
        ReadProcessMemory(g_hProcess, pCount, &nCount, 4, NULL);

        //对每一个卡槽进行免CD
        for (int i = 0; i < nCount; i++)
        {
            //pFirst[0] = pFirst[1];//读和写

            int nRecoveryTime;
            ReadProcessMemory(g_hProcess, pFirst + 1, &nRecoveryTime, 4, NULL);
            WriteProcessMemory(g_hProcess, pFirst, &nRecoveryTime, 4, NULL);
            
            //卡槽间的偏移量为50
            pFirst = (int *)((int)pFirst + 0x50);
        }
        Sleep(100);
    }
}


void ModifyCD()
{
    CreateThread(0, 0, ModifyCDThread, 0, 0, 0);
}

int _tmain(int argc, _TCHAR* argv[])
{
    //获取游戏窗口所在进程的进程ID,也就是PID
    HWND hWnd = FindWindow(NULL, TEXT("植物大战僵尸中文版"));
    if (NULL == hWnd)
    {
        printf("查找窗口失败\n");
        return 0;
    }
    
    DWORD dwProcessId;
    GetWindowThreadProcessId(hWnd, &dwProcessId);
    printf("进程ID:%d\n", dwProcessId);
    
    //获取进程句柄
    g_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (NULL == g_hProcess)
    {
        printf("打开进程失败\n");
        return 0;
    }

    ModifySun();
    ModifyGuanka();
    ModifyMoney();
    ModifyPause();

    ModifyCDThread(0);
    getchar();
    return 0;
}

 

posted @ 2017-11-05 23:35  gd_沐辰  阅读(16046)  评论(0编辑  收藏  举报