內存型遊戲外掛講解
一,要想做好外掛,那麽必不可少的就是要找到遊戲基址和偏移,首先講解一下遊戲基址和偏移的找法:
這裏我們使用CE來找尋基址和偏移
我們先來找尋遊戲生命基址
首先選擇遊戲進程,選擇好後,數值類型選擇“字節”,掃描類型選擇“精確數值”。然後在數值框中輸入當前生命,點“新的掃描”按扭。
掃描完成後,把人物掛一次,改變一下生命,然後再在數據框中輸入現在的生命,點“再次掃描”,直到找到生命動態地址為止。
這裏我們找到了,我們的生命動態地址為02A5E05B,我們雙擊他到下面,這時我們發現,我們修改他的數值,遊戲的生命也會發生改變。
但是這只是一個動態地址,重新打開遊戲我們會發現,這個地址會改變。
這裏我要闡明一下動態地址計算法則:
動態地址=遊戲一級基址的值+偏移
下面我們右擊這個地址,並選擇圖中所選菜單:
我們遊戲中再次改變一下生命,就會發現掃描出了結果
此時點擊詳細信息
從圖中我們可以得知,更改的地址是02A5E008.
這時候,偏移我們就可以計算出來了,我們拿現在動態地址02A5E05B減去這個地址02A5E008,得到的結果是十六進制53.這個結果就是偏移。
此時我們掃描一下這個值:
掃描出了2個結果,地址以綠色顯示,表示已經是一級基址,我們取00622880,這樣一級基址也就出來了。
我們的生命基址和偏移順利找到。
同理我們也要先找到子彈基址,在找子彈基址時候我們首次掃描選擇“未知的初始數值",然後在改變子彈後或沒有改變子彈的情況下選擇”改變的數值“或”未改變的數值"
最終我們子彈基址偏移為00622898+偏移B8
二,編寫這個外掛
好了,相信大家已經對內存弄的外掛已經有了一定的了解了,那麽如何使用編程語言去編寫這個外掛呢?
當然,易語言乃內在型外掛開發首選利器,精易模塊對內存寫入寫出的操作做出了很好的封裝。但題主今天偏偏不走正道,帶大家使用c#來開發這個外掛,目的也就是為了讓大家更清楚的認識編程語言對內存的底層操作。
內在操作工具類Memory:
class Memory { public static bool IsRunning = false; public int dwProcessId; [DllImport("kernel32.dll")] public static extern bool ReadProcessMemory(int hProcess, int IpBaseAddress, out int IpBuffer, int nSize, IntPtr IpNumberOfBytesRead); [DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(int hProcess, int IpBaseAddress, int[] IpBuffer, int nSize, IntPtr IpNumberOfBytesWritten); [DllImport("User32.dll")] public static extern IntPtr FindWindow(string IpClassName, string IpWindowName);//根據窗口名得到窗口句柄 [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);//獲取進程ID,第一個參數從FindWindow獲取 [DllImport("kernel32.dll")] public static extern int OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); //返回進程句柄,第三個參數從GetWindowThreadProcessId獲取 [DllImport("kernel32.dll")] private static extern void CloseHandle(int hObject); public int getHProcess(bool IsRead) { int hProcess; if (IsRead == true) { hProcess = OpenProcess(0x0010 | 0x0020, false, dwProcessId); } else { hProcess = OpenProcess(0x1F0FFF, false, dwProcessId);//獲取最高寫入權限 } return hProcess; } public bool injectionProcess(string processTitle)//註入進程 { IntPtr hwnd = FindWindow(null, processTitle); GetWindowThreadProcessId(hwnd, out dwProcessId); if (dwProcessId != 0) { IsRunning = true; } return IsRunning; } public int readMemory(int processAddress) { if (IsRunning == true) { int hProcess = getHProcess(true); ReadProcessMemory(hProcess, processAddress, out processAddress, 4, IntPtr.Zero); CloseHandle(hProcess); return processAddress; } else return 0; } public void wirteMemory(int value, int processAddress, int offset) { if (IsRunning == true) { int hProcess = getHProcess(false); processAddress += offset; WriteProcessMemory(hProcess, processAddress, new int[] { value }, 4, IntPtr.Zero); CloseHandle(hProcess); } } public void wirteMemory(int value, int processAddress) { if (IsRunning == true) { int hProcess = getHProcess(false); WriteProcessMemory(hProcess, processAddress, new int[] { value }, 4, IntPtr.Zero); CloseHandle(hProcess); } } }
主程序調用:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } Memory memory = new Memory(); private void button1_Click(object sender, EventArgs e) { } private void button3_Click(object sender, EventArgs e) { int processAddress = memory.readMemory(0x00622898); memory.wirteMemory(100, processAddress, 0x53); } private void button2_Click(object sender, EventArgs e) { int processAddress = memory.readMemory(0x00622898); memory.wirteMemory(3, processAddress, 0x53); } private void Form1_Load(object sender, EventArgs e) { this.Size = new Size(200, 200); } private void button4_Click(object sender, EventArgs e) { bool isRunning = memory.injectionProcess("SMYNES v1.20"); if (isRunning == false) { MessageBox.Show("註入遊戲失敗,請檢查遊戲是否啟動!"); } else { this.Size = new Size(450, 200); button4.Visible = false; panel1.Visible = true; } } private void radioButton3_CheckedChanged(object sender, EventArgs e) { timer1.Start(); } private void timer1_Tick(object sender, EventArgs e) { int processAddress = memory.readMemory(0x00622898); memory.wirteMemory(2, processAddress, 0xB8); } private void radioButton4_CheckedChanged(object sender, EventArgs e) { timer1.Stop(); } }
這樣,內存型外掛就此大功告成。
偷偷告訴大家的是,百度雲本地300秒免費試用,同樣通過此方面,可以隨意修改免費試用時間,享受終身免費百度雲加速下載,趕快試試吧!
內存型遊戲外掛講解