植物大戰僵屍作弊器源代碼(控制台版)


從之前的文章中,可以知道如何找到植物大戰僵屍的游戲基址,以及其全部內存地址。。

下面將其實現出來。。

說明:通過游戲基址,再加上偏移量,修改游戲在內存中的值。實現無限陽光‘、無限金幣、免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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM