/*************************************/ //wnd.h // /***********************************/ #pragma once #define WM_GRAYCONTROLES WM_USER+100 #define APP_NAME L"植物大战僵尸修改器 v1.2" #define WND_W 360 #define WND_H 230 #define IMG_H 55 #define ID_TIMER 1 #define TIMER_SLEEP_TIME 1000 #include <windows.h> #include <tchar.h> #include <Commctrl.h> #include <psapi.h> #include <process.h> #pragma comment(lib, "psapi") #pragma comment(lib, "comctl32.lib") #pragma comment(linker,"/manifestdependency:\"type='win32'\ name='Microsoft.Windows.Common-Controls' "\ "version='6.0.0.0' \ processorArchitecture='*'\ publicKeyToken='6595b64144ccf1df' \ language='*'\"") BOOL CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM); LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); BOOL EnableDebugPrivilege(HANDLE hProcess); HWND FindDestWnd(); DWORD GetPIDFromeWnd(); HANDLE OpenProcessWithDbg(DWORD PID); //////////////////////////////////// DWORD GetPIDFromeProcesses(LPCTSTR lpWndName);
/*************************************/ //wnd.cpp // /***********************************/ #include "Wnd.h" #include "resource.h" #include "InjectCode.h" BOOL g_bWndActive = false; BOOL EnableDebugPrivilege(HANDLE hProcess) { HANDLE hToken; LUID luid; TOKEN_PRIVILEGES tp; //打开令牌环 BOOL bOK = OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken); if(!bOK) return FALSE; bOK = LookupPrivilegeValue(NULL,SE_SECURITY_NAME,&luid); if(!bOK) return FALSE; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //调整权限 bOK = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),NULL,NULL); if(!bOK) return FALSE; CloseHandle(hToken); return TRUE; } int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR lpCmdLine, int nShowCmd) { InitCommonControls(); HWND hWnd; MSG msg; TCHAR szClsName[] = L"MainWnd"; WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.hInstance = hInst; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_MENUBAR+1); wcex.lpszClassName = szClsName; wcex.lpszMenuName = NULL; wcex.style = 0; wcex.hIconSm = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1)); wcex.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON2)); if(!RegisterClassEx(&wcex)) return 0; hWnd = CreateWindowEx( WS_EX_CONTROLPARENT, szClsName, APP_NAME, (WS_CLIPCHILDREN |WS_CLIPSIBLINGS |WS_MINIMIZEBOX |WS_SYSMENU |WS_CAPTION |WS_TABSTOP) &(~WS_MAXIMIZEBOX ), GetSystemMetrics(SM_CXFULLSCREEN)/2-WND_W/2, GetSystemMetrics(SM_CYFULLSCREEN)/2-WND_H/2, WND_W, WND_H, NULL, NULL, hInst,NULL); if(!hWnd) return 0; ShowWindow(hWnd, nShowCmd); UpdateWindow(hWnd); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HWND hDlg; static RECT rectWnd; RECT rectDlg; static HANDLE hBmp; HDC hdcWnd, hdcMem; PAINTSTRUCT ps; int ID; switch(uMsg) { case WM_KEYDOWN: { switch(wParam) { case VK_F1: ID = IDC_CHECK1; break; case VK_F2: ID = IDC_CHECK2; break; case VK_F3: ID = IDC_CHECK3; break; case VK_F4: ID = IDC_CHECK4; break; case VK_F5: ID = IDC_CHECK5; break; case VK_F6: ID = IDC_CHECK6; break; case VK_F7: ID = IDC_CHECK7; break; case VK_F8: ID = IDC_CHECK8; break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam);; } PostMessage(hDlg, WM_COMMAND, (WPARAM)ID, NULL); return 1; } case WM_PAINT: { hdcWnd = BeginPaint(hWnd, &ps); hdcMem = CreateCompatibleDC (hdcWnd); SelectObject(hdcMem,hBmp); BitBlt(hdcWnd,0,0,WND_W,WND_H,hdcMem,0,0,SRCCOPY); DeleteDC(hdcMem); EndPaint(hWnd, &ps); return 1; } case WM_TIMER: { if( FindDestWnd() == NULL) g_bWndActive = FALSE; else g_bWndActive = TRUE; PostMessage(hDlg, WM_GRAYCONTROLES,0,g_bWndActive); SetTimer(hWnd, ID_TIMER, TIMER_SLEEP_TIME, NULL); return 1; } case WM_DESTROY: KillTimer(hWnd, ID_TIMER); EndDialog(hDlg, 0); PostQuitMessage(0); return 0; case WM_CREATE: { if( FindDestWnd() == NULL) g_bWndActive = FALSE; else g_bWndActive = TRUE; hBmp = LoadImage( (HINSTANCE)GetModuleHandle(0), MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0,0, LR_DEFAULTSIZE); hDlg = CreateDialogParam( (HINSTANCE)GetModuleHandle(0), MAKEINTRESOURCE(IDD_FORMVIEW), hWnd, DlgProc, NULL); GetWindowRect(hDlg,&rectDlg); GetClientRect(hWnd, &rectWnd); MoveWindow(hDlg, (rectWnd.right-rectWnd.left)/2 - (rectDlg.right-rectDlg.left)/2, IMG_H+1,rectDlg.right-rectDlg.left,rectDlg.bottom-rectDlg.top,NULL); ShowWindow(hDlg,SW_SHOW); SetFocus(GetParent(hDlg)); SetTimer(hWnd, ID_TIMER, TIMER_SLEEP_TIME, NULL); } return 1; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } BOOL CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL bSetState; int ctrlID; DWORD PID; HANDLE hProcess = NULL; BOOL bSuccess = FALSE; static INJECT_BLOCK AutoCollect, Nondecrease, DoubleSun_1, DoubleSun_2, DoubleMoney, SecKill_1, SecKill_2, UnlockSlot_1, UnlockSlot_2; static GOODS_BACKUP goodsBackup[GOODS_COUNT]; PINJECT_BLOCK pInjectes[3] = {NULL,NULL,NULL}; switch(uMsg) { case WM_COMMAND: { if(g_bWndActive == FALSE) return FALSE; ctrlID = LOWORD(wParam); if(IsDlgButtonChecked(hDlg, ctrlID) == BST_CHECKED) bSetState = FALSE; else bSetState = TRUE; switch(ctrlID) { case IDC_CHECK1: pInjectes[0] = &AutoCollect; break; case IDC_CHECK2: pInjectes[0] = &Nondecrease; break; case IDC_CHECK3: pInjectes[0] = &DoubleSun_1; pInjectes[1] = &DoubleSun_2; break; case IDC_CHECK4: pInjectes[0] = &DoubleMoney; break; case IDC_CHECK5: case IDC_CHECK6: { PID = GetPIDFromeWnd(); if(PID <= 0) return FALSE; hProcess = OpenProcessWithDbg(PID); if(hProcess == NULL) return FALSE; bSuccess = WriteGoodsAttrToMem(hProcess, (ctrlID==IDC_CHECK5)?GOODS_ATTR_PRICE:GOODS_ATTR_TIME, goodsBackup, bSetState); goto hereleave; } case IDC_CHECK7: pInjectes[0] = &SecKill_1; pInjectes[1] = &SecKill_2; break; case IDC_CHECK8: pInjectes[0] = &UnlockSlot_2; pInjectes[1] = &UnlockSlot_1; break; default: return FALSE; } PID = GetPIDFromeWnd(); if(PID <= 0) return FALSE; hProcess = OpenProcessWithDbg(PID); if(hProcess == NULL) return FALSE; for(int i=0; i<3; i++) { if(pInjectes[i] != NULL) bSuccess = WriteCodeToMem(hProcess, pInjectes[i], bSetState); else break; } hereleave: SetFocus(GetParent(hDlg)); if(bSuccess) CheckDlgButton(hDlg, ctrlID, bSetState); return TRUE; } case WM_GRAYCONTROLES: { EnableWindow(GetDlgItem(hDlg,IDC_CHECK1), lParam); EnableWindow(GetDlgItem(hDlg,IDC_CHECK2), lParam); EnableWindow(GetDlgItem(hDlg,IDC_CHECK3), lParam); EnableWindow(GetDlgItem(hDlg,IDC_CHECK4), lParam); EnableWindow(GetDlgItem(hDlg,IDC_CHECK5), lParam); EnableWindow(GetDlgItem(hDlg,IDC_CHECK6), lParam); EnableWindow(GetDlgItem(hDlg,IDC_CHECK7), lParam); EnableWindow(GetDlgItem(hDlg,IDC_CHECK8), lParam); if(lParam == FALSE) { CheckDlgButton(hDlg, IDC_CHECK1, BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CHECK2, BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CHECK3, BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CHECK4, BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CHECK5, BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CHECK6, BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CHECK7, BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CHECK8, BST_UNCHECKED); } return TRUE; } case WM_INITDIALOG: { AutoCollect.dwBaseAddr = 0x44c5f1; AutoCollect.dwSize = 1; AutoCollect.sbNewCode[0] = 0x1; Nondecrease.dwBaseAddr = 0x433f86; Nondecrease.dwSize = 6; memset(&Nondecrease.sbNewCode, 0x90, 6); DoubleSun_1.dwBaseAddr = 0x44ba22; DoubleSun_1.dwSize = 1; DoubleSun_1.sbNewCode[0] = 0x32; DoubleSun_2.dwBaseAddr = 0x44ba2e; DoubleSun_2.dwSize = 1; DoubleSun_2.sbNewCode[0] = 0x19; DoubleMoney.dwBaseAddr = 0x44ba92; DoubleMoney.dwSize = 1; DoubleMoney.sbNewCode[0] = 0x2; SecKill_1.dwBaseAddr = 0x5671f9; SecKill_1.dwSize = 2; SecKill_1.sbNewCode[0] = 0xeb; SecKill_1.sbNewCode[1] = 0x16; SecKill_2.dwBaseAddr = 0x566d07; SecKill_2.dwSize = 3; SecKill_2.sbNewCode[0] = 0xf6; SecKill_2.sbNewCode[1] = 0x90; SecKill_2.sbNewCode[2] = 0x90; UnlockSlot_1.dwBaseAddr = 0x43470f; UnlockSlot_1.dwSize = 2; UnlockSlot_1.sbNewCode[0] = 0xEB; UnlockSlot_1.sbNewCode[1] = 0x15; UnlockSlot_2.dwBaseAddr = 0x434726; UnlockSlot_2.dwSize = 8; *(LONGLONG*)UnlockSlot_2.sbNewCode = 0xE9EB0AB0027C0A3C; SendMessage(hDlg, WM_GRAYCONTROLES,0,(LPARAM)g_bWndActive?TRUE:FALSE); return TRUE; } } return FALSE; } HWND FindDestWnd() { HWND h = NULL; TCHAR* szDestWndNames[] = { {L"Plants vs. Zombies 1.2.0.1073 RELEASE"}, {L"植物大战僵尸中文版"}, {L"植物大战僵尸"}, {L"PlantsVsZombies"} }; for(int i=0; i<sizeof(szDestWndNames)/sizeof(TCHAR*); i++) { h = FindWindow(NULL, szDestWndNames[i]); if(NULL != h) break; } return h; } DWORD GetPIDFromeWnd() { DWORD id = -1; HWND hWnd; if( (hWnd = FindDestWnd()) == NULL) return -1; GetWindowThreadProcessId(hWnd,&id); return id; } HANDLE OpenProcessWithDbg(DWORD PID) { HANDLE hProcess; hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,PID); if(hProcess == NULL) return NULL; if(!EnableDebugPrivilege(hProcess)) { MessageBox(0, L"提升权限失败!", L"错误提示", 0); CloseHandle(hProcess); return NULL; } return hProcess; } /*********************************** ************************************ ************************************/ BOOL IsDestPID(DWORD PID) { TCHAR szProcessName[MAX_PATH]; TCHAR szDestName[] = L"PlantsVsZombies.exe"; HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION |PROCESS_VM_READ,FALSE,PID); if(hProc == NULL) return FALSE; HMODULE hMod; DWORD cbNeeded; if ( !EnumProcessModules( hProc, &hMod, sizeof(hMod),&cbNeeded )) goto Exit; if(GetModuleBaseName( hProc, hMod, szProcessName,sizeof(szProcessName)/sizeof(TCHAR)) ==0) goto Exit; if(_wcsicmp(szProcessName, szDestName) == 0) { CloseHandle(hProc); return TRUE; } Exit: CloseHandle(hProc); return FALSE; } DWORD GetPIDFromeProcesses(LPCTSTR lpWndName) { DWORD aProcesses[1024],cbNeeded, cProcesses; UINT i; DWORD pid; EnumProcesses(aProcesses, sizeof(aProcesses),&cbNeeded); cProcesses = cbNeeded / sizeof(DWORD); for ( i = 0; i < cProcesses; i++ ) { if( aProcesses[i] != 0 ) { if(IsDestPID(aProcesses[i])) { pid = aProcesses[i]; return pid; } } } return -1; }
/*************************************/ //InjectCode.cpp // /***********************************/ #pragma once #define BUF_LEN 20 //缓存大小 #define GOODS_COUNT 53 //物品的数目 #define GOODS_ATTR_PRICE 1 //物品价格属性标记 #define GOODS_ATTR_TIME 2 //物品冷却时间属性标记 #include <windows.h> //物品属性 typedef struct _GOODS_ATTRIBUTE { DWORD type; //物品种类 DWORD unknown2; DWORD unknown3; DWORD unknown4; DWORD price; //价格 DWORD coolingTime; //冷却时间 DWORD unknown7; DWORD unknown8; DWORD unknown9; }GOODS_ATTRIBUTE,*PGOODS_ATTRIBUTE; //保存物品属性 typedef struct _GOODS_BACKUP { DWORD price; DWORD time; }GOODS_BACKUP,*PGOODS_BACKUP; typedef struct _tagINJECT_BLOCK { DWORD dwBaseAddr; //注入基址 DWORD dwSize; //注入字节数 DWORD dwOldProtect; BYTE sbNewCode[BUF_LEN]; //要注入的代码 BYTE sbOldCode[BUF_LEN]; //保存原来的代码 }INJECT_BLOCK,*PINJECT_BLOCK; BOOL WriteCodeToMem(HANDLE hProcess, PINJECT_BLOCK pInjectBlock, BOOL writeNew); BOOL WriteGoodsAttrToMem(HANDLE hProcess, DWORD AttrBitMark, PGOODS_BACKUP pBackup, BOOL writeNew);
/*************************************/ //InjectCode.cpp // /***********************************/ #include "InjectCode.h" BOOL WriteCodeToMem(HANDLE hProcess, PINJECT_BLOCK pInjectBlock, BOOL writeNew) { BOOL bRtn = FALSE; bRtn = VirtualProtectEx(hProcess, (void*)pInjectBlock->dwBaseAddr, pInjectBlock->dwSize, PAGE_READWRITE, &pInjectBlock->dwOldProtect); if(!bRtn) return FALSE; if(writeNew) { bRtn = ReadProcessMemory(hProcess, (void*)pInjectBlock->dwBaseAddr, pInjectBlock->sbOldCode, pInjectBlock->dwSize, 0); if(!bRtn) return FALSE; bRtn = WriteProcessMemory(hProcess, (void*)pInjectBlock->dwBaseAddr, pInjectBlock->sbNewCode, pInjectBlock->dwSize, 0); if(!bRtn) return FALSE; } else { bRtn = WriteProcessMemory(hProcess, (void*)pInjectBlock->dwBaseAddr, pInjectBlock->sbOldCode, pInjectBlock->dwSize, NULL); if(!bRtn) return FALSE; } bRtn = VirtualProtectEx(hProcess, (void*)pInjectBlock->dwBaseAddr, pInjectBlock->dwSize, pInjectBlock->dwOldProtect, &pInjectBlock->dwOldProtect); if(!bRtn) return FALSE; return bRtn; } BOOL WriteGoodsAttrToMem(HANDLE hProcess, DWORD AttrBitMark, PGOODS_BACKUP pBackup, BOOL writeNew) { const DWORD dwGoodsBase = 0x76c600; BOOL bRtn = FALSE; DWORD dwInject = 0; DWORD dwProtect; DWORD dwPriceAddr, dwTimeAddr; DWORD dwGoodsAddr = dwGoodsBase; bRtn = VirtualProtectEx(hProcess, (void*)dwGoodsAddr, sizeof(GOODS_ATTRIBUTE)*GOODS_COUNT, PAGE_READWRITE, &dwProtect); if(!bRtn) return FALSE; for(int i=0; i<GOODS_COUNT; i++) { dwPriceAddr = dwGoodsAddr+ 16; dwTimeAddr = dwGoodsAddr +20; if(writeNew) { if(GOODS_ATTR_PRICE ==(AttrBitMark & GOODS_ATTR_PRICE)) { bRtn = ReadProcessMemory(hProcess, (void*)dwPriceAddr, (LPVOID)&pBackup->price, 4,0); if(!bRtn) return FALSE; bRtn = WriteProcessMemory(hProcess, (void*)dwPriceAddr, (void*)&dwInject, 4,0); if(!bRtn) return FALSE; } if(GOODS_ATTR_TIME ==(AttrBitMark & GOODS_ATTR_TIME)) { bRtn = ReadProcessMemory(hProcess, (void*)dwTimeAddr, (LPVOID)&pBackup->time, 4,0); if(!bRtn) return FALSE; bRtn = WriteProcessMemory(hProcess, (void*)dwTimeAddr, (void*)&dwInject, 4,0); if(!bRtn) return FALSE; } } else { if(GOODS_ATTR_PRICE ==(AttrBitMark & GOODS_ATTR_PRICE)) { bRtn = WriteProcessMemory(hProcess, (void*)dwPriceAddr, (void*)&pBackup->price, 4,0); if(!bRtn) return FALSE; } if(GOODS_ATTR_TIME ==(AttrBitMark & GOODS_ATTR_TIME)) { bRtn = WriteProcessMemory(hProcess, (void*)dwTimeAddr, (void*)&pBackup->time, 4,0); if(!bRtn) return FALSE; } } dwGoodsAddr += sizeof(GOODS_ATTRIBUTE); ++pBackup; } bRtn = VirtualProtectEx(hProcess, (void*)dwGoodsBase, sizeof(GOODS_ATTRIBUTE), dwProtect, &dwProtect); if(!bRtn) return FALSE; return bRtn; }