00413184 |. E8 77E30100 |CALL PlantsVs.00431500 ; 地上的物品 004131C9 |> 8Bc3 3C010000 MOV EDI,DWORD PTR DS:[EBX+13C] ; edi = 游戏基址
var Form1: TForm1; pGameBase:Pointer; pPlantBaseArray:array[0..100] of pointer; pMonBaseArray:array[0..100] of pointer; pGoodsBaseArray:array[0..100] of pointer; pPlantToolBarBaseArray:array[0..100] of pointer; type stMonsterInfo = record x:single; y:single; nMaxHP:integer; nCurHP:integer; nRow:integer; fSize:single; end; type stPlantToolBarInfo = record nType:integer; nMaxRecovery:integer; nCurRecovery:integer; end; type stGoodsInfo = record nType:integer; end; type stPlantInfo = record bIsProdure:integer; nType:integer; end; implementation {$R *.dfm} procedure GetGameBase(); begin asm pushad mov eax, $6a9ec0 mov eax, [eax] add eax, $768 mov eax, [eax] mov pGameBase, eax //游戏基址 popad end; end; function GetMonsterBase(pMonBase:Pointer):Pointer; begin asm pushad mov esi, pMonBase mov edx, pGameBase//游戏基址 mov edi, $0041C8F0 call edi//获取一个怪物地址 popad end; Result:= Pointer(pMonBase^); end; function GetPlantBase(pPlantBase:Pointer):Pointer; begin asm pushad mov esi, pPlantBase mov edx, pGameBase//游戏基址 mov edi, $0041C950 call edi//获取一个植物地址 popad end; Result:= Pointer(pPlantBase^); end; function GetGoodsBase(pGoodsBase:Pointer):Pointer; begin asm pushad mov esi, pGoodsBase mov edx, pGameBase//游戏基址 mov edi, $0041CA10 call edi//获取一个植物地址 popad end; Result:= Pointer(pGoodsBase^); end; function GetPlantToolbarBase(nIndex:integer):Pointer; var pBase:Pointer; n:integer; begin n:= nIndex * $50 + $28; asm pushad mov eax, pGameBase mov eax, [eax + $144] mov pBase, eax popad end; pBase:= Pointer(DWORD(pBase) + n); Result:= pBase; end; function GetMaxPlantNum():integer; var n:integer; begin asm pushad mov eax, pGameBase mov eax, [eax + $144] mov eax, [eax + $24] mov n, eax popad end; Result:= n; end; procedure FreshMonsterList(); var pMonBase:Integer; n, nIndex:integer; begin nIndex:= 0; pMonBase:= 0; n:= form1.RzComboBox1.ItemIndex; form1.RzComboBox1.Clear; repeat pMonBase:= Integer(GetMonsterBase(@pMonBase)); if pMonBase = -1 then begin form1.RzComboBox1.ItemIndex:= n; exit; end; form1.RzComboBox1.Add('怪物:' + IntToStr(nIndex + 1)) ; pMonBaseArray[nIndex]:= Pointer(pMonBase); nIndex:= nIndex + 1; until(false); form1.RzComboBox1.ItemIndex:= n; end; procedure FreshPlantToolBarList(); var nMaxPlant:integer; i:integer; pPlantBase:Pointer; n, nIndex:integer; begin n:= form1.RzComboBox2.ItemIndex; form1.RzComboBox2.Clear; nIndex:= 0; nMaxPlant:= GetMaxPlantNum(); for i:= 0 to nMaxPlant - 1 do begin pPlantBase:= GetPlantToolbarBase(i); pPlantToolBarBaseArray[nIndex]:= pPlantBase; nIndex:= nIndex + 1; form1.RzComboBox2.Add('植物栏:' + IntToStr(nIndex)); end; form1.RzComboBox2.ItemIndex:= n; end; procedure TForm1.FormCreate(Sender: TObject); begin GetGameBase(); end; procedure FreshPlantList(); var pPlantBase:Integer; n, nIndex:integer; begin n:= form1.RzComboBox4.ItemIndex; form1.RzComboBox4.Clear; nIndex:= 0; pPlantBase:= 0; repeat pPlantBase:= Integer(GetPlantBase(@pPlantBase)); if pPlantBase = -1 then begin form1.RzComboBox4.ItemIndex:= n; exit; end; form1.RzComboBox4.Add('植物:' + IntToStr(nIndex + 1)) ; pPlantBaseArray[nIndex]:= Pointer(pPlantBase); nIndex:= nIndex + 1; until(false); end; procedure FreshGoodsList(); var pGoodsBase:Integer; cItem:TListItem; n, nIndex:integer; begin n:= form1.RzComboBox3.ItemIndex; form1.RzComboBox3.Clear; nIndex:= 0; pGoodsBase:= 0; repeat pGoodsBase:= Integer(GetGoodsBase(@pGoodsBase)); if pGoodsBase = -1 then begin form1.RzComboBox3.ItemIndex:= n; exit; end; form1.RzComboBox3.Add('物品:' + IntToStr(nIndex + 1)) ; pGoodsBaseArray[nIndex]:= Pointer(pGoodsBase); nIndex:= nIndex + 1; until(false); end; procedure TForm1.TabSheet2Show(Sender: TObject); begin form1.RzComboBox1.Clear; FreshMonsterList(); if form1.RzComboBox1.Items.Count > 0 then form1.RzComboBox1.ItemIndex:= 0; end; procedure TForm1.TabSheet5Show(Sender: TObject); begin FreshGoodsList(); if form1.RzComboBox3.Items.Count > 0 then form1.RzComboBox3.ItemIndex:= 0; end; procedure TForm1.TabSheet4Show(Sender: TObject); begin FreshPlantList(); if form1.RzComboBox4.Items.Count > 0 then form1.RzComboBox4.ItemIndex:= 0; end; procedure SetMonsterInfo(pMonBase:Pointer; stMonInfo:stMonsterInfo); var s:single; begin s:= stMonInfo.fSize; asm pushad mov eax, pMonBase mov ecx, stMonInfo.x mov [eax + $2c], ecx mov ecx, stMonInfo.y mov [eax + $30], ecx mov ecx, stMonInfo.nCurHP mov [eax + $C8], ecx mov ecx, stMonInfo.nMaxHP mov [eax + $cc], ecx mov ecx, stMonInfo.nRow mov [eax + $1c], ecx mov ecx, stMonInfo.fSize mov [eax + $11c], ecx popad end; end; procedure GetMonsterInfo(pMonBase:Pointer;stMonInfo:stMonsterInfo); var x:single; y:single; nMaxHP:integer; nCurHP:integer; nRow:integer; fSize:single; begin asm pushad mov eax, pMonBase mov ecx, [eax + $2c] mov x, ecx mov ecx, [eax + $30] mov y, ecx mov ecx, [eax + $c8] mov nCurHP, ecx mov ecx, [eax + $cc] mov nMaxHP, ecx mov ecx, [eax + $1c] mov nRow, ecx mov ecx, [eax + $11c] mov fSize, ecx popad end; form1.RzEdit5.Text:= FloatToStr(x); form1.RzEdit5.Text:= FloatToStr(x); form1.RzEdit6.Text:= FloatToStr(y); form1.RzEdit7.Text:= IntToStr(nMaxHP); form1.RzEdit8.Text:= IntToStr(nCurHP); form1.RzEdit9.Text:= IntToStr(nRow); form1.RzEdit10.Text:= FloatToStr(fSize); end; procedure TForm1.RzButton4Click(Sender: TObject); var pMonBase:Pointer; stInfo:stMonsterInfo; nIndex:integer; begin if form1.RzComboBox1.Items.Count <= 0 then exit; nIndex:= form1.RzComboBox1.ItemIndex; FreshMonsterList(); pMonBase:= Pointer(pMonBaseArray[nIndex]); stInfo.x:= StrToFloat(form1.RzEdit5.Text); stInfo.y:= StrToFloat(form1.RzEdit6.Text); stInfo.nMaxHP:= StrToInt(form1.RzEdit7.Text); stInfo.nCurHP:= StrToInt(form1.RzEdit8.Text); stInfo.nRow:= StrToInt(form1.RzEdit9.Text); stInfo.fSize:= StrToFloat(form1.RzEdit10.Text); nIndex:= form1.RzComboBox1.ItemIndex; FreshMonsterList(); pMonBase:= Pointer(pMonBaseArray[nIndex]); SetMonsterInfo(pMonBase, stInfo); end; procedure TForm1.RzComboBox1Change(Sender: TObject); var stInfo:stMonsterInfo; pMonBase:pointer; nIndex:integer; begin if form1.RzComboBox1.Items.Count <= 0 then exit; nIndex:= form1.RzComboBox1.ItemIndex; FreshMonsterList(); pMonBase:= Pointer(pMonBaseArray[nIndex]); GetMonsterInfo(pMonBase, stInfo); end; procedure TForm1.RzComboBox1CloseUp(Sender: TObject); begin FreshMonsterList(); end; procedure SetGoodsInfo(pGoodsBase:Pointer; stInfo:stGoodsInfo); var nType:integer; begin nType:= stInfo.nType; asm pushad mov eax, pGoodsBase mov ecx, nType mov [eax + $58], ecx popad end; end; procedure GetGoodsInfo(pGoodsBase:Pointer; var stInfo:stGoodsInfo); var nType:integer; begin asm pushad mov eax, pGoodsBase mov ecx, [eax + $58] mov nType, ecx popad end; form1.RzEdit4.Text:= IntToStr(nType); end; procedure TForm1.TabSheet3Show(Sender: TObject); begin FreshPlantToolBarList(); if form1.RzComboBox2.Items.Count > 0 then form1.RzComboBox2.ItemIndex:= 0; end; procedure TForm1.RzComboBox3Change(Sender: TObject); var stInfo:stGoodsInfo; pGoodsBase:pointer; nIndex:integer; begin if form1.RzComboBox3.Items.Count <= 0 then exit; nIndex:= form1.RzComboBox3.ItemIndex; FreshGoodsList(); pGoodsBase:= Pointer(pGoodsBaseArray[nIndex]); GetGoodsInfo(pGoodsBase, stInfo); end; procedure TForm1.RzButton3Click(Sender: TObject); var stInfo:stGoodsInfo; nIndex:integer; pGoodsBase:Pointer; begin if (form1.RzComboBox3.Items.Count <= 0) and (StrToInt(form1.RzEdit4.Text) <= 15) then exit; nIndex:= form1.RzComboBox3.ItemIndex; FreshGoodsList(); pGoodsBase:= Pointer(pGoodsBaseArray[nIndex]); // ShowMessage(IntToStr(DWORD(pGoodsBase))); stInfo.nType:= StrToInt(form1.RzEdit4.Text); SetGoodsInfo(pGoodsBase, stInfo); end; procedure GetPlantInfo(pPlantBase:Pointer; var stInfo:stPlantInfo); var bIsProdure:integer; nType:integer; begin asm pushad mov eax, pPlantBase mov ecx, [eax + $28] mov bIsProdure, ecx mov ecx, [eax + $24] mov nType, ecx popad end; form1.RzEdit3.Text:= IntToStr(bIsProdure); form1.RzEdit2.Text:= IntToStr(nType); end; procedure SetPlantInfo(pPlantBase:Pointer; stInfo:stPlantInfo); var bIsProdure:integer; nType:integer; begin bIsProdure:= stInfo.bIsProdure; nType:= stInfo.nType; asm pushad mov eax, pPlantBase mov ecx, bIsProdure mov [eax + $24], ecx mov ecx, nType mov [eax + $28], ecx popad end; end; procedure TForm1.RzComboBox4Change(Sender: TObject); var stInfo:stPlantInfo; pPlantBase:pointer; nIndex:integer; begin if form1.RzComboBox4.Items.Count <= 0 then exit; nIndex:= form1.RzComboBox4.ItemIndex; FreshPlantList(); pPlantBase:= Pointer(pPlantBaseArray[nIndex]); GetPlantInfo(pPlantBase, stInfo); end; procedure TForm1.RzButton2Click(Sender: TObject); var stInfo:stPlantInfo; nIndex:integer; pPlantBase:Pointer; begin if (MessageBox(form1.Handle, '该功能可能会引起不良效果,请确定要不要使用?使用前请先保存游戏!!', '提示', Windows.MB_ICONWARNING or MB_YESNO) = IDNO) then exit; if (form1.RzComboBox4.Items.Count <= 0) then exit; nIndex:= form1.RzComboBox4.ItemIndex; FreshPlantList(); pPlantBase:= Pointer(pPlantBaseArray[nIndex]); // ShowMessage(IntToStr(DWORD(pGoodsBase))); stInfo.bIsProdure:= StrToInt(form1.RzEdit3.Text); stInfo.nType:= StrToInt(form1.RzEdit2.Text); SetPlantInfo(pPlantBase, stInfo); end; procedure TForm1.RzComboBox4CloseUp(Sender: TObject); begin FreshPlantList(); end; procedure GetPlantToolBarInfo(pPlantBase:Pointer; var stInfo:stPlantToolBarInfo); var nType:integer; nMaxRecovery:integer; nCurRecovery:integer; begin asm pushad mov eax, pPlantBase mov ecx, [eax + $34] mov nType, ecx mov ecx, [eax + $24] mov nCurRecovery, ecx mov ecx, [eax + $28] mov nMaxRecovery, ecx popad end; form1.RzEdit1.Text:= IntToStr(nType); form1.RzEdit11.Text:= IntToStr(nCurRecovery); form1.RzEdit12.Text:= IntToStr(nMaxRecovery); end; procedure SetPlantToolBarInfo(pPlantBase:Pointer; var stInfo:stPlantToolBarInfo); var nType:integer; nMaxRecovery:integer; nCurRecovery:integer; begin nType:= stInfo.nType; nMaxRecovery:= stInfo.nMaxRecovery; nCurRecovery:= stInfo.nCurRecovery; asm pushad mov eax, pPlantBase mov ecx, nType mov [eax + $34], ecx mov ecx, nMaxRecovery mov [eax + $28], ecx mov ecx, nCurRecovery mov [eax + $24], ecx popad end; end; procedure TForm1.RzComboBox2Change(Sender: TObject); var stInfo:stPlantToolBarInfo; pPlantToolBarBase:pointer; nIndex:integer; begin if form1.RzComboBox2.Items.Count <= 0 then exit; nIndex:= form1.RzComboBox2.ItemIndex; FreshPlantToolBarList(); pPlantToolBarBase:= Pointer(pPlantToolBarBaseArray[nIndex]); GetPlantToolBarInfo(pPlantToolBarBase, stInfo); end; procedure TForm1.RzButton1Click(Sender: TObject); var stInfo:stPlantToolBarInfo; nIndex:integer; pPlantToolBarBase:Pointer; begin if (form1.RzComboBox2.Items.Count <= 0) then exit; nIndex:= form1.RzComboBox2.ItemIndex; FreshPlantToolBarList(); pPlantToolBarBase:= Pointer(pPlantToolBarBaseArray[nIndex]); // ShowMessage(IntToStr(DWORD(pGoodsBase))); stInfo.nType:= StrToInt(form1.RzEdit1.Text); stInfo.nMaxRecovery:= StrToInt(form1.RzEdit12.Text); stInfo.nCurRecovery:= StrToInt(form1.RzEdit11.Text); SetPlantToolBarInfo(pPlantToolBarBase, stInfo); end; procedure TForm1.RzButton6Click(Sender: TObject); var nPlantToolBarNum:integer; begin asm pushad mov eax, pGameBase mov eax, [eax + $144] add eax, $24 mov ecx, 9 mov [eax], ecx popad end end; procedure TForm1.RzButton5Click(Sender: TObject); begin asm pushad mov eax, pGameBase add eax, $5560 mov [eax], 9999999 popad end; end; procedure TForm1.RzComboBox3CloseUp(Sender: TObject); begin FreshGoodsList(); end; procedure TForm1.RzComboBox2CloseUp(Sender: TObject); begin FreshPlantToolBarList(); end; function WriteMemory(szProcName:PChar; pAddr:Pointer; szBuf:array of char; dwSize:DWORD):boolean; var hGameWnd:HWND; dwID:DWORD; hProc:THandle; dwWriteByte:DWORD; begin hGameWnd:= FindWindow(nil, szProcName); GetWindowThreadProcessId(hGameWnd, dwID); hProc:= OpenProcess(PROCESS_ALL_ACCESS, false, dwID); if hProc = 0 then begin Result:= false; exit; end; WriteProcessMemory(hProc, pAddr, @szBuf, dwSize, dwWriteByte); CloseHandle(hProc); Result:= true; end; procedure ModiryPlantToolBar(); var nMaxPlant:integer; i:integer; pPlantBase:Pointer; n, nIndex:integer; begin nIndex:= 0; nMaxPlant:= GetMaxPlantNum(); for i:= 0 to nMaxPlant - 1 do begin pPlantBase:= GetPlantToolbarBase(i); asm pushad mov eax, pPlantBase mov [eax + $28], 0 popad end; nIndex:= nIndex + 1; end; end; procedure TForm1.RzButton7Click(Sender: TObject); var szBuf:array[0..2] of char; begin szBuf[0]:= Char($90); szBuf[1]:= Char($90); szBuf[2]:= Char($90); WriteMemory('植物大战僵尸中文版', Pointer($488f7d), szBuf, 3); ModiryPlantToolBar(); asm pushad mov eax, pGameBase add eax, $5560 mov [eax], 9999999 popad end; end; procedure GrowPlant(x,y,nType:integer); begin asm pushad mov eax, y push -1 push nType push x push pGameBase mov edi, $0040D120 call edi popad end; end; procedure TForm1.RzButton8Click(Sender: TObject); var x,y:integer; nType:integer; n:integer; begin randomize; nType:= 0; n:= 0; for x:= 0 to 8 do begin for y:= 0 to 5 do begin if RzComboBox5.ItemIndex = 0 then nType:= math.RandomRange(0, 48) else if RzComboBox5.ItemIndex = 1 then begin nType:= n; n:= n + 1; if n = 48 then n:= 0; end else nType:= RzComboBox5.ItemIndex - 2; GrowPlant(x, y, nType); end; end; end; procedure TForm1.TabSheet1Show(Sender: TObject); var i:integer; begin RzComboBox5.Add('随机种植'); RzComboBox5.Add('顺序种植'); for i:= 1 to 48 do RzComboBox5.Add(IntToStr(i)); RzComboBox5.ItemIndex:= 0; end; procedure TForm1.TabSheet1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin GetGameBase(); end; procedure TForm1.RzButton9Click(Sender: TObject); var szBuf:array[0..3] of char; begin szBuf[0]:= Char($90); szBuf[1]:= Char($90); szBuf[2]:= Char($90); szBuf[3]:= Char($90); WriteMemory('植物大战僵尸中文版', Pointer($52FCF0), szBuf, 4); end; procedure KillAllMonster(); var pMonBase:Integer; n, nIndex:integer; stInfo:stMonsterInfo; begin nIndex:= 0; pMonBase:= 0; repeat pMonBase:= Integer(GetMonsterBase(@pMonBase)); if pMonBase = -1 then begin exit; end; asm pushad mov eax, pMonBase mov [eax + $c8], -1 popad end; until(false); end; procedure TForm1.RzButton10Click(Sender: TObject); begin ShowMessage('由于种种原因,怪物需要再K它一下,O(∩_∩)O哈哈~'); KillAllMonster(); end; end. 以上分析中,红色的数据经过《植物大战僵尸中文第二版》测试通过。 --------------------------------------------------------------- 年度版: 阳光: [[7794F8]+868]+5578 植物冷却状态地址(0为不可用,1为可用):
|
|