內存型游戲外掛講解


一,要想做好外掛,那么必不可少的就是要找到游戲基址和偏移,首先講解一下游戲基址和偏移的找法:
這里我們使用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秒免費試用,同樣通過此方面,可以隨意修改免費試用時間,享受終身免費百度雲加速下載,趕快試試吧!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM