---
# System prepended metadata

title: Security SDK 使用說明文件

---

# Security SDK 使用說明文件

## 目錄
- [SDK 簡介](#SDK-簡介)
- [功能模組使用方式](#功能模組使用方式)
    - [建立 SDK 實例](#建立-SDK-實例)
    - [裝置資訊](#裝置資訊)
    - [模擬器辨識](#模擬器辨識) 
    - [IMU追蹤](#IMU追蹤)
    - [觸控資料](#觸控資料)
- [Callback 機制說明](#Callback-機制說明)
- [附錄](#附錄)

<br/>

## SDK 簡介
Security SDK 提供跨平台的感測器資料收集功能，主要應用於裝置行為識別與異常使用者偵測。SDK 採模組化設計，支援透過 Lua 或 C++ 調用，回傳資料為 C++ 結構（struct）格式。

目前支援 Android 平台，包含以下三大功能模組：

- **裝置資訊收集**：回傳設備的硬體、系統與網路特徵（如 model、CPU Info、RAM、fingerprint 等）。
- **IMU 追蹤（Inertial Measurement Unit）**：包含陀螺儀（Gyroscope）與加速度計，可追蹤角速度、角度變化與加速度。
- **觸控資料紀錄**：定時收集點擊座標與時間戳，用於分析使用者的操作樣態。

> 下圖為 SDK 整體模組架構：
![SecuritySDK_Overview.drawio](https://hackmd.io/_uploads/S1Wspdluxg.png)

<br/>

## 功能模組使用方式

> 平台實作都在預編好的 `libsecuritysdk.so`。
使用者只需要 include 下列檔案，以及加入 SecuritySDK.cpp 即可，其他實作都已經編入 .so。
#### SDK介面檔案：
- `ISecuritySDK.h`：定義功能操作的純虛擬介面
- `SecuritySDKTypes.h`：定義共用資料結構
- `SecuritySDK.h`：統一入口，負責實例建立與平台綁定
- `SecuritySDK.cpp`：因為內含 `cocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread(...)`，避免把 cocos2d 拉進 .so 而使體積暴增，所以放在外面。

#### SDK平台檔案
- `SecuritySDKImplAndroid.h`
- `SecuritySDKImplIOS.h`

#### 模組功能檔案

- `DeviceInfo/DeviceInfo.h`
- `Emulator/EmulatorDetector.h`
- `Emulator/IEmulatorDetectionCondition.h`
- `Emulator/JsonEmulatorCondition.h`
- `IMU/IMUData.h`
- `IMU/IMUSensor.h`
- `TouchEvent/TouchEventCollector.h`
- `TouchEvent/TouchPointData.h`

### 建立 SDK 實例

請於初始化階段建立並註冊 `SecuritySDK` 實例，建議如下使用：
#### C++
```cpp
#include "securitysdk/SecuritySDK.h"
auto securitySDK = SecuritySDK::getInstance();
securitySDK->RegisterSecuritySDK();

// 使用方法：檢測模擬器
securitysdk::DeviceInfo info = securitySDK->getDeviceInfo();

```
#### Lua
在C++使用`RegisterLua(lua_State* L);` 註冊 Lua 綁定類別與方法
```cpp
SecuritySDK::getInstance()->RegisterLua(L);
```
Lua 端初始化與使用
```lua
-- 獲得 C++ 層單例
self.sdk = Inanna.GetSecuritySDK()
-- 初始化平台原生實作（Android / iOS）
self.sdk:RegisterSecuritySDK()


-- 獲得DeviceInfo
local info = self.sdk:getDeviceInfo()
```
所有功能請以 `securitySDK` 作為入口。`RegisterSecuritySDK()` 會根據平台自動建立對應的實作類別

<br/>

### 裝置資訊
可使用下列方法獲取裝置資訊：
```cpp
DeviceInfo info = securitySDK->getDeviceInfo();
```

#### DeviceInfo回傳結構：
```cpp
struct DeviceInfo {
  std::string ID;
  std::string model;
  std::string osVersion;
  std::string cpuInfo;
  std::string fingerprint;
  std::string localIpAddress;
  std::string networkType;
  std::string macAddress;
  std::string kernelABIInfo;
  int totalMemoryMb;
  int availableMemoryMb;
  std::string buildInfo;
  int screenWidth;
  int screenHeight;
};
```

#### DeviceInfo結構說明：
| 欄位名稱                | 型別            | 說明                     |
| ------------------- | ------------- | ---------------------- |
| `ID`                | `std::string` | 裝置唯一識別碼（如 Android ID）  |
| `model`             | `std::string` | 裝置型號                   |
| `osVersion`         | `std::string` | 作業系統版本                 |
| `cpuInfo`           | `std::string` | CPU 架構與型號              |
| `fingerprint`       | `std::string` | 系統建置指紋                 |
| `localIpAddress`    | `std::string` | 裝置的內網 IP 位址            |
| `networkType`       | `std::string` | 網路類型（如 Wi-Fi、LTE）      |
| `macAddress`        | `std::string` | 裝置 MAC 位址              |
| `kernelABIInfo`     | `std::string` | 核心 ABI 描述（如 arm64-v8a） |
| `totalMemoryMb`     | `int`         | 總記憶體（MB）               |
| `availableMemoryMb` | `int`         | 可用記憶體（MB）              |
| `buildInfo`         | `std::string` | 系統 build 資訊            |
| `screenWidth`       | `int`         | 螢幕寬度（像素，橫向解析度）          |
| `screenHeight`      | `int`         | 螢幕高度（像素，縱向解析度）          |

---

<br/>

### 模擬器辨識
模擬器偵測邏輯使用 JsonEmulatorCondition 實作，支援多層邏輯巢狀與字串比對操作，條件配置格式如下：
![image](https://hackmd.io/_uploads/H1YjQmBIlg.png)

#### Function 說明

- `setEmulatorDetectionCondition(const std::string& jsonConfig)`
    - **參數：**
        - `jsonConfig`：JSON 設定字串（而非檔案路徑）
    - **功能：** 載入指定的模擬器判斷條件（JSON 格式字串），供後續判斷使用。
    - **回傳值：** `bool` — 成功載入為 `true`，載入失敗為 `false`


- `reloadEmulatorDetectionCondition()` ⚠️ **已棄用**
    - **功能：** 重新載入上次設定的 JSON 條件內容（已棄用，不建議使用）。
    - **回傳值：** `bool` — 目前固定回傳 `false`

- `getEmulatorDetectionDescription()`
    - **功能：** 回傳目前載入的條件來源描述。
    - **回傳值：** `std::string` — 條件說明文字

- `isEmulator()`
    - **功能：** 執行模擬器判斷，根據目前條件返回結果。若未設定條件，預設為 false。
    - **回傳值：** `bool` — 為模擬器則回傳 `true`，否則回傳 `false`

- `getTriggerRules()`
    - **功能**： 回傳觸發目前判定為模擬器的條件規則
    - **回傳值**： `std::vector<TriggeredRule>` - 字串描述被觸發的規則


#### 資料結構說明
TriggeredRule

| 欄位名稱       | 型別           | 說明                         |
|----------------|----------------|------------------------------|
| `field`     | `std::string`     | 檢測欄位名稱             |
| `operation`    | `std::string`     | 邏輯運算類型         |
| `actualValue`     | `std::string`     | 實際值             |
| `expectedValue`    | `std::string`     | 期望值         |
| `description`    | `std::string`     | 規則描述         |

#### 使用方法
1. **準備 JSON 配置字串**：將模擬器檢測的 JSON 配置準備為字串格式
2. **呼叫 `setEmulatorDetectionCondition(jsonConfig)`** 設定條件（傳入 JSON 字串而非檔案路徑）
3. **呼叫 `isEmulator()`** 檢查是否為模擬器

詳見附錄提供在 `AppDelegate.cpp` 中初始化 `SecuritySDK` 和調用 `JsonEmulator`  的完整範例

#### 支援操作 (Operation)
| 操作名稱                    | 說明           |
| ----------------------- | ------------ |
| `equals`                | 精確匹配         |
| `contains`              | 包含字串         |
| `starts_with`           | 前綴比對         |
| `ends_with`             | 後綴比對         |
| `regex`                 | 通配符比對（\*, ?） |
| `less_than`             | 小於           |
| `greater_than`          | 大於           |
| `less_than_or_equal`    | 小於等於         |
| `greater_than_or_equal` | 大於等於         |


#### 詳細模擬器檢測文件
- [模擬器檢測系統使用說明](https://hackmd.io/ppgD4A8_SeGneP9uSo9YvQ)
- [JSON 模擬器檢測條件系統](https://hackmd.io/4A9gr2pqS-m1sJliby8nMA?view)

---

<br/>

### 觸控資料

#### Function 說明
- `startDetectTouch(const luabridge::LuaRef cb, float durationSeconds, float intervalMs = 0.1f)`
    - **參數：**
        - `cb`：Lua callback 函式，會在指定時間結束時觸發
        - `durationSeconds`：資料收集持續的時間（秒）
        - `intervalMs`：間隔秒數（毫秒）
    - **功能：** 啟動觸控資料收集，期間內會記錄所有點擊座標與時間。
    - **回傳值：** `void`

- `stopDetectTouch(const luabridge::LuaRef cb)`
    - **參數：**
        - `cb`：Lua callback 函式，會在停止後立即觸發
    - **功能：** 中止正在進行中的觸控資料收集流程。
    - **回傳值：** `void`


- `exportTouchData()`
    - **參數：** 無
    - **功能：** 將目前已收集到的觸控點資料導出為列表。
    - **回傳值：** `std::vector<TouchExportData>` — 一組觸控點資料

#### 資料結構說明
TouchExportData

| 欄位名稱       | 型別           | 說明                         |
|----------------|----------------|------------------------------|
| `x`     | `float`     | 點擊座標 X            |
| `y`     | `float`     | 點擊座標 Y             |
| `timestamp`    | `uint64_t`     | 點擊時間         |
| `hasRapidClicks`     | `bool`     | 是否快速點擊             |
| `hasIntegerCoordinates`    | `bool`     | 是否點在整數座標         |

> 每筆點擊紀錄代表一次觸控事件（如點擊螢幕）。


#### 使用順序建議：

1. **開始收集觸控資料**
   呼叫 `startDetectTouch(callback, durationSeconds)` 啟動收集。SDK 將於背景中記錄每次點擊的 `(x, y)` 與對應時間戳。
  
2. **等待結束通知（或手動停止）**
   當收集時間結束，或你主動呼叫 `stopDetectTouch(callback)` 時，SDK 將觸發 callback 通知資料已蒐集完成。

3. **導出觸控資料**
   在 callback 觸發後立即呼叫 `exportTouchData()`，即可取得已收集的 `TouchExportData` 列表，包含所有點擊事件。


---

<br/>

### IMU追蹤

#### Function 說明

- `startIMUTracking(const luabridge::LuaRef cb, float durationSeconds, float sampleIntervalMs = 100.0f)`
    - **參數：**
        - `cb`：Lua callback 函式，會在追蹤時間結束時觸發
        - `durationSeconds`：資料收集持續的時間（秒）
        - `sampleIntervalMs`：取樣區間（豪秒）
    - **功能：** 啟動 IMU 資料收集，並在指定時間結束時觸發 callback。
    - **回傳值：** `void`

- `stopIMUTracking(const luabridge::LuaRef cb)`
    - **參數：**
        - `cb`：Lua callback 函式，會在停止後立即觸發
    - **功能：** 中止正在進行中的 IMU 收集流程。
    - **回傳值：** `void`

- `exportIMUData()`
    - **參數：** 無
    - **功能：** 將當前緩衝區中的 IMU 資料導出為列表
    - **回傳值：** `std::vector<GyroExportData>` — 一組已收集的 IMU 資料點

---
#### 資料結構說明
IMUExportData
| 欄位名稱                    | 型別         | 說明                    |
| ----------------------- | ---------- | --------------------- |
| `timestamp`             | `uint64_t` | 資料結束時的時間戳（單位：ns）      |
| `interval`              | `float`    | 此筆資料涵蓋的時間區段（秒）        |
| `deltaAngles[3]`        | `std::array<float, 3>` | X, Y, Z 軸的角度總變化量      |
| `avgAngularVelocity[3]` | `std::array<float, 3>` | X, Y, Z 軸的平均角速度       |
| `avgAccelVelocity[3]`   | `std::array<float, 3>` | X, Y, Z 軸的平均加速度（保留欄位） |
| `sampleCount`           | `size_t`   | 該筆統計所使用的樣本數           |


#### 使用順序建議：

1. **開始收集 IMU 資料**  
   呼叫 `startIMUTracking(callback, durationSeconds)` 啟動收集。SDK 將每 10ms 取樣一次角速度，並計算累積角度與統計值。
2. **等待結束通知（或手動停止）**  
   當收集時間結束（或你主動呼叫 `stopIMUTracking(callback)` 時），SDK 將觸發 callback 通知資料已準備完成。
3. **導出資料**  
   在 callback 觸發後呼叫 `exportIMUData()`，可取得一組 `IMUExportData` 統計結果，包含時間戳、平均角速度與樣本數等。

<br/>
<br/>

## Callback 機制說明

本 SDK 所有支援 callback 的資料收集 API，皆要求傳入合法的 Lua function 作為 callback。
若未傳入合法函式（`luabridge::LuaRef`），對應的主功能（例如開始或停止收集）將不會執行。

---

### 支援 callback 的 API 一覽

| 函式名稱                     | 觸發時機         |
|------------------------------|------------------|
| `startIMUTracking(const luabridge::LuaRef cb, float durationSeconds)`   | 時間結束後觸發   |
| `stopIMUTracking(const luabridge::LuaRef cb)`       | 停止後立即觸發   |
| `startDetectTouch(const luabridge::LuaRef cb, float durationSeconds)`    | 時間結束後觸發   |
| `stopDetectTouch(const luabridge::LuaRef cb)`        | 停止後立即觸發   |

---

### 行為說明

- 所有 callback 使用 `luabridge::LuaRef` 傳入，必須為有效的 Lua function。
- 若未傳入合法 callback，SDK 會記錄錯誤並**跳過主功能執行**。
- 所有 callback 都會被 `try-catch` 包裝，避免 Lua/C++ 層錯誤導致崩潰。

---

### 使用範例（Lua）

```lua
local function handleGyroDetectionComplete()
    print("陀螺儀偵測完成！時間到了")
end

SecuritySDK.startGyroTracking(handleGyroDetectionComplete, 10)
```

<br/>
<br/>

## 附錄：
### 公開 Interface 定義（ISecuritySDK.h）
```cpp
#ifndef ISECURITYSDK_H
#define ISECURITYSDK_H

#include "SecuritySDKTypes.h"
#include <memory>
#include <string>
#if defined(ANDROID)
#include <jni.h>
#endif
namespace luabridge {
    class LuaRef;
}
namespace securitysdk{

struct ISecuritySDK {
    virtual ~ISecuritySDK() {};

    virtual DeviceInfo getDeviceInfo(std::string *outStringFormat = nullptr) = 0;

    virtual void startIMUTracking(const luabridge::LuaRef cb, float durationSeconds, float sampleIntervalSecond = 0.1f) = 0;
    virtual void stopIMUTracking(const luabridge::LuaRef cb) = 0;
    virtual std::vector<IMUExportData> exportIMUData() = 0;

    virtual void startDetectTouch(const luabridge::LuaRef cb, float durationSeconds, uint64_t intervalMs = 100) = 0;
    virtual void stopDetectTouch(const luabridge::LuaRef cb) = 0;
    virtual std::vector<TouchExportData> exportTouchData() = 0;

    //--------------------------------
    // EmulatorDetection
    //--------------------------------
    // 設定EmulatorDetection, 如果jsonConfig為空，則使用預設的模擬器檢測配置
    virtual bool setEmulatorDetectionCondition(const std::string& jsonConfig = "") = 0;

    // 重啟EmulatorDetection(deprecated)
    virtual bool reloadEmulatorDetectionCondition() = 0; 

    // 取得EmulatorDetection的描述
    virtual std::string getEmulatorDetectionDescription() = 0;

    // 取得EmulatorDetection的觸發規則
    virtual std::vector<TriggeredRule> getTriggeredRules() = 0;

    // 清除EmulatorDetection的觸發規則
    virtual void clearTriggeredRules() = 0;

    // 檢查是否為模擬器
    virtual bool isEmulator() = 0;

};

typedef std::shared_ptr<ISecuritySDK> ISecuritySDKPtr;
}   // namespace securitysdk
#endif // ISECURITYSDK_H
```

### 公開 struct 定義（SecuritySDK.h）
```cpp
#pragma once

#include <string>
#include "scripting/lua-bindings/manual/LuaBasicConversions.h"
#include "scripting/lua-bindings/manual/CCLuaEngine.h"
#include "ISecuritySDK.h"
#if ( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID )
#include "SecuritySDKImplAndroid.h"
#elif ( CC_TARGET_PLATFORM == CC_PLATFORM_IOS )
#include "SecuritySDKImplIOS.h"
#endif


class SecuritySDK
{
	public:
		static SecuritySDK* getInstance();
		SecuritySDK();
		virtual ~SecuritySDK();

		void RegisterLua(lua_State* L);
		void RegisterSecuritySDK();
		void UnregisterSecuritySDK();

		int m_testInt = 640;
		securitysdk::DeviceInfo getDeviceInfo();

		void startIMUTracking(const luabridge::LuaRef cb, float durationSeconds, float sampleIntervalSecond = 0.1f);
		void stopIMUTracking(const luabridge::LuaRef cb);
		std::vector<securitysdk::IMUExportData> exportIMUData();

		void startDetectTouch(const luabridge::LuaRef cb, float durationSeconds, uint64_t intervalMs = 100);
		void stopDetectTouch(const luabridge::LuaRef cb);
		std::vector<securitysdk::TouchExportData> exportTouchData();

		//--------------------------------
		// EmulatorDetection
		//--------------------------------
		// 設定EmulatorDetection, 如果jsonConfigPath為空，則使用預設的模擬器檢測配置
		bool setEmulatorDetectionCondition(const std::string& jsonConfig = "");

		// 重啟EmulatorDetection,
		// 目前JsonEmulatorCondition可以通過setEmulatorDetectionCondition直接修改，如果是有需要動態調整模擬器檢測的可以使用reloadEmulatorDetectionCondition
		bool reloadEmulatorDetectionCondition(); 

		// 取得EmulatorDetection的描述
		std::string getEmulatorDetectionDescription();

		// 取得EmulatorDetection的觸發規則
		std::vector<securitysdk::TriggeredRule> getTriggeredRules();

		// 清除EmulatorDetection的觸發規則
		void clearTriggeredRules();

		// 檢查是否為模擬器
		bool isEmulator();


		void startDetectTouchLua(luabridge::LuaRef cb, luabridge::LuaRef durationRef, luabridge::LuaRef intervalRef);
		luabridge::LuaRef exportTouchDataLua(lua_State* L);
		void startIMUTrackingLua(luabridge::LuaRef cb, luabridge::LuaRef durationRef, luabridge::LuaRef intervalRef);
		luabridge::LuaRef exportIMUDataLua(lua_State* L);
		luabridge::LuaRef getTriggeredRulesLua(lua_State* L);

	protected:
		static SecuritySDK* _instance;

		securitysdk::ISecuritySDKPtr m_securitySDKNative;

		std::vector<securitysdk::IMUExportData> m_IMUExportData = {};
		std::vector<securitysdk::TouchExportData> m_touchExportData = {};
		std::vector<securitysdk::TriggeredRule> m_triggeredRules = {};
		securitysdk::DeviceInfo m_deviceInfo = {};
};
```

### 公開 struct 定義（SecuritySDKTypes.h）
```cpp
#ifndef SECURITYSDKTYPES_H
#define SECURITYSDKTYPES_H

#include <string>
#include <vector>
#include <cstdint>
#include <array>

namespace securitysdk {

struct DeviceInfo {

    std::string ID;
    std::string model;
    std::string osVersion;
    std::string cpuInfo;
    std::string fingerprint;
    std::string localIpAddress;
    std::string networkType;
    std::string macAddress;
    std::string kernelABIInfo;
    int totalMemoryMb;
    int availableMemoryMb;
    std::string buildInfo;
    int screenWidth;
    int screenHeight;

  // 移除用於模擬器檢測的欄位
};

struct TouchExportData {
    float x;
    float y;
    uint64_t timestamp;
    bool hasRapidClicks = false;
    bool hasIntegerCoordinates = false;
};

struct IMUExportData {
    uint64_t timestamp = 0;
    float interval = 0.0f;
    std::array<float, 3> deltaAngles{};
    std::array<float, 3> avgAngularVelocity{};
    std::array<float, 3> avgAccelVelocity{};
    size_t sampleCount = 0;
};


struct TriggeredRule {
  std::string field;           // 檢測欄位
  std::string operation;       // 操作類型
  std::string actualValue;     // 實際值
  std::string expectedValue;   // 期望值
  std::string description;     // 規則描述
};

}   // namespace securitysdk

#endif // SECURITYSDKTYPES_H
```

### 模擬器檢測 JSON 配置範例
#### 預設 Android 配置範例
```json
{
  "logic": "OR",
  "rules": [
    {
      "field": "brand",
      "operation": "equals",
      "values": [
        "generic"
      ],
      "caseSensitive": false
    },
    {
      "field": "model",
      "operation": "contains",
      "values": [
        "android sdk",
        "sdk",
        "emulator",
        "generic"
      ],
      "caseSensitive": false
    },
    {
      "field": "product",
      "operation": "contains",
      "values": [
        "sdk",
        "emulator",
        "generic"
      ],
      "caseSensitive": false
    },
    {
      "field": "device",
      "operation": "contains",
      "values": [
        "generic",
        "sdk"
      ],
      "caseSensitive": false
    },
    {
      "field": "hardware",
      "operation": "contains",
      "values": [
        "goldfish",
        "ranchu",
        "vbox86"
      ],
      "caseSensitive": false
    },
    {
      "field": "board",
      "operation": "contains",
      "values": [
        "goldfish",
        "ranchu",
        "vbox86"
      ],
      "caseSensitive": false
    },
    {
      "field": "host",
      "operation": "contains",
      "values": [
        "ubuntu"
      ],
      "caseSensitive": false
    },
    {
      "field": "localIpAddress",
      "operation": "starts_with",
      "values": [
        "172."
      ],
      "caseSensitive": false
    },
    {
      "field": "kernelABIInfo",
      "operation": "contains",
      "values": [
        "x86",
        "x86_64"
      ],
      "caseSensitive": false
    },
    {
      "field": "totalMemoryMb",
      "operation": "less_than",
      "values": [
        "2048"
      ],
      "caseSensitive": false
    }
  ],
  "groups": [
    {
      "logic": "AND",
      "rules": [
        {
          "field": "brand",
          "operation": "equals",
          "values": [
            "generic"
          ],
          "caseSensitive": false
        },
        {
          "field": "model",
          "operation": "starts_with",
          "values": [
            "android sdk"
          ],
          "caseSensitive": false
        }
      ]
    },
    {
      "logic": "OR",
      "rules": [
        {
          "field": "hardware",
          "operation": "regex",
          "values": [
            "*goldfish*",
            "*ranchu*",
            "*vbox*"
          ],
          "caseSensitive": false
        },
        {
          "field": "board",
          "operation": "regex",
          "values": [
            "*goldfish*",
            "*ranchu*",
            "*vbox*"
          ],
          "caseSensitive": false
        }
      ]
    }
  ]
}
```

#### 預設 iOS 配置範例
>[!Warning] 現在規劃
>目前尚無 iOS 模擬器的參考範例，僅先行建立功能，待未來實際捕捉到 iOS 模擬器資料後（階段二），再完善其相關 JSON 文件。
```json
{}
```


### AppDelegate.cpp 參考範例

```cpp
#include "AppDelegate.h"
#include "securitysdk/ISecuritySDK.h"
#include "securitysdk/SecuritySDKFactory.h"
#include "cocos2d.h"

bool AppDelegate::applicationDidFinishLaunching()
{
    // === SecuritySDK 模擬器檢測初始化 ===
    try {
        // 創建 SecuritySDK 實例並設定為全域實例
        auto securitySDK = createSecuritySDK();
        if (securitySDK) {
            // 將實例設定為全域實例，供 Lua 綁定使用
            extern ISecuritySDK* g_sdk;
            g_sdk = securitySDK;
            
            // 嘗試從多個位置讀取 JSON 配置檔案
            std::string jsonConfig = "";
            auto fileUtils = cocos2d::FileUtils::getInstance();
            std::vector<std::string> configPaths = {
                "emulator_detection_config.json",
                "res/emulator_detection_config.json",
                "src/emulator_detection_config.json",
                "assets/emulator_detection_config.json"
            };
            
            bool configLoaded = false;
            for (const auto& configPath : configPaths) {
                std::string fullPath = fileUtils->fullPathForFilename(configPath);
                if (fileUtils->isFileExist(fullPath)) {
                    jsonConfig = fileUtils->getStringFromFile(fullPath);
                    cocos2d::log("SecuritySDK: JSON 配置檔案讀取成功 - %s", configPath.c_str());
                    configLoaded = true;
                    break;
                }
            }
            
            if (!configLoaded) {
                // 使用內建的預設配置
                jsonConfig = R"({
                "logic": "OR",
                "groups": [
                    {
                    "logic": "AND",
                    "rules": [
                        {
                        "field": "manufacturer",
                        "operation": "contains",
                        "values": ["google", "genymotion", "android_x86"],
                        "caseSensitive": false
                        },
                        {
                        "field": "model",
                        "operation": "contains",
                        "values": ["sdk", "emulator", "google_sdk"],
                        "caseSensitive": false
                        }
                    ]
                    }
                ]
                })";
                cocos2d::log("SecuritySDK: 使用內建預設配置");
            }
            
            // 設定模擬器檢測配置（使用 JSON 字串）
            if (securitySDK->setEmulatorDetectionCondition(jsonConfig)) {
                cocos2d::log("SecuritySDK: 模擬器檢測配置載入成功");
                
                // 執行模擬器檢測
                bool isEmulator = securitySDK->isEmulator();
                cocos2d::log("SecuritySDK: 模擬器檢測結果 - %s", isEmulator ? "檢測到模擬器" : "真實裝置");
                
                // 取得觸發的規則
                auto triggeredRules = securitySDK->getTriggeredRules();
                if (!triggeredRules.empty()) {
                    cocos2d::log("SecuritySDK: 觸發的檢測規則:");
                    for (const auto& rule : triggeredRules) {
                        cocos2d::log("  - %s %s (實際值: %s, 期望值: %s)", 
                                   rule.field.c_str(), 
                                   rule.operation.c_str(),
                                   rule.actualValue.c_str(), 
                                   rule.expectedValue.c_str());
                    }
                }
                
            } else {
                cocos2d::log("SecuritySDK: 模擬器檢測配置載入失敗");
            }
        } else {
            cocos2d::log("SecuritySDK: 創建 SecuritySDK 實例失敗");
        }
    } catch (const std::exception& e) {
        cocos2d::log("SecuritySDK: 初始化異常 - %s", e.what());
    }
    // === SecuritySDK 初始化完成 ===
    
    // ... 其他初始化程式碼 ...
}
```