搜尋

reWASD手把映射軟體遊戲修改器

返回清單
切換到指定樓層
通知這文章過時或找檔案 發表主題

[電玩遊戲] 《reWASD》驅動逆向分析與通訊架構整理 手把映射軟體底層運作原理

[複製連結]
1
ke910703 ( Lv.30 大天使 ) 發表於 3 小時前 | 只看該作者 回覆獎勵 |降序瀏覽 |閱讀模式

快速閱讀精華



  • reWASD 是一款專業級的遊戲控制器映射軟體,底層採用 雙重過濾驅動架構 實現硬體輸入攔截
  • 驅動 `xjn17hlp.sys` 同時具備 HID 裝置過濾NDIS 網路過濾 雙重身分
  • 核心技術亮點:所有設定檔必須經過 `rwsdcompiler.exe` 編譯成二進位格式,驅動不接受原始資料
  • 通訊管道採用 WCF 具名管道 + HTTP REST 雙層架構,具備嚴謹的會話驗證機制
  • 本整理涵蓋 IOCTL 定義、結構體、命令列舉等 使用者模式重建程式碼,供技術研究參考


前言:為什麼研究 reWASD 底層架構?



如果你曾經用過手把映射軟體調整按鍵配置,一定知道 reWASD 在這領域的知名度。但多數玩家只停留在「設定完能用就好」的階段,很少人探究它為什麼能穩定攔截幾乎所有控制器的輸入訊號。

這篇文章要帶你深入底層,看看這套軟體的專業之處——它不是簡單的應用程式層鉤子,而是實打實的 核心模式驅動過濾。我們透過逆向工程取得的第一手資訊,整理出這份技術分析,適合想理解控制器模擬驅動運作原理的開發者參考。

reWASD 雙重過濾驅動架構整理



第一層:HID 裝置過濾機制



reWASD 的驅動在 HID 子系統中插入了一個關鍵過濾點,攔截流程如下:

Physical HID Device → HID Minidriver → xjn17hlp.sys(reWASD Filter) → hidclass.sys


在這個位置,驅動能夠取得完整的 HID Report 原始資料。每個被附加的 HID 裝置都會在過濾裝置擴充區中建立 裝置上下文(Device Context),包含:

  • 按鍵狀態位元遮罩(Button state bitmask)
  • 虛擬控制器表指標(Virtual controller table pointer)
  • HID 報告長度(HID report lengtd)


第二層:NDIS 網路過濾機制



除了本機硬體輸入,reWASD 還處理網路層面的虛擬控制器流量。過濾點設在:

Network Adapter → xjn17hlp.sys → NDIS Stack


這讓軟體能夠支援 網路隧道傳輸的藍牙控制器 等進階應用場景。

HID Report 處理管線心得分享



輸入報告處理流程(sub_1400096D0)



主處理函數位於位址 `0x1400096D0`,處理遊戲控制器報告的重新映射:

  • HidP_GetData — 將原始 HID 報告整理為結構化資料陣列
  • 按鍵處理 — 逐一比對描述符表(每筆 40 位元組):
    • Offset +0:按鍵旗標(1)或軸旗標(0)
    • Offset +4:Usage Page
    • Offset +6:Usage ID
    • Offset +8:邏輯最小值(QWORD)
    • Offset +16:邏輯最大值(QWORD)
    • Offset +32:按鍵位元索引
    • Offset +33:軸子類型
  • 軸重新映射 — 將物理軸對應到虛擬軸:
    • Usage 0x30(X):左類比搖桿 X
    • Usage 0x31(Y):左類比搖桿 Y
    • Usage 0x32(Z):右類比搖桿 X / 左扳機鍵
    • Usage 0x33(Rz):右類比搖桿 Y / 右扳機鍵
    • Usage 0x34(Rx):左扳機鍵(替代)
    • Usage 0x35(Ry):右扳機鍵(替代)
    • Usage 0x39(Hat switch):方向鍵,8 方向編碼
    • Usage 0xC4:加速器
    • Usage 0xC5:剎車
    • Usage Page 6, Usage 0x20:電池電量
  • 方向鍵編碼 — Hat switch 數值映射到位元遮罩:
    • 0 = 上(0x10000000)
    • 1 = 上+右(0x90000000)
    • 2 = 右(0x80000000)
    • 3 = 下+右(0xA0000000)
    • 4 = 下(0x20000000)
    • 5 = 下+左(0x60000000)
    • 6 = 左(0x40000000)
    • 7 = 上+左(0x50000000)
  • HidP_SetData — 將重新映射後的數值寫回 HID 報告
  • 後處理 — 針對特定裝置類型注入額外資料(如 Xbox 扳機鍵作為獨立位元組,位於報告偏移 14-25)


滑鼠/鍵盤報告處理(sub_140004D10)



報告類型處理方式
0x20(滑鼠)複製軸資料(偏移 0-13 的 7 個 WORD);防抖動:600ms 內重複報告抑制;移動閾值:每軸 288 單位;修飾鍵位元組注入於偏移 +527
0x07(鍵盤)掃描 Usage 91(0x5B = 鍵盤應用鍵);根據映射表切換按鍵狀態;依虛擬映射旗標注入/抑制按鍵
0x0C(消費者控制)監控偏移 14 的位元組狀態變化;變化時觸發映射重新計算
0x03(搖桿/遊戲控制器)處理 Hat switch 四位元路由;多控制器區分(上下文+166 的上/下四位元);按鍵狀態變化偵測;分段傳輸(旗標 0x80):處理總大小超過單次傳輸的分段報告,追蹤偏移 536-548 的傳輸進度,驗證標頭(word 0 = 16, word 7 = 總長度, word 8 = 載荷長度)


使用者模式通訊架構



具名管道與服務層



reWASD 服務建立以下具名管道:

\\.\pipe{38F6486F-F91D-419E-AAC9-CB7BDA394B78}


管道建立函數(`sub_140083A30`)標示為 `"DiscSoftReWASDPipeManager"`。




👉 GM後台版 遊戲 推薦 ⬇️⬇️⬇️ 快速玩各種二次元動漫手遊app



控制 IOCTL 針對根裝置物件(裝置類型 `0x2A`),例如:

  • `0x002A69D0` — 取得驅動版本:回傳 16 位元組,檢查版本 >= 3.47;版本匹配(word[0] == 0x2F03)時跳過驅動重新安裝


HTTP REST 多層通訊模型



reWASD 展現了專業產品的通訊結構層次:

  • reWASD 應用程式 → HTTP REST → reWASD Engine
  • Engine → WCF 具名管道(XBServiceCommunicator)
  • XBServiceCommunicator → DiscSoftReWASDPipeManager
  • DiscSoftReWASDPipeManager → DeviceIoControl 到驅動層 + HID Filters IOCTL


`Engine.dll` 內部執行 HTTP 伺服器供 GUI 通訊,包含 `GameServiceController`、`ControllerServiceController`、`EventsController`、`EmulatorEventController` 等控制器。

`Engine.dll` 同時負責編譯巨集與設定,與 `rwsdcompiler.exe` 通訊——後者將 JSON 設定檔編譯為二進位格式,再經由具名管道傳送給服務層。

安全機制:為什麼不能直接呼叫 IOCTL



這是 reWASD 設計上最關鍵的保護層——驅動只接受編譯後的二進位設定檔,不接受原始資料

舉例來說,`IOCTL_REWASD_SET_CONFIG(0xB0191)` 需要 `rwsdcompiler.exe` 產生的特定二進位格式。此外,每個設定檔都有 ServiceProfileId 由服務層追蹤,驅動會驗證設定檔操作是否來自服務建立的合法會話。

簡單來說:你不能直接對驅動發 IOCTL 就期望能用。必須更深入,繞過他們的多重檢查纔行。但理論上,在他們的驅動基礎上開發自己的專案是完全可行的——說不定已經有人在這麼做了。


使用者模式重建定義



IOCTL 定義



#define REWASD_DEVICE_TYPE 0x000B

#define IOCTL_REWASD_INIT             CTL_CODE(REWASD_DEVICE_TYPE, 0,   METHOD_NEITHER,    FILE_ANY_ACCESS) // 720899 / 0xB0003
#define IOCTL_REWASD_READ_DESCRIPTOR  CTL_CODE(REWASD_DEVICE_TYPE, 1,   METHOD_NEITHER,    FILE_ANY_ACCESS) // 720903 / 0xB0007
#define IOCTL_REWASD_READ_INPUT       CTL_CODE(REWASD_DEVICE_TYPE, 2,   METHOD_NEITHER,    FILE_ANY_ACCESS) // 720907 / 0xB000B
#define IOCTL_REWASD_WRITE_OUTPUT     CTL_CODE(REWASD_DEVICE_TYPE, 3,   METHOD_NEITHER,    FILE_ANY_ACCESS) // 720911 / 0xB000F
#define IOCTL_REWASD_FEATURE_REPORT   CTL_CODE(REWASD_DEVICE_TYPE, 4,   METHOD_NEITHER,    FILE_ANY_ACCESS) // 720915 / 0xB0013
#define IOCTL_REWASD_READ_DEVICE_INFO CTL_CODE(REWASD_DEVICE_TYPE, 9,   METHOD_NEITHER,    FILE_ANY_ACCESS) // 720935 / 0xB0027
#define IOCTL_REWASD_NOT_SUPPORTED    CTL_CODE(REWASD_DEVICE_TYPE, 10,  METHOD_NEITHER,    FILE_ANY_ACCESS) // 720939 / 0xB002B
#define IOCTL_REWASD_SET_CONFIG       CTL_CODE(REWASD_DEVICE_TYPE, 100, METHOD_IN_DIRECT,  FILE_ANY_ACCESS) // 721297 / 0xB0191
#define IOCTL_REWASD_VENDOR_IO        CTL_CODE(REWASD_DEVICE_TYPE, 100, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) // 721298 / 0xB0192
#define IOCTL_REWASD_WRITE_EXTENDED   CTL_CODE(REWASD_DEVICE_TYPE, 101, METHOD_IN_DIRECT,  FILE_ANY_ACCESS) // 721301 / 0xB0195
#define IOCTL_REWASD_READ_EXTENDED    CTL_CODE(REWASD_DEVICE_TYPE, 104, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) // 721314 / 0xB01A2


根裝置 IOCTL



#define REWASD_ROOT_DEVICE_TYPE 0x002A

#define IOCTL_REWASD_GET_VERSION      0x002A69D0  // METHOD_BUFFERED, FILE_READ_DATA - returns 16 bytes version info
#define IOCTL_REWASD_ENABLE_DEVICE    0x002AE9E0  // METHOD_BUFFERED, FILE_READ_DATA|FILE_WRITE_DATA - 1 byte bool
#define IOCTL_REWASD_SET_BUTTON_MASK  0x002AE9F0  // METHOD_BUFFERED, FILE_READ_DATA|FILE_WRITE_DATA - 128 byte mask


管道定義



#define REWASD_PIPE_NAME     L"\\\\.\\pipe{38F6486F-F91D-419E-AAC9-CB7BDA394B78}"
#define REWASD_PIPE_OUT_BUF  0x81008   // 528,392 bytes
#define REWASD_PIPE_IN_BUF   0x30D50   // 200,016 bytes
#define REWASD_PIPE_TIMEOUT  500       // ms
#define REWASD_困難WARE_ID   L"root\\xjn17hlp"
#define REWASD_SERVICE_NAME  L"xjn17hlp"
#define REWASD_PARAMS_KEY    L"SYSTEM\\CurrentControlSet\\Services\\xjn17hlp\\Parameters"


命令列舉



// command IDs (from DiscSoftReWASDService)
enum RewasdPipeCommand : uint32_t {
    CMD_GET_VERSION             = 0,
    CMD_GET_PROFILE_INFO        = 1,
    CMD_GET_PROFILE             = 2,
    CMD_ADD_PROFILE             = 3,
    CMD_DEL_PROFILES            = 4,
    CMD_GET_PROFILE_STATE       = 5,
    CMD_SET_PROFILE_STATE       = 6,
    CMD_GET_CONTROLLER_LIST     = 7,
    CMD_GET_CONTROLLER_STATE    = 8,
    CMD_SET_CONTROLLER_STATE    = 9,
    CMD_SET_CONTROLLER_OPTIONS  = 10,
    CMD_SET_VIBRATION           = 11,
    CMD_SET_LED                 = 12,
    CMD_SET_ADAPTIVE_TRIGGERS   = 13,
    CMD_LICENSE_CONTROL         = 14,
    CMD_SET_BLUETOOTH_COD       = 15,
    CMD_GET_RADIO_INFO          = 16,
    CMD_ADD_RADIO               = 17,
    CMD_DEL_RADIO               = 18,
    CMD_BLUETOOTH_SCAN          = 19,
    CMD_PAIR_CONTROLLER         = 20,
    CMD_UNPAIR_CONTROLLER       = 21,
    CMD_ADD_ENGINE_CONTROLLER   = 22,
    CMD_DEL_ENGINE_CONTROLLER   = 23,
    CMD_START_BROADCAST         = 24,
    CMD_STOP_BROADCAST          = 25,
    CMD_STOP_SERVICE            = 26,
    CMD_SET_PREFERENCES         = 27,
    CMD_DEL_OLD_DRIVERS         = 28,
    CMD_SET_WIFI_DATA           = 29,
};


常數定義



// size field encoding
constexpr uint32_t REWASD_REQUEST_SIZE_LENGTH_MASK = 0x00FFFFFF;
constexpr uint32_t REWASD_REQUEST_SIZE_TAG_MASK    = 0xFF000000;
constexpr uint8_t  REWASD_ENGINE_PIPE_TAG          = 0x01;

// add profile flags
constexpr uint16_t REWASD_PROFILE_FLAG_DELETE_OLD  = 0x0001;
constexpr uint16_t REWASD_PROFILE_FLAG_ZLIB        = 0x0002;
constexpr uint16_t REWASD_PROFILE_FLAG_LZSS        = 0x0004;
constexpr uint16_t REWASD_PROFILE_FLAG_ENABLED     = 0x8000;

// key constants
constexpr uint32_t REWASD_MAX_SLOTS                    = 8;
constexpr uint32_t REWASD_MAX_PROFILES                 = 512;
constexpr uint32_t REWASD_MAX_PHYSICAL_CONTROLLERS     = 15;
constexpr uint32_t REWASD_MAX_CONTROLLERS_IN_SERVICE   = 256;
constexpr uint32_t REWASD_MAX_GAMEPAD_BUTTONS          = 35;
constexpr uint32_t REWASD_CONTROLLER_PROFILE_SIZE      = 424800;
constexpr uint32_t REWASD_PROFILE_MAX_COMPRESSED_SIZE  = 200000;
constexpr uint32_t REWASD_CONTROLLER_PROFILE_COMMON_SIZE = 608;
constexpr uint16_t REWASD_SERVICE_DEFAULT_PORT         = 35473;


核心結構體定義



通訊標頭



struct REWASD_REQUEST_HEADER {
    uint32_t size;         
    uint32_t command;      
};
static_assert(sizeof(REWASD_REQUEST_HEADER) == 8);

struct REWASD_RESPONSE_HEADER {
    uint32_t size;
    uint32_t status;        // 0 = succes
};
static_assert(sizeof(REWASD_RESPONSE_HEADER) == 8);


控制器狀態(遊戲控制器模式)



struct REWASD_FINGER_DATA {
    uint16_t x;
    uint16_t y;
    uint8_t  id;
    uint8_t  reserved;
};
static_assert(sizeof(REWASD_FINGER_DATA) == 6);

struct REWASD_CONTROLLER_STATE_Gamepad {
    uint64_t buttons[2];                // 128-bit bitmask
    uint16_t leftTrigger;
    uint16_t rightTrigger;
    int16_t  leftStickX;
    int16_t  leftStickY;
    int16_t  rightStickX;
    int16_t  rightStickY;
    int16_t  tiltX;
    int16_t  tiltY;
    int64_t  gyroXDelta;
    int64_t  gyroYDelta;
    int64_t  gyroZDelta;
    int64_t  accelXDelta;
    int64_t  accelYDelta;
    int64_t  accelZDelta;
    float    quaternionW;
    float    quaternionX;
    float    quaternionY;
    float    quaternionZ;
    REWASD_FINGER_DATA leftFinger;
    REWASD_FINGER_DATA rightFinger;
    uint8_t  ds3PressureCross;
    uint8_t  ds3PressureCircle;
    uint8_t  ds3PressureSquare;
    uint8_t  ds3PressureTriangle;
    uint8_t  ds3PressureL1;
    uint8_t  ds3PressureR1;
    uint8_t  ds3PressureDpadUp;
    uint8_t  ds3PressureDpadDown;
    uint8_t  ds3PressureDpadLeft;
    uint8_t  ds3PressureDpadRight;
    int8_t   scrollDelta[2];
    uint8_t  leftMotor;
    uint8_t  rightMotor;
    uint8_t  leftTriggerMotor;
    uint8_t  rightTriggerMotor;
    uint8_t  redLed;
    uint8_t  greenLed;
    uint8_t  blueLed;
    uint8_t  userLeds;
};
static_assert(sizeof(REWASD_CONTROLLER_STATE_Gamepad) == 128);


控制器資訊



struct REWASD_CONTROLLER_INFO {
    uint8_t  containerId[16];           // GUID
    uint64_t id;
    uint32_t type;
    uint16_t vendorId;
    uint16_t productId;
    uint16_t firmwareVersionMajor;
    uint16_t firmwareVersionMinor;
    uint16_t firmwareVersionBuild;
    uint16_t firmwareVersionRevision;
    uint16_t version;
    uint32_t apiHandle;
    uint8_t  maxLedValue;
    uint8_t  numUserLeds;
    uint32_t devNode;
    uint16_t maxTouchpadX;
    uint16_t maxTouchpadY;
    uint8_t  batteryChargingState;
    uint8_t  batteryLevel;
    uint8_t  batteryKind;
    uint8_t  connectionType;
    uint32_t properties;
    uint64_t guiEngineContext;
    uint64_t controllerBtdAddr;
    uint64_t masterBtdAddr;
    uint8_t  consumerButtons[32];
    int64_t  gyroXCalibrationDelta;
    int64_t  gyroYCalibrationDelta;
    int64_t  gyroZCalibrationDelta;
    wchar_t  manufacturerName[64];      // 128 bytes
    wchar_t  productName[64];           // 128 bytes
    wchar_t  description[64];           // 128 bytes
    wchar_t  containerDescription[64];  // 128 bytes
};
static_assert(sizeof(REWASD_CONTROLLER_INFO) == 656);

struct REWASD_GET_CONTROLLER_LIST_RESPONSE {
    REWASD_RESPONSE_HEADER header;
    REWASD_CONTROLLER_INFO controller[256];
};
static_assert(sizeof(REWASD_GET_CONTROLLER_LIST_RESPONSE) == 167944);


裝置類型列舉



enum RewasdDeviceType : uint8_t {
    DEVICE_TYPE_NONE      = 0,
    DEVICE_TYPE_GAMEPAD_A = 1,   // standard gamepad mode
    DEVICE_TYPE_GAMEPAD_B = 2,   // alternate gamepad mode
    DEVICE_TYPE_MOUSE     = 4,   // mouse emulation
    DEVICE_TYPE_KEYBOARD  = 7,   // keyboard overlay
    DEVICE_TYPE_WHEEL     = 8,   // steering wheel / flight stick
    DEVICE_TYPE_VIRTUAL   = 9,   // virtual network device
    DEVICE_TYPE_NDIS      = 10,  // NDIS-tunneled device (BT)
};


相關檔案下載



底下提供 reWASD 守護程序與相關二進位檔案,供有興趣深入研究的朋友自行分析:



所有站內附件皆會附上安全掃描報告
請會員查看純淨度百分比後判斷使用



相關檔案須知:
取得檔案前,請先詳細閱讀文章內容
避免不必要錯誤與誤會發生。
也可多參考文章討論樓層內容
了解附件檔案相關討論資訊。





常見問題Q&A



Q:reWASD 的驅動為什麼需要同時處理 HID 和 NDIS?
A:HID 過濾負責本機控制器輸入攔截,NDIS 過濾則支援網路隧道傳輸的虛擬控制器(例如藍牙裝置透過網路橋接),這是它能支援多元連線方式的關鍵。

Q:可以直接呼叫驅動的 IOCTL 來繞過授權嗎?
A:不行。reWASD 驅動設計了多層安全機制:設定檔必須經過 `rwsdcompiler.exe` 編譯為特定二進位格式,且每個設定檔綁定 ServiceProfileId,驅動會驗證會話合法性。

Q:這些逆向資訊可以用來做什麼?
A:主要適合兩類用途:一是學習專業級控制器模擬驅動的設計方法,二是理解商業軟體如何保護核心驅動不被濫用。

Q:reWASD 支援哪些類型的裝置模擬?
A:根據裝置類型列舉,支援標準遊戲控制器、替代遊戲控制器模式、滑鼠模擬、鍵盤覆蓋、方向盤/飛行搖桿、虛擬網路裝置、NDIS 隧道裝置等。

Q:通訊架構中的 HTTP 伺服器是暴露在外部的嗎?
A:`Engine.dll` 內部的 HTTP 伺服器主要供本機 GUI 通訊使用,屬於應用程式內部架構,非對外服務。

Q:分析這些二進位檔案需要什麼工具?
A:使用 IDA Pro(分析 C++ 驅動與服務)、ILSpy(反編譯 C# DLL)。所有 DLL 均未經混淆,可讀性高,適合入門練習。

重點回顧



  • reWASD 採用 雙重過濾驅動架構(HID + NDIS),這是它能穩定攔截各類輸入的核心技術
  • 驅動層的安全設計相當嚴謹:編譯後的二進位設定檔 + 服務層會話驗證,形成雙重保護
  • 使用者模式通訊採用 HTTP REST + WCF 具名管道 的多層設計,展現專業軟體的架構水準






大家正在看啥


收藏收藏 分享文章到FB上分享
回覆 使用道具 檢舉
複製專屬你的推廣連結:發至FB與各論壇宣傳:累積點數換GP商品 & 藍鑽
每五點閱率就可以兌換藍鑽積分或遊戲點卡 夢遊推廣文章換GP商品

你需要登入後才可以回覆 登入 | 加入會員

本版積分規則

Copyright (C) 2010-2020 夢遊電玩論壇

廣告合作:請直接聯繫我們,並附上您預刊登位置的預算。  

快速回覆 返回頂端 返回清單