首页 > 技术文章 > winIO介绍

WoodHower 2021-06-04 16:43 原文

WinIO程序库允许在32位的Windows应用程序中直接对I/O端口和物理内存进行存取操作。通过使用一种内核模式的设备驱动器和其它几种底层编程技巧,它绕过了Windows系统的保护机制。

 

因为需要加载驱动,程序要以管理员权限运行,已经在win10 64验证成功

为了省去动态加载DLL,再动态获取函数地址去调用的麻烦,用官方的DLL源码,编译生成WinIo.lib

 

现在介绍64bit平台32位应用程序IO操作

二、WinIo64.sys签名

官方有说到:64位版本的Windows只加载设备驱动程序,这些驱动程序由一个公共CA签发的代码签名证书签署,如Verisign、Thawte等。WinIo64 除非获得了代码签名证书,否则系统不能部署在生产机器上。

1.开启测试模式

 

 

  • Open an elevated command window by right-clicking the icon and clicking "Run as Administrator".(管理员模式运行CMD)

     

  • Type the following command to enable test-signing:(输入以下命令开启测试模式)

bcdedit.exe /set TESTSIGNING ON
 
      • Reboot the machine (重启)
      •  

      • 从以上可知,winIO对64bit平台支持并不好。必须要在测试模式下才能用。现在都win10了还没改善,显得特别鸡肋。对端口的读取可以尝试内联汇编。

      • 2.安装winIO64.sys

      • 简单点就是开启测试模式,然后安装WinIo64.sys的测试签名
        1.打开 WinIO64.sys的属性框,翻到“数字签名”选项卡,点击“详细信息”
        2.在新出来的对话框中点击“查看证书”
        3.在又新出来的对话框中点击“安装证书”
        4.点击“下一步”,然后选择“将所有的证书放入下列存储”
        5.点击浏览,选择“受信任的根证书发布机构”

        三、编译winIO.lib

        1.由于winIO源代码用到了_inp等函数,而这些函数在VS2015后又不支持了,所以用VS2013以下去编译

         

        2.得到WinIo32.dll,WinIo32.lib,WinIo64.dll,WinIo64.lib

        如果是64bit平台32应用程序,就用WinIo32.dll,WinIo32.lib,WinIo64.sys

        3.提取头文件

        C:\Users\pc\Desktop\WinIo\Source\Dll\winio.h
        C:\Users\pc\Desktop\WinIo\Source\Drv\winio_nt.h
        [cpp] view plain copy
         
         print?
        1. C:\Users\pc\Desktop\WinIo\Source\Dll\winio.h  
        2. #ifndef WINIO_H  
        3. #define WINIO_H  
        4.   
        5.   
        6. <span style="background-color: rgb(255, 255, 255);">//#include "..\drv\winio_nt.h"//修改如下,然后把winio_nt.h跟winio.h放到一起  
        7.   
        8. #include "winio_nt.h"</span>  
        9.   
        10. #ifndef WINIO_DLL  
        11. #define WINIO_API _declspec(dllimport)  
        12. #else  
        13. #define WINIO_API   
        14. #endif  
        15.   
        16.   
        17. extern "C"  
        18. {  
        19.   WINIO_API bool _stdcall InitializeWinIo();  
        20.   WINIO_API void _stdcall ShutdownWinIo();  
        21.   WINIO_API PBYTE _stdcall MapPhysToLin(tagPhysStruct &PhysStruct);  
        22.   WINIO_API bool _stdcall UnmapPhysicalMemory(tagPhysStruct &PhysStruct);  
        23.   WINIO_API bool _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal);  
        24.   WINIO_API bool _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal);  
        25.   WINIO_API bool _stdcall GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);  
        26.   WINIO_API bool _stdcall SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);  
        27.   WINIO_API bool _stdcall InstallWinIoDriver(PWSTR pszWinIoDriverPath, bool IsDemandLoaded = false);  
        28.   WINIO_API bool _stdcall RemoveWinIoDriver();  
        29. }  
        30.   
        31.   
        32. extern HANDLE hDriver;  
        33. extern bool IsWinIoInitialized;  
        34. extern bool g_Is64BitOS;  
        35.   
        36.   
        37. bool _stdcall StartWinIoDriver();  
        38. bool _stdcall StopWinIoDriver();  
        39.   
        40.   
        41. #endif  

        四、案例

        1.源代码,管理员模式

        WinIo32.dll,WinIo32.lib,winio.h,winio_nt.h放到编译根目录
         
        [cpp] view plain copy
         
         print?
        1. #include "stdafx.h"  
        2.   
        3.   
        4. #include <windows.h>  
        5.   
        6.   
        7. #include "winio.h"               //winio头文件  
        8. #pragma comment(lib,"winio32.lib")  //包含winio库  
        9.   
        10.   
        11. void main(void)  
        12. {  
        13.       
        14.    
        15.       
        16.        
        17.     unsigned short BASE = 0x71;  
        18.     int iPort = 2;  
        19.     // 初始化WinIo    
        20.     if (!InitializeWinIo())      
        21.     {    
        22.         printf( "Error In InitializeWinIo!\n");  
        23.     exit(1);  
        24.     }  
        25.     int DI_data;  
        26.      DWORD *p=new DWORD;  
        27.   
        28.   
        29.      DI_data = GetPortVal(BASE+iPort,p,4);  
        30.     printf("return value= %d\n", DI_data);  
        31.     printf("receives the value obtained from the port= %x\n", *p);  
        32.        
        33.     ShutdownWinIo();  //关闭WinIo    
        }

        2.运行

        WinIo32.dll,WinIo64.sys放到程序根目录

         
         

         

推荐阅读