当前位置:首页>学习笔记>Unidbg学习笔记(七):JNI 层补环境

Unidbg学习笔记(七):JNI 层补环境

  • 2026-04-17 19:13:08
Unidbg学习笔记(七):JNI 层补环境

90% 的补环境工作发生在 JNI 层。一旦把它拆成"类型 / 取值 / 逻辑"三个维度,这件事就从"痛苦的试错"变成"流程化的操作"。你不再需要记住每个 case 怎么写,你只需要记住这三个问题该问谁。


上一篇把你留在了哪里

上一篇中我们说,补环境是角色扮演,所有外部交互落在四个通道里。其中 JNI 通道占工作量的 90%,是你要扎根最深的那一个。这一篇就专门讲它。

但我要先做一次小小的切换:前面六篇都是在讲"世界观"—— 为什么、是什么、该怎么想。从这篇开始,接下来几篇会非常操作化:给你看代码模板、工具命令、实战流程。

换句话说:前六篇让你明白"补环境是什么",接下来几篇让你明白"补环境怎么做"。


为什么 JNI 补环境"看起来"这么痛苦

刚入门的人写 JNI override 的典型场景是这样的:

  1. 看到一条报错,UnsupportedOperationException: android/os/Build->getSerial()...
  2. 跑去 AbstractJni 的源码里找:callStaticObjectMethodV? callObjectMethodV? 哪一个?
  3. 猜一个,写一个 switch case,复制一份 signature 字符串
  4. 返回一个 new StringObject(vm, "unknown")
  5. 再跑一遍,第二条报错冒出来
  6. 回到第 1 步

每一次新报错都像从头做一遍。你没有"节奏感",没有"套路",整个过程全靠肌肉记忆。半年之后你可能会"熟能生巧",但那不是理解,那只是习惯。

真正的熟练不是"更快地试错",而是把每次报错分解成固定的三个问题,然后用固定的方式逐一回答。


三个维度:把一个 JNI 补环境请求拆成三个问题

任何一次 JNI override,本质上都在回答三个独立的问题:

JNI 补环境的三个维度
维度
问题
答案来自
维度一:类型
我该用哪个返回类型?(Object?int?boolean?)
Unidbg 的报错栈
维度二:取值
返回什么具体的值?("HUAWEI" 还是 "Samsung"?)
Frida / adb / r0tracer
维度三:逻辑
不是单纯返回值,是要执行一段逻辑?
源码 / JDK / 降级策略

这三个维度互相独立。类型不对,取值再对也白搭;取值不对,类型正确也会让签名错;逻辑维度是高阶情况,只有少数方法属于这一类。

关键的简化:一旦你把这三个维度拆开,就可以逐个击破。不要再一次性想"我怎么补 getPackageInfo"。先回答"它该返回什么类型",再回答"该返回什么值",必要时再考虑"它背后要不要真的执行一段逻辑"。

下面我们把这三个维度逐个拆开。


维度一:返回什么类型 — 报错栈直接告诉你

这一维度是最容易的。你完全不需要猜,Unidbg 已经把答案写在报错栈里了。

栈顶方法名 = 返回类型

回忆第五篇的报错三段式:段二是 Unidbg 内部栈,栈顶那一帧一定是 AbstractJni.callXxxMethodV 或 AbstractJni.getXxxField 这样的方法。这个方法名里藏着完整的类型信息

看几个例子:

栈顶方法名拆解三例:callObjectMethodV / callStaticIntMethodV / getStaticObjectField

命名规则非常规整,把它拆开看就能秒懂:

位置
可选值
含义
第 1 段
call
 / get / set / new
调用方法 / 读字段 / 写字段 / 创建对象
第 2 段(可选)
Static
有就是静态方法/字段,无就是实例方法/字段
第 3 段
Object
 / Int / Long / Boolean / Byte / Float / Double / Void
返回类型
第 4 段
Method
 / Field
调方法还是读字段
第 5 段(可选)
V
表示接收 va_list 形式的可变参数(Unidbg 内部用这个版本)

实用记忆

  • 栈顶是 callXxxMethodV —— 你要 override 它
  • Xxx 告诉你返回类型
  • 带 Static 就是静态方法,不带就是实例方法

这一维度唯一需要注意的坑:callObjectMethodV 和 callObjectMethod 是两个不同的方法。Unidbg 内部几乎总是走 V 版本(因为 ARM 调用约定里参数走 va_list)。你 override 时认准带 V 的那个,不带 V 的版本可以完全无视。

六种返回模式的代码模板

明确了返回类型后,下一个问题是怎么构造这个返回值。Unidbg 给你准备了一套固定的"包装类",每个类型对应一个模板。背下这六个模板,你就能应付 95% 的 JNI override。

六种返回模式及代码模板

模板 1:基本类型(int / long / boolean)— 直接返回数值

@Override
publicintcallIntMethodV(BaseVM vm, DvmObject<?> dvmObject,
                          DvmMethod dvmMethod, VaList vaList)
{
    String signature = dvmMethod.getSignature();
switch (signature) {
// android/os/Build$VERSION 里的 SDK_INT, 直接返回整数
case"android/os/Build$VERSION->SDK_INT:I":
return29;  // Android 10
// 屏幕宽度, 单位是像素
case"android/view/Display->getWidth()I":
return1080;
    }
returnsuper.callIntMethodV(vm, dvmObject, dvmMethod, vaList);
}

模板 2:字符串 — 用 StringObject 包装

@Override
public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject,
                                       DvmMethod dvmMethod, VaList vaList) {
    String signature = dvmMethod.getSignature();
switch (signature) {
// 设备型号字符串, 必须用 StringObject 包装
case"android/os/Build->getModel()Ljava/lang/String;":
returnnew StringObject(vm, "MI 10");
// IMEI, 同样是字符串
case"android/telephony/TelephonyManager->getDeviceId()Ljava/lang/String;":
returnnew StringObject(vm, "864394010105011");
    }
returnsuper.callObjectMethodV(vm, dvmObject, dvmMethod, vaList);
}

模板 3:字节数组 — 用 ByteArray 包装

case"com/example/Native->getSignBytes()[B":
// 签名字节数组, 必须包成 ByteArray
byte[] signBytes = newbyte[] { 0x30, (byte0x820x01, (byte0xE3, ... };
returnnew ByteArray(vm, signBytes);

模板 4:自定义对象 — ProxyDvmObject 最灵活

case"android/content/pm/PackageManager->getPackageInfo(Ljava/lang/String;I)"
   + "Landroid/content/pm/PackageInfo;":
// 伪造一个 PackageInfo 对象, 利用 JDK 反射 + 动态代理
// ProxyDvmObject 内部会根据后续方法调用动态响应
try {
        Object packageInfo = new Object() {
public String packageName = "com.example.app";
publicint versionCode = 123;
public String versionName = "1.2.3";
public Object[] signatures = new Object[] { fakeSignature };
        };
return ProxyDvmObject.createObject(vm, packageInfo);
    } catch (Exception e) {
thrownew IllegalStateException(e);
    }

模板 5:JDK 真实类 — resolveClass + newObject

case"java/util/HashMap-><init>()V":
// HashMap 这种 JDK 自带的类, 直接让 Unidbg 用反射绑定真实 Java 类
// 后续所有方法调用会自动走 JDK 的 HashMap 实现
return vm.resolveClass("java/util/HashMap").newObject(new HashMap<>());

模板 6:装箱类型 — DvmInteger / DvmBoolean

case"android/os/Build->getSomeIntegerField()Ljava/lang/Integer;":
// 注意签名返回的是 Ljava/lang/Integer; (装箱类型)
// 不是 int, 所以要用 DvmInteger 包装
return DvmInteger.valueOf(vm, 42);

速查表

返回类型(签名)
用什么构造
举例
I
 / J / Z
直接 return 数值
return 1;
Ljava/lang/String;StringObjectnew StringObject(vm, "...")
[BByteArraynew ByteArray(vm, bytes)
Landroid/xxx/Xxx;
(App 内部类或难构造)
ProxyDvmObject.createObject
见模板 4
Ljava/util/HashMap;
 / Ljava/io/File; 等 JDK 类
resolveClass().newObject()
见模板 5
Ljava/lang/Integer;
 / Ljava/lang/Boolean; 等装箱类
DvmInteger.valueOf
 等
见模板 6

认清这六个模板,维度一这件事就结束了


维度二:返回什么值 — 信息收集工具箱

维度一解决了"用什么形式包装",维度二解决"装进去的具体内容是什么"。

这个维度才是真正的核心。因为:

  • 类型错了 → 代码崩,立刻发现
  • 值错了 → 代码不崩,但最终签名 / 加密结果是错的,你看不到任何报错

这也是第六篇反复强调的"真正危险的是补错了不知道"。所以你不能拍脑袋猜 "HUAWEI",你需要从真机上取真实值

下面这张图是你所有取值工具的全景:

JNI 取值工具箱

按照"简单先用"的原则,工具箱从轻到重排列:

工具一:adb shell — 适合设备全局信息

最轻量。凡是 android.os.Build 这种全设备共享的属性,直接用 adb shell getprop 就能拿到。

# 获取设备型号, 对应 Build->getModel()
adb shell getprop ro.product.model
# 输出: MI 10

# 获取厂商, 对应 Build->getManufacturer()
adb shell getprop ro.product.manufacturer
# 输出: Xiaomi

# 获取 Android 版本, 对应 Build$VERSION->RELEASE
adb shell getprop ro.build.version.release
# 输出: 11

# 获取 API level, 对应 Build$VERSION->SDK_INT
adb shell getprop ro.build.version.sdk
# 输出: 30

# 获取屏幕分辨率, 对应 Display->getRealSize
adb shell wm size
# 输出: Physical size: 1080x2340

# 获取屏幕密度, 对应 Display->getDensity
adb shell wm density
# 输出: Physical density: 440

# 查看当前 SIM 卡运营商, 对应 TelephonyManager->getSimOperatorName
adb shell dumpsys telephony.registry | grep mServiceState

适用场景:凡是可以从系统属性直接读出来的,优先 adb shell。不需要写代码,不需要注入,几秒钟就搞定。

局限getprop 只能拿 Android 系统属性,拿不到 App 内部状态(SharedPreferences、类字段),也拿不到需要权限的值(IMEI、硬件 ID)。

工具二:Frida — 适合动态拿单个方法的返回值

当某个方法的返回值是运行时才算出来的(例如 MessageDigest.digest() 的结果、getApplicationInfo().metaData.getString("API_KEY")),adb 就无能为力了。这时候上 Frida。

场景 A:Hook 法 — 被动抓取

等 App 自己调到这个方法,你就能看到真实返回值:

// Frida hook 脚本, 被动等 App 调用 getDeviceId 时打印返回值
Java.perform(function() {
var TelephonyManager = Java.use('android.telephony.TelephonyManager');
// 重载需要用 overload 指定参数签名, 避免多个同名方法匹配冲突
    TelephonyManager.getDeviceId.overload().implementation = function() {
var result = this.getDeviceId();  // 先调真实方法, 拿到真实返回
console.log('[*] getDeviceId() => ' + result);
return result;  // 返回给 App, 不影响正常运行
    };
});

场景 B:主动 Call — 不等调用

如果这个方法 App 暂时不会调(比如只在登录时调),你可以主动 Call 它:

// Frida 主动 Call: 不等 App 自己调, 直接在 loadLibrary 后拿到 Context, 主动调方法
Java.perform(function() {
// 获取当前 App 的 Application 实例
var currentApplication = Java.use('android.app.ActivityThread')
        .currentApplication();
var context = currentApplication.getApplicationContext();

// 主动调 PackageManager.getPackageInfo 拿签名
var pm = context.getPackageManager();
// GET_SIGNATURES = 64, 告诉 PM 把签名信息一起返回
var pi = pm.getPackageInfo(context.getPackageName(), 64);

// 把签名字节打印成 hex 字符串, 方便复制到 Unidbg 代码里
var signatures = pi.signatures.value;
for (var i = 0; i < signatures.length; i++) {
var bytes = signatures[i].toByteArray();
var hex = '';
for (var j = 0; j < bytes.length; j++) {
// 处理 Java byte 可能为负的情况
            hex += ('0' + (bytes[j] & 0xFF).toString(16)).slice(-2);
        }
console.log('[*] signature[' + i + '] hex = ' + hex);
    }
});

适用场景:抓单个方法、单个字段的返回值,精确可控。

局限:一次只能抓一个。如果你要补 30 个 JNI 回调,写 30 段 Frida 脚本会很累。这时候上下一个工具。

工具三:r0tracer — 批量 trace 一整个类

r0tracer 是 Frida 之上的一个批量 trace 框架。它的核心能力是:给一个类名,自动 hook 这个类的所有方法和字段,打印调用顺序 / 入参 / 返回值

// r0tracer 批量 trace 示例, 一次抓一整个类
// 运行后会自动 hook TelephonyManager 所有公开方法
var ClassName = 'android.telephony.TelephonyManager';
classMethodsTracer(ClassName);

// 或者一次 trace 一个包下的所有类
var PackageName = 'android.os.Build';
classAllMethodsTracer(PackageName);

输出长这样:

*** entered android.telephony.TelephonyManager.getDeviceId
arg[0]: undefined
*** exiting android.telephony.TelephonyManager.getDeviceId
retval: 864394010105011
*** entered android.telephony.TelephonyManager.getSubscriberId
arg[0]: undefined
*** exiting android.telephony.TelephonyManager.getSubscriberId
retval: 460001234567890

你只需要让 App 正常走一次流程,r0tracer 就会把 SO 访问的所有方法 / 字段及其返回值都列出来。把这些值直接粘贴到 Unidbg 的 switch case 里,就完成了整个类的补环境。

实用技巧:关掉调用栈,只留值

r0tracer 默认会打印每次调用的 Java 调用栈,在 trace 几十个方法时控制台会刷屏。打开 r0tracer.js,找到类似:

console.log(Thread.backtrace(this.context,
            Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n'));

把这一行注释掉,或者在 onEnter / onLeave 里注释掉 backtrace 的打印逻辑。输出就会变得极其干净:只剩方法名、入参、返回值,一眼就能扫完。

适用场景:一次补一整个类、一整个包、一个复杂样本的首轮"摸底"。

工具选择原则

需要一个全局属性(型号、版本、分辨率)?
    → adb shell getprop / wm / dumpsys

需要一个动态方法的返回值(digest、签名字节、API Key)?
    → Frida Hook 或主动 Call

需要一次搞定一整个类 / 一整个包的所有方法?
    → r0tracer 批量 trace

所有都拿不到, 或者方法是 App 私有的?
    → 上 JADX 看 Java 层代码, 照实现抄过来(见维度三)

维度三:返回什么逻辑 — 当一个"值"不够用

前两个维度的假设是:SO 调一个 Java 方法,想要一个确定的返回值。你只要把这个值伪造对就行。

但**有时候 SO 调的不是一个"getter",它调的是一段"动作"**。

举几个典型:

  • SO 调 SimpleDateFormat.format(new Date()):它需要一个格式化后的时间字符串,但你事先不知道 SO 什么时候调这个方法,也不知道会传什么时间进来。写死返回 "2024-01-01" 可能让后面的签名算法直接崩(因为第二次调会拿到同样的假时间,算出同样的签名)。
  • SO 调 HashMap.put(key, value) 再 HashMap.get(key):它期望这是一个真实的 Map,存进去的东西能取出来。写死返回一个空 HashMap 不行,因为 get 拿不到值。
  • SO 调 SharedPreferences.getString("some_key", "default"):你不知道 SO 会读哪些 key,手动写 case 来应付所有 key 很累。
  • SO 调 Base64.encodeToString(bytes, flags):你得真的把 bytes 做一次 Base64 编码再返回。

这些情况下你**没法只"返回一个值"**,你得"执行一段逻辑"。

四种处理策略

按照投入成本从低到高排列,先试简单的:

策略 1:JDK 内置类 → 直接绑定

如果这个类是 Java 标准库自带的(java.util.HashMapjava.util.ArrayListjava.text.SimpleDateFormatjava.lang.StringBuilder 等),就让 Unidbg 把它绑定到真实的 JDK 类上。你不需要写任何 case,后续所有方法调用会自动走 JDK 实现。

// 在 callObjectMethodV 里: SO new 一个 HashMap
case"java/util/HashMap-><init>()V":
// 返回一个真实的 JDK HashMap 实例, 后续 put/get 全部由 JDK 处理
return vm.resolveClass("java/util/HashMap").newObject(new HashMap<>());

// 或者更优雅: 在 setJni 之前, 直接让整个类走 JDK
vm.resolveClass("java/util/HashMap");

优点:零代码,JDK 保证行为完全正确。适用java/util/*java/text/*java/lang/* 几乎所有工具类。

策略 2:App 自定义类 → JADX 反编译后复制逻辑

如果这个类是 App 自己写的(com.example.app.utils.Encryptor),JDK 没有它,Android Framework 也没有它。这时候上 JADX:

1. 用 JADX 打开 APK
2. 搜索类名, 找到对应的 Java 源码
3. 把实现逻辑原样复制到 Unidbg 代码里
4. override 对应方法时, 调你复制过来的 Java 实现
// 假设 JADX 反编译后发现 Encryptor.encrypt 只是一个 AES 封装
// 直接把这段 Java 逻辑搬到 Unidbg 项目里做成工具类
case"com/example/app/utils/Encryptor->encrypt([B[B)[B":
    DvmObject<?> arg0 = vaList.getObjectArg(0);  // data
    DvmObject<?> arg1 = vaList.getObjectArg(1);  // key
byte[] data = (byte[]) arg0.getValue();
byte[] key = (byte[]) arg1.getValue();
// 调你自己的 Java 复刻实现
byte[] result = MyEncryptor.encrypt(data, key);
returnnew ByteArray(vm, result);

优点:逻辑和真机完全一致,结果一定对。代价:要读懂 JADX 反编译出来的 Java 代码。对复杂的类来说这一步最耗时。适用:App 自己实现的 Util / Helper / Encoder 类。

策略 3:Framework 类 → 手动简化实现

Android Framework 自带的类(SharedPreferencesBase64PackageInfo)JDK 里没有,App 里也没有。这时候需要你手动简化一个实现

"简化"的意思是:你不需要 100% 复刻 Framework 的行为,只要让 SO 拿到想要的结果就行

// Base64 的手动实现: 直接用 JDK 自带的 java.util.Base64 当后端
case"android/util/Base64->encodeToString([BI)Ljava/lang/String;":
    DvmObject<?> bytesArg = vaList.getObjectArg(0);
int flags = vaList.getIntArg(1);
byte[] bytes = (byte[]) bytesArg.getValue();

// Android 的 Base64 flag 分为 DEFAULT / NO_WRAP / URL_SAFE 等
// 这里只处理最常见的 NO_WRAP (flag=2)
    String encoded;
if ((flags & 2) != 0) {  // NO_WRAP
        encoded = java.util.Base64.getEncoder()
                      .withoutPadding()
                      .encodeToString(bytes);
    } else {
        encoded = java.util.Base64.getEncoder().encodeToString(bytes);
    }
returnnew StringObject(vm, encoded);

优点:绕过了 Framework 依赖,实现透明可控。代价:要理解 Framework 类的关键行为。适用android/util/Base64android/content/SharedPreferencesandroid/os/Bundle 等。

策略 4:复杂逻辑 → 降级返回 null

有时候某个方法太复杂、太边缘,你实在不想花时间 ——  直接返回 null 或空值试一下。很多 SO 拿到 null 会走默认分支,不影响最终结果。

// getSomeRarelyUsedInfo 返回 null 试试, 看 SO 会不会崩
case"android/content/pm/PackageManager->getSomeRarelyUsedInfo()Ljava/lang/Object;":
returnnull;

原则:先返回 null 跑一下,如果 SO 能过,这就是最省力的选择;如果 SO 报 NPE 或者拿到 null 后走了错误分支,再回来补策略 1/2/3。

策略 4 的核心思维不要过度补环境。很多时候你想的"SO 需要这个值"其实是错的,它根本不依赖这个值。节省下来的时间应该花在真正关键的补环境上。


验证闭环 — 跑通不等于跑对

整个流程结束后,千万不要以为"没报错 = 成功"。按照第六篇说的思路,你必须走一次值对照

  1. Unidbg 跑出来的签名 / 加密结果记下来
  2. 真机跑同样的输入,用 Frida hook native 入口打印输出
  3. 两个结果一致 → 真通了
  4. 不一致 → 哪个值伪造错了?回到 r0tracer 输出去对比

只有对照通过的补环境才是真的补环境。不对照,你永远不知道哪个 "unknown" 其实不该是 "unknown"


三维度拆解:为什么这个模型有效

回顾整篇文章,我们做的事情其实只有一个:把一个模糊的任务("补环境")拆成三个独立的子任务

分层简化:把"补环境"拆成可管理的子任务

这种分层简化的思维在所有工程问题里都通用:一个看起来巨大的问题,往往只是三四个独立小问题的组合。把它们拆开,每个都变得可管理。

接下来几篇会继续把剩下三个通道 —— 文件访问(第八篇)、系统调用(第九篇)、库函数(第十篇)—— 也用同样的模式化思路讲一遍。你会发现每一个通道都有自己的"维度拆解",而一旦拆开,补环境这件事就不再神秘。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-04-17 20:02:12 HTTP/2.0 GET : https://67808.cn/a/481648.html
  2. 运行时间 : 0.213781s [ 吞吐率:4.68req/s ] 内存消耗:4,658.78kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=1c73024c0710b7cfa469bca0dbc60928
  1. /yingpanguazai/ssd/ssd1/www/no.67808.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/no.67808.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/no.67808.cn/runtime/temp/6df755f970a38e704c5414acbc6e8bcd.php ( 12.06 KB )
  140. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001045s ] mysql:host=127.0.0.1;port=3306;dbname=no_67808;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001797s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.001024s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000677s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001412s ]
  6. SELECT * FROM `set` [ RunTime:0.001288s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001488s ]
  8. SELECT * FROM `article` WHERE `id` = 481648 LIMIT 1 [ RunTime:0.001562s ]
  9. UPDATE `article` SET `lasttime` = 1776427332 WHERE `id` = 481648 [ RunTime:0.005214s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 65 LIMIT 1 [ RunTime:0.000603s ]
  11. SELECT * FROM `article` WHERE `id` < 481648 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001246s ]
  12. SELECT * FROM `article` WHERE `id` > 481648 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001091s ]
  13. SELECT * FROM `article` WHERE `id` < 481648 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.009235s ]
  14. SELECT * FROM `article` WHERE `id` < 481648 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.008900s ]
  15. SELECT * FROM `article` WHERE `id` < 481648 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.008018s ]
0.217607s