zoukankan      html  css  js  c++  java
  • 植物大战僵尸作弊器源代码(控制台版)

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

    下面将其实现出来。。

    说明:通过游戏基址,再加上偏移量,修改游戏在内存中的值。实现无限阳光‘、无限金币、免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[] = "xC3x04x00";
        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("查找窗口失败
    ");
            return 0;
        }
        
        DWORD dwProcessId;
        GetWindowThreadProcessId(hWnd, &dwProcessId);
        printf("进程ID:%d
    ", dwProcessId);
        
        //获取进程句柄
        g_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
        if (NULL == g_hProcess)
        {
            printf("打开进程失败
    ");
            return 0;
        }
    
        ModifySun();
        ModifyGuanka();
        ModifyMoney();
        ModifyPause();
    
        ModifyCDThread(0);
        getchar();
        return 0;
    }
  • 相关阅读:
    [置顶] Guava学习之Lists
    Study notes for B-tree and R-tree
    uva 620 Cellular Structure
    [置顶] 程序员面试之道(《程序员面试笔试宝典》)之看着别人手拿大把的offer,不淡定了怎么办?
    HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)
    有N个正实数(注意是实数,大小升序排列) x1 , x2 ... xN,另有一个实数M。 需要选出若干个x,使这几个x的和与 M 最接近。 请描述实现算法,并指出算法复杂度
    C# 未能加载文件或程序集“MySQLDriverCS..." 错误解决
    LA 3942 Remember the Word(前缀树&树上DP)
    原根-快速求解一个数的原根
    线程初步了解
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/7789972.html
Copyright © 2011-2022 走看看