C++接入教程
隐私说明
请参照网易易盾隐私政策,请将易盾隐私政策链接放到应用“用户协议”中。
接入说明
接入“智能风控”SDK,开发者需要完成以下步骤:
- 根据游戏开发平台,将SDK拷贝到指定的工程目录,并修改项目配置;接入步骤
- 接入风控SDK必接接口,根据业务需求接入建议接口;SDK接入调用说明
- 若需要接入驱动,则需要配置UAC;配置UAC
- 使用易盾加固工具对游戏进行加固保护,未加固的游戏风控逻辑不运行;加固工具使用说明&兼容性说明
- 验证风控SDK数据上报链路是否正常与防护效果;测试验证
- 按业务常规发版流程进行测试与发版
接入步骤
SDK 涉及到以下文件:
NEPLauncher.h
NEPLauncher.lib
SDK选择
NEPLauncher.lib区分32位或64位,编译选项MT/MD,Unicode/MultiByte,编译工具2003/v141/v142;最低支持的Visual Studio版本为2003。
NEPLauncher.h 在 `C++/NEPLauncherSDK-[版本号]/lib_version/include`文件夹下
NEPLauncher.lib 在 `C++/NEPLauncherSDK-[版本号]/lib_version/x86&x64`文件夹下
接入步骤:
- 根据游戏的位数和编译选项选择合适的lib文件,配置到VS工程属性-链接器-常规-附加库目录
- 将头文件配置到VS工程属性-C/C++-常规-附加包含目录
- 在合适的位置包含头文件:
#include "NEPLauncher.h"
- 链入静态lib:使用
#pragma comment(lib, "NEPLauncher.lib")
或者配置到VS工程属性-链接器-输入-附加依赖项 - 调用SDK初始化接口
NEP_Init
,设置产品编号和透传回调函数 - 调用登录接口
NEP_SetRoleInfo
,设置当前游戏进程登录的玩家角色信息,以便对有恶意、风险行为的用户/角色进行相应的处置 - 调用反外挂状态检查初始化接口
NEP_InstallStatusChecker
,用于异步地检查智能风控的工作状态是否正常 - 调用反外挂状态同步检查接口
NEP_GetSecurityStatus
,用于同步地检查智能风控工作状态,立即返回检查结果 - 调用停止异步检查接口
NEP_UninstallStatusChecker
,用于停止异步检查智能风控工作状态
SDK接入调用说明
必须接入:
建议接入:
SDK初始化接口
接口用途:
用于初始化智能风控 SDK;接入数据透传功能,解决易盾域名被屏蔽而导致数据无法上报的问题。
接入须知:
使用其他接口之前,必须先调用初始化接口(NEP_Init
),建议游戏启动后调用。
函数原型:
bool NEP_Init(LPCWSTR productId, GameSetInfo gameInfo, TRANSCALLBACK callback = NULL);
参数说明:
参数 | 说明 | 必要性 |
---|---|---|
productId | 易盾分配的productId,可登录易盾后台获取 | 必填 |
gameInfo | 与 NEP 相关的一些配置信息 | 必填 |
callback | 用于数据透传的回调函数透传回调函数 | 必填 |
GameSetInfo结构体
enum ServerType {
MAINLAND = 1, // 中国大陆地区
OVERSEAS = 2 // 其他地区
};
struct GameSetInfo {
int server_type; // 服务端所属地区 1-中国大陆地区 2-其他地区
char reserved[1024]; // 保留,暂未使用
}
返回值说明:
返回值 | 说明 |
---|---|
true | 初始化 SDK 成功 |
false | 初始化 SDK 失败 |
示例代码:
{
// 调用初始化接口
bool bIsInit = NEP_Init(L"PRODUCTID12345670", transcallback);
if (bIsInit) {
OutputDebug("初始化接口调用成功\n");;
}
}
透传回调函数
接口用途:
- 策略请求数据:
风控SDK -->> “策略请求数据”msg -->> 游戏客户端 -->> 游戏服务端 -->> 易盾安全服务端 -->> 返回策略数据configData -->> 游戏服务端 -->> 游戏客户端 -->> 风控SDK
- 风控嫌疑数据:
风控SDK -->> “风控嫌疑数据”msg -->> 游戏客户端 -->> 游戏服务端 -->> 易盾安全服务端 -->> 返回结果数据sdkResData -->> 游戏服务端 -->> 游戏客户端 -->> 风控SDK
接入须知:
- 回调函数需要游戏方自行实现,默认每次风控SDK与易盾安全服务端进行通信,都会触发该回调,即每次都会有一次易盾通讯和一次透传数据,这样能最大限度的减少数据的屏蔽的风险;可通过配置调整透传数据,只保留调用设置用户信息接口接口触发一次回调
- 建议“风控嫌疑数据”和“策略请求数据”msg通过游戏原有通信通道与游戏服务端通信,减少数据被拦截的情况
- 游戏服务端对“风控嫌疑数据”和“策略请求数据”msg进行封装,上报到易盾游戏安全服务端需参考数据上报接口和配置下发接口
- 通过游戏服务端中转发到到游戏客户端的数据,需通过调用交互接口反馈给风控SDK,形成数据闭环
函数原型:
typedef bool(__stdcall* TRANSCALLBACK)(LPCSTR msg, uint64_t len, int serviceType);
参数说明:
参数 | 说明 |
---|---|
msg | 风控SDK返回的数据,策略请求数据或外挂嫌疑数据 |
len | 用于数据透传的回调函数 |
serviceType | 服务类型:8 - 初始化配置、策略透传;16 - 嫌疑数据透传 |
示例代码
bool __stdcall transcallback(const char* msg, uint64_t len, int serviceType) {
if (serviceType == 8) {
// 服务类型8 - 策略请求透传服务
// 请将 msg 发送至贵方服务器,再由贵方服务器发送至易盾服务端,key值为sdkData,由易盾服务端响应,
// 返回结果configData,再将结果通过交互接口(NEP_Ioctl)反馈给智能风控sdk,serviceType应保持一致
NEP_Ioctl(configData, configData_size, 8);
} else if (serviceType == 16) {
// 服务类型16 - 风控嫌疑透传服务
// 请将 msg 发送至贵方服务器,再由贵方服务器发送至易盾服务端,key值为token,由易盾服务端响应,
// 返回结果sdkRespData,再将结果通过交互接口(NEP_Ioctl)反馈给智能风控sdk,serviceType应保持一致
NEP_Ioctl(sdkResData, sdkResData_size, 16);
}
return true;
}
设置用户信息接口
接口用途:
设置当前游戏进程登录的玩家角色信息,包括业务ID、角色UID、账号、服务器、人物等级数据等,以便对有恶意、风险行为的用户/角色进行相应的处置。
接入须知:
需在SDK初始化之后调用该接口; 接口中除了传递的json形式字符串,其他字符串统一使用Unicode编码。
函数原型:
bool NEP_SetRoleInfo(
LPCWSTR businessId, // 业务 ID
LPCWSTR account, // 玩家账号
LPCWSTR roleId, // 角色 ID
LPCWSTR roleName, // 角色名称
INT serverId, // 服务器 ID
LPCWSTR serverName, // 服务器名称
INT roleLevel, // 角色等级
INT state = 1, // 仅记录账号(0) 角色登录(1) 登出(2)
LPCSTR gameJson = NULL // 用户需要上传的额外信息,对应一个 json 字符串
);
参数说明:
参数 | 说明 | 必要性 |
---|---|---|
businessId | 当前业务 ID | 必填 |
account | 玩家账号 | 必填 |
roleId | 玩家角色唯一标识 ID,不可为空 | 必填 |
roleName | 游戏角色名 | 必填 |
serverId | 游戏角色所在服务器ID | 必填 |
serverName | 游戏角色所在服务器名称 | 可选(方便检索) |
roleLevel | 角色等级 | 可选(用于嫌疑分析) |
state | 初始化类型,1-表示角色登录;2-表示角色登出;0-表示不记录登录登出行为,仅做记录;默认为 1 | 可选(保障风控与游戏业务登录登出状态一致) |
gameJson | 游戏方想要上传的额外信息,对应一个 json 字符串,默认为空 | 可选(用于数据服务) |
返回值说明:
返回值 | 说明 |
---|---|
true | 初始化角色信息成功 |
false | 初始化角色信息失败 |
示例代码:
// 设置用户信息接口
std::wstring businessId = L"288aafc49af65987989fb57790513ac8c"; // 业务 ID
std::wstring account = L"yd@163.com" //玩家账号
std::wstring roleId = L"123456"; // 角色唯一ID
std::wstring serverName = L"游戏测试服"; // 服务器名
int serverId = 30001; // 服务器ID
std::wstring roleName = L"易小盾"; // 角色名
int roleLevel = 80; // 角色等级
int state = 1; //登录状态
auto packObj = cJSON_CreateObject();
cJSON_AddStringToObject(packObj, "gameVersion", "release_6.33");
cJSON_AddStringToObject(packObj, "ganster", "帮派");
char* packStr = cJSON_Print(packObj);
std::string jsonStr(packStr);
bool ret = NEP_SetRoleInfo(
businessId.c_str(),
account.GetString(),
roleId.c_str(),
roleName.c_str(),
serverId,
serverName.c_str(),
roleLevel,
state,
jsonStr.data());
if (ret) {
OutputDebug("设置成功\n");
}
cJSON_Delete(packObj);
free(packStr);
交互接口
接口用途
设置需要传递给 SDK 的数据,比如初始化配置内容、check 结果信息、透传数据等
接入须知
接口调用的前置条件是:调用了初始化接口
函数原型
std::string NEP_Ioctl(LPCSTR buffer, uint64_t len, int serviceType);
参数说明
参数 | 说明 |
---|---|
buffer | 要传递给 SDK 的数据 |
len | 数据长度 |
serviceType | 服务类型:8 - 初始化配置、策略透传;16 - 嫌疑数据透传; 32 - 获取离线Token |
返回值说明
返回值 | 说明 |
---|---|
"succeed" 或者 离线Token值 | 成功 |
"failed" 或 其他错误说明 | 失败 |
示例代码
// 服务类型8 - 策略和初始化参数透传服务
// 请将 msg 发送至贵方服务器,再由贵方服务器发送至易盾服务端,由易盾服务端响应,
// 返回结果 configData,再将结果通过交互接口(NEP_Ioctl)反馈给智能风控sdk
NEP_Ioctl(configData, configData_size, 8);
...
// 服务类型16 - 嫌疑数据透传服务
// 请将 msg 发送至贵方服务器,再由贵方服务器发送至易盾服务端,由易盾服务端响应,
// 返回结果 sdkResData,再将结果通过交互接口(NEP_Ioctl)反馈给智能风控sdk
NEP_Ioctl(sdkResData, sdkResData_size, 16);
开启风控状态监控
接口用途:
异步检测风控SDK运行状态,在检测到风控SDK运行异常时通过回调通知,实时知晓风控SDK运行状态,监控安全模块异常情况。
接入须知:
当接入SDK,但尚未加固时,会初始化失败,在加固后可正常; 当检测到异常调用回调函数时,会传入一个状态码,游戏客户端可以根据该状态码采取一定的措施,例如:警告弹框、踢下线、崩溃退出游戏等。
函数原型:
// 状态校验枚举
enum NEPSTATUS {
eNEP_Status_Normal = 0, // 正常
eNEP_Status_NotLoaded = 1, // 反外挂核心未启动
eNEP_Status_FileNotFount = 2, // 反外挂文件未找到
eNEP_Status_FileModified = 4, // 反外挂文件被篡改
eNEP_Status_Suspended = 8, // 反外挂功能停止
eNEP_Status_TiggerEvent = 16, // 反外挂功能异常
eNEP_Status_InternalWardenError = 32, // 内部校验错误
eNEP_Status_NetworkError = 64, // 网络错误
};
// NEP状态校验回调函数
typedef bool(_stdcall* NEPStatusCallback)(NEPSTATUS statusCode);
// 接口调用返回值枚举
enum INSTALLRESULT {
SUCCESS_INSTALLED = 0,
FAIL_CALLBACK_INVALID = 1,
FAIL_INTERVAL_INVALID = 2,
FAIL_UNEXPECTED = 4
};
// 状态检查初始化接口
INSTALLRESULT NEP_InstallStatusChecker(
NEPStatusCallback callback, // 回调函数
ULONG intervalSeconds = 60, // 校验间隔,单位为秒,范围为(20, 3600),间隔时间后开始第一次校验
bool isCallbackOnlyAbnormal = true // true:仅在检测到异常时回调 false: 完成一轮检测即调用
);
参数说明:
参数 | 说明 |
---|---|
callback | 状态校验回调函数,用于接收检测状态码并做后续处理 |
intervalSeconds | 异步校验时间间隔,单位为秒,范围限定在(20, 3600) |
isCallbackOnlyAbnormal | true:仅在检测到异常时调用回调函数 false: 每次检测完成后无论是否异常均调用回调函数 |
返回值说明:
函数返回值释义如下表
返回值 | 说明 |
---|---|
SUCCESS_INSTALLED | 初始化成功 |
FAIL_CALLBACK_INVALID | 回调函数非法 |
FAIL_INTERVAL_INVALID | 时间间隔非法 |
FAIL_UNEXPECTED | 内部错误(当接入SDK,未加固时,函数调用结果均为该值,加固后可正常),需联系易盾方 |
回调传递的状态码释义如下表
状态码 | 说明 |
---|---|
eNEP_Status_Normal | 智能风控工作正常 |
eNEP_Status_NotLoaded | 反外挂核心未启动 |
eNEP_Status_FileNotFount | 反外挂文件未找到 |
eNEP_Status_FileModified | 反外挂文件被篡改 |
eNEP_Status_Suspended | 反外挂功能停止 |
eNEP_Status_TiggerEvent | 反外挂功能异常 |
eNEP_Status_InternalWardenError | 内部校验错误 |
示例代码:
bool _stdcall AsyncCheck(NEPSTATUS statusCode) {
CStringW msg;
msg.Format(L"[*] %s: %lld\n", __FUNCTIONW__, static_cast<uint64_t>(statusCode));
OutputDebug(msg);
return true;
}
....
{
INSTALLRESULT intallResult = NEP_InstallStatusChecker(AsyncCheck, 30, true);
if (intallResult == SUCCESS_INSTALLED) {
OutputDebug("风控状态监控开启成功\n");
} else if (intallResult == FAIL_UNEXPECTED) {
OutputDebug("风控状态监控接口调用异常:目标游戏未启动或游戏未加固\n");
}
}
检测风控状态
接口用途:
立即校验并获取智能风控运行状态;用于在某些场景中需通过风控SDK运行状态实时给出相应的处理结果。
接入须知:
必须在开启风控状态监控完成后,才能调用该接口;该接口会在当前线程完成所有校验逻辑,同步地返回状态码。
函数原型:
NEPSTATUS NEP_GetSecurityStatus();
参数说明:
该接口无参数。
返回值说明:
同开启风控状态监控状态码释义表。
示例代码:
....
{
INSTALLRESULT intallResult = NEP_InstallStatusChecker(AsyncCheck, 30, true);
}
....
{
NEPSTATUS nepStatus = NEP_GetSecurityStatus();
if (nepStatus != eNEP_Status_Normal) {
OutputDebug("智能风控运行状态异常\n");
}
}
停止风控状态监控
接口用途:
停止对风控SDK运行状态的异步检测,一般情况下不推荐这么做。
接入须知:
直接调用即可,会立即停止对智能风控运行状态的异步检测; 若调用该函数前并未初始化,不会引起程序失败;
在调用该函数后,不能再调用检测风控状态
函数原型:
void NEP_UninstallStatusChecker();
参数说明:
该接口无参数
返回值说明:
该接口无返回值。
示例代码:
....
{
NEP_UninstallStatusChecker();
OutputDebug("风控状态监控已停止\n");
}
配置UAC
注:若需要开启驱动防护功能,则需要进行配置
NEP驱动的安装与卸载需要管理员权限,因此被加固的PE文件在运行时需要具备管理员权限,即用户双击程序打开游戏时,若没有管理员权限,会要求授予,否则将无法打开游戏。这里介绍通过Visual Studio 开启UAC配置的方式。
右键目标VS工程,选择属性,之后依次点击链接器-清单文件:
- 生成清单一栏选择 是 (/MANIFEST)
- 启用用户账户控制(UAC)一栏选择 是 (/MANIFESTUAC:)
- UAC执行级别一栏选择 requireAdministrator (/level='requireAdministrator')
配置完成后重新编译,再加固即可。
加固工具使用说明
解开加固工具压缩包,可看到NHPProtect.jar与config.ini两个文件;
其中配置文件config.ini中请填写易盾后台关联的appKey,请勿泄漏或自行更改;
加固工具为NHPProtect.jar, 依赖Java运行时环境(推荐Java版本为1.8)适用于 Windows、Linux以及Mac系统;
以下均以Windows环境下描述,其他系统环境使用方法类似。
命令行参数
java -jar NHPProtect.jar -WinEnc [options] -input %path/to/input/file%
参数说明
参数 | 说明 |
---|---|
-WinEnc | 必填项,用于标识加固对象为Windows平台上的应用或游戏 |
[options] | 可选项,用于标识加固开启的功能 |
-input [file_path] | 必填项,参数后跟待加固的zip包或PE文件的路径 |
可选参数说明:
参数 | 说明 |
---|---|
-yunconfig | 推荐使用,用于开启易盾后台配置的反外挂功能,目前暂不支持本地配置反外挂功能,反外挂加固时该参数必选 |
-target [pe_filename] | 指定保护的PE文件,仅当input 参数不为PE文件时需要指定,若input 参数为单独PE文件,则无需再指定该参数 |
-enginetype [type] | type值可选DEFAULT, cocos2d,u3d_mono, u3d_il2cpp 不填该参数时默认为DEFAULT,表示常规应用 |
-SingleStaticVM | 该参数单独使用,指定PE文件单独加壳 |
加固示例
- 游戏主程序
java -jar NHPProtect.jar -WinEnc -yunconfig -input %path/to/game.exe%
- 单独PE加壳
java -jar NHPProtect.jar -WinEnc -SingleStaticVM -input %path/to/pe/file%
兼容DRM方案
端游智能风控的加固方案针对游戏需要使用其他DRM(数字版权管理)解决方案打包的情况做了兼容,在使用加固前,请先使用其他DRM方案进行打包,再使用易盾方提供的加固工具进行加固。
如若要兼容Steam DRM方案,请先使用其DRM打包工具的兼容模式打包,打包完成后再使用易盾的加固工具,Steam DRM兼容模式的打包命令如下,详细请见Steam官方文档对这部分的说明:
drm_wrap [appid] %path/to/input.exe% %path/to/output.exe% drmtoolp 6
若有遇到其他DRM方案无法兼容的情况,请及时告知易盾方,相关技术人员会第一时间排查并给出解决方案。
兼容性说明
签名(重要)
加固接入反外挂后,返回的文件中包含两个未签名的PE文件:游戏加固目标Game.exe与智能风控核心模块NEP2.dll。
由于加固过程中使用了PE加壳等技术,部分设备上会存在被部分杀毒软件误报的情况。因此这里必须对Game.exe与NEP2.dll进行签名,而NEP2.dll在加固过程中默认获取易盾方签名。
客户端兼容性
目前支持的客户端平台有:
- Windows 7 及以上
但考虑到游戏性能、不同的图形引擎支持等情况,NEP会根据产品方的需求对系统支持做相应调整。
测试验证
在完全接入易盾智能风控之后,上线之前,需做测试验证,主要的测试维度有:反外挂功能是否启用、外挂检测数据是否上报、兼容性、回归测试。
功能启用情况测试
验证反外挂功能已接入:
- 启动接入后的游戏
- 管理员模式打开ProcessExplorer或其他进程检测工具
- 观察游戏进程的模块列表,若包含NEP2.dll,则说明成功接入
数据上报测试
智能风控检测的异常数据分为两种,一种是确认的风险行为或外挂数据,这部分数据会同步到易盾官网后台,可以直接查询到;
另一种是疑似外挂的可疑数据,这部分会先上传至易盾私有后台,经过后台反外挂规则和运营同学排查后,筛选出新的确认外挂数据再同步到易盾官网后台。
如何验证官网后台数据上报正常:
-
启动加固后的游戏(需要登录,否则无法同步到账号数据)
-
启动Cheat Engine (后简称CE,一般常用来修改游戏内存、调试游戏进程,可篡改本地客户端的数据,达到作弊的效果)
-
使用CE打开游戏进程(在菜单中点击File - Open Process,之后选择对应游戏)
-
稍等片刻(约5分钟),前往易盾官网后台查询数据
这里列举一些可能引起数据上报无法打通的问题,在自测无法查询到数据时,可以逐一排查比对:
- 接入SDK所用APP_ID与加固时的APP_KEY不对应(官网后台查看)
- 接入SDK时用户唯一标识UID为空
- 游戏未登录,导致检测数据无法关联
- 游戏启动后马上关闭,即游戏进程在检测数据上报之前已退出
外挂样本测试
游戏方若有平时积累的外挂样本,可以在此环节进行测试,开启游戏开启外挂,验证易盾反外挂的检测效果,检测效果可以在易盾官网后台查看。
登录易盾官网后台,在左侧菜单选择“智能风控”,在展开项中选择“数据中心”,在“数据查询”中可看到给定时间范围内所有的检测数据。
请知悉,由于PC端外挂种类较多,外挂确认的方法较为复杂,为了避免误报,易盾官网展示的“外挂检测”数据都是完全确认的,也即会有一部分未确认的外挂数据未展示在易盾官网后台。
因此若官网后台查询不到检测数据,请联系易盾方检查私有后台数据,若私有后台有数据,则易盾方录入特征后会将这部分数据同步至官网后台,无需升级方案;若私有后台未检测到数据,请将外挂样本及其测试方法一并反馈至易盾方,易盾方会进行相应的外挂分析,若有必要,会迭代风控SDK。
兼容性测试
易盾端游智能风控已在兼容性说明提及的系统中做了测试,确保上线的功能稳定有效。
游戏方在接入后,进一步兼容性测试可以按照游戏本身锁需兼容的设备及系统进行验证测试。
如果有因为引入易盾智能风控导致的问题,请将问题现象及复现步骤反馈给易盾,易盾方会第一时间排查并给出解决方案。
其他回归性测试
按照游戏的常规回归测试进行,如果发现有功能异常、卡顿、黑屏、CPU或内存占用过高等现象,请先进行原版自测,在确认是引入易盾反外挂模块导致的问题后,请将问题现象及复现步骤反馈给易盾,易盾方会第一时间排查并给出解决方案。
常见问题
编译报错:“不安全代码只会在使用/unsafe编译的情况下出现”
解决方案:
1、vs菜单“项目”中找到“(解决方案名称)属性”项,单击进入项目属性设置界面;
2、在项目属性界面中找到“生成”选项卡
3、在“生成”选项中找到“允许不安全代码”,勾选上