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 = 0;
            do {
                bool flag = GetPortVal((IntPtr)0x64, out dwVal, 1);
            }
            while ((dwVal & 0x2) > 0);
        }
        /// 模拟键盘标按下
        public static void KeyDown(Keys vKeyCoad) {
            if (!IsInitialize) return;

            int btScancode = 0;
            btScancode = MapVirtualKey((uint)vKeyCoad, 0);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_DATA, (IntPtr)0x60, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);
        }
        /// 模拟键盘弹出
        public static void KeyUp(Keys vKeyCoad) {
            if (!IsInitialize) return;

            int btScancode = 0;
            btScancode = MapVirtualKey((uint)vKeyCoad, 0);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_DATA, (IntPtr)0x60, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode | 0x80), 1);
        }
    }

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

使用实例

 String pass = "123456";
        foreach (char chr in pass) {
            WinIO.KeyDown((Keys)chr);
            Thread.CurrentThread.Join(100);
            WinIO.KeyUp((Keys)chr);
            Thread.CurrentThread.Join(100);
        }
        Thread.CurrentThread.Join(100);
        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 = 2,
        LEFTUP = 4,
        MIDDLEDOWN = 0x20,
        MIDDLEUP = 0x40,
        MOVE = 1,
        RIGHTDOWN = 8,
        RIGHTUP = 0x10,
        VIRTUALDESK = 0x4000,
        VK_A = 0x41,
        VK_ADD = 0x6b,
        VK_B = 0x42,
        VK_BACK = 8,
        VK_C = 0x43,
        VK_CANCEL = 3,
        VK_CAPITAL = 20,
        VK_CLEAR = 12,
        VK_CONTROL = 0x11,
        VK_D = 0x44,
        VK_DECIMAL = 110,
        VK_DELETE = 0x2e,
        VK_DIVIDE = 0x6f,
        VK_DOWN = 40,
        VK_E = 0x45,
        VK_END = 0x23,
        VK_ESCAPE = 0x1b,
        VK_EXECUTE = 0x2b,
        VK_F = 70,
        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 = 120,
        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 = 1,
        VK_LEFT = 0x25,
        VK_M = 0x4d,
        VK_MBUTTON = 4,
        VK_MENU = 0x12,
        VK_N = 0x4e,
        VK_NEXT = 0x22,
        VK_NULTIPLY = 0x6a,
        VK_NUM0 = 0x30,
        VK_NUM1 = 0x31,
        VK_NUM2 = 50,
        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 = 100,
        VK_NUMPAD5 = 0x65,
        VK_NUMPAD6 = 0x66,
        VK_NUMPAD7 = 0x67,
        VK_NUMPAD8 = 0x68,
        VK_NUMPAD9 = 0x69,
        VK_O = 0x4f,
        VK_P = 80,
        VK_PAUSE = 0x13,
        VK_PRINT = 0x2a,
        VK_PRIOR = 0x21,
        VK_Q = 0x51,
        VK_R = 0x52,
        VK_RBUTTON = 2,
        VK_RETURN = 13,
        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 = 9,
        VK_U = 0x55,
        VK_UP = 0x26,
        VK_V = 0x56,
        VK_W = 0x57,
        VK_X = 0x58,
        VK_Y = 0x59,
        VK_Z = 90,
        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 = 0;
        do {
            ols.ReadIoPortByteEx(0x64, ref dwVal);
        }
        while ((dwVal & 0x2) > 0);
    }
    public static void KeyDown(Char ch) {
        int btScancode = MapVirtualKey((uint)(Key)ch, 0);
        KBCWait4IBE();
        ols.WriteIoPortByte(0x64, 0xd2);
        KBCWait4IBE();
        ols.WriteIoPortByte(0x60, (byte)btScancode);
    }

    public static void KeyUp(Char ch) {
        int btScancode = MapVirtualKey((uint)(Key)ch, 0);
        KBCWait4IBE();
        ols.WriteIoPortByte(0x64, 0xd2);
        KBCWait4IBE();
        ols.WriteIoPortByte(0x60, (byte)(btScancode | 0x80));
    }
}

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

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

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

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

--幸福海

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

时间: 2024-07-31 02:10:47

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

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

他有这样一个JS PassGuardCtrl.js 部分代码 1 defaults:{ 2             obj:null, 3             random:null,//随机因子数 4             hidPwdName:'password',//隐藏密码框名字,用来保存加密后的密码值 5             outInputClass:'',//要把密码输入框写到的位置 6             params:{//附加属性,可选 7          

成为最有价值的汽车网站,易车还差点什么

日前,国内大数据服务提供商"缔元信?网络数据"发布<垂直网站转型及价值评估研究>报告.报告根据网站发展的新阶段,摒弃了传统的以浏览量.访问用户.浏览时长等为核心指标的网站价值评估体系,首次提出涵盖精准用户数.转化用户数.交易用户数三大指标的垂直网站价值评估新标准.新标准的推出符合网站发展到更高级阶段的新形势,更加科学.合理. 报告中,汽车网站易车与旅游网站携程.房产网站搜房一起,被缔元信援引为新标准下网站价值的典范.依据新标准的三项指标,汽车网站的精准用户数即查询报价用户数

易语言 为别人软件加入广告或者密码(特别思路)

洪雨的的这款软件比较奇特,是忽然想到一个思路,然后实现了一下. exe文件都有一个很有趣的地方,只要内部完整,就可以运行. 比如一个exe文件,我们运行的时候,电脑知道他是exe所以可以直接运行. 假如洪雨将它换一下扩展名,变成“.jpg”图片文件. 那么电脑就会认为这是一个jpg图片文件,然后当作图片文件来运行,我们会看到无法显示的图片文件. 但是内部还是exe的完整代码. 易语言可以直接执行这个jpg文件,我们用命令强行让电脑用exe方法运行就可以了. 这样子,我们就能达到一种伪装加壳运行的

[易飞]易飞-日常管理小工具

1.易飞9.X审核元, 作用:审核元件异常替换组件 下载:http://download.csdn.net/detail/david_520042/7177295 2.数据库管理工具. 作用:触发器,存储过程,视图,函数批量查询,批量禁用启用. 下载:http://download.csdn.net/detail/david_520042/7716395 3.easyflow表单提醒 作用:需要审核的表单,运行之后自动提醒. 下载:http://download.csdn.net/detail/

如何设置电信光猫?图解手把手教你(超级详细)

自从电信升级成光纤之后,光猫经常有点小问题的,如果电信说帮你设置好漫天要价的话,求人还不如求自己,或者电信送的光猫坏了,买他们的超贵,自己买一个又好又便宜的自己设置就的了 注意:2016年以后,电信为了他们所谓的利益,估计是想强制用户在他们哪里购买光猫.已经把原始超级密码恶意修改掉新光猫插上线路即刻被系统修改密码即telecomadmin加八位数的密码,如果你们一体光猫带路由需要改密码的,你们只能问他们电信告诉你们密码了,我们这里师傅告诉的,因为光猫属于用户终端,使用权知情权用户都有的.没有说强

【Zabbix】Zabbix对接AD域

zabbix对接AD域 需要的信息:一个域账号密码,使用的端口:域名 1. 先查看php是否安装了ldap模块php –m (查看已安装的php模块)若没有安装请参照我之前写的文章"在已编译安装的PHP环境下安装LDAP模块".2. LDAP用户:方法A.域通过zabbix管理员配置,需要知道域控的同名Admin账号的账号密码:方法B.已知某域控账号,有权限访问域控,可在zabbix上创建同名的账号,添加为"超级管理员".在zabbix页面上,选择"管理&

华为HCNA-初级网络基础

内容描述 本文摘自HCNA2网络基础知识,共包含五个Module,全面地介绍了构建一个基本的IP网络所涉及的各种主要技术,重点描述了交换.路由和网络服务等基础内容,以及这些内容如何在VRP上配置和实现的. Module 1系统地介绍了TCP/IP协议模型,侧重讲述了数据链路层.网络层和传输层的功能和作用,其主要目的是帮助读者加深对数据通信中"层次"的理解,并且熟悉和掌握数据在网络中的端到端传输过程. Module 2介绍了华为通用路由平台VRP的基础知识及其操作指导,主要包含了VRP的

500万已备好,亿万级会员红利也已开放

一卡易重磅推出的[会员+]开放平台将于7月1日正式启动,日前正在接受合作伙伴开发者奖励申请.我们已备好500万,放胆来拿! 十年磨一剑 今朝显锋芒 在互联网的冲击下,残酷的倒闭潮可谓一浪接一浪,而绝大多数的商家不是固守线下,就是盲目崇拜线上,无数的事实证明实体企业/商户只有将线上线下完美融合,两条腿走路才能实现真正的互联网+. 一卡易,作为业内唯一一家线上线下无缝打通的会员营销系统提供商,已深耕会员经济10年,拥有多个研发专利,在业内赢得了极高的品牌认可.尤其2016年以来,随着自助买单.小票红

Java多线程编程模式实战指南(二):Immutable Object模式--转载

本文由本人首次发布在infoq中文站上:http://www.infoq.com/cn/articles/java-multithreaded-programming-mode-immutable-object.转载请注明作者: 黄文海 出处:http://viscent.iteye.com. 多线程共享变量的情况下,为了保证数据一致性,往往需要对这些变量的访问进行加锁.而锁本身又会带来一些问题和开销.Immutable Object模式使得我们可以在不使用锁的情况下,既保证共享变量访问的线程安