网站首页 新闻首页 网页设计图形动画软件编程网站开发办公软件操作系统数据库网络技术认证考试范文资料黑客攻防 书籍教程 进入论坛

c#做外挂 step by step

http://www.diybl.com/ 2007-12-21  网络 点击:  [ 评论 ]
文章搜索:    【点击打包该文章】

第一课:C#使用WINDOW API和对内存的操作。
这一课是些简单的东西,了解的可以直接越过。考虑到大多数使用c#的人都是做网站的,可能没有机会接触这些,所以我在这里做一下粗略的介绍。

step 1:认识WINAPI
   
windows系统里提供了很多的函数,我们如果做外挂的话,就需要用到其中的函数(以下简称API)。(废话:这些API被封装在系统路径下的DLL文件里。事实上,我们不用关心它在哪,我们只要知道怎么用就可以了,)用起来很简单,格式如下:
    public partial class Form1 : Form
    {
        [DllImport("kernel32.dll")]          \
        public static extern int ReadProcessMemory( |
            int hProcess,               |
            int lpBaseAddress,             |
            int[] lpBuffer,                >代码段1
            int nSize,                    |
            int lpNumberOfBytesWritten         |
        );                      /
        ...
        public Form1()
        {
            InitializeComponent();
            ReadProcessMemory(processhandle,...          >代码2
            ...
        }
        ...
    }
代码段1就是引用api的代码。我们引用的函数,是做外挂时最常用的函数,从它的名字就可以看的出来它的作用---读取进程内存。(废话:从代码里,我们很容易看的出来,这个函数被封装在了kernel32.dll这个文件里。)引用之后,我们就可以在自己的代码中使用这个函数了(如代码2)。
(废话:WINDOWS还提供很多的API,如果你有兴趣了解的话,可以到网上搜WINAPI手册。想深入了解的话,可以看MSDN。)
step 2:读写内存
    下面我来说一下,如何使用上一步引用的那个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;
         

[1] [2]
如果图片或页面不能正常显示请点击这里 站内搜索:   

文章评论

请您留言

 

最新新闻