Frida + frida-tools + Objection 版本对照:frida==16.7.19 最稳组合及 64 位进程错误

版本对照表组件 最新版 最稳版 说明frida 17.5.x 16.7.19 17 仍有 iOS/Objection 兼容问题frida-tools 13.x(最新) 13.7.1 随 frida 走,一般不用指定objection 最新版 最新版 两套 frida 都支持frida-server 与 frida 客户端相同版本 16.7.19 设备端必须与 PC 端版本一致安装命令 最稳定组合(推荐) pip install frida==16.7.19 frida-tools==13.7.1 objection适合:Android 逆向、SSL Pinning、Objection Explore、大多数中文教程。 使用最新版 Frida 17 pip install frida==17.5.1 frida-tools objection适合:需要最新特性,iOS 逆向可能遇到问题时再降级。 常见错误:unable to handle 64-bit processes frida-ps -U Failed to enumerate processes: unable to handle 64-bit processes due to build configuration原因:安装了 32 位 Python,而 Android frida-server 是 64 位的。 检查 Python 位数: python -c "import struct; print(struct.calcsize('P')*8)"如果输出 32,说明是 32 位 Python。 解决方法:从 python.org 下载并安装 64 位 Python(安装时勾选"Add to PATH") 重新创建虚拟环境:python -m venv frida_env .\frida_env\Scripts\activate pip install frida==16.7.19 frida-tools objection验证:frida-ps -Ufrida-server 版本必须匹配 设备端 frida-server 版本必须与 PC 端 pip install frida 安装的版本完全一致。 例如 PC 端安装了 frida==16.7.19,则设备端 frida-server 也必须是 16.7.19。 从 GitHub releases 下载对应版本: # Android arm64 frida-server-16.7.19-android-arm64# 推送到设备 adb push frida-server-16.7.19-android-arm64 /data/local/tmp/frida-server adb shell "chmod 755 /data/local/tmp/frida-server" adb shell "/data/local/tmp/frida-server &"版本混用报错 如果 PC 端 frida 版本和 frida-server 版本不一致,会看到: unable to communicate with remote frida-server Failed to spawn: unable to find process with name 'xxx'解决方法:保持两端版本一致,不要跨大版本(如 PC 16.x + server 14.x)。

Frida / frida-tools / Objection 版本对齐 + 32 位 Python 的坑

CTF / 授权渗透 / 自己应用的安全测试里 Frida 是常用工具。装的时候版本三个(frida、frida-tools、objection)加设备端 frida-server 要对得上,不然经常 unable to communicate with remote frida-server。 目前最稳的组合 写在最前面——如果你不追新,直接抄这套: pip install frida==16.7.19 frida-tools==13.7.1 objection设备端 frida-server-16.7.19(对应 Android 架构)。这套是当前社区教程覆盖最广、踩坑最少的组合。 用最新 Frida 17 呢 装最新版: pip install frida frida-tools objectionfrida-tools 会跟着 Frida 版本自动装匹配的(一般是 13.x)。Objection 最新版也已经跟上了 Frida 17,但 iOS 场景仍有已知问题,比如:ObjC is not defined 部分 explore 命令异常 SSL Pinning 相关脚本行为变化Android 场景 Frida 17 已经比较稳。iOS 建议留在 16.7.x。 frida-ps -U 报"unable to handle 64-bit" 一装完想连手机测: frida-ps -U崩: Failed to enumerate processes: unable to handle 64-bit processes due to build configuration几乎 100% 是你装了 32 位 Python,而设备上 frida-server 是 64 位。Frida 的 Python 绑定的位数必须和目标进程匹配。 先确认 Python 位数: python -c "import struct;print(struct.calcsize('P')*8)"输出 32 就是罪魁祸首。 解法:从 python.org 下 64-bit 安装包(找 "Windows installer (64-bit)" 或者 "Windows embeddable package (64-bit)") 卸载 32 位 Python 新建虚拟环境:python -m venv frida_env frida_env\Scripts\activate pip install frida==16.7.19 frida-tools==13.7.1 objection主机 Frida vs 设备 frida-server 必须版本一致 主机 Python 侧和手机上的 frida-server 必须严格同版本号,包括小版本。混版本症状: frida.core.RPCException: unable to communicate with remote frida-server对齐流程: # 1. 主机装什么版本 frida --version # 假设 16.7.19# 2. 下对应设备端 # github.com/frida/frida/releases → frida-server-16.7.19-android-arm64.xz# 3. 手机架构 adb shell getprop ro.product.cpu.abi # arm64-v8a → 用 android-arm64 # armeabi-v7a → 用 android-arm# 4. 推送 + 启动 adb push frida-server-16.7.19-android-arm64 /data/local/tmp/frida-server adb shell "chmod +x /data/local/tmp/frida-server" adb shell "/data/local/tmp/frida-server &"# 5. 主机验证 frida-ps -U | head环境里有多个 frida.exe pip show frida 显示当前 venv 装了,但 frida-ps -U 还是老版本行为——大概率是 PATH 上另一个 Python 里也有 frida.exe: where frida where frida-ps看到两条以上路径,把不想用的从 PATH 里挪走,或者用 venv 里的绝对路径调: D:\project\frida_env\Scripts\frida-ps.exe -U一张速查表症状 常见原因unable to handle 64-bit 32 位 Pythonunable to communicate with remote frida-server 版本不一致 / server 没起 / SELinuxObjC is not defined(iOS) Objection + Frida 17 兼容问题Failed to attach: process not found root 权限 / SELinux / SEAndroidfrida-server 起来立刻退出 架构下错、缺可执行权限一句话总结 64 位 Python + frida==16.7.19 frida-tools==13.7.1 + 同版本 frida-server 是当前最稳的组合。Frida 17 追新可以,iOS 用户等它再稳一稳。

PyTorch 读取 CSV 数据:pandas 转 Tensor、自定义 Dataset 与 DataLoader

快速读取(小数据) 先用 pandas 读 CSV,再一次性转成 Tensor: import pandas as pd import torchdf = pd.read_csv("house.csv")# 前 N-1 列是特征,最后一列是标签 x = torch.tensor(df.iloc[:, :-1].values, dtype=torch.float32) y = torch.tensor(df.iloc[:, -1].values, dtype=torch.float32)print(x.shape, y.shape) # torch.Size([N, features]) torch.Size([N])iloc[:, :-1] 取除最后列之外的所有列,iloc[:, -1] 取最后一列。 自定义 Dataset(正式训练推荐) 当数据量大或需要在线增强时,继承 Dataset 类实现懒加载: import pandas as pd import torch from torch.utils.data import Datasetclass CSVDataset(Dataset): def __init__(self, path): self.data = pd.read_csv(path) def __len__(self): return len(self.data) def __getitem__(self, index): row = self.data.iloc[index] x = torch.tensor(row[:-1].values, dtype=torch.float32) y = torch.tensor(row[-1], dtype=torch.float32) return x, y必须实现三个方法:__init__:加载/读取数据 __len__:返回样本总数 __getitem__:返回第 index 个样本DataLoader 分批读取 from torch.utils.data import DataLoaderdataset = CSVDataset("house.csv")loader = DataLoader( dataset, batch_size=32, shuffle=True, num_workers=4 # 多进程预取,Windows 下注意加 if __name__ == "__main__" )for x_batch, y_batch in loader: print(x_batch.shape) # [32, features] print(y_batch.shape) # [32]DataLoader 自动处理:打乱数据(shuffle=True) 按 batch_size 分批 多线程预取(num_workers)完整训练示例 import torch import torch.nn as nn from torch.utils.data import DataLoadermodel = nn.Sequential( nn.Linear(2, 16), nn.ReLU(), nn.Linear(16, 1) )optimizer = torch.optim.Adam(model.parameters(), lr=1e-3) criterion = nn.MSELoss()dataset = CSVDataset("house.csv") loader = DataLoader(dataset, batch_size=8, shuffle=True)for epoch in range(100): for x, y in loader: pred = model(x).squeeze() loss = criterion(pred, y) optimizer.zero_grad() loss.backward() optimizer.step() if epoch % 10 == 0: print(f"Epoch {epoch}, Loss: {loss.item():.4f}")训练集与验证集分割 from torch.utils.data import random_splitdataset = CSVDataset("house.csv")train_size = int(0.8 * len(dataset)) val_size = len(dataset) - train_sizetrain_set, val_set = random_split(dataset, [train_size, val_size])train_loader = DataLoader(train_set, batch_size=32, shuffle=True) val_loader = DataLoader(val_set, batch_size=32)处理标签类型 回归任务用 float32,分类任务用 long: # 回归:y 是连续值 y = torch.tensor(row[-1], dtype=torch.float32)# 分类:y 是类别编号 y = torch.tensor(int(row[-1]), dtype=torch.long)分类时对应的 loss 是 nn.CrossEntropyLoss(),回归时用 nn.MSELoss()。

用 Python 构建高考志愿填报系统:位次换算与录取概率预测

为什么不用深度学习 这个场景是表格数据回归预测,不是图像识别。数据量有限(全国高校 × 省份 × 年份),LightGBM 等梯度提升模型在表格数据上通常比神经网络效果更好,且训练速度快。 技术栈 Python ├── Pandas 数据清洗和处理 ├── LightGBM 预测最低录取位次 ├── FastAPI 后端 API ├── SQLAlchemy 数据库 ORM └── Vue3 前端展示第一层:位次换算 真正决定录取的是位次,而非分数。同一个位次在不同年份对应的分数不同: import pandas as pd# 读取当年一分一段表 score_table = pd.read_csv("score_rank_2025.csv") # 结构:score, rank(分数→位次)def score_to_rank(score: int, year: int) -> int: df = score_table[score_table["year"] == year] row = df[df["score"] == score] if row.empty: # 取最接近的分数 row = df.iloc[(df["score"] - score).abs().argsort()[:1]] return int(row["rank"].values[0])位次越小录取概率越高(1 代表全省第一名)。 第二层:训练预测模型 历史录取数据结构:year school major province min_rank plan_count2023 清华 计算机 江苏 235 152024 清华 计算机 江苏 198 12import lightgbm as lgb from sklearn.model_selection import train_test_splitdf = pd.read_csv("admission_history.csv")features = ["year", "school_id", "major_id", "province_id", "plan_count"] target = "min_rank"X_train, X_test, y_train, y_test = train_test_split( df[features], df[target], test_size=0.2, random_state=42 )model = lgb.LGBMRegressor(n_estimators=500, learning_rate=0.05) model.fit(X_train, y_train)也可以替换为 XGBRegressor 或 CatBoostRegressor,效果相近。 第三层:计算录取概率 基于历史波动区间: def admission_probability(school_id, major_id, province_id, student_rank: int, year: int) -> float: # 预测今年最低录取位次 predicted_min_rank = model.predict([[year, school_id, major_id, province_id, plan_count]])[0] # 历史波动标准差 history = df[(df.school_id == school_id) & (df.major_id == major_id)] std = history["min_rank"].std() # 学生位次越小(越靠前)于预测线,概率越高 z = (predicted_min_rank - student_rank) / (std + 1) from scipy.stats import norm return float(norm.cdf(z))输出 0.0~1.0 的概率值。 冲/稳/保 分类 def classify(prob: float) -> str: if prob >= 0.8: return "保" # 稳上 elif prob >= 0.5: return "稳" # 有竞争力 else: return "冲" # 有风险但值得一试FastAPI 接口 from fastapi import FastAPIapp = FastAPI()@app.get("/predict") def predict(school: str, major: str, province: str, score: int, year: int): rank = score_to_rank(score, year) prob = admission_probability(school, major, province, rank, year) label = classify(prob) return { "rank": rank, "probability": round(prob, 3), "label": label }模型效果优化特征工程:加入招生人数变化趋势、学校综合排名、专业热度 位次分段:分段训练(Top 1000 / 1000~10000 / 10000+),各段波动规律不同 时序权重:近年数据给更高权重(sample_weight 参数) 多省合并训练:数据量小时跨省训练,加省份编码作为特征数据来源 历年录取数据可从各省教育考试院官网下载,或使用第三方爬虫整理的开源数据集(GitHub 搜索"高考录取数据")。确保数据包含:学校、专业、省份、年份、最低分、最低位次、计划人数。

波士顿房价预测是回归还是分类?多元 vs 多输出的区别

有人问:"波士顿房价预测(Boston Housing)是多分类问题吧?" 不是。这是回归问题(Regression)。顺带把三个常混的概念都拆一下——多元回归、多输出回归、多分类。 波士顿房价预测的本质 数据集大致:CRIM RM LSTAT PTRATIO ... MEDV(房价,单位万美元)0.00632 6.575 4.98 15.3 ... 24.00.02731 6.421 9.14 17.8 ... 21.60.03237 6.998 2.94 18.7 ... 33.4输入:13 个特征 输出:MEDV = 房价,一个连续值(可以是 18.3、24.7、33.4...)输出是连续数字 → 回归,不是分类。 什么时候会变成分类 自己把房价切段: 0 – 15 → "低价" 15 – 30 → "中价" 30+ → "高价"这样任务就变成了三分类——但这已经不是原始 Boston Housing 任务了,是你人为改造的。原任务永远是回归。 三个概念区分 1. 多元回归(Multiple Regression) 多个输入特征 → 一个输出。 波士顿房价就是这种:13 个特征 → 1 个房价。 import torch.nn as nnmodel = nn.Sequential( nn.Linear(13, 64), nn.ReLU(), nn.Linear(64, 1), # 输出 1 维 ) loss_fn = nn.MSELoss()"多元"指的是输入的元数(features 多),不是输出多。 2. 多输出回归(Multi-output Regression) 多个输入 → 多个连续输出。 例子:预测未来一栋房子的售价 + 出租金 + 涨幅百分比——3 个连续输出。 model = nn.Sequential( nn.Linear(13, 64), nn.ReLU(), nn.Linear(64, 3), # 输出 3 维 ) loss_fn = nn.MSELoss() # 依然是 MSE,输出是向量3. 多分类(Multi-class Classification) 输入 → 多个类别中选一个。 MNIST 手写数字识别是典型: model = nn.Sequential( nn.Linear(784, 128), nn.ReLU(), nn.Linear(128, 10), # 10 类 ) loss_fn = nn.CrossEntropyLoss() # 内部含 softmax标签是类别编号(整数 0-9),损失是 CrossEntropy。 4. 顺带:多标签分类(Multi-label Classification) 输入 → 多个类别可同时为真。 例子:一张图片可能同时含"猫、狗、汽车"三个标签。 model = nn.Sequential( nn.Linear(784, 128), nn.ReLU(), nn.Linear(128, 3), nn.Sigmoid(), # 每维独立 0-1 ) loss_fn = nn.BCELoss() # 二元交叉熵每维独立判 0 或 1。 四类对照表任务类型 输出个数 输出类型 最后一层 损失 例子多元回归 1 连续 Linear(_, 1) MSELoss Boston Housing 房价多输出回归 K 连续 Linear(_, K) MSELoss 同时预测房价 + 租金二分类 1 0/1 Linear(_, 1)+Sigmoid BCELoss 垃圾邮件识别多分类 K 类别编号 Linear(_, K) CrossEntropyLoss MNIST 数字识别多标签分类 K K 个 0/1 Linear(_, K)+Sigmoid BCELoss 图片多标签Boston Housing 数据集的争议 顺带一提——波士顿房价数据集本身有伦理问题。数据里有个特征 B(黑人人口相关变量)设计上带有种族偏见,2022 年 scikit-learn 明确 deprecated 了这个数据集: # 老代码,会警告 from sklearn.datasets import load_boston# 新推荐 from sklearn.datasets import fetch_california_housing现在教学上一般用 California Housing 或 Ames Housing 数据集替代——同样是回归任务,没有伦理争议、样本更多。 用 California Housing 的替代示例 from sklearn.datasets import fetch_california_housing import torch, torch.nn as nn from torch.utils.data import DataLoader, TensorDatasetdata = fetch_california_housing() X = torch.tensor(data.data, dtype=torch.float32) y = torch.tensor(data.target, dtype=torch.float32).unsqueeze(1)loader = DataLoader(TensorDataset(X, y), batch_size=64, shuffle=True)model = nn.Sequential( nn.Linear(8, 64), nn.ReLU(), nn.Linear(64, 32), nn.ReLU(), nn.Linear(32, 1), ) optim = torch.optim.Adam(model.parameters(), lr=1e-3) loss_fn = nn.MSELoss()for epoch in range(20): for x, target in loader: optim.zero_grad() pred = model(x) loss = loss_fn(pred, target) loss.backward() optim.step() print(f"epoch {epoch}: loss={loss.item():.4f}")跑起来 20 轮 loss 会稳定下降——回归任务的经典流程。 一句话总结 波士顿房价 = 回归任务(输出连续价格),属于"多元回归"(多个输入 → 一个输出),不是"多输出回归"、也不是"多分类"。教学优先用 California Housing 数据集,避开原数据集的伦理争议。