标题:[原创]c#类,封装了键盘,和鼠标模拟,和内存读取
只看楼主
dreamsfly
Rank: 2
等 级:论坛游民
帖 子:152
专家分:13
注 册:2007-6-29
 问题点数:0 回复次数:34 
[原创]c#类,封装了键盘,和鼠标模拟,和内存读取
*/ --------------------------------------------------------------------------------------
*/ 出自: 编程中国 http://www.bc-cn.net
*/ 作者: dreamsfly E-mail:xingyu900@163.com QQ:20573886
*/ 时间: 2007-11-5 编程论坛首发
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------


发一个自己写的c#类,封装了键盘,和鼠标模拟,和内存读取

键盘和鼠标模拟用了2种方式,一种是系统api,还有一种是winio
鼠标模拟不是很好,建议不要用,外带一个很简单的内存读取方法。
大家把类的功能多多修改,让我们写外挂更方便,呵呵。

我下面将开源


本主题包含附件: sf_200779104937.rar (28181bytes)

key kk = new key();
// IntPtr a = new IntPtr();
kk.sendwinio();
kk.MykeyDown((int)key.VirtualKeys.VK_F1);
System.Threading.Thread.Sleep(2000);
kk.MykeyUp((int)key.VirtualKeys.VK_F1);
这是模拟键盘的调用方式

类的源代码在3楼,象下看
,请各位高手多多完善。谢谢了
注明,我的获取进程pid的方式,是通过进程名获取的


ApIBasgF.rar (27.81 KB) 发一个自己写的c#类,封装了键盘,和鼠标模拟,和内存读取


[此贴子已经被作者于2007-11-5 21:23:31编辑过]

搜索更多相关主题的帖子: 鼠标 内存 键盘 封装 模拟 
2007-07-09 11:56
pacocai
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:1583
专家分:0
注 册:2007-3-12
得分:0 
不是源代码,给的东西是直接编译好的…………郁闷。楼主不能直接提供源程吗?

浮生若梦天边月,醉死如酒水中星。红楼一梦千人叹,岂让万夫空做贱。博客:http://hi.baidu.com/rxvip
2007-07-20 19:17
dreamsfly
Rank: 2
等 级:论坛游民
帖 子:152
专家分:13
注 册:2007-6-29
得分:0 

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Management;
namespace sendkey
{
public class key
{
const uint PROCESS_ALL_ACCESS = 0x001F0FFF;
const uint KEYEVENTF_EXTENDEDKEY = 0x1;
const uint KEYEVENTF_KEYUP = 0x2;
private readonly int MOUSEEVENTF_LEFTDOWN = 0x2;
private readonly int MOUSEEVENTF_LEFTUP = 0x4;
const uint KBC_KEY_CMD = 0x64;
const uint KBC_KEY_DATA = 0x60;
//得到窗体句柄的函数,FindWindow函数用来返回符合指定的类名( ClassName )和窗口名( WindowTitle )的窗口句柄
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(
string lpClassName, // pointer to class name
string lpWindowName // pointer to window name
);
[DllImport("user32.dll")]
private static extern int GetWindowThreadProcessId(IntPtr id,int pid);

[DllImport("kernel32.dll")]
private static extern void CloseHandle
(
uint hObject //Handle to object
);
//读取进程内存的函数
[DllImport("kernel32.dll")]
static extern bool ReadProcessMemory(uint hProcess, IntPtr lpBaseAddress,
IntPtr lpBuffer, uint nSize, ref uint lpNumberOfBytesRead);
//得到目标进程句柄的函数
[DllImport("kernel32.dll")]
public static extern uint OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
//鼠标事件声明
[DllImport("user32.dll")]
static extern bool setcursorpos(int x, int y);
[DllImport("user32.dll")]
static extern void mouse_event(mouseeventflag flags, int dx, int dy, uint data, UIntPtr extrainfo);
//键盘事件声明
[DllImport("user32.dll")]
static extern byte MapVirtualKey(byte wCode, int wMap);
[DllImport("user32.dll")]
static extern short GetKeyState(int nVirtKey);
[DllImport("user32.dll")]
static extern void keybd_event( byte bVk, byte bScan,uint dwFlags,uint dwExtraInfo);
//键盘事件声明winio
[DllImport("winio.dll")]
public static extern bool InitializeWinIo();
[DllImport("winio.dll")]
public static extern bool GetPortVal(IntPtr wPortAddr, out int pdwPortVal, byte bSize);
[DllImport("winio.dll")]
public static extern bool SetPortVal(uint wPortAddr, IntPtr dwPortVal, byte bSize);
[DllImport("winio.dll")]
public static extern byte MapPhysToLin(byte pbPhysAddr, uint dwPhysSize, IntPtr PhysicalMemoryHandle);
[DllImport("winio.dll")]
public static extern bool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, byte pbLinAddr);
[DllImport("winio.dll")]
public static extern bool GetPhysLong(IntPtr pbPhysAddr, byte pdwPhysVal);
[DllImport("winio.dll")]
public static extern bool SetPhysLong(IntPtr pbPhysAddr, byte dwPhysVal);
[DllImport("winio.dll")]
public static extern void ShutdownWinIo();


/// <summary>
/// 获取进程pid
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private int pid(String name)
{
try
{
ObjectQuery oQuery = new ObjectQuery("select * from Win32_Process where Name='" + name + "'");
ManagementObjectSearcher oSearcher = new ManagementObjectSearcher(oQuery);
ManagementObjectCollection oReturnCollection = oSearcher.Get();

string pid = "";
string cmdLine;
StringBuilder sb = new StringBuilder();
foreach (ManagementObject oReturn in oReturnCollection)
{
pid = oReturn.GetPropertyvalue("ProcessId").ToString();
//cmdLine = (string)oReturn.GetPropertyvalue("CommandLine");

//string pattern = "-ap \"(.*)\"";
//Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
// Match match = regex.Match(cmdLine);
//string appPoolName = match.Groups[1].ToString();
//sb.AppendFormat("W3WP.exe PID: {0} AppPoolId:{1}\r\n", pid, appPoolName);
}
return Convert.ToInt32(pid);
}
catch (Exception ss)
{ return 0; }

}
private int pid(IntPtr id)
{
int pid=0;
pid=GetWindowThreadProcessId(id, pid);
return 260;
}
/// <summary>
/// 读取内存值
/// </summary>
/// <param name="name">进程id</param>
/// <param name="dizhi">读取的内存地址</param>
/// <returns></returns>
//public String getread(String QEC,String EC, IntPtr dizhi, uint size)
//{
// Byte bt = new Byte();
// IntPtr id=FindWindow(QEC, EC);
// uint hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid(id));
// IntPtr fanhui = new IntPtr();
// String gg = null;
// if (hProcess == 0)
// {
// // gg = ReadProcessMemory(hProcess, dizhi, fanhui, size, 0);
// // CloseHandle(hProcess);

// }
// return gg;
//}
public String getread(String jincheng, String EC, IntPtr dizhi, uint size)
{
byte[] vBuffer = new byte[4];
IntPtr vBytesAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 得到缓冲区的地址

uint vNumberOfBytesRead = 0;
Byte bt = new Byte();
//IntPtr id = FindWindow(QEC, EC);
uint hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid(jincheng));
//pid(0);
IntPtr fanhui = new IntPtr();
String gg = null;
//if (hProcess == 0)
//{
if (ReadProcessMemory(hProcess, dizhi, vBytesAddress, (uint)vBuffer.Length, ref hProcess))
{
CloseHandle(hProcess);
}
else
{
CloseHandle(hProcess);
}

// }
int vInt = Marshal.ReadInt32(vBytesAddress);
return vInt.ToString() ;
}
/// <summary>
/// 获取键盘状态
/// </summary>
/// <param name="Key"></param>
/// <returns></returns>
public bool GetState(VirtualKeys Key)
{
return (GetKeyState((int)Key) == 1);
}
/// <summary>
/// 发送键盘事件
/// </summary>
/// <returns></returns>
public void Send(VirtualKeys Key, bool State)
{
if (State != GetState(Key))
{
byte a= MapVirtualKey((byte)Key, 0);
keybd_event((byte)Key, MapVirtualKey((byte)Key, 0), 0, 0);
System.Threading.Thread.Sleep(1000);
keybd_event((byte)Key, MapVirtualKey((byte)Key, 0), KEYEVENTF_KEYUP, 0);
}
}
/// <summary>
/// 初始化winio
/// </summary>
public void sendwinio()
{
if (InitializeWinIo())
{
KBCWait4IBE();
}
}
private void KBCWait4IBE() //等待键盘缓冲区为空
{
//int[] dwVal = new int[] { 0 };
int dwVal = 0;
do
{
//这句表示从&H64端口读取一个字节并把读出的数据放到变量dwVal中
//GetPortVal函数的用法是GetPortVal 端口号,存放读出数据的变量,读入的长度
bool flag = GetPortVal((IntPtr)0x64, out dwVal, 1);
}
while ((dwVal & 0x2) > 0);
}
/// <summary>
/// 模拟键盘标按下
/// </summary>
/// <param name="vKeyCoad"></param>
public void MykeyDown(int vKeyCoad)
{
int btScancode = 0;

btScancode = MapVirtualKey((byte)vKeyCoad, 0);
// btScancode = vKeyCoad;

KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);// '发送键盘写入命令
//SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)0xe2, 1);// '写入按键信息,按下键
KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);// '发送键盘写入命令
//SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);// '写入按键信息,按下键

}
/// <summary>
/// 模拟键盘弹出
/// </summary>
/// <param name="vKeyCoad"></param>
public void MykeyUp(int vKeyCoad)
{
int btScancode = 0;
btScancode = MapVirtualKey((byte)vKeyCoad, 0);
//btScancode = vKeyCoad;

KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD,(IntPtr) 0xD2, 1); //'发送键盘写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)0xe0, 1);// '写入按键信息,释放键
KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1); //'发送键盘写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);// '写入按键信息,释放键
}
/// <summary>
/// 模拟鼠标按下
/// </summary>
/// <param name="vKeyCoad"></param>
public void MyMouseDown(int vKeyCoad)
{
int btScancode = 0;

btScancode = MapVirtualKey((byte)vKeyCoad, 0);
//btScancode = vKeyCoad;

KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD,(IntPtr)0xD3, 1);// '发送键盘写入命令
//SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode|0x80), 1);// '写入按键信息,按下键

}
/// <summary>
/// 模拟鼠标弹出
/// </summary>
/// <param name="vKeyCoad"></param>
public void MyMouseUp(int vKeyCoad)
{
int btScancode = 0;
btScancode = MapVirtualKey((byte)vKeyCoad, 0);
// btScancode = vKeyCoad;

KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD,(IntPtr) 0xD3, 1); //'发送键盘写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode | 0x80), 1);// '写入按键信息,释放键
}
/// <summary>
/// 发送鼠标事件
/// </summary>
/// <returns></returns>
public void SendMouse()
{

}
/// <summary>
/// 鼠标动作枚举
/// </summary>
public enum mouseeventflag : uint
{
move = 0x0001,
leftdown = 0x0002,
leftup = 0x0004,
rightdown = 0x0008,
rightup = 0x0010,
middledown = 0x0020,
middleup = 0x0040,
xdown = 0x0080,
xup = 0x0100,
wheel = 0x0800,
virtualdesk = 0x4000,
absolute = 0x8000
}
/// <summary>
/// 键盘动作枚举
/// </summary>
public enum VirtualKeys : byte
{
//VK_NUMLOCK = 0x90, //数字锁定键
//VK_SCROLL = 0x91, //滚动锁定
//VK_CAPITAL = 0x14, //大小写锁定
//VK_A = 62, //键盘A
VK_LBUTTON=1, //鼠标左键
   VK_RBUTTON=2,  //鼠标右键
    VK_CANCEL=3,    //Ctrl+Break(通常不需要处理)
    VK_MBUTTON=4,   //鼠标中键
    VK_BACK=8,     //Backspace
    VK_TAB=9,     //Tab
    VK_CLEAR=12,    //Num Lock关闭时的数字键盘5
    VK_RETURN=13,   //Enter(或者另一个)
    VK_SHIFT=16,    //Shift(或者另一个)
    VK_CONTROL=17,   //Ctrl(或者另一个)
    VK_MENU=18,    //Alt(或者另一个)
    VK_PAUSE=19,    //Pause
    VK_CAPITAL=20,   //Caps Lock
    VK_ESCAPE=27,   //Esc
    VK_SPACE=32,    //Spacebar
    VK_PRIOR=33,    //Page Up
    VK_NEXT=34,    //Page Down
    VK_END=35,     //End
    VK_HOME=36,    //Home
    VK_LEFT=37,    //左箭头
    VK_UP=38,     //上箭头
    VK_RIGHT=39,    //右箭头
    VK_DOWN=40,    //下箭头
    VK_SELECT=41,   //可选
    VK_PRINT=42,    //可选
    VK_EXECUTE=43,   //可选
    VK_SNAPSHOT=44,  //Print Screen
    VK_INSERT=45,   //Insert
    VK_DELETE=46,   //Delete
    VK_HELP=47,   //可选
VK_NUM0=48, //0
VK_NUM1=49, //1
VK_NUM2=50, //2
VK_NUM3=51, //3
VK_NUM4=52, //4
VK_NUM5=53, //5
VK_NUM6=54, //6
VK_NUM7=55, //7
VK_NUM8=56, //8
VK_NUM9=57, //9
VK_A=65, //A
VK_B=66, //B
VK_C=67, //C
VK_D=68, //D
VK_E=69, //E
VK_F=70, //F
VK_G=71, //G
VK_H=72, //H
VK_I=73, //I
VK_J=74, //J
VK_K=75, //K
VK_L=76, //L
VK_M=77, //M
VK_N=78, //N
VK_O=79, //O
VK_P=80, //P
VK_Q=81, //Q
VK_R=82, //R
VK_S=83, //S
VK_T=84, //T
VK_U=85, //U
VK_V=86, //V
VK_W=87, //W
VK_X=88, //X
VK_Y=89, //Y
VK_Z=90, //Z
VK_NUMPAD0=96, //0
VK_NUMPAD1=97, //1
VK_NUMPAD2=98, //2
VK_NUMPAD3=99, //3
VK_NUMPAD4=100, //4
VK_NUMPAD5=101, //5
VK_NUMPAD6=102, //6
VK_NUMPAD7=103, //7
VK_NUMPAD8=104, //8
VK_NUMPAD9=105, //9
   VK_NULTIPLY=106,  //数字键盘上的*
    VK_ADD=107,    //数字键盘上的+
   VK_SEPARATOR=108, //可选
   VK_SUBTRACT=109,  //数字键盘上的-
   VK_DECIMAL=110,  //数字键盘上的.
   VK_DIVIDE=111,   //数字键盘上的/
VK_F1=112,
VK_F2=113,
VK_F3=114,
VK_F4=115,
VK_F5=116,
VK_F6=117,
VK_F7=118,
VK_F8=119,
VK_F9=120,
VK_F10=121,
VK_F11=122,
VK_F12=123,
VK_NUMLOCK=144,  //Num Lock
   VK_SCROLL=145   // Scroll Lock
}
}
}

这个就是原码,你创建一个类文件复制进去编译一下就可以了


www. 我的原创下载
2007-07-20 23:05
dreamsfly
Rank: 2
等 级:论坛游民
帖 子:152
专家分:13
注 册:2007-6-29
得分:0 

这个类,封装了2个方式,一种是系统api[user32.dll]文件,调用方式
key kk = new key();
kk.send(key.VirtualKeys.VK_F1,GetState(key.VirtualKeys.VK_F1));

这是模拟键盘的F1.

这是模拟键盘的winio调用方式
key kk = new key();
// IntPtr a = new IntPtr();
kk.sendwinio();
kk.MykeyDown((int)key.VirtualKeys.VK_F1);
System.Threading.Thread.Sleep(2000);
kk.MykeyUp((int)key.VirtualKeys.VK_F1);

也是模拟f1,之间的差别就是,winio调用方式能穿透一部分游戏,达到一部分外挂的效果.


www. 我的原创下载
2007-07-20 23:15
dreamsfly
Rank: 2
等 级:论坛游民
帖 子:152
专家分:13
注 册:2007-6-29
得分:0 
这是读取内存地址的方法
getread("进程名称","","内存基址",0)

本来这个类想写成外挂专用类,但是最近工作忙,没时间写。
有些地方写的还不好。暂时能用

www. 我的原创下载
2007-07-20 23:20
lileifeng
Rank: 1
等 级:新手上路
帖 子:12
专家分:0
注 册:2007-6-26
得分:0 

牛人!!佩服你。。。
小弟学的很初级,看不懂!!!

2007-07-24 02:26
guoxhvip
Rank: 8Rank: 8
来 自:聖西羅南看臺
等 级:贵宾
威 望:44
帖 子:4052
专家分:135
注 册:2006-10-8
得分:0 
LZ强 顶了

愛生活 && 愛編程
2007-07-24 05:09
白菜粉条
Rank: 1
等 级:新手上路
帖 子:76
专家分:0
注 册:2007-5-25
得分:0 

不错,看看!


我不是不想不郁闷,台湾问题没有解决啊!
2007-07-24 09:56
botailang
Rank: 1
等 级:新手上路
帖 子:77
专家分:0
注 册:2007-4-13
得分:0 

佩服lz
支持一下!


笨人多福
2007-07-24 10:15
随风逐流
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:passerby
等 级:版主
威 望:8
帖 子:4054
专家分:271
注 册:2007-6-13
得分:0 

顶了,问下楼住,很早以前我就知道游戏中的血量和蓝的内存地址都是动态的,可否做个抓这两个内存的方法?顺便解释一下可否?


[url=http://www./html/6/6694/]极道金丹[/url][url=http://www./html/2/2849/]九阴九阳[/url][url=http://www./html/2/2596/]凡人修仙传[/url]
2007-07-24 10:31



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-153959-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023405 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved