CheatEngine工具的基本使用
推荐视频你能学会的Cheat Engine零基础入门教程
将ce官方给的闯关游戏通关即可
C/C++和汇编语言基础
附上汇编代码转换网站
WIN32开发基础
了解WIN32命名规则,会使用GPT和查找微软官方文档即可
推荐通过看微软官方文档Win32 和 C++ 入门 能创建第一个windows程序即可
示例游戏版本: 中文年度加强版1.1.0.1056
主要参考资料
【补档】豪哥植物大战僵尸修改教程视频合集
C/C++全栈软件安全课(调试、反调试、游戏反外挂、软件逆向)持续更新中~~~~
逆向工程实战 揭秘汇编/反汇编(win32+游戏逆向实战)
部分参考: 公布我所找到的所有基址及各种功能实现方法
基址 0x00355E0C
阳光 +868 +5578
金钱 +950 +50
花肥 +950 +220
巧克力 +950 +250
树肥 +950 +258
树高 +950 +11C
杀虫剂 +950 +224
卡槽数 +868 +15C +24
卡槽栏 +868 +15C +5C 此后每个植物栏相隔0x50
植物当前冷却值 +868 +15C +4C 此后每个植物冷却相隔0x50
植物冷却值上限 +868 +15C +50 此后每个植物冷却上限相隔0x50
植物当前数量 +868 +D4
植物种植函数EBP +868
僵尸当前数量 +868 +B8
僵尸种植函数EBP +868 +178
根据变量的变化使用CE寻找,找到之后再通过指针扫描寻找可用的基址
阳光 内存实际值=游戏显示值
智慧树高度 内存实际值=游戏显示值
金钱 内存实际值=游戏显示值/10
花肥,杀虫剂,巧克力,树肥 内存实际值=游戏显示值+1000
关键函数和变量
十个卡槽,每个卡槽对应一个植物,可以在坚果保龄球2中根据卡槽1(最左边的卡槽)的坚果变化来找到卡槽的地址,之后再寻找基址
具体方法: 初值未知,如果卡槽1的植物和新的卡槽1(原卡槽2)的植物相同,则扫不变的值,否则扫变化的值
卡槽之间的偏移可以通过浏览卡槽1内存区域看出,为0x50
坚果植物卡槽编号:
普通坚果 3
爆炸坚果 49
巨型坚果 50
设置卡槽植物函数
具体方法: 仅针对一个卡槽,初始值未知,种植后持续变化,冷却完毕后不变,反复扫描并查找基址,查看对应内存区域再对照植物编号可以发现卡槽间的偏移为0x50
冷却特点: 可种植状态冷却值为0,种植后冷却值持续增长,到达冷却上限后,冷却值清零,植物重新可种植
注意: 直接将冷却值置0会导致无法种植
修改方法:
以方法2为例
7E 16 对应汇编指令为 jle 0x18
修改为jmp $+2 即 eb 00 (相对当前指令2字节后的指令)
直接执行冷却值达到冷却上限后的函数(冷却值清零,植物冷却完毕可种植)
附上汇编代码转换网站
关键代码
前文已经给出了阳光的地址 基址为0x355E0C 偏移+868 +5578
查找对阳光修改的代码即可
阳光减少代码
阳光增加代码
基本过程:
设置阳光值为9999
修改阳光减少代码使得种植物不消耗阳光
修改阳光增加代码使得阳光不变化(防止阳光过多导致溢出)
具体方法: 在生存模式浓雾进行,初值未知,通过在雾区种植和铲除路灯花引起的变化来判断,最终可以发现是4字节数据,数值代表雾的浓度,255代表浓雾,0代表没雾,再查找修改雾值的代码
寻找浓雾地址
浓雾修改代码
mov [ecx],edx这行代码修改了雾值,可以改为mov [ecx],0
注意硬编码为0xc7,0x01,0x00,0x00,0x00,0x00 由于较长无法直接修改代码,所以这里选择使用hook技术
hook的基本过程
值得一提的是jmp指令后跟的偏移值是以jmp的下一条指令首地址计算
jmp指令偏移值=目的地址-(jmp指令首地址+5) 这里的5是jmp指令本身的长度 +5便是下一条指令
offset=desAddr-(jmpAddr+5)
hook前 指令为mov [ecx],edx add ecx,04
hook后 指令被修改为jmp
hookcode 新分配空间前5个字节正是原始代码 之后是hook代码和jmp返回代码
程序是执行种植植物的函数后再执行增加植物数量的功能
首先查找草坪上的植物数量,初值0,随着种植个数增加 基址0x355E0C 偏移+868 +D4
再查找是什么修改了植物数量,下断点之后再种植一个植物
断下后查看调用堆栈中的返回地址,即可找到种植函数
这个功能最初使用远程线程注入dll来实现,注入dll虽然比较简单但是却并不通用,在此仅做介绍,比较推荐使用远程代码注入的方式实现
远程线程是当前进程在目标进程中创建一个线程并执行特定代码(这段代码必须在目标进程中而不是当前进程中)
注入dll是因为dll在被进程或线程加载时执行dll的DllMain函数,通过这一特点我们可以实现一些特殊功能
优点: 便于实现
缺点: dll注入容易被检测到
基本过程:
很多教程只给出了如何注入dll,没有演示如何卸载
如果只注入不卸载会导致下次再注入时不会执行特定函数(由于dll已经被加载过) 不方便实时调试更新dll等问题
基本过程:
这里使用了三种方法
注意: 不要将代码写入switch(reason)之外,否则可能会导致多次执行
执行结果
这是写dll函数时遇到的问题 如果直接用 mov ecx,[BaseAddr+0x355E0C]会导致代码执行失败,推测是这条指令访存过慢所以无效
建议mov ecx,BaseAddr之后通过对寄存器操作达到目的
和远程线程dll注入类似,CreateRemoteThread函数要求的函数原型是
基本过程:
与种植植物思路类似
首先在头脑风暴中通过种植僵尸来找到僵尸数量地址
然后找到僵尸数量增加代码
再通过查看调用堆栈和参数找到种植僵尸call
参数应该也是x y type ebp (注意没有-1)
僵尸种植函数的x值在一个call上方,这个call是个switch结构,没有参数,所以x值也没被修改
DLL代码
enum
Type {
Sunlight, Money, TreeHeight, Chocolate, TreeFood, FlowerFood, Insecticide
};
unsigned
int
offsetTable[10] = { 0x5578,0x50,0x11c,0x250,0x258,0x220,0x224 };
unsigned
int
getSomething(
HANDLE
handle,
DWORD
BaseAddr,unsigned
int
type) {
unsigned
int
num = 0;
DWORD
addr = BaseAddr + 0x00355E0C;
ReadProcessMemory(handle, addr, &addr,
sizeof
(
DWORD
), NULL);
if
(type == Sunlight)
addr += 0x868;
else
addr += 0x950;
ReadProcessMemory(handle, (
LPVOID
)addr, &addr,
sizeof
(
DWORD
), NULL);
addr += offsetTable[type];
ReadProcessMemory(handle, (
LPVOID
)addr, &num,
sizeof
(
DWORD
), 0);
return
num;
}
void
setSomething(
HANDLE
handle,
DWORD
BaseAddr,unsigned
int
type, unsigned
int
num) {
DWORD
addr = BaseAddr + 0x00355E0C;
ReadProcessMemory(handle, addr, &addr,
sizeof
(
DWORD
), NULL);
if
(type == Sunlight)
addr += 0x868;
else
addr += 0x950;
ReadProcessMemory(handle, (
LPVOID
)addr, &addr,
sizeof
(
DWORD
), NULL);
addr += offsetTable[type];
WriteProcessMemory(handle, (
LPVOID
)addr, &num,
sizeof
(
DWORD
), 0);
}
enum
Type {
Sunlight, Money, TreeHeight, Chocolate, TreeFood, FlowerFood, Insecticide
};
unsigned
int
offsetTable[10] = { 0x5578,0x50,0x11c,0x250,0x258,0x220,0x224 };
unsigned
int
getSomething(
HANDLE
handle,
DWORD
BaseAddr,unsigned
int
type) {
unsigned
int
num = 0;
DWORD
addr = BaseAddr + 0x00355E0C;
ReadProcessMemory(handle, addr, &addr,
sizeof
(
DWORD
), NULL);
if
(type == Sunlight)
addr += 0x868;
else
addr += 0x950;
ReadProcessMemory(handle, (
LPVOID
)addr, &addr,
sizeof
(
DWORD
), NULL);
addr += offsetTable[type];
ReadProcessMemory(handle, (
LPVOID
)addr, &num,
sizeof
(
DWORD
), 0);
return
num;
}
void
setSomething(
HANDLE
handle,
DWORD
BaseAddr,unsigned
int
type, unsigned
int
num) {
DWORD
addr = BaseAddr + 0x00355E0C;
ReadProcessMemory(handle, addr, &addr,
sizeof
(
DWORD
), NULL);
if
(type == Sunlight)
addr += 0x868;
else
addr += 0x950;
ReadProcessMemory(handle, (
LPVOID
)addr, &addr,
sizeof
(
DWORD
), NULL);
addr += offsetTable[type];
WriteProcessMemory(handle, (
LPVOID
)addr, &num,
sizeof
(
DWORD
), 0);
}
BOOL
SetPlantCard(
HANDLE
hProcess,
DWORD
BaseAddr,
DWORD
nCard,
DWORD
plantType) {
DWORD
cardAddr = BaseAddr + 0x355E0C;
ReadProcessMemory(hProcess, cardAddr, &cardAddr,
sizeof
(
DWORD
), NULL);
cardAddr += 0x868;
ReadProcessMemory(hProcess, cardAddr, &cardAddr,
sizeof
(
DWORD
), NULL);
cardAddr += 0x15C;
ReadProcessMemory(hProcess, cardAddr, &cardAddr,
sizeof
(
DWORD
), NULL);
cardAddr += 0x5C+nCard*0x50;
return
WriteProcessMemory(hProcess, cardAddr, &plantType,
sizeof
(
DWORD
), NULL);
}
BOOL
SetPlantCard(
HANDLE
hProcess,
DWORD
BaseAddr,
DWORD
nCard,
DWORD
plantType) {
DWORD
cardAddr = BaseAddr + 0x355E0C;
ReadProcessMemory(hProcess, cardAddr, &cardAddr,
sizeof
(
DWORD
), NULL);
cardAddr += 0x868;
ReadProcessMemory(hProcess, cardAddr, &cardAddr,
sizeof
(
DWORD
), NULL);
cardAddr += 0x15C;
ReadProcessMemory(hProcess, cardAddr, &cardAddr,
sizeof
(
DWORD
), NULL);
cardAddr += 0x5C+nCard*0x50;
return
WriteProcessMemory(hProcess, cardAddr, &plantType,
sizeof
(
DWORD
), NULL);
}
BOOL
WriteProcessCodeMemory(
HANDLE
hProcess,
LPVOID
lpStartAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize) {
DWORD
dwOldProtect;
if
(!VirtualProtectEx(hProcess, lpStartAddress, nSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) {
return
FALSE;
}
BOOL
bResult = WriteProcessMemory(hProcess, lpStartAddress, lpBuffer, nSize, NULL);
VirtualProtectEx(hProcess, lpStartAddress, nSize, dwOldProtect, &dwOldProtect);
return
bResult;
}
BOOL
Uncooled(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
code[2] = { 0xeb,0x00 };
return
WriteProcessCodeMemory(hProcess, BaseAddr + 0x9ce02, code, 2);
}
BOOL
RecoveryCooling(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
OriginalCode[2] = { 0x7E ,0x16 };
return
WriteProcessCodeMemory(hProcess, BaseAddr + 0x9ce02, OriginalCode, 2);
}
BOOL
WriteProcessCodeMemory(
HANDLE
hProcess,
LPVOID
lpStartAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize) {
DWORD
dwOldProtect;
if
(!VirtualProtectEx(hProcess, lpStartAddress, nSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) {
return
FALSE;
}
BOOL
bResult = WriteProcessMemory(hProcess, lpStartAddress, lpBuffer, nSize, NULL);
VirtualProtectEx(hProcess, lpStartAddress, nSize, dwOldProtect, &dwOldProtect);
return
bResult;
}
BOOL
Uncooled(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
code[2] = { 0xeb,0x00 };
return
WriteProcessCodeMemory(hProcess, BaseAddr + 0x9ce02, code, 2);
}
BOOL
RecoveryCooling(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
OriginalCode[2] = { 0x7E ,0x16 };
return
WriteProcessCodeMemory(hProcess, BaseAddr + 0x9ce02, OriginalCode, 2);
}
BOOL
WriteProcessCodeMemory(
HANDLE
hProcess,
LPVOID
lpStartAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize) {
DWORD
dwOldProtect;
if
(!VirtualProtectEx(hProcess, lpStartAddress, nSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) {
return
FALSE;
}
BOOL
bResult = WriteProcessMemory(hProcess, lpStartAddress, lpBuffer, nSize, NULL);
VirtualProtectEx(hProcess, lpStartAddress, nSize, dwOldProtect, &dwOldProtect);
return
bResult;
}
BOOL
UnlimitedSun(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
Code[3] = { 0x29,0xdb,0 };
BOOL
flag;
flag = setSomething(hProcess, BaseAddr, Sunlight, 9999);
flag &= WriteProcessCodeMemory(hProcess, BaseAddr + 0x27690, Code, 2);
flag &= WriteProcessCodeMemory(hProcess, BaseAddr + 0x3C0AB, &Code[2], 1);
return
flag;
}
BOOL
RecoverySunConsume(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
OriginalCode[3] = { 0x3B,0xD8,0x32 };
BOOL
flag = WriteProcessCodeMemory(hProcess, BaseAddr + 0x27690, OriginalCode, 2);
flag &= WriteProcessCodeMemory(hProcess, BaseAddr + 0x3C0AB, &OriginalCode[2], 1);
return
flag;
}
BOOL
WriteProcessCodeMemory(
HANDLE
hProcess,
LPVOID
lpStartAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize) {
DWORD
dwOldProtect;
if
(!VirtualProtectEx(hProcess, lpStartAddress, nSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) {
return
FALSE;
}
BOOL
bResult = WriteProcessMemory(hProcess, lpStartAddress, lpBuffer, nSize, NULL);
VirtualProtectEx(hProcess, lpStartAddress, nSize, dwOldProtect, &dwOldProtect);
return
bResult;
}
BOOL
UnlimitedSun(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
Code[3] = { 0x29,0xdb,0 };
BOOL
flag;
flag = setSomething(hProcess, BaseAddr, Sunlight, 9999);
flag &= WriteProcessCodeMemory(hProcess, BaseAddr + 0x27690, Code, 2);
flag &= WriteProcessCodeMemory(hProcess, BaseAddr + 0x3C0AB, &Code[2], 1);
return
flag;
}
BOOL
RecoverySunConsume(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
OriginalCode[3] = { 0x3B,0xD8,0x32 };
BOOL
flag = WriteProcessCodeMemory(hProcess, BaseAddr + 0x27690, OriginalCode, 2);
flag &= WriteProcessCodeMemory(hProcess, BaseAddr + 0x3C0AB, &OriginalCode[2], 1);
return
flag;
}
BOOL
WriteProcessCodeMemory(
HANDLE
hProcess,
LPVOID
lpStartAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize) {
DWORD
dwOldProtect;
if
(!VirtualProtectEx(hProcess, lpStartAddress, nSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) {
return
FALSE;
}
BOOL
bResult = WriteProcessMemory(hProcess, lpStartAddress, lpBuffer, nSize, NULL);
VirtualProtectEx(hProcess, lpStartAddress, nSize, dwOldProtect, &dwOldProtect);
return
bResult;
}
LPVOID
SetHook(
HANDLE
hProcess,
LPVOID
desAddr,
LPCVOID
hookCode,
SIZE_T
hookCodeSize,
SIZE_T
origCodeSize) {
BYTE
origCode[10] = { 0 }, jmpCode[5] = { 0xE9,0,0,0,0 };
if
(!ReadProcessMemory(hProcess, desAddr, origCode, origCodeSize, NULL))
return
NULL;
LPVOID
allocAddr = VirtualAllocEx(hProcess, NULL, hookCodeSize + origCodeSize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if
(!allocAddr)
return
NULL;
*(
DWORD
*)(jmpCode + 1) = (
DWORD
)desAddr + 5 - ((
DWORD
)allocAddr + hookCodeSize + origCodeSize + 5);
if
(!WriteProcessCodeMemory(hProcess, allocAddr, origCode, origCodeSize)
|| !WriteProcessCodeMemory(hProcess, (
DWORD
)allocAddr + origCodeSize, hookCode, hookCodeSize)
|| !WriteProcessCodeMemory(hProcess, (
DWORD
)allocAddr + origCodeSize + hookCodeSize, jmpCode, 5))
{
VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE);
return
NULL;
}
*(
DWORD
*)(jmpCode + 1) = ((
DWORD
)allocAddr + origCodeSize) - ((
DWORD
)desAddr + 5);
WriteProcessCodeMemory(hProcess, desAddr, jmpCode, 5);
if
(origCodeSize > 5)
{
BYTE
nopCode[5] = { 0x90,0x90,0x90,0x90,0x90 };
if
(!WriteProcessCodeMemory(hProcess, (
DWORD
)desAddr + 5, nopCode, origCodeSize - 5))
{
VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE);
return
NULL;
}
}
return
allocAddr;
}
BOOL
UnHook(
HANDLE
hProcess,
LPVOID
desAddr,
SIZE_T
origCodeSize,
LPVOID
allocAddr) {
BYTE
origCode[10] = { 0 };
if
(!ReadProcessMemory(hProcess, allocAddr, origCode, origCodeSize, NULL))
return
FALSE;
if
(!WriteProcessCodeMemory(hProcess, desAddr, origCode, origCodeSize))
return
FALSE;
if
(!VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE))
return
FALSE;
return
TRUE;
}
BOOL
WriteProcessCodeMemory(
HANDLE
hProcess,
LPVOID
lpStartAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize) {
DWORD
dwOldProtect;
if
(!VirtualProtectEx(hProcess, lpStartAddress, nSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) {
return
FALSE;
}
BOOL
bResult = WriteProcessMemory(hProcess, lpStartAddress, lpBuffer, nSize, NULL);
VirtualProtectEx(hProcess, lpStartAddress, nSize, dwOldProtect, &dwOldProtect);
return
bResult;
}
LPVOID
SetHook(
HANDLE
hProcess,
LPVOID
desAddr,
LPCVOID
hookCode,
SIZE_T
hookCodeSize,
SIZE_T
origCodeSize) {
BYTE
origCode[10] = { 0 }, jmpCode[5] = { 0xE9,0,0,0,0 };
if
(!ReadProcessMemory(hProcess, desAddr, origCode, origCodeSize, NULL))
return
NULL;
LPVOID
allocAddr = VirtualAllocEx(hProcess, NULL, hookCodeSize + origCodeSize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if
(!allocAddr)
return
NULL;
*(
DWORD
*)(jmpCode + 1) = (
DWORD
)desAddr + 5 - ((
DWORD
)allocAddr + hookCodeSize + origCodeSize + 5);
if
(!WriteProcessCodeMemory(hProcess, allocAddr, origCode, origCodeSize)
|| !WriteProcessCodeMemory(hProcess, (
DWORD
)allocAddr + origCodeSize, hookCode, hookCodeSize)
|| !WriteProcessCodeMemory(hProcess, (
DWORD
)allocAddr + origCodeSize + hookCodeSize, jmpCode, 5))
{
VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE);
return
NULL;
}
*(
DWORD
*)(jmpCode + 1) = ((
DWORD
)allocAddr + origCodeSize) - ((
DWORD
)desAddr + 5);
WriteProcessCodeMemory(hProcess, desAddr, jmpCode, 5);
if
(origCodeSize > 5)
{
BYTE
nopCode[5] = { 0x90,0x90,0x90,0x90,0x90 };
if
(!WriteProcessCodeMemory(hProcess, (
DWORD
)desAddr + 5, nopCode, origCodeSize - 5))
{
VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE);
return
NULL;
}
}
return
allocAddr;
}
BOOL
UnHook(
HANDLE
hProcess,
LPVOID
desAddr,
SIZE_T
origCodeSize,
LPVOID
allocAddr) {
BYTE
origCode[10] = { 0 };
if
(!ReadProcessMemory(hProcess, allocAddr, origCode, origCodeSize, NULL))
return
FALSE;
if
(!WriteProcessCodeMemory(hProcess, desAddr, origCode, origCodeSize))
return
FALSE;
if
(!VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE))
return
FALSE;
return
TRUE;
}
LPVOID
DeFogByHook(
HANDLE
hProcess,
LPVOID
BaseAddr) {
unsigned
char
hookCode[9] = {
0xc7,0x01,0x00,0x00,0x00,0x00,
0x83,0xc1,0x04
};
return
SetHook(hProcess, (
DWORD
)BaseAddr + 0x26173, hookCode,
sizeof
(hookCode), 5);
}
BOOL
RecoveryFogByUnHook(
HANDLE
hProcess,
LPVOID
BaseAddr,
LPVOID
allocAddr) {
return
UnHook(hProcess, (
DWORD
)BaseAddr + 0x26173, 5, allocAddr);
}
LPVOID
DeFogByHook(
HANDLE
hProcess,
LPVOID
BaseAddr) {
unsigned
char
hookCode[9] = {
0xc7,0x01,0x00,0x00,0x00,0x00,
0x83,0xc1,0x04
};
return
SetHook(hProcess, (
DWORD
)BaseAddr + 0x26173, hookCode,
sizeof
(hookCode), 5);
}
BOOL
RecoveryFogByUnHook(
HANDLE
hProcess,
LPVOID
BaseAddr,
LPVOID
allocAddr) {
return
UnHook(hProcess, (
DWORD
)BaseAddr + 0x26173, 5, allocAddr);
}
BOOL
InjectDllByRemoteThread(
DWORD
desProcId,
WCHAR
* dllPath) {
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, desProcId);
if
(!hProcess)
return
FALSE;
DWORD
pathSize = (wcslen(dllPath) + 1) * 2;
LPVOID
newMemAddr = VirtualAllocEx(hProcess, 0, pathSize, MEM_COMMIT, PAGE_READWRITE);
if
(!newMemAddr)
return
FALSE;
if
(!WriteProcessMemory(hProcess, newMemAddr, dllPath, pathSize, NULL))
{
VirtualFreeEx(hProcess, newMemAddr, 0, MEM_RELEASE);
return
FALSE;
}
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryW, newMemAddr, 0, NULL);
if
(!hThread)
{
VirtualFreeEx(hProcess, newMemAddr, 0, MEM_RELEASE);
return
FALSE;
}
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, newMemAddr, 0, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
return
TRUE;
}
BOOL
InjectDllByRemoteThread(
DWORD
desProcId,
WCHAR
* dllPath) {
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, desProcId);
if
(!hProcess)
return
FALSE;
DWORD
pathSize = (wcslen(dllPath) + 1) * 2;
LPVOID
newMemAddr = VirtualAllocEx(hProcess, 0, pathSize, MEM_COMMIT, PAGE_READWRITE);
if
(!newMemAddr)
return
FALSE;
if
(!WriteProcessMemory(hProcess, newMemAddr, dllPath, pathSize, NULL))
{
VirtualFreeEx(hProcess, newMemAddr, 0, MEM_RELEASE);
return
FALSE;
}
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryW, newMemAddr, 0, NULL);
if
(!hThread)
{
VirtualFreeEx(hProcess, newMemAddr, 0, MEM_RELEASE);
return
FALSE;
}
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, newMemAddr, 0, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
return
TRUE;
}
BOOL
UnLoadDllByRemoteThread(
DWORD
dwProcessId,
LPCWSTR
lpDllName)
{
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if
(hProcess == NULL)
return
FALSE;
LPVOID
lpRemoteDllName = VirtualAllocEx(hProcess, NULL, (wcslen(lpDllName) + 1) *
sizeof
(
WCHAR
), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if
(lpRemoteDllName == NULL)
{
CloseHandle(hProcess);
return
FALSE;
}
if
(!WriteProcessMemory(hProcess, lpRemoteDllName, lpDllName, (wcslen(lpDllName) + 1) *
sizeof
(
WCHAR
), NULL))
{
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
HMODULE
hModules[1024],DesModule=NULL;
DWORD
dwSize = 0;
if
(!EnumProcessModules(hProcess, hModules,
sizeof
(hModules), &dwSize))
{
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
for
(
DWORD
i = 0; i < (dwSize /
sizeof
(
HMODULE
)); i++)
{
WCHAR
szModuleName[MAX_PATH] = { 0 };
if
(GetModuleFileNameExW(hProcess, hModules[i], szModuleName, MAX_PATH) > 0)
{
if
(wcsicmp(szModuleName, lpDllName) == 0)
{
DesModule = hModules[i];
}
}
}
if
(!DesModule) {
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, DesModule, 0, NULL);
if
(hThread == NULL)
{
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
TRUE;
}
BOOL
UnLoadDllByRemoteThread(
DWORD
dwProcessId,
LPCWSTR
lpDllName)
{
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if
(hProcess == NULL)
return
FALSE;
LPVOID
lpRemoteDllName = VirtualAllocEx(hProcess, NULL, (wcslen(lpDllName) + 1) *
sizeof
(
WCHAR
), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if
(lpRemoteDllName == NULL)
{
CloseHandle(hProcess);
return
FALSE;
}
if
(!WriteProcessMemory(hProcess, lpRemoteDllName, lpDllName, (wcslen(lpDllName) + 1) *
sizeof
(
WCHAR
), NULL))
{
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
HMODULE
hModules[1024],DesModule=NULL;
DWORD
dwSize = 0;
if
(!EnumProcessModules(hProcess, hModules,
sizeof
(hModules), &dwSize))
{
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
for
(
DWORD
i = 0; i < (dwSize /
sizeof
(
HMODULE
)); i++)
{
WCHAR
szModuleName[MAX_PATH] = { 0 };
if
(GetModuleFileNameExW(hProcess, hModules[i], szModuleName, MAX_PATH) > 0)
{
if
(wcsicmp(szModuleName, lpDllName) == 0)
{
DesModule = hModules[i];
}
}
}
if
(!DesModule) {
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, DesModule, 0, NULL);
if
(hThread == NULL)
{
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
TRUE;
}
#include<windows.h>
#include<stdio.h>
BOOL
GrowPlant(
DWORD
BaseAddr,
DWORD
x,
DWORD
y,
DWORD
TypePlant) {
LPVOID
PlantFunc = BaseAddr + 0x18D70;
__asm {
pushad
push -1
push TypePlant
mov eax, y
push x
mov ecx, BaseAddr
mov ecx, [ecx+0x355E0C]
mov ecx, [ecx + 0x868]
push ecx
call PlantFunc
popad
}
return
TRUE;
}
BOOL
WINAPI DllMain(
HMODULE
hInstance,
DWORD
fdwReason,
LPVOID
lpReserved) {
DWORD
BaseAddr = GetModuleHandle(NULL);
DWORD
pid = GetCurrentProcessId();
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
LPVOID
PlantFunc = BaseAddr + 0x18D70;
DWORD
ebpAddr = BaseAddr+0x355E0C,num=0;
ReadProcessMemory(hProcess, ebpAddr, &ebpAddr,
sizeof
(
DWORD
), NULL);
ebpAddr += 0x868;
ReadProcessMemory(hProcess, ebpAddr, &ebpAddr,
sizeof
(
DWORD
), NULL);
DWORD
x = 1, y = 1, TypePlant = 16;
switch
(fdwReason)
{
case
DLL_PROCESS_ATTACH:
__asm {
pushad
push - 1
push TypePlant
mov eax, y
push x
push ebpAddr
call PlantFunc
popad
}
x = 3, y = 2, TypePlant = 18;
__asm {
pushad
push - 1
push TypePlant
mov eax, y
push x
mov ecx, BaseAddr
mov ecx, [ecx+0x355E0C]
mov ecx, [ecx + 0x868]
push ecx
call PlantFunc
popad
}
GrowPlant(BaseAddr,7,3,23);
break
;
break
;
case
DLL_PROCESS_DETACH:
MessageBoxW(0, L
"ProcessDeTachDll!"
, L
"window2"
, 0);
break
;
}
return
TRUE;
}
#include<windows.h>
#include<stdio.h>
BOOL
GrowPlant(
DWORD
BaseAddr,
DWORD
x,
DWORD
y,
DWORD
TypePlant) {
LPVOID
PlantFunc = BaseAddr + 0x18D70;
__asm {
pushad
push -1
push TypePlant
mov eax, y
push x
mov ecx, BaseAddr
mov ecx, [ecx+0x355E0C]
mov ecx, [ecx + 0x868]
push ecx
call PlantFunc
popad
}
return
TRUE;
}
BOOL
WINAPI DllMain(
HMODULE
hInstance,
DWORD
fdwReason,
LPVOID
lpReserved) {
DWORD
BaseAddr = GetModuleHandle(NULL);
DWORD
pid = GetCurrentProcessId();
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
LPVOID
PlantFunc = BaseAddr + 0x18D70;
DWORD
ebpAddr = BaseAddr+0x355E0C,num=0;
ReadProcessMemory(hProcess, ebpAddr, &ebpAddr,
sizeof
(
DWORD
), NULL);
ebpAddr += 0x868;
ReadProcessMemory(hProcess, ebpAddr, &ebpAddr,
sizeof
(
DWORD
), NULL);
DWORD
x = 1, y = 1, TypePlant = 16;
switch
(fdwReason)
{
case
DLL_PROCESS_ATTACH:
__asm {
pushad
push - 1
push TypePlant
mov eax, y
push x
push ebpAddr
call PlantFunc
popad
}
x = 3, y = 2, TypePlant = 18;
__asm {
pushad
push - 1
push TypePlant
mov eax, y
push x
mov ecx, BaseAddr
mov ecx, [ecx+0x355E0C]
mov ecx, [ecx + 0x868]
push ecx
call PlantFunc
popad
}
GrowPlant(BaseAddr,7,3,23);
break
;
break
;
case
DLL_PROCESS_DETACH:
MessageBoxW(0, L
"ProcessDeTachDll!"
, L
"window2"
, 0);
break
;
}
return
TRUE;
}
__asm {
pushad
push - 1
push TypePlant
mov eax, y
push x
mov ecx,[BaseAddr+ 0x355E0C]
mov ecx,[ecx+0x868]
mov num, ecx
push ecx
call PlantFunc
popad
}
__asm {
pushad
push - 1
push TypePlant
mov eax, y
push x
mov ecx,[BaseAddr+ 0x355E0C]
mov ecx,[ecx+0x868]
mov num, ecx
push ecx
call PlantFunc
popad
}
DWORD
WINAPI ThreadProc(
_In_
LPVOID
lpParameter
);
DWORD
WINAPI ThreadProc(
_In_
LPVOID
lpParameter
);
BOOL
GrowPlantByInjectCode(
DWORD
dwProcessId,
DWORD
BaseAddr,
DWORD
x,
DWORD
y,
DWORD
PlantType)
{
BOOL
bSuccess = FALSE;
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if
(hProcess != NULL)
{
BYTE
InjectCode[50] = {
0x55,
0x89, 0xE5,
0x60,
0x68, 0xFF, 0xFF, 0xFF, 0xFF,
0x68, 0x00, 0x00, 0x00, 0x00,
0xB8, 0x00, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x00,
0xB9, 0x00, 0x00, 0x00, 0x00,
0x8B, 0x89, 0x0C, 0x5E, 0x35, 0x00,
0x8B, 0x89, 0x68, 0x08, 0x00, 0x00,
0x51,
0xE8, 0x00, 0x00, 0x00, 0x00,
0x61,
0xC9,
0xC3
};
DWORD
dwCodeSize = 50, desFunc = BaseAddr + 0x18D70;
LPVOID
lpRemoteCodeMem = VirtualAllocEx(hProcess, NULL, dwCodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
*(
DWORD
*)&InjectCode[10] = PlantType;
*(
DWORD
*)&InjectCode[15] = y;
*(
DWORD
*)&InjectCode[20] = x;
*(
DWORD
*)&InjectCode[25] = BaseAddr;
*(
DWORD
*)&InjectCode[43] = desFunc-((
DWORD
)lpRemoteCodeMem+42+5) ;
if
(lpRemoteCodeMem != NULL)
{
SIZE_T
dwBytesWritten = 0;
if
(WriteProcessMemory(hProcess, lpRemoteCodeMem, InjectCode, dwCodeSize, &dwBytesWritten) &&
dwBytesWritten == dwCodeSize)
{
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpRemoteCodeMem,NULL, 0, NULL);
if
(hThread != NULL)
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
bSuccess = TRUE;
}
}
VirtualFreeEx(hProcess, lpRemoteCodeMem, 0, MEM_RELEASE);
}
CloseHandle(hProcess);
}
return
bSuccess;
}
BOOL
GrowPlantByInjectCode(
DWORD
dwProcessId,
DWORD
BaseAddr,
DWORD
x,
DWORD
y,
DWORD
PlantType)
{
BOOL
bSuccess = FALSE;
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if
(hProcess != NULL)
{
BYTE
InjectCode[50] = {
0x55,
0x89, 0xE5,
0x60,
0x68, 0xFF, 0xFF, 0xFF, 0xFF,
0x68, 0x00, 0x00, 0x00, 0x00,
0xB8, 0x00, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x00,
0xB9, 0x00, 0x00, 0x00, 0x00,
0x8B, 0x89, 0x0C, 0x5E, 0x35, 0x00,
0x8B, 0x89, 0x68, 0x08, 0x00, 0x00,
0x51,
0xE8, 0x00, 0x00, 0x00, 0x00,
0x61,
0xC9,
0xC3
};
DWORD
dwCodeSize = 50, desFunc = BaseAddr + 0x18D70;
LPVOID
lpRemoteCodeMem = VirtualAllocEx(hProcess, NULL, dwCodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
*(
DWORD
*)&InjectCode[10] = PlantType;
*(
DWORD
*)&InjectCode[15] = y;
*(
DWORD
*)&InjectCode[20] = x;
*(
DWORD
*)&InjectCode[25] = BaseAddr;
*(
DWORD
*)&InjectCode[43] = desFunc-((
DWORD
)lpRemoteCodeMem+42+5) ;
if
(lpRemoteCodeMem != NULL)
{
SIZE_T
dwBytesWritten = 0;
if
(WriteProcessMemory(hProcess, lpRemoteCodeMem, InjectCode, dwCodeSize, &dwBytesWritten) &&
dwBytesWritten == dwCodeSize)
{
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpRemoteCodeMem,NULL, 0, NULL);
if
(hThread != NULL)
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
bSuccess = TRUE;
}
}
VirtualFreeEx(hProcess, lpRemoteCodeMem, 0, MEM_RELEASE);
}
CloseHandle(hProcess);
}
return
bSuccess;
}
BOOL
GrowZombie(
DWORD
BaseAddr,
DWORD
x,
DWORD
y,
DWORD
ZombieType) {
LPVOID
PlantZombieFunc = BaseAddr + 0x35390;
__asm {
pushad
push x
push ZombieType
mov eax,y
mov ecx,BaseAddr
mov ecx,[ecx+0x355E0C]
mov ecx,[ecx+0x868]
mov ecx,[ecx+0x178]
call PlantZombieFunc
popad
}
return
TRUE;
}
BOOL
GrowZombie(
DWORD
BaseAddr,
DWORD
x,
DWORD
y,
DWORD
ZombieType) {
LPVOID
PlantZombieFunc = BaseAddr + 0x35390;
__asm {
pushad
push x
push ZombieType
mov eax,y
mov ecx,BaseAddr
mov ecx,[ecx+0x355E0C]
mov ecx,[ecx+0x868]
mov ecx,[ecx+0x178]
call PlantZombieFunc
popad
}
return
TRUE;
}
BOOL
GrowZombieByRemoteThread(
DWORD
dwProcessId,
DWORD
BaseAddr,
DWORD
x,
DWORD
y,
DWORD
ZombieType) {
BOOL
bSuccess = FALSE;
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if
(hProcess != NULL)
{
BYTE
InjectCode[50] = {
0x55,
0x89, 0xE5,
0x60,
0x68, 0x00, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x00,
0xB8, 0x00, 0x00, 0x00, 0x00,
0xB9, 0x00, 0x00, 0x00, 0x00,
0x8B, 0x89, 0x0C, 0x5E, 0x35, 0x00,
0x8B, 0x89, 0x68, 0x08, 0x00, 0x00,
0x8B, 0x89, 0x78, 0x01, 0x00, 0x00,
0xE8, 0x00, 0x00, 0x00, 0x00,
0x61,
0xC9,
0xC3
};
DWORD
dwCodeSize = 50, desFunc = BaseAddr + 0x35390;
LPVOID
lpRemoteCodeMem = VirtualAllocEx(hProcess, NULL, dwCodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
*(
DWORD
*)&InjectCode[5] = x;
*(
DWORD
*)&InjectCode[10] = ZombieType;
*(
DWORD
*)&InjectCode[15] = y;
*(
DWORD
*)&InjectCode[20] = BaseAddr;
*(
DWORD
*)&InjectCode[43] = desFunc - ((
DWORD
)lpRemoteCodeMem + 42 + 5);
if
(lpRemoteCodeMem != NULL)
{
SIZE_T
dwBytesWritten = 0;
if
(WriteProcessMemory(hProcess, lpRemoteCodeMem, InjectCode, dwCodeSize, &dwBytesWritten) &&
dwBytesWritten == dwCodeSize)
{
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpRemoteCodeMem, NULL, 0, NULL);
if
(hThread != NULL)
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
bSuccess = TRUE;
}
}
VirtualFreeEx(hProcess, lpRemoteCodeMem, 0, MEM_RELEASE);
}
CloseHandle(hProcess);
}
return
bSuccess;
}
BOOL
GrowZombieByRemoteThread(
DWORD
dwProcessId,
DWORD
BaseAddr,
DWORD
x,
DWORD
y,
DWORD
ZombieType) {
BOOL
bSuccess = FALSE;
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if
(hProcess != NULL)
{
BYTE
InjectCode[50] = {
0x55,
0x89, 0xE5,
0x60,
0x68, 0x00, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x00,
0xB8, 0x00, 0x00, 0x00, 0x00,
0xB9, 0x00, 0x00, 0x00, 0x00,
0x8B, 0x89, 0x0C, 0x5E, 0x35, 0x00,
0x8B, 0x89, 0x68, 0x08, 0x00, 0x00,
0x8B, 0x89, 0x78, 0x01, 0x00, 0x00,
0xE8, 0x00, 0x00, 0x00, 0x00,
0x61,
0xC9,
0xC3
};
DWORD
dwCodeSize = 50, desFunc = BaseAddr + 0x35390;
LPVOID
lpRemoteCodeMem = VirtualAllocEx(hProcess, NULL, dwCodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
*(
DWORD
*)&InjectCode[5] = x;
*(
DWORD
*)&InjectCode[10] = ZombieType;
*(
DWORD
*)&InjectCode[15] = y;
*(
DWORD
*)&InjectCode[20] = BaseAddr;
*(
DWORD
*)&InjectCode[43] = desFunc - ((
DWORD
)lpRemoteCodeMem + 42 + 5);
if
(lpRemoteCodeMem != NULL)
{
SIZE_T
dwBytesWritten = 0;
if
(WriteProcessMemory(hProcess, lpRemoteCodeMem, InjectCode, dwCodeSize, &dwBytesWritten) &&
dwBytesWritten == dwCodeSize)
{
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpRemoteCodeMem, NULL, 0, NULL);
if
(hThread != NULL)
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
bSuccess = TRUE;
}
}
VirtualFreeEx(hProcess, lpRemoteCodeMem, 0, MEM_RELEASE);
}
CloseHandle(hProcess);
}
return
bSuccess;
}
#include<stdio.h>
#include<windows.h>
#include <tlhelp32.h>
#include <string.h>
#include <shlwapi.h>
#include <psapi.h>
enum
Type {
Sunlight, Money, TreeHeight, Chocolate, TreeFood, FlowerFood, Insecticide
};
unsigned
int
offsetTable[10] = { 0x5578,0x50,0x11c,0x250,0x258,0x220,0x224 };
DWORD
GetProcessIdByName(
const
wchar_t
* processName) {
HANDLE
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if
(snapshot == INVALID_HANDLE_VALUE) {
return
0;
}
PROCESSENTRY32 processEntry = { 0 };
processEntry.dwSize =
sizeof
(PROCESSENTRY32);
if
(!Process32First(snapshot, &processEntry)) {
CloseHandle(snapshot);
return
0;
}
do
{
wchar_t
currentProcessName[MAX_PATH];
wcscpy_s(currentProcessName, MAX_PATH, processEntry.szExeFile);
if
(wcscmp(currentProcessName, processName) == 0) {
CloseHandle(snapshot);
return
processEntry.th32ProcessID;
}
}
while
(Process32Next(snapshot, &processEntry));
CloseHandle(snapshot);
return
0;
}
LPVOID
GetModuleBaseAddress(
DWORD
processId,
LPCWSTR
moduleName) {
LPVOID
lpBaseAddress = NULL;
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
if
(hProcess != NULL) {
HMODULE
hMods[1024];
DWORD
cbNeeded;
if
(EnumProcessModules(hProcess, hMods,
sizeof
(hMods), &cbNeeded)) {
DWORD
dwModuleCount = cbNeeded /
sizeof
(
HMODULE
);
for
(
DWORD
i = 0; i < dwModuleCount; i++) {
TCHAR
szModName[MAX_PATH];
if
(GetModuleFileNameEx(hProcess, hMods[i], szModName, MAX_PATH)) {
if
(wcsstr(szModName, moduleName)) {
MODULEINFO modInfo = { 0 };
if
(GetModuleInformation(hProcess, hMods[i], &modInfo,
sizeof
(MODULEINFO))) {
lpBaseAddress = modInfo.lpBaseOfDll;
break
;
}
}
}
}
}
CloseHandle(hProcess);
}
return
lpBaseAddress;
}
BOOL
WriteProcessCodeMemory(
HANDLE
hProcess,
LPVOID
lpStartAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize) {
DWORD
dwOldProtect;
if
(!VirtualProtectEx(hProcess, lpStartAddress, nSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) {
return
FALSE;
}
BOOL
bResult = WriteProcessMemory(hProcess, lpStartAddress, lpBuffer, nSize, NULL);
VirtualProtectEx(hProcess, lpStartAddress, nSize, dwOldProtect, &dwOldProtect);
return
bResult;
}
LPVOID
SetHook(
HANDLE
hProcess,
LPVOID
desAddr,
LPCVOID
hookCode,
SIZE_T
hookCodeSize,
SIZE_T
origCodeSize) {
BYTE
origCode[10] = { 0 }, jmpCode[5] = { 0xE9,0,0,0,0 };
if
(!ReadProcessMemory(hProcess, desAddr, origCode, origCodeSize, NULL))
return
NULL;
LPVOID
allocAddr = VirtualAllocEx(hProcess, NULL, hookCodeSize + origCodeSize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if
(!allocAddr)
return
NULL;
*(
DWORD
*)(jmpCode + 1) = (
DWORD
)desAddr + 5 - ((
DWORD
)allocAddr + hookCodeSize + origCodeSize + 5);
if
(!WriteProcessCodeMemory(hProcess, allocAddr, origCode, origCodeSize)
|| !WriteProcessCodeMemory(hProcess, (
DWORD
)allocAddr + origCodeSize, hookCode, hookCodeSize)
|| !WriteProcessCodeMemory(hProcess, (
DWORD
)allocAddr + origCodeSize + hookCodeSize, jmpCode, 5))
{
VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE);
return
NULL;
}
*(
DWORD
*)(jmpCode + 1) = ((
DWORD
)allocAddr + origCodeSize) - ((
DWORD
)desAddr + 5);
WriteProcessCodeMemory(hProcess, desAddr, jmpCode, 5);
if
(origCodeSize > 5)
{
BYTE
nopCode[5] = { 0x90,0x90,0x90,0x90,0x90 };
if
(!WriteProcessCodeMemory(hProcess, (
DWORD
)desAddr + 5, nopCode, origCodeSize - 5))
{
VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE);
return
NULL;
}
}
return
allocAddr;
}
BOOL
UnHook(
HANDLE
hProcess,
LPVOID
desAddr,
SIZE_T
origCodeSize,
LPVOID
allocAddr) {
BYTE
origCode[10] = { 0 };
if
(!ReadProcessMemory(hProcess, allocAddr, origCode, origCodeSize, NULL))
return
FALSE;
if
(!WriteProcessCodeMemory(hProcess, desAddr, origCode, origCodeSize))
return
FALSE;
if
(!VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE))
return
FALSE;
return
TRUE;
}
unsigned
int
getSomething(
HANDLE
handle,
DWORD
BaseAddr, unsigned
int
type) {
unsigned
int
num = 0;
DWORD
addr = BaseAddr + 0x00355E0C;
ReadProcessMemory(handle, (
LPVOID
)addr, &addr,
sizeof
(
DWORD
), NULL);
if
(type == Sunlight)
addr += 0x868;
else
addr += 0x950;
ReadProcessMemory(handle, (
LPVOID
)addr, &addr,
sizeof
(
DWORD
), NULL);
addr += offsetTable[type];
ReadProcessMemory(handle, (
LPVOID
)addr, &num,
sizeof
(
DWORD
), 0);
return
num;
}
BOOL
setSomething(
HANDLE
handle,
DWORD
BaseAddr, unsigned
int
type, unsigned
int
num) {
DWORD
addr = BaseAddr + 0x00355E0C;
ReadProcessMemory(handle, addr, &addr,
sizeof
(
DWORD
), NULL);
if
(type == Sunlight)
addr += 0x868;
else
addr += 0x950;
ReadProcessMemory(handle, (
LPVOID
)addr, &addr,
sizeof
(
DWORD
), NULL);
addr += offsetTable[type];
return
WriteProcessMemory(handle, (
LPVOID
)addr, &num,
sizeof
(
DWORD
), 0);
}
BOOL
Uncooled(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
code[2] = { 0xeb,0x00 };
return
WriteProcessCodeMemory(hProcess, BaseAddr + 0x9ce02, code, 2);
}
BOOL
RecoveryCooling(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
OriginalCode[2] = { 0x7E ,0x16 };
return
WriteProcessCodeMemory(hProcess, BaseAddr + 0x9ce02, OriginalCode, 2);
}
BOOL
UnlimitedSun(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
Code[3] = { 0x29,0xdb,0 };
BOOL
flag;
flag = setSomething(hProcess, BaseAddr, Sunlight, 9999);
flag &= WriteProcessCodeMemory(hProcess, BaseAddr + 0x27690, Code, 2);
flag &= WriteProcessCodeMemory(hProcess, BaseAddr + 0x3C0AB, &Code[2], 1);
return
flag;
}
BOOL
RecoverySunConsume(
HANDLE
hProcess,
DWORD
BaseAddr) {
unsigned
char
OriginalCode[3] = { 0x3B,0xD8,0x32 };
BOOL
flag = WriteProcessCodeMemory(hProcess, BaseAddr + 0x27690, OriginalCode, 2);
flag &= WriteProcessCodeMemory(hProcess, BaseAddr + 0x3C0AB, &OriginalCode[2], 1);
return
flag;
}
LPVOID
DeFogByHook(
HANDLE
hProcess,
LPVOID
BaseAddr) {
unsigned
char
hookCode[9] = {
0xc7,0x01,0x00,0x00,0x00,0x00,
0x83,0xc1,0x04
};
return
SetHook(hProcess, (
DWORD
)BaseAddr + 0x26173, hookCode,
sizeof
(hookCode), 5);
}
BOOL
RecoveryFogByUnHook(
HANDLE
hProcess,
LPVOID
BaseAddr,
LPVOID
allocAddr) {
return
UnHook(hProcess, (
DWORD
)BaseAddr + 0x26173, 5, allocAddr);
}
BOOL
InjectDllByRemoteThread(
DWORD
desProcId,
WCHAR
* dllPath) {
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, desProcId);
if
(!hProcess)
return
FALSE;
DWORD
pathSize = (wcslen(dllPath) + 1) * 2;
LPVOID
newMemAddr = VirtualAllocEx(hProcess, 0, pathSize, MEM_COMMIT, PAGE_READWRITE);
if
(!newMemAddr)
return
FALSE;
if
(!WriteProcessMemory(hProcess, newMemAddr, dllPath, pathSize, NULL))
{
VirtualFreeEx(hProcess, newMemAddr, 0, MEM_RELEASE);
return
FALSE;
}
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryW, newMemAddr, 0, NULL);
if
(!hThread)
{
VirtualFreeEx(hProcess, newMemAddr, 0, MEM_RELEASE);
return
FALSE;
}
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, newMemAddr, 0, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
return
TRUE;
}
BOOL
UnLoadDllByRemoteThread(
DWORD
dwProcessId,
LPCWSTR
lpDllName)
{
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if
(hProcess == NULL)
return
FALSE;
LPVOID
lpRemoteDllName = VirtualAllocEx(hProcess, NULL, (wcslen(lpDllName) + 1) *
sizeof
(
WCHAR
), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if
(lpRemoteDllName == NULL)
{
CloseHandle(hProcess);
return
FALSE;
}
if
(!WriteProcessMemory(hProcess, lpRemoteDllName, lpDllName, (wcslen(lpDllName) + 1) *
sizeof
(
WCHAR
), NULL))
{
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
HMODULE
hModules[1024],DesModule=NULL;
DWORD
dwSize = 0;
if
(!EnumProcessModules(hProcess, hModules,
sizeof
(hModules), &dwSize))
{
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
for
(
DWORD
i = 0; i < (dwSize /
sizeof
(
HMODULE
)); i++)
{
WCHAR
szModuleName[MAX_PATH] = { 0 };
if
(GetModuleFileNameExW(hProcess, hModules[i], szModuleName, MAX_PATH) > 0)
{
if
(wcsicmp(szModuleName, lpDllName) == 0)
{
DesModule = hModules[i];
}
}
}
if
(!DesModule) {
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, DesModule, 0, NULL);
if
(hThread == NULL)
{
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
FALSE;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
VirtualFreeEx(hProcess, lpRemoteDllName, 0, MEM_RELEASE);
CloseHandle(hProcess);
return
TRUE;
}
BOOL
GrowPlantByInjectCode(
DWORD
dwProcessId,
DWORD
BaseAddr,
DWORD
x,
DWORD
y,
DWORD
PlantType)
{
BOOL
bSuccess = FALSE;
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if
(hProcess != NULL)
{
BYTE
InjectCode[50] = {
0x55,
0x89, 0xE5,
0x60,
0x68, 0xFF, 0xFF, 0xFF, 0xFF,
0x68, 0x00, 0x00, 0x00, 0x00,
0xB8, 0x00, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x00,
0xB9, 0x00, 0x00, 0x00, 0x00,
0x8B, 0x89, 0x0C, 0x5E, 0x35, 0x00,
0x8B, 0x89, 0x68, 0x08, 0x00, 0x00,
0x51,
0xE8, 0x00, 0x00, 0x00, 0x00,
0x61,
0xC9,
0xC3
};
DWORD
dwCodeSize = 50, desFunc = BaseAddr + 0x18D70;
LPVOID
lpRemoteCodeMem = VirtualAllocEx(hProcess, NULL, dwCodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
*(
DWORD
*)&InjectCode[10] = PlantType;
*(
DWORD
*)&InjectCode[15] = y;
*(
DWORD
*)&InjectCode[20] = x;
*(
DWORD
*)&InjectCode[25] = BaseAddr;
*(
DWORD
*)&InjectCode[43] = desFunc-((
DWORD
)lpRemoteCodeMem+42+5) ;
if
(lpRemoteCodeMem != NULL)
{
SIZE_T
dwBytesWritten = 0;
if
(WriteProcessMemory(hProcess, lpRemoteCodeMem, InjectCode, dwCodeSize, &dwBytesWritten) &&
dwBytesWritten == dwCodeSize)
{
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpRemoteCodeMem,NULL, 0, NULL);
if
(hThread != NULL)
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
bSuccess = TRUE;
}
}
VirtualFreeEx(hProcess, lpRemoteCodeMem, 0, MEM_RELEASE);
}
CloseHandle(hProcess);
}
return
bSuccess;
}
BOOL
GrowZombieByInjectCode(
DWORD
dwProcessId,
DWORD
BaseAddr,
DWORD
x,
DWORD
y,
DWORD
ZombieType) {
BOOL
bSuccess = FALSE;
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if
(hProcess != NULL)
{
BYTE
InjectCode[50] = {
0x55,
0x89, 0xE5,
0x60,
0x68, 0x00, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x00,
0xB8, 0x00, 0x00, 0x00, 0x00,
0xB9, 0x00, 0x00, 0x00, 0x00,
0x8B, 0x89, 0x0C, 0x5E, 0x35, 0x00,
0x8B, 0x89, 0x68, 0x08, 0x00, 0x00,
0x8B, 0x89, 0x78, 0x01, 0x00, 0x00,
0xE8, 0x00, 0x00, 0x00, 0x00,
0x61,
0xC9,
0xC3
};
DWORD
dwCodeSize = 50, desFunc = BaseAddr + 0x35390;
LPVOID
lpRemoteCodeMem = VirtualAllocEx(hProcess, NULL, dwCodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
*(
DWORD
*)&InjectCode[5] = x;
*(
DWORD
*)&InjectCode[10] = ZombieType;
*(
DWORD
*)&InjectCode[15] = y;
*(
DWORD
*)&InjectCode[20] = BaseAddr;
*(
DWORD
*)&InjectCode[43] = desFunc - ((
DWORD
)lpRemoteCodeMem + 42 + 5);
if
(lpRemoteCodeMem != NULL)
{
SIZE_T
dwBytesWritten = 0;
if
(WriteProcessMemory(hProcess, lpRemoteCodeMem, InjectCode, dwCodeSize, &dwBytesWritten) &&
dwBytesWritten == dwCodeSize)
{
HANDLE
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpRemoteCodeMem, NULL, 0, NULL);
if
(hThread != NULL)
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
bSuccess = TRUE;
}
}
VirtualFreeEx(hProcess, lpRemoteCodeMem, 0, MEM_RELEASE);
}
CloseHandle(hProcess);
}
return
bSuccess;
}
BOOL
SetPlantCard(
HANDLE
hProcess,
DWORD
BaseAddr,
DWORD
nCard,
DWORD
plantType) {
DWORD
cardAddr = BaseAddr + 0x355E0C;
ReadProcessMemory(hProcess, cardAddr, &cardAddr,
sizeof
(
DWORD
), NULL);
cardAddr += 0x868;
ReadProcessMemory(hProcess, cardAddr, &cardAddr,
sizeof
(
DWORD
), NULL);
cardAddr += 0x15C;
ReadProcessMemory(hProcess, cardAddr, &cardAddr,
sizeof
(
DWORD
), NULL);
cardAddr += 0x5C+nCard*0x50;
return
WriteProcessMemory(hProcess, cardAddr, &plantType,
sizeof
(
DWORD
), NULL);
}
void
choiceMenu(
HANDLE
hProcess,
DWORD
Pid,
LPVOID
BaseAddr) {
DWORD
choice = 0;
unsigned
int
num = 0;
DWORD
fogAddr = 0;
unsigned
int
x, y, Type;
while
(1) {
system
(
"cls"
);
printf
(
"\t\t\t\tWelcome to PVZ Modifier!\n"
);
printf
(
"\t\t\t\t\t0.退出\n"
);
printf
(
"\t\t\t\t\t1.修改阳光数\n"
);
printf
(
"\t\t\t\t\t2.修改金钱数\n"
);
printf
(
"\t\t\t\t\t3.修改智慧树高\n"
);
printf
(
"\t\t\t\t\t4.修改巧克力数\n"
);
printf
(
"\t\t\t\t\t5.修改树肥\n"
);
printf
(
"\t\t\t\t\t6.修改花肥\n"
);
printf
(
"\t\t\t\t\t7.修改杀虫剂\n"
);
printf
(
"\t\t\t\t\t8.无限冷却\n"
);
printf
(
"\t\t\t\t\t9.恢复冷却\n"
);
printf
(
"\t\t\t\t\t10.无限阳光\n"
);
printf
(
"\t\t\t\t\t11.恢复阳光消耗\n"
);
printf
(
"\t\t\t\t\t12.除雾\n"
);
printf
(
"\t\t\t\t\t13.恢复雾\n"
);
printf
(
"\t\t\t\t\t14.种植植物\n"
);
printf
(
"\t\t\t\t\t15.生成僵尸\n"
);
printf
(
"\t\t\t\tPlease choose your option:[ ]\b\b"
);
scanf
(
"%d"
, &choice);
switch
(choice){
case
0:
return
;
case
1:
case
2:
case
3:
case
4:
case
5:
case
6:
case
7:
printf
(
"\t\t\t\tPlease input Num:"
);
scanf
(
"%d"
, &num);
setSomething(hProcess, BaseAddr, choice - 1, num);
break
;
case
8:
Uncooled(hProcess, BaseAddr);
break
;
case
9:
RecoveryCooling(hProcess, BaseAddr);
break
;
case
10:
UnlimitedSun(hProcess,BaseAddr);
break
;
case
11:
RecoverySunConsume(hProcess, BaseAddr);
break
;
case
12:
fogAddr=(
DWORD
)DeFogByHook(hProcess, BaseAddr);
break
;
case
13:
RecoveryFogByUnHook(hProcess, BaseAddr,fogAddr );
break
;
case
14:
printf
(
"请输入X Y PlantType: "
);
scanf
(
"%d%d%d"
, &x, &y, &Type);
GrowPlantByInjectCode(Pid, BaseAddr,x,y,Type );
break
;
case
15:
printf
(
"请输入X Y ZombieType: "
);
scanf
(
"%d%d%d"
, &x, &y, &Type);
GrowZombieByInjectCode(Pid, BaseAddr, x, y, Type);
break
;
}
}
}
int
main() {
DWORD
Pid = GetProcessIdByName(L
"PlantsVsZombies.exe"
);
HANDLE
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE,Pid);
DWORD
BaseAddr=GetModuleBaseAddress(Pid, L
"PlantsVsZombies.exe"
);
choiceMenu(hProcess, Pid, BaseAddr);
CloseHandle(hProcess);
return
0;
}
#include<stdio.h>
#include<windows.h>
#include <tlhelp32.h>
#include <string.h>
#include <shlwapi.h>
#include <psapi.h>
enum
Type {
Sunlight, Money, TreeHeight, Chocolate, TreeFood, FlowerFood, Insecticide
};
unsigned
int
offsetTable[10] = { 0x5578,0x50,0x11c,0x250,0x258,0x220,0x224 };
DWORD
GetProcessIdByName(
const
wchar_t
* processName) {
HANDLE
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if
(snapshot == INVALID_HANDLE_VALUE) {
return
0;
}
PROCESSENTRY32 processEntry = { 0 };
processEntry.dwSize =
sizeof
(PROCESSENTRY32);
if
(!Process32First(snapshot, &processEntry)) {
CloseHandle(snapshot);
return
0;
}
do
{
wchar_t
currentProcessName[MAX_PATH];
wcscpy_s(currentProcessName, MAX_PATH, processEntry.szExeFile);
if
(wcscmp(currentProcessName, processName) == 0) {
CloseHandle(snapshot);
return
processEntry.th32ProcessID;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!