做外挂小记(2)--接上C#篇

http://hi.baidu.com/859729391/blog/item/58a4f21285a43a876438dbfd.html

 

大家都知道C#对底层的支持是非常不好....但是我们还是可以通过一些方法来读PID

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;//我们可以通过此类来查找进程pid,比通过API的来的简单的许多.
using System.Management;

namespace ok
{
    public partial class Form1 : Form
    {
        public Form1()
        {
       
            InitializeComponent();
           
   

           public class getpid//定义取得pid的类

      {       public string pid;//为了省事,我直接声明一个公共字段了,当然你也可以写属性写构造啦!

           System.Diagnostics.Process[] processes = Process.GetProcesses();
           
//获得当前所有进程列表 ,注意是个数组,除非你的电脑只有一个进程
            foreach (Process a in processes)   //遍历每一个进程 ,如果出错请声明一下a   
            {
                if(a.ProcessName.ToString()=="xxx.exe")//如果进程名等于xxx.exe,可以用资源管理器查看

                    {

                          pid= a.Id.ToString();//就输出他的pid,这样就可以获得pid了

//当然Process a的属性还有很多,总之很强大,例如   a.MachineName.ToString();//获取关联进程机器名
//                                                                             a.MainWindowTitle.ToString();//获取主窗口的窗口名

//红色部分可以任意替换,如果你不知道进程名,知道窗口名,就用a.MainWindowTitle.ToString()="记事本"

                 }            

                }                
            }  
        }

//这样,我们就获得了进程的pid了,下面我们来修改内存...还是得调用API..下面我们来写个内存读写类.

//呵呵,说来说去还是要用API

public class read_and_write//定义一个类,类名随便你写....我就通俗点了,直接用read_and_write

    {
        const uint PROCESS_ALL_ACCESS = 0x001F0FFF;
        const uint KEYEVENTF_EXTENDEDKEY = 0x1;
        const uint KEYEVENTF_KEYUP = 0x2;
        const uint KBC_KEY_CMD = 0x64;
        const uint KBC_KEY_DATA = 0x60;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName );

        //得到窗体句柄的函数,FindWindow函数用来返回符合指定的类名( ClassName )和窗口名( WindowTitle )的窗口句柄
        [DllImport("user32.dll")]
        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

//取得pid的一种函数,我们上面已经获得pid了,所以这里用不到了.

         [DllImport("kernel32.dll")]
        static extern bool ReadProcessMemory(uint hProcess, IntPtr lpBaseAddress,
        IntPtr lpBuffer, uint nSize, ref uint lpNumberOfBytesRead);
//读取进程内存的函数,非常重要
        [DllImport("kernel32.dll")]
        static extern bool WriteProcessMemory(uint hProcess, IntPtr lpBaseAddress,
        uint[] lpBuffer, uint nSize, ref uint lpNumberOfBytesWritten);
//写入进程内存函数,更重要
        [DllImport("kernel32.dll")]
        public static extern uint OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
        //得到目标进程句柄的函数                
//上面是调用一些API函数,不用记,COPY就行了,不记得就百度一下      

        public void write(string pid,IntPtr address,int wordin)//定义写内存的方法
        {
          byte[] vBuffer = new byte[4];
          IntPtr vBytesAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 得到缓冲区的地址


          uint hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, Convert.ToInt32(pid));

//这个大家很熟悉了..获得进程句柄,并且得到绝对控制权限,3个参数(绝对控制,总是false,pid注意是int类型)
          uint[] PinballScoreWrite = new uint[] { Convert.ToUInt32(wordin) };//定义欲写入
//写入的值,,注意是个数组,不是数组能不能我也不清楚,你可以试试            
         WriteProcessMemory(hProcess, address, PinballScoreWrite, (uint)vBuffer.Length, ref hProcess);
//这个就是写入内存了,参数列表(进程句柄,地址(注意其类型),写入的值,长度,ref hProcess)

//注意最后一个参数是引用传递..可能可以填0.                      

          CloseHandle(hProcess);//养成良好习惯,关闭句柄


        }
    

       public string read(string pid,IntPtr address,int wordin)//定义读内存的方法,既然是读就有返回值

      {

              byte[] vBuffer = new byte[4];
          IntPtr vBytesAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 同上


          uint hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, Convert.ToInt32(pid));//同上


          uint[] PinballScoreWrite = new uint[] { Convert.ToUInt32(wordin) };//同上            
         if(ReadProcessMemory(hProcess, address, PinballScoreWrite, (uint)vBuffer.Length, ref hProcess);)

//假如读的出,这是个bool型判断,就就是true,则执行

    {     

          CloseHandle(hProcess);//关闭句柄

          return Convert.Tostring( Marshal.ReadInt32(address));//返回address地址存放的值,就可以调用了

       else//否则什么都不做,只关闭句柄

      {

            CloseHandle(hProcess);

        }

      }

}
  
}

//这样我们就可以调用了...小记(3)则写一个如何调用read_and_write的类..^ ^

 

posted on 2011-09-11 18:38  l1b2q31  阅读(356)  评论(0编辑  收藏  举报

导航