领先的中文IT技术网站    IT技术从现在起飞

飞诺旗下: 技术社区 | 在线电子书 | 在线试题 | 资源下载 | 飞诺搜索 | 技术博客
用户名: 密   码:
   飞诺网 加入收藏
飞诺网 软件编程 新闻频道 开发频道 系统频道 服务器 网络频道 网络安全 Java频道 C/C++ PHP开发 电子书 资源下载 社 区 博 客 在线试题
软件编程 C C++ Java VB Delphi Foxpro 汇编语言 游戏开发 移动开发 软件工程师 软工与管理 VC shell编程 C#
编程开发 JAVA C/C++ C++ VC C语言 VB C# Delphi Foxpro 汇编 shell编程 游戏开发 软件工程师 WEB开发 PHP ASP Asp.net JSP AJAX CGI JavaScript HTML CSS 数据库 MSSQL Mysql Oracle Access Sybase DB2 sql2005 Office Word Excel Powerpoint Wps 认证考试 二级C语言 三级网络 程序员 网络工程师 思科认证

您当前的位置:飞诺网 >>  软件编程 >> 游戏开发

c#做外挂 step by step

www.diybl.com    时间 : 2010-06-15  作者:佚名   编辑:壹枝雪糕 点击:   [ 评论 ]

windows系统里提供了很多的函数,我们如果做外挂的话,就需要用到其中的函数(以下简称API)。(废话:这些API被封装在系统路径下的DLL文件里。事实上,我们不用关心它在哪,我们只要知道怎么用就可以了,)用起来很简单,格式如下:
    public partial class Form1 : Form
    {
        [DllImport("kernel32.dll")]          
        public static extern int ReadProcessMemory( 
            int hProcess,               
            int lpBaseAddress,            
            int[] lpBuffer,                
            int nSize,                   
            int lpNumberOfBytesWritten        
        );                     
        ...
        public Form1()
        {
            InitializeComponent();
            ReadProcessMemory(processhandle,...        
          
        }
        ...
    }
代码段1就是引用api的代码。我们引用的函数,是做外挂时最常用的函数,从它的名字就可以看的出来它的作用---读取进程内存。(废话:从代码里,我们很容易看的出来,这个函数被封装在了kernel32.dll这个文件里。)引用之后,我们就可以在自己的代码中使用这个函数了

   下面我来说一下,如何使用上一步引用的那个API读取游戏的数据。先来看看参数:
      public static extern int ReadProcessMemory(     
            int hProcess,          //进程,如果你是做外挂的话,它代表你要挂的那个游戏。
      int lpBaseAddress,      //你要读取的内存地址
      int[] lpBuffer,          //从上面那个参数地址里读出来的东西(调用这个函数的就是为了它)  不管这个参数是什么类型,它应该是一个数组,否则读不出东西来
            int nSize,              //长度,上一个参数,类型是int,那个长度应该用4
            int lpNumberOfBytesWritten  //用0就行了,想知道它是干嘛的,自己去MSND吧
关于第一个参数hProcess如何获取,我过会再说。假设它已经搞定了,那么这个函数,我们需要关心的只有lpBaseAddress和lpBuffer,既读的地址,和读出来的值。(废话:对了,这个函数貌似还有个返回值,我们这里用不到它。如果你有兴趣了解,MSDN)读出来的值out int lpBuffer我们在引用API的时候声明为int型了,但是,我们要从内存里读的值不一定总是int。我们可以多次引用这个API,第3个参数分别用不同的类型。
下面,我们结合实际,来写一段读取诛仙人物HP的代码。首先,我们需要知道人物HP的地址,(废话:如何知道这个地址,用CE还是IE,你自己搞定吧。)我是用IE在这里http://www.ghoffice.com/bbs/read.php?tid-35908-fpage-2.html找到的,它这里是这样写的:
人物基址:[[&H12F830]+&H28]=base
生命:[base+&H254]
(注:&H表示16进制,在C#里我们用0x表示)
一对[]表示读一次地址。也就是说123表示值123,而[123]就表示从地址123读出来的值。几对[],就要用几次ReadProcessMemory,我们来写下代码:
  int[] Base=new int[1];
    int[] hp=new int[1];
    ReadProcessMemory(process, 0x12F830, Base;, 4, 0);//相当于Base=[&H12F830]
    ReadProcessMemory(process, Base+0x28, Base;, 4, 0);//相当于Base=[Base+&H28]
    //读出了人物基址base
    ReadProcessMemory(process, Base+0x254, hp;, 4, 0);//相当于hp=[base+&H254]
    //读出了hp
怎么样,很简单吧。
我们读HP只用了3行ReadProcessMemory。有的时候,读某个值可能需要很多对[],就要写N行ReadProcessMemory,这样写起来就很麻烦,看起来也很晕。下面我们来写个函数,让读内存的过程看起来和[]表示法差不多。
        //为了看起来好看,函数的名字最好短些,所以我们用r,表示read
        public static int r(int add)
        {
            int[] r=new int[1];
            try
            {
                ReadProcessMemory(process, add, r, 4, 0);
              return r[0];
            }
            catch (Exception ex)
            {
                return -1;
            }
        }
这个函数很简单,不用我多说了吧。
有了这个函数,上面的读取HP的代码,我们就可以写成这样了:
    int Base;
    int hp;
    Base=r(r(0x12F830)+0x28);
    //读出了人物基址base
    hp=r(base+&H254);
    //读出了hp
看起来清晰多了吧。

下面我来说下读取字符串,首先引用API:
        [DllImport("kernel32.dll")]
        public static extern int ReadProcessMemory(
            int hProcess,
            int lpBaseAddress,
            byte[] lpBuffer,
            int nSize,
            int lpNumberOfBytesRead
        );
然后和上面一样,写一个读字符串的方法。
        public static string rString(IntPtr process, uint add)
        {
            string[] r;
            string temp;
            byte[] b = new byte[256];
            try
            {
                API.ReadProcessMemory(process, (IntPtr)add, b, 256, (IntPtr)0);
                //读出的byte[]要按Unicode编码为字符串
                temp = System.Text.Encoding.Unicode.GetString(b);
                //截取第一段字符串
                r = temp.Split(''\0'');
                return r[0];
            }
            catch (Exception ex)
            {
                return "error";
            }
        }

如果图片或页面不能正常显示请点击这里
游戏开发推荐文章

文章评论

BBS社区热贴