当前位置: 首页 > wzjs >正文

免费seo推广软件郑州seo技术培训班

免费seo推广软件,郑州seo技术培训班,高州手机网站建设公司,大气公司网站源码版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ Android 线程相关命令 获取 PID adb shell pidof com.shizhuang.duapp查看线程信息 方法一:进入 /proc//task 进入 adb shell 执行下面命令 c…

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/

Android 线程相关命令

获取 PID

adb shell pidof com.shizhuang.duapp

查看线程信息

方法一:进入 /proc//task

进入 adb shell 执行下面命令

cd /proc/$(pidof com.shizhuang.duapp)/task
ls

这个目录中每一个子目录的名字就是该 App 的一个线程的 TID(Thread ID)。

你还可以进一步查看每个线程的状态:

cat /proc/$(pidof com.shizhuang.duapp)/task/<tid>/status

例如:

cat /proc/$(pidof com.shizhuang.duapp)/task/22432/status

方法二:使用 top 或 htop 查看线程

使用 top 查看线程信息

top -H -p $(pidof com.shizhuang.duapp)
  • -H 表示以线程方式查看

  • -p 指定 PID

word/media/image1.png

或者使用 htop 查看线程信息

htop -p $(pidof com.shizhuang.duapp)

word/media/image2.png

通过 kill 命令 停止 / 挂起 / 恢复线程

kill 是 Linux 系统中用来向进程发送信号的命令,最常用于终止进程。虽然它名字叫 “kill”,但它可以发送多种信号,不只是“终止”。

进入 adb shell,比如线程/进程 id 为 22432

# 停止指定进程/线程 
kill 22432# 强制停止进程/线程
kill -9 22432# 强制停止 com.cyrus.example
kill -9 $(pidof com.cyrus.example)# 挂起进程/线程
kill -19 22432# 继续进程/线程
kill -18 22432

kill 命令详细介绍:https://man7.org/linux/man-pages/man1/kill.1.html

常见信号类型(默认是 SIGTERM):

信号名数值含义
SIGHUP1挂起信号,通常用于重启进程配置
SIGINT2中断信号,类似 Ctrl+C
SIGQUIT3退出信号,类似 Ctrl+\
SIGKILL9强制终止信号(无法捕获)
SIGTERM15终止信号(可捕获、默认)
SIGSTOP19暂停进程(无法捕获)
SIGCONT18恢复被暂停的进程

使用 Frida 调用 kill 命令

kill 在 C 语言中是定义在 <signal.h> 中的一个标准函数,它本质上是一个系统调用的封装函数。

kill 函数(C 标准库中的定义)

#include <signal.h>int kill(pid_t pid, int sig);
  • pid:要发送信号的进程 ID。

  • sig:要发送的信号编号,比如 SIGKILL, SIGTERM, SIGSTOP 等。

  • 返回值:返回 0 表示成功。返回 -1 表示失败,并设置 errno。

在底层,kill() 实际上会触发系统调用(比如 Linux 的 syscall kill),让内核发送信号给指定的进程。

它是 UNIX/Linux 系统里最常用的进程间通信(IPC)手段之一。

1. JS + NativeFunction 调用 libc 中的 kill

查找 libc 中的 kill 函数,并使用 NativeFunction 封装引用

const killPtr = Module.findExportByName(null, 'kill');
const kill = new NativeFunction(killPtr, 'int', ['int', 'int']);

2. 在 JS 中调用这个函数

挂起线程

// 挂起进程
const result = kill(22432, 19);if (result === 0) {console.log("✅ Signal sent!");
} else {console.log("❌ Failed to send signal.");
}

恢复线程

// 恢复线程
const result = kill(22432, 18);if (result === 0) {console.log("✅ Signal sent!");
} else {console.log("❌ Failed to send signal.");
}

3. suspendThread / resumeThread

封装 suspendThread / resumeThread 函数用于挂起和恢复线程。

kill.js:

// 加载 libc 中的 kill 函数
const killPtr = Module.findExportByName(null, 'kill');
const kill = new NativeFunction(killPtr, 'int', ['int', 'int']);// 信号常量
const SIGSTOP = 19;  // 暂停进程(不可被捕获)
const SIGCONT = 18;  // 继续执行进程// 封装 suspend/resume 函数
function suspendThread(pid) {const result = kill(pid, SIGSTOP);if (result === 0) {console.log(`✅ 成功挂起 PID=${pid}`);} else {console.log(`❌ 挂起失败 PID=${pid}`);}
}function resumeThread(pid) {const result = kill(pid, SIGCONT);if (result === 0) {console.log(`✅ 成功恢复 PID=${pid}`);} else {console.log(`❌ 恢复失败 PID=${pid}`);}
}

执行脚本:

frida -H 127.0.0.1:1234 -F -l kill.js

调用示例:

 // 挂起线程 
suspendThread(22432);  // 替换为目标线程或进程的 PID// 恢复线程
resumeThread(22432);

word/media/image3.png

suspendOtherThread

实现一个 suspendOtherThread 函数,挂起除了 excludeList 中指定名字的所有线程。

1. 读取线程列表

遍历 /proc/${pid}/task/ 目录下所有目录的名称得到 线程id

const taskDir = `/proc/${pid}/task/`;var dirList = Java.use('java.io.File').$new(taskDir).listFiles()for (let i = 0; i < dirList.length; i++) {// 线程idconst tid = parseInt(dirList[i].getName());}

2. 读取线程名称

线程名称就在 /proc/ p i d / t a s k / {pid}/task/ pid/task/{tid}/comm 文件中,读取 comm 文件内容得到线程名称。

/*** 读取文件内容并返回字符串** @param path 文件路径* @returns {string|null} 文件内容*/
function readFileAsString(path) {const File = Java.use("java.io.File");const FileInputStream = Java.use("java.io.FileInputStream");const InputStreamReader = Java.use("java.io.InputStreamReader");const BufferedReader = Java.use("java.io.BufferedReader");const StringBuilder = Java.use("java.lang.StringBuilder");const file = File.$new(path);if (!file.exists()) {console.log(`❌ 文件不存在: ${path}`);return null;}const fis = FileInputStream.$new(file);const isr = InputStreamReader.$new(fis, "UTF-8");const reader = BufferedReader.$new(isr);const sb = StringBuilder.$new();let line;while ((line = reader.readLine()) !== null) {sb.append(line);}reader.close();return sb.toString();
}/*** comm 文件内容就是线程名称** @param pid   进程 id* @param tid   线程 id* @returns {string} 线程名称*/
function readComm(pid, tid) {const path = `/proc/${pid}/task/${tid}/comm`;return readFileAsString(path);
}

相关文档:

  • https://docs.oracle.com/javase/8/docs/api/java/io/File.html

  • https://frida.re/docs/javascript-api/#file

3. 挂起线程

挂起除了 excludeList 中指定名字的所有线程

function suspendOtherThread(pid, excludeList) {Java.perform(function () {const taskDir = `/proc/${pid}/task/`;var dirList = Java.use('java.io.File').$new(taskDir).listFiles()for (let i = 0; i < dirList.length; i++) {const tid = parseInt(dirList[i].getName());if (isNaN(tid)) continue;const threadName = readComm(pid, tid);if (!threadName) continue;// 只要 threadName 包含 excludeList 中的任意关键字,就会被排除(跳过不挂起)if (excludeList.some(keyword => threadName.includes(keyword))) {console.log(`🟢 跳过线程 "${threadName}" (TID=${tid})`);} else {console.log(`🛑 挂起线程 "${threadName}" (TID=${tid})`);suspendThread(tid);}}})
}

4. 调用示例

// 示例:只保留 excludeList 中指定的线程运行,其它全部挂起
const pid = Process.id;
const excludeList = ["main","RenderThread","m.cyrus.example","frida",
];suspendOtherThread(pid, excludeList);

执行脚本

frida -H 127.0.0.1:1234 -F -l kill.js

效果如下:

word/media/image4.png

resumeOtherThread

恢复线程也是类似。

/*** 恢复除了 excludeList 中指定名字的所有线程* @param {number} pid - 当前进程 PID* @param {string[]} excludeList - 不需要恢复的线程名字数组*/
function resumeOtherThread(pid, excludeList) {Java.perform(function () {const taskDir = `/proc/${pid}/task/`;var dirList = Java.use('java.io.File').$new(taskDir).listFiles()for (let i = 0; i < dirList.length; i++) {const tid = parseInt(dirList[i].getName());if (isNaN(tid)) continue;const threadName = readComm(pid, tid);if (!threadName) continue;// 只要 threadName 包含 excludeList 中的任意关键字,就会被排除(跳过不恢复)if (excludeList.some(keyword => threadName.includes(keyword))) {console.log(`🟢 跳过线程 "${threadName}" (TID=${tid})`);} else {console.log(`🔄 恢复线程 "${threadName}" (TID=${tid})`);resumeThread(tid);}}})
}

执行脚本

frida -H 127.0.0.1:1234 -F -l kill.js

调用示例:

// 示例:只保留 excludeList 中指定的线程运行,其它全部挂起
const pid = Process.id;
const excludeList = ["main","RenderThread","m.cyrus.example","frida",
];resumeOtherThread(pid, excludeList);

输出如下:

🟢 跳过线程 "m.cyrus.example" (TID=31263)
🔄 恢复线程 "Jit thread pool" (TID=31269)
✅ 成功恢复 PID=31269
🔄 恢复线程 "Signal Catcher" (TID=31274)
✅ 成功恢复 PID=31274
🔄 恢复线程 "ADB-JDWP Connec" (TID=31275)
✅ 成功恢复 PID=31275
🔄 恢复线程 "HeapTaskDaemon" (TID=31276)
✅ 成功恢复 PID=31276
🔄 恢复线程 "ReferenceQueueD" (TID=31277)
✅ 成功恢复 PID=31277
🔄 恢复线程 "FinalizerDaemon" (TID=31278)
✅ 成功恢复 PID=31278
🔄 恢复线程 "FinalizerWatchd" (TID=31279)
✅ 成功恢复 PID=31279
🔄 恢复线程 "Binder:31263_1" (TID=31280)
✅ 成功恢复 PID=31280
🔄 恢复线程 "Binder:31263_2" (TID=31281)
✅ 成功恢复 PID=31281
🔄 恢复线程 "Binder:31263_3" (TID=31282)
✅ 成功恢复 PID=31282
🔄 恢复线程 "Profile Saver" (TID=31283)
✅ 成功恢复 PID=31283
🟢 跳过线程 "RenderThread" (TID=31284)
🔄 恢复线程 "Binder:31263_4" (TID=31287)
✅ 成功恢复 PID=31287
🟢 跳过线程 "m.cyrus.example" (TID=31293)
🟢 跳过线程 "gmain" (TID=31294)
🔄 恢复线程 "gdbus" (TID=31296)
✅ 成功恢复 PID=31296
🔄 恢复线程 "Thread-20" (TID=31297)
✅ 成功恢复 PID=31297
🟢 跳过线程 "m.cyrus.example" (TID=31263)
🔄 恢复线程 "Jit thread pool" (TID=31269)
✅ 成功恢复 PID=31269
🔄 恢复线程 "Signal Catcher" (TID=31274)
✅ 成功恢复 PID=31274
🔄 恢复线程 "ADB-JDWP Connec" (TID=31275)
✅ 成功恢复 PID=31275
🔄 恢复线程 "HeapTaskDaemon" (TID=31276)
✅ 成功恢复 PID=31276
🔄 恢复线程 "ReferenceQueueD" (TID=31277)
✅ 成功恢复 PID=31277
🔄 恢复线程 "FinalizerDaemon" (TID=31278)
✅ 成功恢复 PID=31278
🔄 恢复线程 "FinalizerWatchd" (TID=31279)
✅ 成功恢复 PID=31279
🔄 恢复线程 "Binder:31263_1" (TID=31280)
✅ 成功恢复 PID=31280
🔄 恢复线程 "Binder:31263_2" (TID=31281)
✅ 成功恢复 PID=31281
🔄 恢复线程 "Binder:31263_3" (TID=31282)
✅ 成功恢复 PID=31282
🔄 恢复线程 "Profile Saver" (TID=31283)
✅ 成功恢复 PID=31283
🟢 跳过线程 "RenderThread" (TID=31284)
🔄 恢复线程 "Binder:31263_4" (TID=31287)
✅ 成功恢复 PID=31287
🟢 跳过线程 "m.cyrus.example" (TID=31293)
🟢 跳过线程 "gmain" (TID=31294)
🔄 恢复线程 "gdbus" (TID=31296)
✅ 成功恢复 PID=31296
🔄 恢复线程 "Thread-38" (TID=31297)
✅ 成功恢复 PID=31297

完整源码

// 加载 libc 中的 kill 函数
const killPtr = Module.findExportByName(null, 'kill');
const kill = new NativeFunction(killPtr, 'int', ['int', 'int']);// 信号常量
const SIGSTOP = 19;  // 暂停进程(不可被捕获)
const SIGCONT = 18;  // 继续执行进程/*** 挂起线程** @param pid 线程 id*/
function suspendThread(pid) {const result = kill(pid, SIGSTOP);if (result === 0) {console.log(`✅ 成功挂起 PID=${pid}`);} else {console.log(`❌ 挂起失败 PID=${pid}`);}
}/*** 恢复线程** @param pid 线程 id*/
function resumeThread(pid) {const result = kill(pid, SIGCONT);if (result === 0) {console.log(`✅ 成功恢复 PID=${pid}`);} else {console.log(`❌ 恢复失败 PID=${pid}`);}
}/*** 读取文件内容并返回字符串** @param path 文件路径* @returns {string|null} 文件内容*/
function readFileAsString(path) {const File = Java.use("java.io.File");const FileInputStream = Java.use("java.io.FileInputStream");const InputStreamReader = Java.use("java.io.InputStreamReader");const BufferedReader = Java.use("java.io.BufferedReader");const StringBuilder = Java.use("java.lang.StringBuilder");const file = File.$new(path);if (!file.exists()) {console.log(`❌ 文件不存在: ${path}`);return null;}const fis = FileInputStream.$new(file);const isr = InputStreamReader.$new(fis, "UTF-8");const reader = BufferedReader.$new(isr);const sb = StringBuilder.$new();let line;while ((line = reader.readLine()) !== null) {sb.append(line);}reader.close();return sb.toString();
}/*** comm 文件内容就是线程名称** @param pid   进程 id* @param tid   线程 id* @returns {string} 线程名称*/
function readComm(pid, tid) {const path = `/proc/${pid}/task/${tid}/comm`;return readFileAsString(path);
}/*** 挂起除了 excludeList 中指定名字的所有线程* @param {number} pid - 当前进程 PID* @param {string[]} excludeList - 不需要挂起的线程名字数组*/
function suspendOtherThread(pid, excludeList) {Java.perform(function () {const taskDir = `/proc/${pid}/task/`;var dirList = Java.use('java.io.File').$new(taskDir).listFiles()for (let i = 0; i < dirList.length; i++) {const tid = parseInt(dirList[i].getName());if (isNaN(tid)) continue;const threadName = readComm(pid, tid);if (!threadName) continue;// 只要 threadName 包含 excludeList 中的任意关键字,就会被排除(跳过不挂起)if (excludeList.some(keyword => threadName.includes(keyword))) {console.log(`🟢 跳过线程 "${threadName}" (TID=${tid})`);} else {console.log(`🛑 挂起线程 "${threadName}" (TID=${tid})`);suspendThread(tid);}}})
}/*** 恢复除了 excludeList 中指定名字的所有线程* @param {number} pid - 当前进程 PID* @param {string[]} excludeList - 不需要恢复的线程名字数组*/
function resumeOtherThread(pid, excludeList) {Java.perform(function () {const taskDir = `/proc/${pid}/task/`;var dirList = Java.use('java.io.File').$new(taskDir).listFiles()for (let i = 0; i < dirList.length; i++) {const tid = parseInt(dirList[i].getName());if (isNaN(tid)) continue;const threadName = readComm(pid, tid);if (!threadName) continue;// 只要 threadName 包含 excludeList 中的任意关键字,就会被排除(跳过不恢复)if (excludeList.some(keyword => threadName.includes(keyword))) {console.log(`🟢 跳过线程 "${threadName}" (TID=${tid})`);} else {console.log(`🔄 恢复线程 "${threadName}" (TID=${tid})`);resumeThread(tid);}}})
}// 示例:只保留 excludeList 中指定的线程运行,其它全部挂起
const pid = Process.id;
const excludeList = ["main","RenderThread","m.cyrus.example","frida",
];// suspendOtherThread(pid, excludeList);
resumeOtherThread(pid, excludeList);

执行脚本

frida -H 127.0.0.1:1234 -F -l kill.js

开源地址:https://github.com/CYRUS-STUDIO/frida_thread

http://www.dtcms.com/wzjs/529073.html

相关文章:

  • 信用网站建设标准合作seo公司
  • 网站 板块 模块免费网站推广网址
  • 个人网站可以做淘宝客百度首页 百度一下
  • 怎么下载黑龙江人社app优化网站链接的方法
  • 帮别人做设计图的网站我想做地推怎么找渠道
  • 专门做蛋糕面包的网站晚上网站推广软件免费版
  • 老域名对做网站的nba最新排名榜
  • 做网站流量赚钱站长工具ping检测
  • 自己做网络棋牌网站流程推广普通话心得体会
  • 做我的世界壁纸网站seo优化工具推荐
  • 网站服务器备案查询网站关键词优化设计
  • 微服务网站开发国内新闻摘抄
  • 苏州化妆品网站建设新乡网站seo
  • 网络营销型网站设计电商广告网络推广
  • 做什么网站好百度竞价渠道户
  • 建设好网站靠什么赚钱如何做网站
  • 网站开发创意想法推广公司是做什么的
  • 广告平面设计作品seo怎么弄
  • 长春设计网站seo每天一贴博客
  • 免费网站做seo有哪些推广平台和渠道
  • 网站设计速成百度指数查询排行榜
  • 网站制作案例图片成都本地推广平台
  • 套模板做网站流程网络营销的方式都有哪些
  • 自家电脑做网站搜狗网站收录
  • 公司做网站发生的费用分录网球新闻最新消息
  • 点子网站制作百度指数分析官网
  • 哈尔滨建设网站制作杭州小周seo
  • php二次网站开发步骤常见的网络营销方式
  • 网站目录创建下载链接哪里能搜索引擎优化
  • 用手机做网站的软件百度首页 百度