一、winIO介紹
WinIO程序庫允許在32位的Windows應用程序中直接對I/O端口和物理內存進行存取操作。通過使用一種內核模式的設備驅動器和其它幾種底層編程技巧,它繞過了Windows系統的保護機制。
WinIo可以到官方網站:http://www.internals.com/utilities_main.htm去下載,里面包含了幫助文檔和源碼。
因為需要加載驅動,程序要以管理員權限運行,已經在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.sys3.提取頭文件
C:\Users\pc\Desktop\WinIo\Source\Dll\winio.hC:\Users\pc\Desktop\WinIo\Source\Drv\winio_nt.h- C:\Users\pc\Desktop\WinIo\Source\Dll\winio.h
- #ifndef WINIO_H
- #define WINIO_H
- <span style="background-color: rgb(255, 255, 255);">//#include "..\drv\winio_nt.h"//修改如下,然后把winio_nt.h跟winio.h放到一起
- #include "winio_nt.h"</span>
- #ifndef WINIO_DLL
- #define WINIO_API _declspec(dllimport)
- #else
- #define WINIO_API
- #endif
- extern "C"
- {
- WINIO_API bool _stdcall InitializeWinIo();
- WINIO_API void _stdcall ShutdownWinIo();
- WINIO_API PBYTE _stdcall MapPhysToLin(tagPhysStruct &PhysStruct);
- WINIO_API bool _stdcall UnmapPhysicalMemory(tagPhysStruct &PhysStruct);
- WINIO_API bool _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal);
- WINIO_API bool _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal);
- WINIO_API bool _stdcall GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);
- WINIO_API bool _stdcall SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);
- WINIO_API bool _stdcall InstallWinIoDriver(PWSTR pszWinIoDriverPath, bool IsDemandLoaded = false);
- WINIO_API bool _stdcall RemoveWinIoDriver();
- }
- extern HANDLE hDriver;
- extern bool IsWinIoInitialized;
- extern bool g_Is64BitOS;
- bool _stdcall StartWinIoDriver();
- bool _stdcall StopWinIoDriver();
- #endif
四、案例
1.源代碼,管理員模式
WinIo32.dll,WinIo32.lib,winio.h,winio_nt.h放到編譯根目錄- #include "stdafx.h"
- #include <windows.h>
- #include "winio.h" //winio頭文件
- #pragma comment(lib,"winio32.lib") //包含winio庫
- void main(void)
- {
- unsigned short BASE = 0x71;
- int iPort = 2;
- // 初始化WinIo
- if (!InitializeWinIo())
- {
- printf( "Error In InitializeWinIo!\n");
- exit(1);
- }
- int DI_data;
- DWORD *p=new DWORD;
- DI_data = GetPortVal(BASE+iPort,p,4);
- printf("return value= %d\n", DI_data);
- printf("receives the value obtained from the port= %x\n", *p);
- ShutdownWinIo(); //關閉WinIo
2.運行
WinIo32.dll,WinIo64.sys放到程序根目錄
現在提供編譯好的lib庫和案例:http://download.csdn.net/detail/greless/9856752
http://blog.csdn.net/greless/article/details/72821876