代码改变世界

银行安全控件自动输入

  吴峰  阅读(1043)  评论(1编辑  收藏  举报

手里银行卡较多,经常忘记还信用卡,想做个应用自动查询银行卡余额。

在做网页自动登录时,碰到银行安全控件,控件屏蔽了windows的sendmessage和postmessage

 

只能求助winio,模拟最底层的按键

 

1. 下载winio

http://www.internals.com/utilities/WinIo.zip

 

2.安装数据签名证书

 

 

3. 打开windows的测试模式

  管理员模式在 cmd 下运行 bcdedit /set testsigning on

 

4. 代码

  导入方法

复制代码
[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;
            }
            else
                throw new Exception("Load WinIO Failed!");
        }

        public static void Shutdown()
        {
            if (IsInitialize)
                ShutdownWinIo();
            IsInitialize = false;
        }
复制代码

 

模拟键盘按下和弹起

复制代码
//等待键盘缓冲区为空
        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(0x64, (IntPtr)0xD2, 1); //发送准备写命令
            KBCWait4IBE();
            SetPortVal(0x60, (IntPtr)btScancode, 1); //写入按键
        }
        // 模拟键盘弹出
        public static void KeyUp(Keys vKeyCoad)
        {
            if (!IsInitialize) return;

            int btScancode = 0;
            btScancode = MapVirtualKey((uint)vKeyCoad, 0);
            KBCWait4IBE();
            SetPortVal(0x64, (IntPtr)0xD2, 1);
            KBCWait4IBE();
            SetPortVal(0x60, (IntPtr)(btScancode | 0x80), 1); //弹出
        }
复制代码

 

重要的事情说三遍

管理员运行

管理员运行

管理员运行

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示