赞
踩
目录
第一步:Windows系统开启测试模式(针对64位系统,32系统不需要)
第二步:WinIo64.sys安装签名(针对64位系统,32系统不需要)
开发环境:winxp、win7、win10 32位及64位
开发语言:Java和c++
必要文件:WinIo32.dll、WinIo64.dll、WinIo32.sys、WinIo64.sys
(注:有些步骤的详细做法非常简单,如果不明白请问度哥)
开启测试模式:cmd执行命令:bcdedit /set testsigning on 然后重启,电脑右下角出现测试模式......
关闭测试模式:cmd执行命令:bcdedit /set testsigning off 然后重启,电脑右下角测试模式消失
参考链接如下:
win10:https://jingyan.baidu.com/article/72ee561a724b74e16138df1c.html
win7、winxp:https://jingyan.baidu.com/article/acf728fd21c3e7f8e510a3ef.html
1、打开 WinIO64.sys的属性框,翻到“数字签名”选项卡,点击“详细信息”
2、在新出来的对话框中点击“查看证书”
3、在又新出来的对话框中点击“安装证书”
4、点击“下一步”,然后选择“将所有的证书放入下列存储”
5、点击浏览,选择“受信任的根证书发布机构”
6、点击“下一步”,然后点击“完成”
7、在弹出的“安全性警告”对话框中选择“是”,才能导入成功
8、重启电脑
网上有很多人使用jnative实现的,这里使用jna实现。jnative是在jna的基础上封装的有局限性。以下是maven依赖:
- <dependencies>
- <dependency>
- <groupId>net.java.dev.jna</groupId>
- <artifactId>jna</artifactId>
- <version>4.4.0</version>
- </dependency>
- <dependency>
- <groupId>net.java.dev.jna</groupId>
- <artifactId>jna-platform</artifactId>
- <version>4.4.0</version>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- <version>3.9</version>
- </dependency>
- </dependencies>

winio代码实现
- import com.sun.jna.Library;
- import com.sun.jna.Native;
- import com.sun.jna.Pointer;
- import com.sun.jna.WString;
- import com.sun.jna.win32.W32APIOptions;
-
- /**
- * author songxq
- * date 2020/6/18
- * description
- */
- public interface WinIo extends Library {
-
- /**
- * 系统架构32位或者64位
- */
- String ARCH = System.getProperty("os.arch");
- /**
- * 使用的winio版本
- */
- String WIN_IO_LIB_NAME = "x86".equals(ARCH) ? "WinIo32" : "WinIo64";
-
- WinIo INSTANCE = (WinIo) Native.loadLibrary(WIN_IO_LIB_NAME, WinIo.class, W32APIOptions.DEFAULT_OPTIONS);
-
- /**
- * PS/2键盘的命令端口
- */
- int CONTROL_PORT = 0x64;
- /**
- * PS/2键盘的数据端口
- */
- int DATA_PORT = 0x60;
-
- /**
- * 初始化winiolib库
- * @param path 驱动文件绝对路径
- * @return
- */
- boolean InitializeWinIo(WString path);
-
- /**
- * 释放资源及开辟的内存空间
- */
- void ShutdownWinIo();
-
- /**
- * 读数据
- * 98/ME系列使用GetPortVal NT/2000/XP系列可以使用_inp/_inpw/_inpd
- * @param portAddr io地址
- * @param pPortVal 指针变量
- * @param size 数据大小
- * @return
- */
- boolean GetPortVal(int portAddr, Pointer pPortVal, int size);
-
- /**
- * 写数据
- * @param portAddr io地址
- * @param portVal 指针变量
- * @param size 数据大小
- * @return
- */
- boolean SetPortVal(int portAddr, int portVal, int size);
- }

键盘调用代码
-
- import com.sun.jna.Memory;
- import com.sun.jna.Pointer;
- import com.sun.jna.WString;
-
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.nio.file.Files;
- import java.nio.file.Paths;
- import java.nio.file.StandardCopyOption;
-
- /**
- * author songxq
- * date 2020/6/18
- * description
- */
- public class VirtualKB {
-
- private static final WinIo WIN_IO = WinIo.INSTANCE;
-
- private static final String WIN_BASE_SYSTEM32 = "C:\\Windows\\System32";
-
- private static final String WINIO_INSTALL_PATH = "C:\\INSTALLWINIO";
-
- private static final String WINIO_INSTALL_EXE = "C:\\INSTALLWINIO\\InstallWinIo.exe";
-
- private static final String WIN_32_SYS = "WinIo32.sys";
-
- private static final String WIN_64_SYS = "WinIo64.sys";
-
- //keyame
- public static final String Tab = "Tab";
- public static final String Esc = "Esc";
- public static final String Backspace = "Backspace";
- public static final String Enter = "Enter";
- public static final String LCtrl = "LCtrl";
- public static final String LShift = "LShift";
- public static final String RShift = "RShift";
- public static final String LAlt = "LAlt";
- public static final String Space = "Space";
- public static final String CapsLock = "CapsLock";
- public static final String F1 = "F1";
- public static final String F2 = "F2";
- public static final String F3 = "F3";
- public static final String F4 = "F4";
- public static final String F5 = "F5";
- public static final String F6 = "F6";
- public static final String F7 = "F7";
- public static final String F8 = "F8";
- public static final String F9 = "F9";
- public static final String F10 = "F10";
- public static final String F11 = "F11";
- public static final String F12 = "F12";
- public static final String NumLock = "NumLock";
- public static final String ScrollLock = "ScrollLock";
-
-
- static{
- String x86 = "x86";
- String driverName;
- if (x86.equals(WinIo.ARCH)) {
- driverName = WIN_BASE_SYSTEM32 + File.separator + WIN_32_SYS;
- } else {
- driverName = WIN_BASE_SYSTEM32 + File.separator + WIN_64_SYS;
- }
- if(!WIN_IO.InitializeWinIo(new WString(driverName))){
- installSys();
- }
- }
-
- /**
- * 等待缓冲区置空
- */
- private static void KBCWait4IBE() {
- int val;
- do {
- Pointer p = new Memory(8);
- if (!WIN_IO.GetPortVal(WinIo.CONTROL_PORT, p, 1)) {
- throw new RuntimeException("Cannot Get The Port!");
- }
- val = p.getInt(0);
- } while ((0x2 & val) > 0);
- }
-
-
- private static void down(int key) {
- KBCWait4IBE();
- WIN_IO.SetPortVal(WinIo.CONTROL_PORT, 0xd2, 1);
- KBCWait4IBE();
- WIN_IO.SetPortVal(WinIo.DATA_PORT, key, 1);
- }
-
- private static void up(int key) {
- KBCWait4IBE();
- WIN_IO.SetPortVal(WinIo.CONTROL_PORT, 0xd2, 1);
- KBCWait4IBE();
- WIN_IO.SetPortVal(WinIo.DATA_PORT, (key | 0x80), 1);
- }
-
- private static void press(String[] words, long firstSleepTime, long sleepTime) throws Exception{
- if (null == words || words.length == 0) {
- throw new IllegalArgumentException("words Is NULL Or Empty");
- }
- int minSleepTime = 50;
- if (sleepTime < minSleepTime) {
- throw new IllegalArgumentException("SleepTime Less Than 50 ms");
- }
- if (firstSleepTime > 0) {
- Thread.sleep(firstSleepTime);
- }
- for (String word : words) {
- Integer vk = VirtualKBMapping.VK_MAP.get(word);
- if (null == vk) {
- vk = VirtualKBMapping.NEED_SHIFT_VK.get(word);
- }
- if (null == vk) {
- throw new RuntimeException(word + " Not Support");
- }
- boolean needShift = word.length() == 1 && null != VirtualKBMapping.NEED_SHIFT_VK.get(word);
- if (needShift) {
- down(VirtualKBMapping.VK_MAP.get("LShift"));
- }
- down(vk);
- Thread.sleep(sleepTime);
- up(vk);
- if (needShift) {
- up(VirtualKBMapping.VK_MAP.get("LShift"));
- }
- }
- }
-
- /**
- * 键盘输入文本
- * @param content 文本
- * @param sleepTime 等待时间间隔
- */
- public static void inputStr(String content,long sleepTime) throws Exception {
- if (null == content || content.length() == 0) {
- throw new IllegalArgumentException("content Is NULL Or Empty");
- }
- char[] chars = content.toCharArray();
- for (int i=0;i<chars.length;i++){
- press(new String[]{String.valueOf(chars[i])},sleepTime,50);
- }
- }
-
- /**
- * 键盘按键
- * @param keyname 按键名称
- * @param sleepTime 等待时间间隔
- */
- public static void pressKey(String keyname,long sleepTime) throws Exception {
- if (null == keyname || keyname.length() == 0) {
- throw new IllegalArgumentException("keyname Is NULL Or Empty");
- }
- press(new String[]{keyname},sleepTime,50);
- }
-
- private static void extract(final String fileName, final String name) {
- if (new File(fileName).exists()) {
- return;
- }
- try(InputStream inputStream = VirtualKB.class.getResourceAsStream("/" + name)) {
- Files.copy(inputStream, Paths.get(fileName), StandardCopyOption.REPLACE_EXISTING);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 执行sys驱动安装
- */
- public static void installSys() {
- if (!new File(WINIO_INSTALL_EXE).exists()) {
- if(!new File(WINIO_INSTALL_PATH).exists()){
- new File(WINIO_INSTALL_PATH).mkdirs();
- }
- extract(WINIO_INSTALL_EXE,"InstallWinIo.exe");
- }
- Runtime rn = Runtime.getRuntime();
- Process p = null;
- try {
- p = rn.exec(WINIO_INSTALL_EXE);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }

虚拟键盘映射代码
-
- import org.apache.commons.lang3.StringUtils;
-
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.Map;
-
- /**
- * author songxq
- * date 2020/6/18
- * description
- */
- public class VirtualKBMapping {
-
- /**
- * 映射基本键map
- */
- static final Map<String, Integer> VK_MAP = new HashMap<>();
-
- /**
- * 映射shift转换键map
- */
- static final Map<String, Integer> NEED_SHIFT_VK = new HashMap<>();
-
- static {
- VK_MAP.put("Esc", 0x01);
- VK_MAP.put("1", 0x02);
- VK_MAP.put("2", 0x03);
- VK_MAP.put("3", 0x04);
- VK_MAP.put("4", 0x05);
- VK_MAP.put("5", 0x06);
- VK_MAP.put("6", 0x07);
- VK_MAP.put("7", 0x08);
- VK_MAP.put("8", 0x09);
- VK_MAP.put("9", 0x0a);
- VK_MAP.put("0", 0x0b);
- VK_MAP.put("-", 0x0c);
- VK_MAP.put("=", 0x0d);
- VK_MAP.put("Backspace", 0x0e);
- VK_MAP.put("Tab", 0x0f);
- VK_MAP.put("q", 0x10);
- VK_MAP.put("w", 0x11);
- VK_MAP.put("e", 0x12);
- VK_MAP.put("r", 0x13);
- VK_MAP.put("t", 0x14);
- VK_MAP.put("y", 0x15);
- VK_MAP.put("u", 0x16);
- VK_MAP.put("i", 0x17);
- VK_MAP.put("o", 0x18);
- VK_MAP.put("p", 0x19);
- VK_MAP.put("[", 0x1a);
- VK_MAP.put("]", 0x1b);
- VK_MAP.put("Enter", 0x1c);
- VK_MAP.put("LCtrl", 0x1d);
- VK_MAP.put("a", 0x1e);
- VK_MAP.put("s", 0x1f);
- VK_MAP.put("d", 0x20);
- VK_MAP.put("f", 0x21);
- VK_MAP.put("g", 0x22);
- VK_MAP.put("h", 0x23);
- VK_MAP.put("j", 0x24);
- VK_MAP.put("k", 0x25);
- VK_MAP.put("l", 0x26);
- VK_MAP.put(";", 0x27);
- VK_MAP.put("'", 0x28);
- VK_MAP.put("`", 0x29);
- VK_MAP.put("LShift", 0x2a);
- VK_MAP.put("\\", 0x2b);
- VK_MAP.put("z", 0x2c);
- VK_MAP.put("x", 0x2d);
- VK_MAP.put("c", 0x2e);
- VK_MAP.put("v", 0x2f);
- VK_MAP.put("b", 0x30);
- VK_MAP.put("n", 0x31);
- VK_MAP.put("m", 0x32);
- VK_MAP.put(",", 0x33);
- VK_MAP.put(".", 0x34);
- VK_MAP.put("/", 0x35);
- VK_MAP.put("RShift", 0x36);
- VK_MAP.put("LAlt", 0x38);
- VK_MAP.put("Space", 0x39);
- VK_MAP.put("CapsLock", 0x3a);
- VK_MAP.put("F1", 0x3b);
- VK_MAP.put("F2", 0x3c);
- VK_MAP.put("F3", 0x3d);
- VK_MAP.put("F4", 0x3e);
- VK_MAP.put("F5", 0x3f);
- VK_MAP.put("F6", 0x40);
- VK_MAP.put("F7", 0x41);
- VK_MAP.put("F8", 0x42);
- VK_MAP.put("F9", 0x43);
- VK_MAP.put("F10", 0x44);
- VK_MAP.put("NumLock", 0x45);
- VK_MAP.put("ScrollLock", 0x46);
- VK_MAP.put("F11", 0x57);
- VK_MAP.put("F12", 0x58);
- }
-
- static {
- NEED_SHIFT_VK.put("!", 0x02);
- NEED_SHIFT_VK.put("@", 0x03);
- NEED_SHIFT_VK.put("#", 0x04);
- NEED_SHIFT_VK.put("$", 0x05);
- NEED_SHIFT_VK.put("%", 0x06);
- NEED_SHIFT_VK.put("^", 0x07);
- NEED_SHIFT_VK.put("&", 0x08);
- NEED_SHIFT_VK.put("*", 0x09);
- NEED_SHIFT_VK.put("(", 0x0a);
- NEED_SHIFT_VK.put(")", 0x0b);
- NEED_SHIFT_VK.put("_", 0x0c);
- NEED_SHIFT_VK.put("+", 0x0d);
- NEED_SHIFT_VK.put("{", 0x1a);
- NEED_SHIFT_VK.put("}", 0x1b);
- NEED_SHIFT_VK.put(":", 0x27);
- NEED_SHIFT_VK.put("\"", 0x28);
- NEED_SHIFT_VK.put("~", 0x29);
- NEED_SHIFT_VK.put("|", 0x2b);
- NEED_SHIFT_VK.put("<", 0x33);
- NEED_SHIFT_VK.put(">", 0x34);
- NEED_SHIFT_VK.put("?", 0x35);
- NEED_SHIFT_VK.put("Q", 0x10);
- NEED_SHIFT_VK.put("W", 0x11);
- NEED_SHIFT_VK.put("E", 0x12);
- NEED_SHIFT_VK.put("R", 0x13);
- NEED_SHIFT_VK.put("T", 0x14);
- NEED_SHIFT_VK.put("Y", 0x15);
- NEED_SHIFT_VK.put("U", 0x16);
- NEED_SHIFT_VK.put("I", 0x17);
- NEED_SHIFT_VK.put("O", 0x18);
- NEED_SHIFT_VK.put("P", 0x19);
- NEED_SHIFT_VK.put("A", 0x1e);
- NEED_SHIFT_VK.put("S", 0x1f);
- NEED_SHIFT_VK.put("D", 0x20);
- NEED_SHIFT_VK.put("F", 0x21);
- NEED_SHIFT_VK.put("G", 0x22);
- NEED_SHIFT_VK.put("H", 0x23);
- NEED_SHIFT_VK.put("J", 0x24);
- NEED_SHIFT_VK.put("K", 0x25);
- NEED_SHIFT_VK.put("L", 0x26);
- NEED_SHIFT_VK.put("Z", 0x2c);
- NEED_SHIFT_VK.put("X", 0x2d);
- NEED_SHIFT_VK.put("C", 0x2e);
- NEED_SHIFT_VK.put("V", 0x2f);
- NEED_SHIFT_VK.put("B", 0x30);
- NEED_SHIFT_VK.put("N", 0x31);
- NEED_SHIFT_VK.put("M", 0x32);
- }
-
- /**
- * 返回所有支持的按键
- */
- public static String[] getSupportKeys() {
- String[] vkArray = VK_MAP.keySet().toArray(new String[0]);
- String[] needShiftVKArray = NEED_SHIFT_VK.keySet().toArray(new String[0]);
- String[] supportKeys = new String[vkArray.length + needShiftVKArray.length];
- System.arraycopy(vkArray, 0, supportKeys, 0, vkArray.length);
- System.arraycopy(needShiftVKArray, 0, supportKeys, vkArray.length, needShiftVKArray.length);
- return supportKeys;
- }
-
- /**
- * 返回是否支持按键
- */
- public static boolean isSupportKey(String key) {
- return StringUtils.join(Arrays.asList(VirtualKBMapping.getSupportKeys()),"").contains(key);
- }
- }

c++装载驱动代码可以生成为dll文件调用,也可生成为exe文件调用。这里编译为exe。
注:生成dll文件及exe文件的时候一定生成64位的文件(32位系统不需要这个)。
- #include "stdafx.h"
-
- #include <windows.h>
- #include <winsvc.h>
- #include <conio.h>
- #include <stdio.h>
- #include <string.h>
- #include <tchar.h>
- #pragma comment (lib, "Advapi32.lib")
- #pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )
-
- #define DRIVER_NAME "WinIo64"
- #define DRIVER_PATH "C:\\Windows\\System32\\WinIo64.sys"
-
- //装载NT驱动程序
- BOOL LoadNTDriver(char* lpszDriverName, char* lpszDriverPath)
- {
- char szDriverImagePath[256];
- //得到完整的驱动路径
- GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);
-
- BOOL bRet = FALSE;
-
- SC_HANDLE hServiceMgr = NULL;//SCM管理器的句柄
- SC_HANDLE hServiceDDK = NULL;//NT驱动程序的服务句柄
-
- //打开服务控制管理器
- hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
-
- if (hServiceMgr == NULL)
- {
- //OpenSCManager失败
- printf("OpenSCManager() Faild ! \n");
- //printf(GetLastError());
- bRet = FALSE;
- goto BeforeLeave;
- }
- else
- {
- OpenSCManager成功
- printf("OpenSCManager() ok ! \n");
- }
-
- //创建驱动所对应的服务
- hServiceDDK = CreateService(hServiceMgr,
- lpszDriverName, //驱动程序的在注册表中的名字
- lpszDriverName, // 注册表驱动程序的 DisplayName 值
- SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限
- SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序
- SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值
- SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值
- szDriverImagePath, // 注册表驱动程序的 ImagePath 值
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
-
- DWORD dwRtn;
- //判断服务是否失败
- if (hServiceDDK == NULL)
- {
- dwRtn = GetLastError();
- if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS)
- {
- //由于其他原因创建服务失败
- printf("CrateService() Faild ! \n");
- ///printf(dwRtn);
- bRet = FALSE;
- goto BeforeLeave;
- }
- else
- {
- //服务创建失败,是由于服务已经创立过
- printf("CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n");
- }
-
- // 驱动程序已经加载,只需要打开
- hServiceDDK = OpenService(hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS);
- if (hServiceDDK == NULL)
- {
- //如果打开服务也失败,则意味错误
- dwRtn = GetLastError();
- printf("OpenService() Faild ! \n");
- //printf(dwRtn);
- bRet = FALSE;
- goto BeforeLeave;
- }
- else
- {
- printf("OpenService() ok ! \n");
- }
- }
- else
- {
- printf("CrateService() ok ! \n");
- }
-
- //开启此项服务
- bRet = StartService(hServiceDDK, NULL, NULL);
- if (!bRet)
- {
- DWORD dwRtn = GetLastError();
- if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING)
- {
- printf("StartService() Faild ! \n" );
- //printf(dwRtn);
- bRet = FALSE;
- goto BeforeLeave;
- }
- else
- {
- if (dwRtn == ERROR_IO_PENDING)
- {
- //设备被挂住
- printf("StartService() Faild ERROR_IO_PENDING ! \n");
- bRet = FALSE;
- goto BeforeLeave;
- }
- else
- {
- //服务已经开启
- printf("StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n");
- bRet = TRUE;
- goto BeforeLeave;
- }
- }
- }
- bRet = TRUE;
- //离开前关闭句柄
- BeforeLeave:
- if (hServiceDDK)
- {
- CloseServiceHandle(hServiceDDK);
- }
- if (hServiceMgr)
- {
- CloseServiceHandle(hServiceMgr);
- }
- return bRet;
- }
-
- //卸载驱动程序
- BOOL UnloadNTDriver(char * szSvrName)
- {
- BOOL bRet = FALSE;
- SC_HANDLE hServiceMgr = NULL;//SCM管理器的句柄
- SC_HANDLE hServiceDDK = NULL;//NT驱动程序的服务句柄
- SERVICE_STATUS SvrSta;
- //打开SCM管理器
- hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if (hServiceMgr == NULL)
- {
- //带开SCM管理器失败
- printf("OpenSCManager() Faild ! \n");
- //printf(GetLastError());
- bRet = FALSE;
- goto BeforeLeave;
- }
- else
- {
- //带开SCM管理器失败成功
- printf("OpenSCManager() ok ! \n");
- }
- //打开驱动所对应的服务
- hServiceDDK = OpenService(hServiceMgr, szSvrName, SERVICE_ALL_ACCESS);
-
- if (hServiceDDK == NULL)
- {
- //打开驱动所对应的服务失败
- printf("OpenService() Faild ! \n");
- //printf(GetLastError());
- bRet = FALSE;
- goto BeforeLeave;
- }
- else
- {
- printf("OpenService() ok ! \n");
- }
- //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。
- if (!ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrSta))
- {
- printf("ControlService() Faild %d !\n", GetLastError());
- }
- else
- {
- //打开驱动所对应的失败
- printf("ControlService() ok !\n");
- }
- //动态卸载驱动程序。
- if (!DeleteService(hServiceDDK))
- {
- //卸载失败
- printf("DeleteSrevice() Faild %d !\n", GetLastError());
- }
- else
- {
- //卸载成功
- printf("DelServer:eleteSrevice() ok !\n");
- }
- bRet = TRUE;
- BeforeLeave:
- //离开前关闭打开的句柄
- if (hServiceDDK)
- {
- CloseServiceHandle(hServiceDDK);
- }
- if (hServiceMgr)
- {
- CloseServiceHandle(hServiceMgr);
- }
- return bRet;
- }
-
-
- int main(int argc, char* argv[])
- {
- //加载驱动
- BOOL bRet = LoadNTDriver(DRIVER_NAME, DRIVER_PATH);
- if (!bRet)
- {
- printf("install winio error\n");
- return 0;
- }
- //加载成功
-
- //printf("install winio successed!\n");
- //getch();
-
-
- //这时候你可以通过注册表,或其他查看符号连接的软件验证。
- //printf("press any to unload the driver!\n");
- //getch();
-
- //卸载驱动
- //BOOL bRet = UnloadNTDriver(DRIVER_NAME);
- //if (!bRet)
- //{
- // printf("unload winio error!\n");
- // return 0;
- //}
- //printf("unload winio successed!\n");
- //return 0;
- }

大家按照上述代码都写好后就是执行了。有人可能成功了,有人可能还不行。所以下面介绍下这个代码基本的运行逻辑。供大家自行调整bug。
windows系统开启测试模式后,winio64.sys安装签名后。
执行代码:
1、***首先执行装载winio64.sys驱动代码,就是c++生成的dll或者exe文件里的LoadNTDriver方法。(这一步必须有,网上大部分没有这一步,所以大部分你试了都不会成功。)
2、执行winio的初始化方法 InitializeWinIo
3、KBCWait4IBE方法等待0x64控制端口空闲
4、0x64控制端口空闲时SetPortVal发送命令到0x64端口,在发送按键对应的虚拟码到0x60端口即可
5、winio.ShutdownWinIo释放资源
6、winio64.sys驱动加载后,系统重启后需要重新加载(注意)
以上即是本人实践总结,欢迎留言交流。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。