564 lines
16 KiB
C#
564 lines
16 KiB
C#
using UnityEngine;
|
||
using System.Runtime.InteropServices;
|
||
using System;
|
||
using System.Text;
|
||
using AOT;
|
||
|
||
namespace NTESHTPSec
|
||
{
|
||
public enum RequestCmdID
|
||
{
|
||
// 签名信息
|
||
Cmd_GetSignInfo = 0,
|
||
// 越狱状态
|
||
Cmd_IsRootDevice = 2,
|
||
// SDK版本
|
||
Cmd_GetHTPVersion = 7,
|
||
// 获取超时数据
|
||
Cmd_GetCollectData = 8,
|
||
// 初始化配置内容,防止初始化失败情况下,客户可以通过服务端请求初始化配置并传递给SDK
|
||
Cmd_SetConfigData = 16,
|
||
// 客户服务端将check结果传递给SDK,便于执行后续动作
|
||
Cmd_SetResponseData = 17,
|
||
// 获取服务端设备指纹
|
||
Cmd_GetDeviceId = 20,
|
||
};
|
||
|
||
// 安全通信结果类
|
||
public class SafeCommResult
|
||
{
|
||
public static int SC_CODE_OK = 0;
|
||
public static int SC_FILE_NOTEXIST = -1; // apk包文件无文件
|
||
public static int SC_FILE_IS_BROKEN = -2; // apk包文件损坏
|
||
public static int SC_PROTOCOL_VERSION_ERROR = -3; // 协议版本不匹配
|
||
public static int SC_PARAM_ERROR = -4; // 参数错误
|
||
public static int SC_DATA_TAMPERED = -5; // 数据被篡改
|
||
public static int SC_DATA_DECRYPT_ERROR = -6; // 数据解密失败
|
||
public static int SC_ALG_ERROR = -7; // 算法不匹配,指定算法解密
|
||
public static int SC_TIMEOUT = -8; // 超时
|
||
public static int SC_ENV = -9; // 当前环境存在frida xposed unidbg
|
||
public static int SC_DEVICE = -10; // 设备不匹配
|
||
|
||
public static int SC_NOT_INIT = -201; // 未初始化
|
||
public static int SC_CLOSED = -202; // 试用到期
|
||
public static int SC_BUFF_MALLOC_ERROR = -98; // 这种情况一般不会出现
|
||
public static int SC_INSIDE_ERROR = -99; //内部错误,一般不会出现
|
||
|
||
public int ret;
|
||
public byte[] encBytes;
|
||
public string encResult;
|
||
public string signResult;
|
||
public byte[] decResult;
|
||
|
||
public SafeCommResult()
|
||
{
|
||
ret = SC_INSIDE_ERROR;
|
||
decResult = null;
|
||
encBytes = null;
|
||
}
|
||
}
|
||
|
||
public class AntiCheatResult
|
||
{
|
||
public int code;
|
||
public string codeStr;
|
||
public string token;
|
||
public string businessId;
|
||
|
||
public AntiCheatResult(int code, string codeStr, string token, string businessId)
|
||
{
|
||
this.code = code;
|
||
this.codeStr = codeStr;
|
||
this.token = token;
|
||
this.businessId = businessId;
|
||
}
|
||
}
|
||
|
||
public class NTESRiskSecProtect : MonoBehaviour
|
||
{
|
||
|
||
private static bool isInitialized = false;
|
||
|
||
public delegate void InitCallback(int code, string msg, string content);
|
||
public delegate void getTokenAysncBlock(AntiCheatResult result);
|
||
private static getTokenAysncBlock getTokenAsyncCallback;
|
||
public delegate void TokenBlockCallback(string token, int code, string codeStr, string businessId);
|
||
|
||
// 初始化
|
||
public static void init(string productId, InitCallback callback)
|
||
{
|
||
if (isInitialized)
|
||
{
|
||
System.Console.Write("NTESSecProtect is already initialized. ");
|
||
return;
|
||
}
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
System.Console.Write("NTESSecProtect is start initialized. " + callback);
|
||
___initWithProductId(productId, callback);
|
||
|
||
}
|
||
#endif
|
||
|
||
isInitialized = true;
|
||
}
|
||
|
||
// 登录
|
||
public static int setRoleInfo(string businessId, string roleId, string roleName, string roleAccount, string roleServer, int serverid, string gameJson)
|
||
{
|
||
int ret = 0;
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
ret = ___setRoleInfo(businessId, roleId, roleName, roleAccount, roleServer, serverid, gameJson);
|
||
|
||
}
|
||
#endif
|
||
return ret;
|
||
}
|
||
|
||
/**
|
||
* 获取Token,默认超时3s
|
||
*
|
||
* @param bussinessId 场景id
|
||
* @param timeout 超时时间(范围:10000ms以内 单位:ms)
|
||
*
|
||
* @return 获取到的token,用于校验是否有作弊行为
|
||
*/
|
||
public static AntiCheatResult getToken(int timeout, string businessId)
|
||
{
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
|
||
IntPtr outPtr = IntPtr.Zero;
|
||
IntPtr codeStrPtr = IntPtr.Zero;
|
||
string token = null;
|
||
string codeStr = null;
|
||
int tokenOutLen = 0;
|
||
int codeStrOutLen = 0;
|
||
int ret = ___getToken(businessId, timeout, ref outPtr, ref tokenOutLen, ref codeStrPtr, ref codeStrOutLen);
|
||
|
||
byte[] cc = new byte[tokenOutLen];
|
||
Marshal.Copy(outPtr, cc, 0, tokenOutLen);
|
||
token = Encoding.ASCII.GetString(cc);
|
||
___safeFree(ref outPtr);
|
||
|
||
byte[] codeStrBytes = new byte[codeStrOutLen];
|
||
Marshal.Copy(codeStrPtr, codeStrBytes, 0, codeStrOutLen);
|
||
codeStr = Encoding.ASCII.GetString(codeStrBytes);
|
||
___safeFree(ref codeStrPtr);
|
||
|
||
AntiCheatResult result = new AntiCheatResult(ret, codeStr, token, businessId);
|
||
|
||
return result;
|
||
|
||
}
|
||
#endif
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 获取Token,默认超时3s
|
||
*
|
||
* @param bussinessId 场景id
|
||
* @param timeout 超时时间(范围:10000ms以内 单位:ms)
|
||
* @param callback 获取Token完成后回调
|
||
*
|
||
*/
|
||
public static void getTokenAsync(int timeout, String businessId, getTokenAysncBlock callback)
|
||
{
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
getTokenAsyncCallback = callback;
|
||
|
||
TokenBlockCallback callbackC = new TokenBlockCallback(getTokenCallback);
|
||
___getTokenAsync(businessId, timeout, callbackC);
|
||
|
||
}
|
||
#endif
|
||
}
|
||
|
||
[MonoPInvokeCallback(typeof(TokenBlockCallback))]
|
||
private static void getTokenCallback(string token, int code, string message, string businessId)
|
||
{
|
||
AntiCheatResult result = new AntiCheatResult(code, message, token, businessId);
|
||
if (null != getTokenAsyncCallback)
|
||
{
|
||
getTokenAsyncCallback(result);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取Token,默认超时3s
|
||
*
|
||
* @param bussinessId 场景id
|
||
* @param timeout 超时时间(范围:10000ms以内 单位:ms)
|
||
* @param callback 获取Token完成后回调(直接传入回调,避免同步问题)
|
||
*
|
||
*/
|
||
public static void getTokenAsync(int timeout, String businessId, TokenBlockCallback callback)
|
||
{
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
___getTokenAsync(businessId, timeout, callback);
|
||
|
||
}
|
||
#endif
|
||
}
|
||
|
||
//退出登陆
|
||
public static void logOut()
|
||
{
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
___logOut();
|
||
}
|
||
#endif
|
||
}
|
||
|
||
public static string ioctl(RequestCmdID request, string data)
|
||
{
|
||
string result = "unsupported request";
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
result = ___ioctl(request, data);
|
||
}
|
||
#endif
|
||
|
||
return result;
|
||
}
|
||
|
||
//设置服务器类型
|
||
public static void setServerType(int serverType)
|
||
{
|
||
Debug.Log($"setServerType -> {serverType}");
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
___setServerType(serverType);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
//设置渠道信息
|
||
public static void setChannel(string channel)
|
||
{
|
||
Debug.Log($"setChannel -> {channel}");
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
___setChannel(channel);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
//设置渠道信息
|
||
public static void setExtraData(string key, string value)
|
||
{
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
___setExtraData(value, key);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
public static void setHost(string host)
|
||
{
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
___setHost(host);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
// 获取数据签名
|
||
public static string getDataSign(string inputData)
|
||
{
|
||
string result = null;
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
if (inputData != null && inputData.Length > 0)
|
||
{
|
||
result = ___getDataSign(inputData);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
return result;
|
||
}
|
||
|
||
public static int safeCommToServer(int alg, byte[] inputData, int dataSize, ref IntPtr outData, ref int outLen)
|
||
{
|
||
int ret = 0;
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
|
||
ret = ___safeCommToServer(alg, inputData, dataSize, ref outData, ref outLen);
|
||
|
||
}
|
||
#endif
|
||
|
||
return ret;
|
||
}
|
||
public static int safeCommToServerByte(int alg, byte[] inputData, int dataSize, ref IntPtr outData, ref int outLen)
|
||
{
|
||
int ret = 0;
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
|
||
ret = ___safeCommToServerByte(alg, inputData, dataSize, ref outData, ref outLen);
|
||
|
||
}
|
||
#endif
|
||
|
||
return ret;
|
||
}
|
||
public static int safeCommFromServer(int alg, int timeout, string inputData, int dataSize, ref IntPtr outData, ref int outLen)
|
||
{
|
||
int ret = 0;
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
|
||
ret = ___safeCommFromServer(alg, timeout, inputData, dataSize, ref outData, ref outLen);
|
||
|
||
}
|
||
#endif
|
||
|
||
return ret;
|
||
}
|
||
public static int safeCommFromServerByte(int alg, int timeout, byte[] inputData, int dataSize, ref IntPtr outData, ref int outLen)
|
||
{
|
||
int ret = 0;
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
|
||
ret = ___safeCommFromServerByte(alg, timeout, inputData, dataSize, ref outData, ref outLen);
|
||
|
||
}
|
||
#endif
|
||
|
||
return ret;
|
||
}
|
||
public static NTESHTPSec.SafeCommResult safeCommToServerByteV30(int version, int alg, byte[] inputData, bool isCrucial)
|
||
{
|
||
NTESHTPSec.SafeCommResult safeCommResult = new NTESHTPSec.SafeCommResult();
|
||
if (inputData == null || inputData.Length == 0)
|
||
{
|
||
safeCommResult.ret = NTESHTPSec.SafeCommResult.SC_PARAM_ERROR;
|
||
return safeCommResult;
|
||
}
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
try
|
||
{
|
||
var ptr = IntPtr.Zero;
|
||
var size = oOOO00Oo0000o0OO(version, false, isCrucial, alg, inputData, inputData.Length, ref ptr);
|
||
if (size <= 0 )
|
||
{
|
||
safeCommResult.ret = size;
|
||
}
|
||
else
|
||
{
|
||
safeCommResult.ret = NTESHTPSec.SafeCommResult.SC_CODE_OK;
|
||
safeCommResult.encBytes = new byte[size];
|
||
Marshal.Copy(ptr, safeCommResult.encBytes, 0, size);
|
||
___safeFree(ref ptr);
|
||
}
|
||
}
|
||
catch (System.Exception e)
|
||
{
|
||
Debug.LogError("safeCommToServer" + e.ToString());
|
||
}
|
||
|
||
}
|
||
#endif
|
||
return safeCommResult;
|
||
}
|
||
public static NTESHTPSec.SafeCommResult safeCommToServerV30(int version, int alg, byte[] inputData, bool isCrucial)
|
||
{
|
||
NTESHTPSec.SafeCommResult safeCommResult = new NTESHTPSec.SafeCommResult();
|
||
if (inputData == null || inputData.Length == 0)
|
||
{
|
||
safeCommResult.ret = NTESHTPSec.SafeCommResult.SC_PARAM_ERROR;
|
||
return safeCommResult;
|
||
}
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
|
||
try
|
||
{
|
||
var ptr = IntPtr.Zero;
|
||
var size = oOOO00Oo0000o0OO(version, true, isCrucial, alg, inputData, inputData.Length, ref ptr);
|
||
if (size <= 0 )
|
||
{
|
||
safeCommResult.ret = size;
|
||
}
|
||
else
|
||
{
|
||
safeCommResult.ret = NTESHTPSec.SafeCommResult.SC_CODE_OK;
|
||
safeCommResult.encResult = Marshal.PtrToStringAnsi(ptr);
|
||
___safeFree(ref ptr);
|
||
}
|
||
}
|
||
catch (System.Exception e)
|
||
{
|
||
Debug.LogError("safeCommToServer" + e.ToString());
|
||
}
|
||
|
||
}
|
||
#endif
|
||
|
||
return safeCommResult;
|
||
}
|
||
public static void registerTouchEvent(ulong gameplayId, ulong sceneId)
|
||
{
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
|
||
___registerTouchEvent(gameplayId, sceneId);
|
||
|
||
}
|
||
#endif
|
||
|
||
}
|
||
public static void unregisterTouchEvent()
|
||
{
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
|
||
___unregisterTouchEvent();
|
||
|
||
}
|
||
#endif
|
||
|
||
}
|
||
public static void safeFree(ref IntPtr outData)
|
||
{
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||
{
|
||
|
||
___safeFree(ref outData);
|
||
|
||
}
|
||
#endif
|
||
|
||
}
|
||
|
||
// ret为0时,signResult保存签名结果
|
||
public static NTESHTPSec.SafeCommResult htpSign(int version, int alg, byte[] inputData)
|
||
{
|
||
NTESHTPSec.SafeCommResult safeCommResult = new NTESHTPSec.SafeCommResult();
|
||
if (inputData == null || inputData.Length == 0)
|
||
{
|
||
safeCommResult.ret = NTESHTPSec.SafeCommResult.SC_PARAM_ERROR;
|
||
return safeCommResult;
|
||
}
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
try
|
||
{
|
||
var ptr = IntPtr.Zero;
|
||
var size = ___htpSign(version, alg, inputData, inputData.Length, ref ptr);
|
||
if (size <= 0)
|
||
{
|
||
safeCommResult.ret = size;
|
||
}
|
||
else
|
||
{
|
||
safeCommResult.ret = NTESHTPSec.SafeCommResult.SC_CODE_OK;
|
||
safeCommResult.signResult = Marshal.PtrToStringAnsi(ptr);
|
||
___safeFree(ref ptr);
|
||
}
|
||
}
|
||
catch (System.Exception e)
|
||
{
|
||
Debug.LogError("htpSign" + e.ToString());
|
||
}
|
||
#endif
|
||
return safeCommResult;
|
||
}
|
||
|
||
public static void clearAllBlock()
|
||
{
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
___clearAllBlock();
|
||
#endif
|
||
}
|
||
|
||
#if UNITY_IPHONE || UNITY_IOS
|
||
[DllImport("__Internal")]
|
||
private static extern void ___initWithProductId(string productId, InitCallback callback);
|
||
[DllImport("__Internal")]
|
||
private static extern int ___setRoleInfo(string businessId, string roleId, string roleName, string roleAccount, string roleServer, int serverid, string gameJson);
|
||
[DllImport("__Internal")]
|
||
private static extern int ___getToken(string bussinessId, int timeout, ref IntPtr outData, ref int outLen, ref IntPtr codeStr, ref int codeStrOutLen);
|
||
[DllImport("__Internal")]
|
||
private static extern void ___getTokenAsync(string bussinessId, int timeout, TokenBlockCallback callback);
|
||
[DllImport("__Internal")]
|
||
private static extern void ___logOut();
|
||
[DllImport("__Internal")]
|
||
private static extern void ___clearAllBlock();
|
||
[DllImport("__Internal")]
|
||
private static extern string ___ioctl(RequestCmdID request, string data);
|
||
[DllImport("__Internal")]
|
||
private static extern void ___setServerType(int type);
|
||
[DllImport("__Internal")]
|
||
private static extern void ___setChannel(string channel);
|
||
[DllImport("__Internal")]
|
||
private static extern void ___setExtraData(string value, string key);
|
||
[DllImport("__Internal")]
|
||
private static extern void ___setHost(string host);
|
||
[DllImport("__Internal")]
|
||
private static extern string ___getDataSign(string data);
|
||
[DllImport("__Internal")]
|
||
public static extern int ___safeCommToServer(int alg, byte[] inputData, int dataSize, ref IntPtr outData, ref int outLen);
|
||
[DllImport("__Internal")]
|
||
public static extern int ___safeCommToServerByte(int alg, byte[] inputData, int dataSize, ref IntPtr outData, ref int outLen);
|
||
[DllImport("__Internal")]
|
||
public static extern int ___safeCommFromServer(int alg, int timeout, string inputData, int dataSize, ref IntPtr outData, ref int outLen);
|
||
[DllImport("__Internal")]
|
||
public static extern int ___safeCommFromServerByte(int alg, int timeout, byte[] inputData, int dataSize, ref IntPtr outData, ref int outLen);
|
||
[DllImport("__Internal")]
|
||
public static extern int oOOO00Oo0000o0OO(int version, bool encode, bool isCrucial, int alg, byte[] data, int len, ref IntPtr ptr);
|
||
[DllImport("__Internal")]
|
||
public static extern int ___htpSign(int alg, int version, byte[] src, int dataSize, ref IntPtr outData);
|
||
[DllImport("__Internal")]
|
||
public static extern void ___registerTouchEvent(ulong gameplayId, ulong sceneId);
|
||
[DllImport("__Internal")]
|
||
public static extern void ___unregisterTouchEvent();
|
||
[DllImport("__Internal")]
|
||
public static extern void ___safeFree(ref IntPtr outData);
|
||
|
||
#endif
|
||
|
||
}
|
||
|
||
} |