Phần 3 : Lập Trình Auto Game C# ,Sử dụng Cheat Engine để đọc bộ nhớ Game

0

Tiếp tục phần 3 Lập Trình Auto Game với C# 

đầu tiên tạo 1 listview và bố trí lại Gui theo như hình dưới

Tạo 1 ListView
Danh sách list view chứa ID là pid của game, và Tên nhân vật trong game.
Thiết lập các thuộc tính cho Listview
Để đọc được tên nhân vật, các chỉ số trong game chúng ta cần tìm chính xác địa chỉ của nó, hay còn gọi là Base adress(tìm trong cheat Engine). chỉ cần tìm được adress màu xanh lục và các offset, thì mỗi khi loadgame thì sẽ luôn đọc được tên nhân vật.
1: vd tìm tên nhân vật

Tải CHEAT ENGINE TẠI ĐÂY
mở Cheat Engine lên  mở game, ở đây mình chọn game đao kiếm 2

Chọn game DK2
Sau đó ở khung Value: gõ tên nhân vật vào và chọn theo như hình dưới, vì tên nhân vật là kiểu String và chọn Utf-16 để  có thể  tìm base bằng  tiếng việt có dấu.
Dùng cheat để tìm base adress 
Thêm các địa chỉ tìm được vào khung 3
Vì có nhiều giá trị giống nhau  nên ta lần lượt chọn tất cả các  base và đổi type sang text với độ dài chuỗi là 255 để xem kết quả chính xác nhất
Sau khi ra các kết quả thì ta lần lượt đổi tên  từng địa chỉ, nếu tên nhân vật trong game cũng thay đổi thì ta đã tìm ra được địa chỉ ban đầu.
với mỗi địa chỉ tìm được sau khi load game sẽ bị thay đổi  vì mỗi game chứa 1 bộ địa chỉ được phân bố riêng. để giải quyết vấn đề trên  chúng ta cần tìm được địa chỉ xanh(địa chỉ không bị thay đổi) hoặc  tìm các offset khác của nó để khi load game nó luôn trỏ đúng địa chỉ cần lấy.
Đổi tên giá trị để tìm base adress ban đầu.
Sử dụng Pointer Scan để tìm địa chỉ không bị thay đổi bao gồm offset

Pointer Scan
Sau khi Scan sẽ ra các địa chỉ và giá trị  cần tìm , chúng ta chỉ chú ý những base adress và offset có giá trị lặp lại nhiều lần.

Để cho chắc ăn giá trị đó không thay đổi thì mình sẽ dùng 1 nick game khác  để check, nếu như khi dùng cheat enigine  mở game thứ 2 mà giá trị nào trong bảng Pointer Scan không thay đổi và vẫn giữ nguyên giá trị thì  đó chính xác là  chúng ta đã tìm được  địa chỉ chứa tên nhân vật.

CODE CHỨC NĂNG ĐỌC TÊN NHÂN VẬT 
quay trở lại với visual Studio mở source Auto đã làm ở bài 2 ra và tạo 1 Class với tên MemoryDK2


Tạo class MemoryDK2
nội dung class MemoryDK2 có chứa các hàm hỗ trợ đọc bộ nhớ game
với hàm ReadInt32(); để đọc các địa chỉ kiểu int
vd :      int Ptr1 = MemoryDk2.ReadInt32((int)Address_name + Base, 4, handle);


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace AutoControlAppPC
{
    public class MemoryDK2
    {
        [DllImport("kernel32.dll")]
        public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
            [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);

        public static byte[] ReadBytes(IntPtr Handle, Int64 Address, uint BytesToRead)
        {
            IntPtr ptrBytesRead;
            byte[] buffer = new byte[BytesToRead];
            ReadProcessMemory(Handle, new IntPtr(Address), buffer, BytesToRead, out ptrBytesRead);
            return buffer;
        }

        public static int ReadInt32(long Address, uint length = 4, IntPtr? Handle = null)
        {
            return BitConverter.ToInt32(ReadBytes((IntPtr)Handle, Address, length), 0);
        }
        public static string ReadString(long Address, uint length = 32, IntPtr? Handle = null)
        {
            string temp3 = Encoding.Unicode.GetString(ReadBytes((IntPtr)Handle, Address, length));

            string[] temp3str = temp3.Split('\0');
            return temp3str[0];
        }

    }
}
vd mình tìm được địa chỉ là : 
Địa chỉ kèm offset tìm được
Sau đó trong form2 mình sẽ viết 1 hàm  để đọc địa chỉ trên.
Mỗi địa chỉ và offset đi kèm ký tự 0x ở phía trước.
Việc còn lại chỉ là gọi hàm GetNameChar kèm truyền vào base ,handle của game là có thể lấy được tên nhân vật.
public static string GetNameChar(int Base, IntPtr handle)
{
int Address_name = 0x94B6CC;
int Ptr1 = MemoryDK2.ReadInt32((int)Address_name + Base, 4, handle);
int Ptr2 = MemoryDK2.ReadInt32((int)Ptr1 + 0X108, 4, handle);
int Ptr3 = MemoryDK2.ReadInt32((int)Ptr2 + 0XC8, 4, handle);
int Ptr4 = Ptr3 + 0X0;
string PtrRead = MemoryDK2.ReadString(Ptr4, 255, handle);
return PtrRead;
}


Sau đó tạo thêm 1 mảng     ListViewItem[] lv1;
trong hàm 
CheckLoadGame  bây giờ sẽ như sau :

public void CheckLoadGame(string name)
        {
            if (IsGameAvailable(name))
            {
                try
                {
                    Process[] processlist = Process.GetProcessesByName(name); // 
                    Console.WriteLine(processlist.ToString());
                    foreach (Process process in processlist) // 2
                    {
                        label1.Text = "Loa Game Thành Công";
                        //Lấy base game 
                        int Base = (int)process.MainModule.BaseAddress.ToInt32();
                        //lấy tên nhân vật dựa vào hàm GetNameChar cùng 2 tham số ở dưới 
                        string tennv = GetNameChar(Base, process.Handle);
                        //lấy pid của game 
                        string Pid = process.Id.ToString();
                        //Thêm pid và tên nhân vật vào Listview
                        ListViewItem lv1 = new ListViewItem() { Text = Pid.ToString() };
                        lv1.SubItems.Add(new ListViewItem.ListViewSubItem() { Text = tennv });
                        listView1.Items.Add(lv1);
                    }
                }
                catch (Exception)
                {
                    label1.Text = "Loa Game Thất Bại";
                }
            }
            else
            {
                label1.Text = "Không tìm thấy Game";
            }
        }
        #endregion
F5 để build và thưởng thức thành quả
F5 chạy chương trình 

Full code :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using KAutoHelper;
using System.Threading;
using System.Threading.Tasks;
namespace AutoControlAppPC
{
    public partial class Form2 : Form
    {
        public Process[] myProcess;
        ListViewItem[] lv1;
        public Form2()
        {
            InitializeComponent();
        }
        #region CheckLoadGame
        public bool IsGameAvailable(string name)
        {
            myProcess = Process.GetProcessesByName(name);
            if (myProcess.Length != 0) { return true; } else { return false; }
        }
        public void CheckLoadGame(string name)
        {
            if (IsGameAvailable(name))
            {
                try
                {
                    Process[] processlist = Process.GetProcessesByName(name); // 
                    Console.WriteLine(processlist.ToString());
                    foreach (Process process in processlist) // 2
                    {
                        label1.Text = "Loa Game Thành Công";
                        //Lấy base game 
                        int Base = (int)process.MainModule.BaseAddress.ToInt32();
                        //lấy tên nhân vật dựa vào hàm GetNameChar cùng 2 tham số ở dưới 
                        string tennv = GetNameChar(Base, process.Handle);
                        //lấy pid của game 
                        string Pid = process.Id.ToString();
                        //Thêm pid và tên nhân vật vào Listview
                        ListViewItem lv1 = new ListViewItem() { Text = Pid.ToString() };
                        lv1.SubItems.Add(new ListViewItem.ListViewSubItem() { Text = tennv });
                        listView1.Items.Add(lv1);
                    }
                }
                catch (Exception)
                {
                    label1.Text = "Loa Game Thất Bại";
                }
            }
            else
            {
                label1.Text = "Không tìm thấy Game";
            }
        }
        #endregion
        private void Form2_Load(object sender, EventArgs e)
        {
            CheckLoadGame("dj2");
        }
        //Hàm chính của chúng ta để click ẩn.
        void ControlClick(int pid, int x, int y)
        {
            if (checkBox1.Checked)
            {
                IntPtr hWnd = IntPtr.Zero;
                hWnd = Process.GetProcessById(pid).MainWindowHandle;
                AutoControl.BringToFront(hWnd);
                AutoControl.SendClickOnPosition(hWnd, x, y);
            }
            else
            {
                IntPtr hWnd = IntPtr.Zero;
                hWnd = Process.GetProcessById(pid).MainWindowHandle;
                AutoControl.SendClickOnPosition(hWnd, x, y);
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            ControlClick(5968, 538, 579);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Task.Run(() => GetMail(5968));
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                this.TopMost = true;
                label2.Text = "Kích hoạt OnTop";
            }
            else
            {
                this.TopMost = false;
                label2.Text = "Hủy kích hoạt OnTop";
            }
        }
        public void Sleep(double delay)
        {
            double delayTime = 0;
            while (delayTime < delay)
            {
                Thread.Sleep(TimeSpan.FromSeconds(1));
                delayTime++;
            }
        }
        void GetMail(int Pid)
        {
            ControlClick(Pid, 784, 527); //1
            Sleep(0.1);
            ControlClick(Pid, 260, 195);//2
            int num = 12;//12 dòng
            int Posy = 195;//tọa độ y 
            for (int i = 0; i < num; i++)
            {
                Posy = Posy + 20; //sau mỗi lần y sẽ + thêm 20
                ControlClick(Pid, 260, Posy); //2
                ControlClick(Pid, 543, 413); //3
            }
            Sleep(0.1);
            ControlClick(Pid, 260, 453); //4
            Sleep(0.1);
            ControlClick(Pid, 324, 453); //5
            Sleep(0.1);
            ControlClick(Pid, 784, 527);//6
        }

        public string GetNameChar(int Base, IntPtr handle)
        {
            int Address_name = 0x94B6CC;
            int Ptr1 = MemoryDK2.ReadInt32((int)Address_name + Base, 4, handle);
            int Ptr2 = MemoryDK2.ReadInt32((int)Ptr1 + 0X108, 4, handle);
            int Ptr3 = MemoryDK2.ReadInt32((int)Ptr2 + 0XC8, 4, handle);
            int Ptr4 = Ptr3 + 0X0;
            string PtrRead = MemoryDK2.ReadString(Ptr4, 255, handle);
            return PtrRead;
        }
    }
   }
Nếu thấy hay hay click vào quảng cáo giúp mình nhé

Post a Comment

0Comments
Post a Comment (0)