原文:C# 实现对接电信交费易自动缴费 续(winio/winring0 自动填密码)

自动填密码大家可能都不莫生,最有名的应该是 按键精灵 只要是一个可以输入的地方都可以能过按键精灵来完成输入.我今天要讲的是使用 winio/winring0来完成类似的功能

如果要自动填充密码方式基本上有 消息级的模拟 和 驱动级的模拟,

消息级的模拟如 C# 直接使用 SendKeys 就可以完成 API下可以使用 SendMessage完成 即有了这个神器为什么还要用三方?

答案:现在一些网都使用了ActiveX安全插件,如网银,支付宝,等,还有我们上一次说到的 翼支付和手机支付 它们基本上屏蔽了 SendMessage 有些就算可以使用但是不能得到正确的加密数据.还有更可气的是 在服务器远程操作中手动输入都不能输入密码.

驱动级的就是硬盘的模拟 模拟键盘,大牛们可以直接操作  I/O 我这里讲的是使用三方类库来完成,

第一个是 winIO 在XP时候我一直使用它,但到了  win7+64位模式下使用有点小问题,winIO 64位下驱动数字签名有点问题不能直接运行,需要将 win7转到测试模式下,安装数字证书而用程序还要在测试模式使用,如果是自己有可以凑合着,如果是给客户去使用,客户绝对会说你脑残,我运行个程序还要调这调那,当然是不愿意了.

我现在就以 32位模式下来演示如何使用 winIO,首先是下载winIO 最新版本为 3.0 网官下载地址 http://www.internals.com/

解压后,得到上图所示的文件 这个地方有用的 就是最后4个文件其它的是源文件和例子帮助文件之类的,

跟据系统的不同来使用不同的文件 如果是  32位的就使用32结尾的两个.呵呵 直接把这两个放到你开发目录下的 bin/release 或 bin/debug下面就行了

然后就是调用

 public class WinIO {
public const int KBC_KEY_CMD = 0x64;//输入键盘按下消息的端口 public const int KBC_KEY_DATA = 0x60;//输入键盘弹起消息的端口 [DllImport("WinIo32.dll")]
public static extern bool InitializeWinIo(); [DllImport("WinIo32.dll")]
public static extern bool GetPortVal(IntPtr wPortAddr, out int pdwPortVal, byte bSize); [DllImport("WinIo32.dll")]
public static extern bool SetPortVal(uint wPortAddr, IntPtr dwPortVal, byte bSize); [DllImport("WinIo32.dll")]
public static extern byte MapPhysToLin(byte pbPhysAddr, uint dwPhysSize, IntPtr PhysicalMemoryHandle); [DllImport("WinIo32.dll")]
public static extern bool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, byte pbLinAddr); [DllImport("WinIo32.dll")]
public static extern bool GetPhysLong(IntPtr pbPhysAddr, byte pdwPhysVal); [DllImport("WinIo32.dll")]
public static extern bool SetPhysLong(IntPtr pbPhysAddr, byte dwPhysVal); [DllImport("WinIo32.dll")]
public static extern void ShutdownWinIo(); [DllImport("user32.dll")]
public static extern int MapVirtualKey(uint Ucode, uint uMapType); private WinIO() {
IsInitialize = true;
}
public static void Initialize() {
if (InitializeWinIo()) {
KBCWait4IBE();
IsInitialize = true;
}
}
public static void Shutdown() {
if (IsInitialize)
ShutdownWinIo();
IsInitialize = false;
} private static bool IsInitialize { get; set; } ///等待键盘缓冲区为空
private static void KBCWait4IBE() {
int dwVal = ;
do {
bool flag = GetPortVal((IntPtr)0x64, out dwVal, );
}
while ((dwVal & 0x2) > );
}
/// 模拟键盘标按下
public static void KeyDown(Keys vKeyCoad) {
if (!IsInitialize) return; int btScancode = ;
btScancode = MapVirtualKey((uint)vKeyCoad, );
KBCWait4IBE();
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, );
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)0x60, );
KBCWait4IBE();
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, );
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, );
}
/// 模拟键盘弹出
public static void KeyUp(Keys vKeyCoad) {
if (!IsInitialize) return; int btScancode = ;
btScancode = MapVirtualKey((uint)vKeyCoad, );
KBCWait4IBE();
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, );
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)0x60, );
KBCWait4IBE();
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, );
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode | 0x80), );
}
}

上面这个类也是网上搜出来的,感觉前辈们的分享.此处只模拟了键盘的 按下和弹起

使用实例

 String pass = "";
foreach (char chr in pass) {
WinIO.KeyDown((Keys)chr);
Thread.CurrentThread.Join();
WinIO.KeyUp((Keys)chr);
Thread.CurrentThread.Join();
}
Thread.CurrentThread.Join();
WinIO.Shutdown();

这个地方按下的时候,稍停下,弹起也一样
这样的话 winIO 的调用就完成了

另一个神器就是 WinRing0 这个是一个开源的项目,可以通杀 32 64位系统, 不需要为驱动安装数字签名,自从发现了这个以后,我所有的需要自动填密码的项目都使用了它

虽说开源,但是这个在网上的使用文档还是比较少,有的都是自带的一些文档和使用实例没有特殊意义的例子,说实话,这项目的找了好久才找到下载地址,大家如需要就留个邮箱,

我看到后就发给你

我们打开 release目录,

复制相关的文件到你的工作开发目录下.

source\sample\Cs\OpenLibSys.cs 找到这个cs文件,这个是官方的所有的功能的封装,包括 I/O PCI CPU 等操作.把它加到我们的工程项目中

新建一个类 WinRing 代码如下

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using OpenLibSys; class WinRing { public enum Key {
ABSOLUTE = 0x8000,
LEFTDOWN = ,
LEFTUP = ,
MIDDLEDOWN = 0x20,
MIDDLEUP = 0x40,
MOVE = ,
RIGHTDOWN = ,
RIGHTUP = 0x10,
VIRTUALDESK = 0x4000,
VK_A = 0x41,
VK_ADD = 0x6b,
VK_B = 0x42,
VK_BACK = ,
VK_C = 0x43,
VK_CANCEL = ,
VK_CAPITAL = ,
VK_CLEAR = ,
VK_CONTROL = 0x11,
VK_D = 0x44,
VK_DECIMAL = ,
VK_DELETE = 0x2e,
VK_DIVIDE = 0x6f,
VK_DOWN = ,
VK_E = 0x45,
VK_END = 0x23,
VK_ESCAPE = 0x1b,
VK_EXECUTE = 0x2b,
VK_F = ,
VK_F1 = 0x70,
VK_F10 = 0x79,
VK_F11 = 0x7a,
VK_F12 = 0x7b,
VK_F2 = 0x71,
VK_F3 = 0x72,
VK_F4 = 0x73,
VK_F5 = 0x74,
VK_F6 = 0x75,
VK_F7 = 0x76,
VK_F8 = 0x77,
VK_F9 = ,
VK_G = 0x47,
VK_H = 0x48,
VK_HELP = 0x2f,
VK_HOME = 0x24,
VK_I = 0x49,
VK_INSERT = 0x2d,
VK_J = 0x4a,
VK_K = 0x4b,
VK_L = 0x4c,
VK_LBUTTON = ,
VK_LEFT = 0x25,
VK_M = 0x4d,
VK_MBUTTON = ,
VK_MENU = 0x12,
VK_N = 0x4e,
VK_NEXT = 0x22,
VK_NULTIPLY = 0x6a,
VK_NUM0 = 0x30,
VK_NUM1 = 0x31,
VK_NUM2 = ,
VK_NUM3 = 0x33,
VK_NUM4 = 0x34,
VK_NUM5 = 0x35,
VK_NUM6 = 0x36,
VK_NUM7 = 0x37,
VK_NUM8 = 0x38,
VK_NUM9 = 0x39,
VK_NUMLOCK = 0x90,
VK_NUMPAD0 = 0x60,
VK_NUMPAD1 = 0x61,
VK_NUMPAD2 = 0x62,
VK_NUMPAD3 = 0x63,
VK_NUMPAD4 = ,
VK_NUMPAD5 = 0x65,
VK_NUMPAD6 = 0x66,
VK_NUMPAD7 = 0x67,
VK_NUMPAD8 = 0x68,
VK_NUMPAD9 = 0x69,
VK_O = 0x4f,
VK_P = ,
VK_PAUSE = 0x13,
VK_PRINT = 0x2a,
VK_PRIOR = 0x21,
VK_Q = 0x51,
VK_R = 0x52,
VK_RBUTTON = ,
VK_RETURN = ,
VK_RIGHT = 0x27,
VK_S = 0x53,
VK_SCROLL = 0x91,
VK_SELECT = 0x29,
VK_SEPARATOR = 0x6c,
VK_SHIFT = 0x10,
VK_SNAPSHOT = 0x2c,
VK_SPACE = 0x20,
VK_SUBTRACT = 0x6d,
VK_T = 0x54,
VK_TAB = ,
VK_U = 0x55,
VK_UP = 0x26,
VK_V = 0x56,
VK_W = 0x57,
VK_X = 0x58,
VK_Y = 0x59,
VK_Z = ,
WHEEL = 0x800,
XDOWN = 0x80,
XUP = 0x100
} static OpenLibSys.Ols ols = null; [DllImport("user32.dll")]
public static extern int MapVirtualKey(uint Ucode, uint uMapType); public static Boolean init() {
ols = new OpenLibSys.Ols();
return ols.GetStatus() == (uint)Ols.Status.NO_ERROR;
} private static void KBCWait4IBE() {
byte dwVal = ;
do {
ols.ReadIoPortByteEx(0x64, ref dwVal);
}
while ((dwVal & 0x2) > );
}
public static void KeyDown(Char ch) {
int btScancode = MapVirtualKey((uint)(Key)ch, );
KBCWait4IBE();
ols.WriteIoPortByte(0x64, 0xd2);
KBCWait4IBE();
ols.WriteIoPortByte(0x60, (byte)btScancode);
} public static void KeyUp(Char ch) {
int btScancode = MapVirtualKey((uint)(Key)ch, );
KBCWait4IBE();
ols.WriteIoPortByte(0x64, 0xd2);
KBCWait4IBE();
ols.WriteIoPortByte(0x60, (byte)(btScancode | 0x80));
}
}

也只是模拟了 按下和弹起 以下为调用方式

String pwd = "";
foreach (char chr in pwd) {
WinRing.init();
WinRing.KeyDown(chr);
Thread.Sleep();
WinRing.KeyUp(chr);
}
Thread.CurrentThread.Join();

到此 这两个类库的使用就介绍完了,但是在真正项目中可能会遇到各种问题,这就需我们的经验和处理问题的能力了.

注:这两个类库有一个通病就是不支持 USB键盘的模拟.估计是我没有研究出来吧

--幸福海

博客地址:http://www.cnblogs.com/ningqhai/

C# 实现对接电信交费易自动缴费 续(winio/winring0 自动填密码)的更多相关文章

  1. C# 实现对接电信交费易自动缴费

    他有这样一个JS PassGuardCtrl.js 部分代码    1 defaults:{  2             obj:null,  3             random:null,/ ...

  2. Eureka 系列(08)心跳续约与自动过期

    Eureka 系列(08)心跳续约与自动过期 [TOC] Spring Cloud 系列目录 - Eureka 篇 在上一篇 Eureka 系列(07)服务注册与主动下线 中对服务的注册与下线进行了分 ...

  3. freeswitch对接电信线路VOLTE视频通话

    在public.xml上设置视频编码: <action application="export" data="nolocal:absolute_codec_stri ...

  4. MRCPv2在电信智能语音识别业务中的应用

    1. MRCPv2协议简介 媒体资源控制协议(Media Resource Control Protocol, MRCP)是一种基于TCP/IP的通讯协议,用于客户端向媒体资源服务器请求提供各种媒体资 ...

  5. 生信云实证Vol.12:王者带飞LeDock!开箱即用&一键定位分子库+全流程自动化,3.5小时完成20万分子对接

    LeDock是苏黎世大学Zhao HongTao在博士期间开发的一款分子对接软件,专为快速准确地将小分子灵活对接到蛋白质而设计.LeDock优于大部分商业软件,在Astex多样性集合上实现了大于90% ...

  6. 那些年,我们开发的接口之:QQ登录(OAuth2.0)

    那些年,我们开发的接口之:QQ登录(OAuth2.0) 吴剑 2013-06-14 原创文章,转载必须注明出处:http://www.cnblogs.com/wu-jian 前言 开发这些年,做过很多 ...

  7. Immutable Object模式

    多线程共享变量的情况下,为了保证数据一致性,往往需要对这些变量的访问进行加锁.而锁本身又会带来一些问题和开销.Immutable Object模式使得我们可以在不使用锁的情况下,既保证共享变量访问的线 ...

  8. QQ登录(OAuth2.0)

    QQ登录(OAuth2.0) 那些年,我们开发的接口之:QQ登录(OAuth2.0) 吴剑 2013-06-14 原创文章,转载必须注明出处:http://www.cnblogs.com/wujian ...

  9. 群晖NAS再折腾

    端口转发 两年前我买了一台双盘位的群晖NAS,配置两个4T的硬盘,这玩意儿一度改变了我使用电脑的模式,真是爽爆了!最最主要的功能就是我能用它规整我所有的资料,并且不管何时何地,只要有网就能访问.为了能 ...

随机推荐

  1. 【原创】leetCodeOj ---Remove Duplicates from Sorted List II 解题报告

    明日深圳行,心情紧张,写博文压压惊 囧 ------------------------------------- 原题地址: https://oj.leetcode.com/problems/rem ...

  2. Android RxJava使用介绍(三) RxJava的操作符

    上一篇文章已经具体解说了RxJava的创建型操作符.本片文章将继续解说RxJava操作符.包括: Transforming Observables(Observable的转换操作符) Filterin ...

  3. Codeforces 484E Sign on Fence(是持久的段树+二分法)

    题目链接:Codeforces 484E Sign on Fence 题目大意:给定给一个序列,每一个位置有一个值,表示高度,如今有若干查询,每次查询l,r,w,表示在区间l,r中, 连续最长长度大于 ...

  4. OA项目设计的能力③

    1.然后来了一个,写在我们的主要要求之一,有回波数据还需要添加的方法,我们需要知道,事实上,页被传递id演出id通讯实体name,所以想要回显就是须要得到privilegeIds,假设像上一篇在jsp ...

  5. Net中的反应式编程

    Net中的反应式编程(Reactive Programming)   系列主题:基于消息的软件架构模型演变 一.反应式编程(Reactive Programming) 1.什么是反应式编程:反应式编程 ...

  6. PHP制作pdf文档方法

    原文:PHP制作pdf文档方法 本篇博客是在看完 php+mysql web书以后自己的测试代码,虽然是测试代码,但不是简单的粘贴复制,为了学习thinkPHP框架,自己就用这个来做的,而且这本书已经 ...

  7. hdu 5030 Rabbit&#39;s String(后缀数组&amp;二分法)

    Rabbit's String Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  8. 红帽/CentOS ext4无法格式化大分区 补充ext4格式化方式

    普通情况下,XFS出现丢数据的情况为海量小文件IO场景.在该场景下,inode占用教大. 通过上文的方式进行格式化,inode数量较小.通过大量測试,能够使用例如以下方法提升mkfs.ext4后文件系 ...

  9. MySQL列:innodb的源代码的分析的基础数据结构

    在过去的一年中的数据库相关的源代码分析.前段时间分析levelDB实施和BeansDB实现,数据库网络分析这两篇文章非常多.他们也比较深比较分析,所以没有必要重复很多劳力.MYSQL,当然主要还是数据 ...

  10. [DEEP LEARNING An MIT Press book in preparation]Linear algebra

    线性代数是数学的一个重要分支,它经常被施加到project问题,要了解学习和工作深入研究的深度,因此,对于线性代数的深刻理解是非常重要的.下面是我总结的距离DL book性代数中抽取出来的比較有意思的 ...