内联接口
内联类 Inline类
检测类方法需要您开启 本机代码转换器 并且仅编译Microsoft Windows的Intel平台,您才可以使用。
如果您的软件具有跨平台需求,则您无法使用该功能。
_advanced_checkProtection
检测动态库是否被脱壳,如果一切正常则返回预期值,如果检测到异常则返回0或其他数值。
| 参数 | 描述 | 返回值 | 描述 |
|---|---|---|---|
| 预期的数值 | 整数型 注意:您只能填写常量 | 预期的数值 | 整数型 |
示例:
public static void main(String[] args) {
int expected = 0xFF_FF_FF_FF;
if ((expected = Inline.advanced_checkProtection(0x12_34_56_78)) == 0xFF_FF_FF_FF) {
// 巴拉巴拉 ...
}
// 其他运算 ...
}注意
这仅仅只是示例,在您的项目中,您可以根据实际情况使用。
_advanced_checkCRCImage
检测动态库内存镜像是否被修改 (例如: 补丁),如果一切正常则返回预期值,如果检测到异常则返回0或其他数值。
| 参数 | 描述 | 返回值 | 描述 |
|---|---|---|---|
| 预期的数值 | 整数型 注意:您只能填写常量 | 预期的数值 | 整数型 |
示例:
public static void main(String[] args) {
int expected = 0xFF_FF_FF_FF;
if ((expected = Inline.advanced_checkCRCImage(0x12_34_56_78)) == 0xFF_FF_FF_FF) {
// 巴拉巴拉 ...
}
// 其他运算 ...
}_advanced_checkIsVirtualPC
检测动态库是否在虚拟机运行,如果一切正常则返回预期值,如果检测到异常则返回0或其他数值。
| 参数 | 描述 | 返回值 | 描述 |
|---|---|---|---|
| 预期的数值 | 整数型 注意:您只能填写常量 | 预期的数值 | 整数型 |
示例:
public static void main(String[] args) {
int expected = 0xFF_FF_FF_FF;
if ((expected = Inline.advanced_checkIsVirtualPC(0x12_34_56_78)) == 0xFF_FF_FF_FF) {
// 巴拉巴拉 ...
}
// 其他运算 ...
}_advanced_checkIsDebuggerPresent
检测动态库是否被调试器调试,如果一切正常则返回预期值,如果检测到异常则返回0或其他数值。
| 参数 | 描述 | 返回值 | 描述 |
|---|---|---|---|
| 预期的数值 | 整数型 注意:您只能填写常量 | 预期的数值 | 整数型 |
示例:
public static void main(String[] args) {
int expected = 0xFF_FF_FF_FF;
if ((expected = Inline.advanced_checkIsDebuggerPresent(0x12_34_56_78)) == 0xFF_FF_FF_FF) {
// 巴拉巴拉 ...
}
// 其他运算 ...
}trycatch
当启用 @NativeObfuscation 注解参数 manualTryCatch 为 true 时,
详情请见:manualTryCatch 参数
您可以使用本方法来进行手动捕获异常,而不会在所有执行点加入异常处理判断。
示例:
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
@NativeObfuscation(manualTryCatch = true)
public static void main(String[] args) {
try (BufferedReader reader = Files.newBufferedReader(Paths.get("xxx_xxx.bin"))) {
String line;
while ((line = reader.readLine()) != null) {
Inline.trycatch(); // here
System.out.println(line);
}
} catch (IOException exception) {
// do something...
}
}验证包装类 Wrapper类
在对接使用 幻影盾X 的验证包装类方法之前,我们十分推荐您学习并且熟练使用 java.util.Optional 类
_debug_addDefaultCloudConstant
在调试环境中,添加云常量环境。
| 参数 | 描述 |
|---|---|
| 用户组 | 字符串 |
| 常量值 | 字符串 |
示例:
public static void main(String[] args) {
Wrapper._debug_addDefaultCloudConstant("用户组A", "1234567");
}通知
自 幻影盾X 20240404 起,我们可以使用以下参数添加云常量
# 在 JVM 启动参数中添加指定参数
# -Dphantom-shield-x.cloud-constant.${hash}.${index}=${constant}
# `hash` 对应 `getCloudConstant` 中的 `hash`
# `index` 对应 `getCloudConstant` 中的 `index`
# `constant` 对应 `getCloudConstant` 中的 返回值
java -Dphantom-shield-x.cloud-constant.123456.0=helloworldgetUserId
获取用户的唯一识别码。
成功则返回包装后的用户ID
失败则返回 Optional.EMPTY
本方法应该在登录之后使用
| 返回值 | 描述 |
|---|---|
| 用户的UID | Optional<Long> |
示例:
public static void main(String[] args) {
if (!Wrapper.getUserId().isEmpty()) {
System.out.println(Wrapper.getUserId().get());
} else {
System.err.println("获取失败");
}
}getUsername
获取用户的用户名。
成功则返回包装后的用户用户名
失败则返回 Optional.EMPTY
本方法应该在登录之后使用
| 返回值 | 描述 |
|---|---|
| 用户的用户名 | Optional<String> |
示例:
public static void main(String[] args) {
if (!Wrapper.getUsername().isEmpty()) {
System.out.println(Wrapper.getUsername().get());
} else {
System.err.println("获取失败");
}
}getNickname
获取用户的昵称。
成功则返回包装后的用户昵称
失败则返回 Optional.EMPTY
本方法应该在登录之后使用
| 返回值 | 描述 |
|---|---|
| 用户的昵称 | Optional<String> |
示例:
public static void main(String[] args) {
if (!Wrapper.getNickname().isEmpty()) {
System.out.println(Wrapper.getNickname().get());
} else {
System.err.println("获取失败");
}
}login
用户登录接口
| 参数 | 描述 | 返回值 | 描述 |
|---|---|---|---|
| 用户名 | 字符串 | 返回码 | 整数型 |
| 密码 | 字符串 |
示例:
public static void main(String[] args) {
switch (Wrapper.login("用户名", "密码")) {
case 0:
System.out.println("登录成功");
break;
default:
System.out.println("登录失败");
break;
}
}以下是错误码详解:
| 错误码 | 描述 | 错误码 | 描述 |
|---|---|---|---|
| 4 | 用户名不存在或者密码错误 | 99 | 时间戳校验失败 |
| 5 | 你的账户被管理员封禁 | 101 | 这个软件已停止服务,请联系软件管理员 |
| 6 | 这个软件已停止服务,请联系软件管理员 | 102 | 用户名不存在 |
| 7 | 软件管理员暂时封禁了你的账号,请联系软件管理员 | 103 | 机器码不匹配,请换绑 |
| 8 | 你没有购买该软件的任何订阅 | 104 | 版本过低请更新软件 |
| 9 | 软件维护中 | -1 | 请检查因特网连接是否正常 |
| 97 | 签名验证失败 | -2 | 签名校验失败 |
| 98 | 机器码不匹配 | -3 | 内部错误 |
getVerifyToken
获取登录后地验证 Token 。
成功则返回 Token 。
失败则返回 null。
本方法应该在登录之后使用
| 返回值 | 描述 |
|---|---|
| 用户验证后的Token | 字符串 |
示例:
public static void main(String[] args) {
System.err.println(Wrapper.getVerifyToken());
}setAsSuspected
将用户设置为嫌疑人。
你可以在用户无法正常触发的地方添加这个方法。
使用该方法之后程序会自动关闭。
本方法应该在登录之后使用
| 参数 | 描述 |
|---|---|
| 原因 | 字符串 |
示例:
public static void main(String[] args) {
if (checkIsCracked()) {
Wrapper.setAsSuspected("Deobf?");
}
}getCloudConstant
获取云常量
获取在后台设置的常量
成功则返回包装后的常量
失败则返回 Optional.EMPTY
本方法应该在登录之后使用
| 参数 | 描述 | 返回值 | 描述 |
|---|---|---|---|
| 用户组名称的哈希值 | 整数型 该数值应该通过 "用户组".hashcode() 获取,并且应该是常量 | 常量 | Optional<String> |
| 云常量索引 | 整数型 |
示例:
public static void main(String[] args) {
System.out.println(Wrapper.getCloudConstant(123456, 0));
}getExpiredDate
获取指定用户组到期时间
成功则返回包装后的到期时间
失败则返回 Optional.EMPTY
本方法应该在登录之后使用
| 参数 | 描述 | 返回值 | 描述 |
|---|---|---|---|
| 用户组名称 | 字符串 | 到期时间 | Optional<LocalDateTime> |
示例:
public static void main(String[] args) {
System.out.println(Wrapper.getExpiredDate("用户组").get());
}getExpiredDates
获取该用户所有用户组到期时间
成功则返回到期时间映射表
失败则返回空映射
本方法应该在登录之后使用
| 返回值 | 描述 |
|---|---|
| 到期时间映射表 | Map<String, LocalDateTime> |
示例:
public static void main(String[] args) {
System.out.println(Wrapper.getExpiredDates());
}hasRole
判断是否拥有某用户组
成功则返回 true
失败则返回 false
本方法应该在登录之后使用
| 参数 | 描述 | 返回值 | 描述 |
|---|---|---|---|
| 用户组名称 | 字符串 | 是否存在 | 布尔值 |
示例:
public static void main(String[] args) {
System.out.println(Wrapper.hasRole("用户组"));
}@LoadAfterLogin 注解
在登录之后加载指定类
本注解只能注解在 Class 中
| 参数 | 描述 |
|---|---|
| 用户组名称 (value) | 字符串 |
| 优先级 (priority) | 整数 |
优先级数字越小越先加载。
警告
在动态加载 Class 时,会自动初始化该 Class。
您很可能需要延后初始化/手动初始化/按照正常 Class 初始化顺序初始化该类的静态字段和静态代码块中的代码。
否则可能会出现不必要的错误。
示例:
@LoadAfterLogin(value = "用户组A", priority = 0)
public class ClassA {
}