Xposed插件(钱庄APP IP代理转发)核心内容提炼
FunWinHook 代码开发全过程提炼总结该Xposed插件自带前端UI,核心功能是实现钱庄APP请求/响应的代理转发,全程以文件为IP中转载体,突破进程隔离限制,具体链路:用户前端输入代理IP→Root权限创建目标目录+初始化文件→写入IP→Xposed Hook钱庄APP时读取IP(赋值给变量)→拦截请求/响应并转发至该IP,无任何步骤脱节(所有文件、Shell操作均通过工具类实现,核心Ho
钱庄APP Shark框架网络请求Hook常见问题
Xposed Hook 钱庄 APP 常见问题及解决方案
Xposed Hook钱庄APP核心问题、重复Hook成因及解决方案提炼
Xposed插件(钱庄APP IP代理转发)核心内容提炼
Android Studio与Hook模块开发相关问题及实现方案梳理
FunWinHook 代码开发全过程提炼总结
钱庄APP Hook核心代码深度分析报告
一、核心结论
该Xposed插件自带前端UI,核心功能是实现钱庄APP请求/响应的代理转发,全程以/data/local/tmp/funwin/proxy_ip.conf文件为IP中转载体,突破进程隔离限制,具体链路:用户前端输入代理IP→Root权限创建目标目录+初始化文件→写入IP→Xposed Hook钱庄APP时读取IP(赋值给PROXY_IP变量)→拦截请求/响应并转发至该IP,无任何步骤脱节(所有文件、Shell操作均通过com.example.funwinhook.Util工具类实现,核心Hook逻辑在com.example.funwinhook.*ank*.SendSharkDumping类中)。
二、全链路实现步骤(完全对应最新源码,无遗漏、无多余内容)
步骤1:前端输入IP,通过Util工具类完成目录创建、文件初始化与IP写入(核心类:MainActivity + Util)
插件通过MainActivity实现前端交互,所有Shell命令执行、目录创建、文件操作均调用Util工具类(包名:com.example.funwinhook.Util)完成,无需其他工具类,具体逻辑:
-
前端布局:MainActivity包含IP输入框(EditText)和确认按钮(Button),用户输入IP后点击按钮触发后续操作;
-
核心前置操作:先调用
Util.mkdirs("/data/local/tmp/funwin"),以Root权限创建目标目录(mkdir -p 命令,自动创建多级目录,目录已存在则直接返回成功); -
文件初始化:调用
Util.initIpFile("/data/local/tmp/funwin/proxy_ip.conf"),执行touch命令创建文件、chmod 777命令赋予全权限(文件已存在则无需初始化); -
IP写入操作:获取输入框IP字符串,调用
Util.writeFileByShell(IP内容, "/data/local/tmp/funwin/proxy_ip.conf"),通过Shell命令echo 【IP】 > /data/local/tmp/funwin/proxy_ip.conf覆盖写入IP; -
权限依赖:所有操作均通过
Util.ShellExecutor内部类执行(默认以SU权限,调用exec/execBatch方法执行Shell命令),因/data/local/tmp是系统目录,普通权限无法操作,需设备Root并授予SU权限; -
执行反馈:通过Toast提示用户初始化成功/失败(失败原因含:无Root权限、命令执行异常、路径/内容为空),
Util类内部通过TAG="FunWinTag"打印日志,记录操作结果; -
最终结果:
/data/local/tmp/funwin/proxy_ip.conf文件中仅存储一行纯文本(用户输入的代理IP,如192.168.1.100),目录与文件权限配置完成。
步骤2:Xposed Hook钱庄APP,通过Util工具类读取文件中的IP(核心类:SendSharkDumping + Util)
核心Hook逻辑在com.example.funwinhook.*ank*.SendSharkDumping类中(该类实现IXposedHookLoadPackage接口),Xposed检测到钱庄APP(目标包名:)启动后,立即通过Util工具类读取IP并赋值给PROXY_IP变量,具体步骤:
-
核心变量定义:
SendSharkDumping类中定义核心配置变量,包括PROXY_IP(存储代理IP,初始值为空字符串)、ROOT_DIR(最终根目录:/data/local/tmp/funwin)、PROXY_IP_FILE(IP配置文件名:proxy_ip.conf)、PROXY_PORT(代理端口:8080)、TARGET_PORT(目标端口:8888)等; -
Hook触发时机:Xposed调用
handleLoadPackage方法,先判断当前启动应用包名是否为目标包名(),非目标包名则跳过Hook; -
IP读取操作:在
handleLoadPackage方法中,调用Util.readFile(ROOT_DIR, PROXY_IP_FILE)(传入根目录和文件名),通过Java文件API读取目标文件内容,读取失败(文件不存在等)则将PROXY_IP设为空字符串; -
IP读取细节:
Util.readFile方法内部通过FileInputStream、BufferedReader读取文件,以UTF-8编码转换为字符串,过滤空格/换行等无效字符,读取失败则返回null,此时PROXY_IP仍为空字符串; -
日志提示:若
PROXY_IP为空字符串,打印警告日志,提示用户“代理IP未配置:请在前端APP配置后重启钱庄”; -
额外操作:读取IP后,启动8899端口主动调用服务(通过ActiveCallHttpServer类),该服务仅启动一次(通过
isServerStarted变量标记,避免重复启动); -
Hook初始化:调用
initHookCallback方法,设置请求/响应回调,Hook钱庄APP的***Application类onCreate方法,后续初始化Shark网络框架Hook; -
最终结果:
PROXY_IP变量赋值完成(非空则为代理IP,空则未配置),8899端口服务启动(若未启动),Hook初始化完成,等待拦截网络请求/响应。
步骤3:拦截请求/响应,实现IP代理转发(核心类:SendSharkDumping + 转发相关类)
SendSharkDumping类实现SharkRequestCallback、SharkResponseCallback接口,通过Hook钱庄APP的Shark网络框架,拦截请求/响应后,调用转发类将数据转发至PROXY_IP对应的代理地址,核心依赖PROXY_IP、PROXY_PORT、TARGET_PORT变量,所有文件/Shell操作仍依赖Util工具类,具体逻辑:
3.1 拦截请求(Shark网络框架Hook)
-
Hook初始化:在
initHookCallback方法中,通过Hook ***Application类的onCreate方法,在APP初始化完成后,Hook Shark网络框架(通过HookSharkFramework类),再Hook SendShark相关方法; -
请求解析与回调:当请求被拦截并解析完成后,会触发SendSharkDumping类的
onSharkRequestParsed方法(两个重载),原因是初始开发时仅4个入参,后续新增业务需求需额外加1个入参,为兼容原有逻辑未删除旧方法;两个重载分别对应带/不带原始请求对象,均会获取请求体、请求头、接口名。 -
转发执行:调用
RequestForwarder.forwardToBurp方法,传入PROXY_IP、PROXY_PORT、TARGET_PORT及解析后的请求信息,完成请求转发至代理工具(Burp等); -
转发细节:转发逻辑由RequestForwarder类负责,无需额外代理开关判断,若
PROXY_IP为空,转发会按默认逻辑处理(日志提示未配置IP)。
3.2 拦截响应(Shark网络框架Hook)
-
核心逻辑:与请求拦截、转发完全一致,当响应被拦截并解析完成后,触发SendSharkDumping类的
onSharkResponseParsed方法(两种重载,对应带/不带原始响应对象); -
转发执行:调用
ResponseForwarder.forwardToBurp方法,传入PROXY_IP、PROXY_PORT、TARGET_PORT及解析后的响应信息,完成响应转发至代理工具; -
结果处理:代理工具(Burp等)返回篡改后的报文后,由转发类处理并回写至原请求/响应链路,完成整个转发流程。
3.3 最终结果
钱庄APP(目标包名:)的所有请求/响应均会被拦截,通过RequestForwarder、ResponseForwarder类转发至PROXY_IP对应的代理IP(端口8080),可通过Burp/Charles等工具(监听对应端口)捕获、篡改报文;核心依赖SendSharkDumping类实现Hook逻辑,Util工具类实现辅助操作。
三、补充说明
核心目录、文件及变量配置(对应SendSharkDumping类)
-
目录配置:
ROOT_DIR = /data/local/tmp/funwin(由BASE_DIR + FUNWIN_DIR拼接,集中配置,全项目复用); -
文件配置:
PROXY_IP_FILE = proxy_ip.conf(IP配置文件名,抽象命名+配置后缀,便于维护); -
端口配置:
PROXY_PORT = 8080(代理工具端口)、TARGET_PORT = 8888(转发目标端口); -
IP变量:
PROXY_IP(存储代理IP,初始为空,通过Util.readFile读取赋值); -
目录创建:通过
Util.mkdirs(ROOT_DIR)实现,采用mkdir -p命令,支持多级目录创建,目录已存在则不重复操作,避免报错; -
文件权限:
Util.initIpFile赋予文件777全权限,确保所有进程可读写,避免权限不足导致的读取/写入失败; -
在模拟器中访问
/data/local/tmp/及下属funwin目录时无法访问,核心原因是该目录为Android系统临时根目录,模拟器中普通文件管理器无Root权限;可通过ADB命令(adb shell su获取Root,ls /data/local/tmp/funwin查看目录,cat /data/local/tmp/funwin/proxy_ip.conf查看IP),或使用MT/RE管理器开启Shell权限后访问。
四、关键疑问及解答(结合最新代码,无多余内容)
-
疑问1:为何在MT管理器中看不到
/data/local/tmp/funwin/proxy_ip.conf文件?
解答:安卓11以上系统限制,第三方文件管理器默认无权限访问系统目录;需更新MT管理器至最新版,开启“请求Shell权限”或通过Shizuku授权,或用ADB命令访问。 -
疑问2:为何必须先设置代理IP,再打开钱庄APP?
解答:钱庄APP启动后,SendSharkDumping类的handleLoadPackage方法会触发一次IP读取(赋值给PROXY_IP),启动后再设置IP(写入文件),不会重新读取;需先调用Util类完成目录创建、文件初始化、IP写入,再启动APP,否则PROXY_IP为空,日志会提示未配置IP。 -
疑问3:将IP写入本地文件,与直接写死在代码里的区别是什么?
解答:核心是“跨进程数据共享”和“可维护性”,而非持久化:
- 写死在代码里:IP仅固定在SendSharkDumping类的PROXY_IP变量中,修改IP需重新编译代码,且无法跨进程动态更新;
- 写入本地文件:文件存储在系统公共目录,前端APP可通过Util类写入IP,SendSharkDumping类在APP启动时读取,无需重新编译,且支持动态修改IP(修改后重启APP即可生效)。 -
疑问4:为何写入本地文件就能实现转发?(进程隔离相关)
解答:Xposed模块代码会注入到目标APP(钱庄APP,包名)进程中运行,与前端APP是两个独立进程(进程隔离),无法直接共享数据;/data/local/tmp/funwin是系统公共目录,所有进程有权限访问,相当于“数据中转站”,前端APP通过Util类写入IP,注入钱庄APP进程的SendSharkDumping类通过Util类读取IP,突破进程隔离限制。 -
疑问5:市面上APP无网时的问卷信息如何存储?
解答:无网时会将问卷信息存储在手机本地(如localStorage、SQLite数据库),待联网后自动同步至服务器,与本插件“通过Util类操作本地文件存储IP”的本地存储逻辑一致。 -
疑问6:为何新增mkdirs方法创建目录?
解答:为了保证/data/local/tmp/funwin目录一定存在,避免因目录不存在导致后续文件创建、IP写入失败;mkdir -p命令可自动创建多级目录,兼容后续路径扩展,同时目录已存在时不重复操作,提升效率。 -
疑问7:为何SendSharkDumping类要实现两个回调接口?
解答:这是方法重载(方法名相同、入参不同):当时因新增业务需求,需要新增一个接口来满足功能,所以设计了两个同名的回调方法,仅入参有差异,用于接收Shark网络框架拦截解析后的请求/响应数据,进而触发转发逻辑、实现精准转发。
五、完整链路总结(一句话串起所有逻辑,完全对应最新代码)
用户在MainActivity前端输入IP→点击按钮,依次调用Util.mkdirs(ROOT_DIR)创建目录、Util.initIpFile(ROOT_DIR+“/proxy_ip.conf”)初始化文件(创建+赋权777)、Util.writeFileByShell(IP内容, 路径)写入IP(通过Util.ShellExecutor执行SU权限Shell命令)→钱庄APP(包名)启动,Xposed触发SendSharkDumping类的handleLoadPackage方法→判断为目标包名后,调用Util.readFile(ROOT_DIR, PROXY_IP_FILE)读取IP并赋值给PROXY_IP,启动8899端口主动调用服务,初始化Shark网络框架Hook→Hook拦截到请求/响应并解析后,触发SendSharkDumping的回调方法,调用对应转发类,传入PROXY_IP、PROXY_PORT等参数,将请求/响应转发至代理工具→代理工具返回篡改后的报文,由转发类回写至原链路,完成全流程转发;核心依赖SendSharkDumping类实现Hook逻辑,Util类实现辅助操作,通过系统公共文件突破进程隔离,实现跨进程IP共享。
(注:文档部分内容可能由 AI 生成)
更多推荐



所有评论(0)