這個問題來自伴水的《划拳機器人》
,對本文用途感興趣的朋友請大致閱讀伴水的文章,在文章中我用這個方法寫了剪刀五號
,戰績不錯,當然屬於作弊的方法了。
剪刀五號的思路就是每次出拳,盡量讓對方能贏,然後根據一個位址區段來掃描記憶體中對方所贏的局數的儲存地址,找到後在得到比賽結果時把記憶體資料改掉。這個類似以前打單機遊戲時用的fpe之類的修改工具。當然,如果對方故意犯規,一局也不贏,你是找不到他的地址的,這樣可以通過正常途徑來擷取勝利。
把剪刀五號核心代碼簡化後,主要為三個api函數
OpenProcess,ReadProcessMemory,WriteProcessMemory
代碼大致如下:
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Runtime.InteropServices;
namespace
ConsoleApplication4
...
{
//
開啟不安全的程式碼開關:項目-右鍵-屬性-產生-允許不安全的程式碼
class
Program
...
{
[DllImport(
"
kernel32.dll
"
)]
public
static
extern
IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
[DllImport(
"
kernel32.dll
"
)]
public
static
extern
Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
uint
[] lpBuffer, UInt32 nSize, IntPtr lpNumberOfBytesWritten);
[DllImport(
"
kernel32.dll
"
)]
public
static
extern
Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
uint
[] lpBuffer, UInt32 nSize, IntPtr lpNumberOfBytesRead);
static
IntPtr pAddress
=
(IntPtr)
0x12bdad8
;
static
uint
[] Read
=
new
uint
[
1
];
static
uint
[] Write
=
new
uint
[]
...
{
0x64
}
;
static
private
int
mm
=
999
;
static
void
Main(
string
[] args)
...
{
unsafe
...
{
fixed
(
int
*
i
=
&
mm)
...
{ pAddress
=
(IntPtr)i; }
}
IntPtr h
=
OpenProcess(
0x1F0FFF
,
0
, (UInt32)System.Diagnostics.Process.GetCurrentProcess().Id);
ReadProcessMemory(h, pAddress, Read,
4
, (IntPtr)
0
);
//
擷取記憶體資料
Console.WriteLine(Read[
0
]);
//
輸出999
WriteProcessMemory(h, pAddress, Write,
4
, (IntPtr)
0
);
//
修改記憶體資料
Console.WriteLine(mm);
//
輸出100
Console.Read();
}
}
}