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

使用frida来spawn Fork 的子进程

索引

  • 需求
    • 测试程序
        • 父进程代码
        • 子进程代码
    • x64dbg
        • 插件功能
        • 开始调试
    • frida
    • 运行环境
        • 用到的文件和代码

需求

最近在学基础的Windows逆向知识,遇到个小问题。一个进程使用CreateProcessW创建的进程该如何在启动时附加,我想调试这个子进程启动时运行的函数。

谷歌搜索都给我翻烂了,最后发现还是得用英文搜。比如x64dbg attach child process就出现了这个结果: How to debug child process?

在测试完这个x64dbg插件之后,我想着frida有没有这样的功能,于是也搜索了一下frida hook muti process,也出现了一个方案,说是frida10就已经有了这个功能: Frida hook multiple processes

下面我简单说一下这两种的使用方法

测试程序

先用C++写一个简单的测试程序,用来创建子进程,代码很简单,直接调用CreateProcessW来启动一个子进程

父进程代码
#include <windows.h>
#include <iostream>
#include <stdio.h>int main() {// 定义进程信息结构体PROCESS_INFORMATION pi;// 定义启动信息结构体STARTUPINFO si;// 初始化结构体ZeroMemory(&si, sizeof(si));si.cb = sizeof(si);ZeroMemory(&pi, sizeof(pi));// Notepad 可执行文件的路径LPCWSTR notepadPath = L"SubProcess.exe";// 文件路径作为命令行参数LPWSTR cmdLine = NULL;DWORD currentProcessId = GetCurrentProcessId();// 创建新进程if (CreateProcessW(notepadPath, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {printf("新进程已成功创建!\n");printf("新进程的进程ID:%d, 当前进程id: %d \n", pi.dwProcessId, currentProcessId);// 可以等待进程结束,或者继续执行其他操作// WaitForSingleObject(pi.hProcess, INFINITE);// 关闭进程和线程句柄CloseHandle(pi.hProcess);CloseHandle(pi.hThread);}else {printf("无法创建新进程。错误代码:%d", GetLastError());}int i = 0;while (true) {i += 1;printf("*************** 父进程id: %d, 第%d次等待 *******************\n", currentProcessId, i);Sleep(2000);}return 0;
}
子进程代码
#include <stdio.h>
#include <windows.h>int main()
{int i = 0;DWORD currentProcessId = GetCurrentProcessId();while (true) {i += 1;printf("############### 子进程id: %d, 第%d次等待 ####################\n", currentProcessId, i);Sleep(3000);}
}

x64dbg

x64dbg是使用插件来附加子进程

插件地址:https://github.com/therealdreg/DbgChild

安装步骤:

  1. 先下载releases下面的文件DbgChild.Beta.10.zip
  2. 解压到x64dbg目录
  3. 打开x64dbg,插件里面就有DbgChild

解压后的目录结构
在这里插入图片描述
复制到x64dbg之后的目录结构
在这里插入图片描述

插件功能

我说一下我用的几个选项的含义
在这里插入图片描述

  1. 主动去触发hook进程创建
  2. 自动hook进程创建,一般选这个就行
  3. 取消hook NTDLL,我看演示的视频在启动子进程的时候都会主动点一次这个,不过下面有个自动取消hook默认是勾选的,我测试的时候不点这个也可以
  4. 启动监听程序,这个是必须的,且要在创建子进程之前启动
开始调试

勾选第二个选项并启动监听程序,使用x64dbg打开ForkProcess.exe,运行程序,这时候会有一个很长的等待,我开始以为是卡住了,后面发现它只是比较慢,要等个一分钟吧。用任务管理搜索其实SubProcess.exe已经启动了,不知道是哪里卡住了。

接着就会弹出一个新的x64dbg窗口,并且已经附加到了SubProcess了,
在这里插入图片描述
这里不清楚为啥子进程没有在入口断点断住,不过影响不大,因为x64dbg会记忆断点位置,我只需要现在打上断点,那么在下次启动的时候就会自动断下,比如这里在SubProcess的x64dbg程序里用Ctrl+G跳转到printf函数并且打上断点。重复上面的操作重新启动ForkProcess的时候,附加到SubProcess的x64dbg就会断在printf

如果在启动ForkProcess之后再想去附加SubProcess,printf的前几次就无法下断点了。

frida

根据上面搜索到的链接显示,frida10就已经支持这个功能了。不过现在已经frida16了,这里面的代码也不能用了,得看github的最新代码:https://github.com/frida/frida-python/blob/main/examples/child_gating.py

直接拷下来,稍微做点改动,代码比较长,为了方便讲js和Python代码分开

child_gating.py

import threading
import os
import frida
from frida_tools.application import Reactorclass Application:def __init__(self):self._stop_requested = threading.Event()self._reactor = Reactor(run_until_return=lambda reactor: self._stop_requested.wait())self._device = frida.get_local_device()self._sessions = set()self._device.on("child-added", lambda child: self._reactor.schedule(lambda: self._on_child_added(child)))self._device.on("child-removed", lambda child: self._reactor.schedule(lambda: self._on_child_removed(child)))self._device.on("output", lambda pid, fd, data: self._reactor.schedule(lambda: self._on_output(pid, fd, data)))def run(self):self._reactor.schedule(lambda: self._start())self._reactor.run()def _start(self):argv = [r"T:\Code\VisualStudio\ForkProcess\x64\Release\ForkProcess.exe"]env = {}print(f"✔ spawn(argv={argv})")pid = self._device.spawn(argv, env=env, stdio="pipe")self._instrument(pid)def _stop_if_idle(self):if len(self._sessions) == 0:self._stop_requested.set()def _instrument(self, pid):print(f"✔ attach(pid={pid})")session = self._device.attach(pid)session.on("detached", lambda reason: self._reactor.schedule(lambda: self._on_detached(pid, session, reason)))print("✔ enable_child_gating()")session.enable_child_gating()print("✔ create_script()")frida_js_code = self.read_jscode()script = session.create_script(frida_js_code)script.on("message", lambda message, data: self._reactor.schedule(lambda: self._on_message(pid, message)))print("✔ load()")script.load()print(f"✔ resume(pid={pid})")self._device.resume(pid)self._sessions.add(session)def read_jscode(self):path = os.path.dirname(os.path.abspath(__file__))file = os.path.join(path, "child_gating.js")with open(file, encoding='utf-8') as f:jscode = f.read()return jscodedef _on_child_added(self, child):print(f"⚡ child_added: {child}")self._instrument(child.pid)def _on_child_removed(self, child):print(f"⚡ child_removed: {child}")def _on_output(self, pid, fd, data):pass#print(f"⚡ output: pid={pid}, fd={fd}, data={repr(data)}")def _on_detached(self, pid, session, reason):print(f"⚡ detached: pid={pid}, reason='{reason}'")self._sessions.remove(session)self._reactor.schedule(self._stop_if_idle, delay=0.5)def _on_message(self, pid, message):if message["type"] == "send":payload = message['payload']s = payload["format_str"] % tuple(payload["format_args"])print(f"⚡ message: pid={pid}, payload={s}")elif message["type"] == "error":print(f"⚡ message: pid={pid}, error: description={message['description']} stack={message['stack']}")else:print(f"⚡ message: pid={pid}, payload={message}")app = Application()
app.run()

child_gating.js

// 根据%读取printf的参数
function vspritf(format_str, args){let printf_args = [];if (format_str.indexOf("%") === -1) {return printf_args;}var pos = 0;for (let index = 0; index < format_str.length; index++) {pos = format_str.indexOf("%", pos);if(pos == -1)break;var format_ch = format_str.substr(pos+1, 1);let length = printf_args.length;let arg;switch (format_ch) {case "s":arg = args[length+1].readAnsiString()break;case "d": arg = args[length+1].toInt32()break;case "p":arg = args[length+1].toInt32()break;case "f":arg = args[length+1]break;default:arg = args[length+1]break;}printf_args.push(arg);pos += index+2;}return printf_args;
}let ProcessModAddress = Process.findModuleByName('ForkProcess.exe');
// Offset是在x64dbg里计算的偏移,
// 本来我想使用Module.findExportByName(null, "printf"),发现得到的偏移不知道是哪里的
let Offset = '0x1070';
// 如果没有获取到ForkProcess,说明是子进程
if(!ProcessModAddress){ProcessModAddress = Process.findModuleByName('SubProcess.exe');Offset = '0x1010';
}
// 通过偏移计算printf的实际地址
let pvPrintf = ProcessModAddress.base.add(Offset);
// 调用Windows获取进程pid的api
let pvGetCurrentProcessId = Module.findExportByName("kernel32.dll", "GetCurrentProcessId")
var GetCurrentProcessId = new NativeFunction(pvGetCurrentProcessId, 'uint32', []);console.log(GetCurrentProcessId(), Offset, pvPrintf)
// hook函数
Interceptor.attach(pvPrintf, {onEnter: function (args) {let format_str = args[0].readAnsiString()send({"format_str": format_str,"format_args": vspritf(format_str, args)})} 
});

运行结果如下:
在这里插入图片描述
这里我只测试了Windows,Linux和安卓应该也可以,官网给的例子是Linux的,安卓的话自行测试

运行环境

  • python==3.8.17
  • frida==16.1.2
  • frida-tools==12.1.3
  • vs2017
用到的文件和代码

https://github.com/kanadeblisst00/frida_child_gating

相关文章:

使用frida来spawn Fork 的子进程

索引 需求测试程序父进程代码子进程代码 x64dbg插件功能开始调试 frida运行环境用到的文件和代码 需求 最近在学基础的Windows逆向知识&#xff0c;遇到个小问题。一个进程使用CreateProcessW创建的进程该如何在启动时附加&#xff0c;我想调试这个子进程启动时运行的函数。 …...

网工笔记整理:策略工具Filter-policy的使用

一、概述 Filter-Policy&#xff08;过滤-策略&#xff09;是一个很常用的路由信息过滤工具&#xff0c;能够对接收、发布、引入的路由进行过滤&#xff0c;可应用于IS-IS、OSPF、BGP等协议。 Filter-policy在距离矢量路由协议中的应用 filter-policy import&#xff1a;不发…...

数据结构和算法——查找算法

目录 线性查找法 二分查找法 插值查找法 斐波那契查找法 线性查找法 可以是有序的&#xff0c;也可以是无序的。 public class SeqSearch {public static void main(String[] args) {int[] arr new int[]{1, 9, 11, -1, 34, 89};int res seqSearch(arr, 34);}public st…...

Blender:对模型着色

Blender&#xff1a;使用立方体制作动漫头像-CSDN博客 上一步已经做了一个头像模型&#xff0c;我做的太丑了&#xff0c;就以这个外星人头像为例 首先切换到着色器编辑器 依次搜索&#xff1a;纹理坐标、映射、分离xyz和颜色渐变 这里的功能也是非常丰富和强大&#xff0c…...

加密市场波动:地缘政治与美股走弱引发不确定性!

伴随着国庆假期的结束&#xff0c;多日波动率维持低位的加密市场也似乎开始苏醒。近期多次突破28000美元未果的比特币&#xff0c;于9日15:00开始从27800美元附近下跌&#xff0c;最低跌至27260美元&#xff0c;同期以太坊也至1550美元左右&#xff0c;创近半个月来新低。 Coin…...

ElementUI编辑表格单元格与查看模式切换的应用

需求&#xff1a;有时候在填写表单的时候&#xff0c;想要在输入的时候是input输入框的状态&#xff0c;但是当鼠标移出输入框失去焦点时&#xff0c;希望是查看的状态&#xff0c;这种场景可以通过 v-if实现 vue2ElementUi里面使用如下&#xff1a; 1.el-table标签注册 cell-…...

spring-创建Webservice服务

Web service是一个平台独立的&#xff0c;松耦合的&#xff0c;自包含的、基于可编程的web的应用程序&#xff0c;可使用开放的XML标准来描述、发布、发现、协调和配置这些应用程序&#xff0c;用于开发分布式的互操作的应用程序。webservice用的是soap协议。 客户通过发送请求…...

Maven系列第3篇:详解maven解决依赖问题

maven系列目标&#xff1a;从入门开始开始掌握一个高级开发所需要的maven技能。 这是maven系列第3篇。 我们先来回顾一下什么是maven&#xff1f; maven是apache软件基金会组织维护的一款自动化构件工具&#xff0c;专注服务于java平台的项目构件和依赖管理。 本文主要内容…...

读书笔记:多Transformer的双向编码器表示法(Bert)-4

多Transformer的双向编码器表示法 Bidirectional Encoder Representations from Transformers&#xff0c;即Bert&#xff1b; 第二部分 探索BERT变体 从本章开始的诸多内容&#xff0c;以理解为目标&#xff0c;着重关注对音频相关的支持&#xff08;如果有的话&#xff09;…...

Stable Diffusion XL搭建

本文参考&#xff1a;Stable Diffusion XL1.0正式发布了&#xff0c;赶紧来尝鲜吧-云海天教程 Stable Diffision最新模型SDXL 1.0使用全教程 - 知乎 1、SDXL与SD的区别 &#xff08;1&#xff09;分辨率得到了提升 原先使用SD生成图片&#xff0c;一般都是生成512*512&…...

面试题-React(十一):性能优化之PureComponent和memo

一、React性能优化的重要性 随着应用的复杂性增加&#xff0c;React组件的渲染可能成为性能瓶颈。频繁的渲染可能导致不必要的性能开销和卡顿。为了确保应用的高性能和流畅用户体验&#xff0c;我们需要采取一些措施来优化组件的渲染。 二、PureComponent-自动浅比较 PureCo…...

<图像处理> Fast角点检测

Fast角点检测 基本原理是使用圆周长为N个像素的圆来判定其圆心像素P是否为角点&#xff0c;如下图所示为圆周长为16个像素的圆&#xff08;半径为3&#xff09;&#xff1b;OpenCV还提供圆周长为12和8个像素的圆来检测角点。 相对中心像素的位置信息 //圆周长为16 static c…...

基于centos、alpine制作Java JDK基础镜像

文章目录 前言一、 简介二、制作JDK/Java基础镜像1.准备事项2.制作Dockerfile脚本2.1.基于centos作为基础镜像2.2.基于alpine作为基础镜像3.构建镜像4.测试验证前言 在日常开发中,但凡项目需要docker容器化部署,制作项目镜像前都需要在Dockerfile中配置Java基础镜像。为什么…...

【AI视野·今日Robot 机器人论文速览 第五十二期】Wed, 11 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Wed, 11 Oct 2023 Totally 31 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers RoboHive: A Unified Framework for Robot Learning Authors Vikash Kumar, Rutav Shah, Gaoyue Zhou, Vincent Moens, Vittor…...

hive 知识总结

​编辑 社区公告教程下载分享问答JD 登 录 注册 01 hive 介绍与安装 1 hive介绍与原理分析 Hive是一个基于Hadoop的开源数据仓库工具&#xff0c;用于存储和处理海量结构化数据。它是Facebook 2008年8月开源的一个数据仓库框架&#xff0c;提供了类似于SQL语法的HQL&#xf…...

golang/云原生/Docker/DevOps/K8S/持续 集成/分布式/etcd 教程

3-6个月帮助学员掌握golang后端开发岗位必备技术点 教程时长: 150小时 五大核心专栏,原理源码案例分析项目实战直击工作岗位 golang&#xff1a;解决go语言编程问题 工程组件&#xff1a;解决golang工程化问题 分布式中间件&#xff1a;解决技术栈单一及分布式开发问题 云原生…...

jeecg库login登录过程分析笔记

jeecg库&#xff08;版本jeecg-boot-v3.5.1last&#xff09;实现了用户登录功能&#xff0c;二开时为了借鉴jeecg用户登录的方法&#xff0c;跑了一遍登录方法&#xff1a; org.jeecg.modules.system.controller.LoginController#login 定义这个方法的类的路径是&#xff1a;…...

echarts仪表盘vue

<div class"ybptx" ref"btryzb"></div>mounted() {this.getBtData();},getBtData() {var chart this.$echarts.init(this.$refs.btryzb);var data_czzf 88;var option {series: [{name: 内层数据刻度,type: gauge,radius: 80%,min: 0,max: 1…...

管道和重定向分号-连接符

本文介绍shell脚本常用命令连接符&#xff1a;管道符( | )、重定向( < 、>、>>、2> 、&> )、分号( ; ) 本文内容同微信公众号【凡登】&#xff0c;关注不迷路&#xff0c;学习上高速&#xff0c;欢迎关注共同学习。 1、管道 进程的通信方式之一&#xf…...

WSL VScode连接文件后无法修改(修改报错)

权限问题 usrname:用户名 dirpath:要修改的文件夹路径 sudo chown -R usrname /dirpath...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...