Init
This commit is contained in:
commit
706aac68aa
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.idea
|
||||
1
exFilter/__init__.py
Normal file
1
exFilter/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .core import Filter
|
||||
23
exFilter/core.py
Normal file
23
exFilter/core.py
Normal file
@ -0,0 +1,23 @@
|
||||
import logging
|
||||
import sys
|
||||
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
class Filter:
|
||||
def __init__(self):
|
||||
self.logger = logging.getLogger("exFilter")
|
||||
self.logger.info("core Initialized")
|
||||
|
||||
|
||||
def start(self):
|
||||
self.logger.info("core Started")
|
||||
|
||||
return
|
||||
|
||||
|
||||
def stop(self):
|
||||
self.logger.info("core Stopped")
|
||||
return
|
||||
|
||||
15
main.py
Normal file
15
main.py
Normal file
@ -0,0 +1,15 @@
|
||||
from exFilter import Filter
|
||||
|
||||
|
||||
def main():
|
||||
filter = Filter()
|
||||
filter.start()
|
||||
return
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
||||
|
||||
0
scripts/libusbHook.js
Normal file
0
scripts/libusbHook.js
Normal file
0
scripts/pcieHook.js
Normal file
0
scripts/pcieHook.js
Normal file
23
testMod/libusb/Makefile
Normal file
23
testMod/libusb/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
obj-m += libusbMod.o
|
||||
|
||||
KDIR := /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
# 默认目标:只编译内核模块
|
||||
all: libusbMod.ko
|
||||
|
||||
# 编译内核模块
|
||||
libusbMod.ko:
|
||||
make -C $(KDIR) M=$(PWD) modules
|
||||
|
||||
# 清理所有生成文件
|
||||
clean:
|
||||
make -C $(KDIR) M=$(PWD) clean
|
||||
|
||||
# 加载模块
|
||||
load:
|
||||
sudo insmod libusbMod.ko
|
||||
|
||||
# 卸载模块
|
||||
unload:
|
||||
sudo rmmod libusbMod
|
||||
106
testMod/libusb/libusbMod.c
Normal file
106
testMod/libusb/libusbMod.c
Normal file
@ -0,0 +1,106 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Leo");
|
||||
MODULE_DESCRIPTION("Monitor usb_submit_urb() data submission only");
|
||||
|
||||
static struct kprobe kp;
|
||||
|
||||
// 兼容 x86_64 和 arm64 获取第一个参数
|
||||
static struct urb *get_urb_from_regs(struct pt_regs *regs)
|
||||
{
|
||||
#if defined(CONFIG_ARM64)
|
||||
return (struct urb *)regs->regs[0];
|
||||
#elif defined(CONFIG_X86_64)
|
||||
return (struct urb *)regs->di;
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
}
|
||||
|
||||
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct urb *urb_kern = get_urb_from_regs(regs);
|
||||
|
||||
if (!urb_kern)
|
||||
return 0;
|
||||
|
||||
pr_info("[usbFilter] 提交URB进程: %s (pid: %d)\n", current->comm, current->pid);
|
||||
|
||||
if (urb_kern->dev) {
|
||||
pr_info("[usbFilter] USB设备: busnum=%d, devnum=%d, VID=0x%04x, PID=0x%04x\n",
|
||||
urb_kern->dev->bus->busnum,
|
||||
urb_kern->dev->devnum,
|
||||
urb_kern->dev->descriptor.idVendor,
|
||||
urb_kern->dev->descriptor.idProduct);
|
||||
}
|
||||
|
||||
pr_info("[usbFilter] URB: %p, pipe=0x%x, flags=0x%x\n",
|
||||
urb_kern, urb_kern->pipe, urb_kern->transfer_flags);
|
||||
|
||||
pr_info("[usbFilter] pipe: 端点=%d, 方向=%s, 类型=%s\n",
|
||||
usb_pipeendpoint(urb_kern->pipe),
|
||||
usb_pipein(urb_kern->pipe) ? "IN" : "OUT",
|
||||
usb_pipetype(urb_kern->pipe) == PIPE_CONTROL ? "CONTROL" :
|
||||
usb_pipetype(urb_kern->pipe) == PIPE_ISOCHRONOUS ? "ISO" :
|
||||
usb_pipetype(urb_kern->pipe) == PIPE_BULK ? "BULK" :
|
||||
usb_pipetype(urb_kern->pipe) == PIPE_INTERRUPT ? "INTERRUPT" : "UNKNOWN");
|
||||
|
||||
// 打印控制传输的setup包内容
|
||||
if (usb_pipetype(urb_kern->pipe) == PIPE_CONTROL && urb_kern->setup_packet) {
|
||||
char setup_hex[3 * 8 + 1] = {0};
|
||||
int i;
|
||||
unsigned char *setup = (unsigned char *)urb_kern->setup_packet;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
snprintf(setup_hex + i * 3, sizeof(setup_hex) - i * 3, "%02X ", setup[i]);
|
||||
}
|
||||
pr_info("[usbFilter] 控制传输setup包(8字节hex): %s\n", setup_hex);
|
||||
}
|
||||
|
||||
// 打印控制传输的数据内容
|
||||
if (urb_kern->transfer_buffer && urb_kern->transfer_buffer_length > 0) {
|
||||
unsigned int to_copy = min(32U, (unsigned int)urb_kern->transfer_buffer_length);
|
||||
unsigned char data[32] = {0};
|
||||
memcpy(data, urb_kern->transfer_buffer, to_copy);
|
||||
|
||||
char hex[3 * 32 + 1] = {0};
|
||||
int i;
|
||||
for (i = 0; i < to_copy; ++i) {
|
||||
snprintf(hex + i * 3, sizeof(hex) - i * 3, "%02X ", data[i]);
|
||||
}
|
||||
pr_info("[usbFilter] 提交数据(前32字节hex): %s\n", hex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init usb_hook_init(void)
|
||||
{
|
||||
kp.symbol_name = "usb_submit_urb";
|
||||
kp.pre_handler = handler_pre;
|
||||
|
||||
if (register_kprobe(&kp) < 0)
|
||||
{
|
||||
pr_err("[usbFilter] 无法注册 kprobe\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr_info("[usbFilter] 成功 hook usb_submit_urb()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit usb_hook_exit(void)
|
||||
{
|
||||
unregister_kprobe(&kp);
|
||||
pr_info("[usbFilter] 已卸载 usb_submit_urb hook\n");
|
||||
}
|
||||
|
||||
module_init(usb_hook_init);
|
||||
module_exit(usb_hook_exit);
|
||||
16
testMod/netlink/Makefile
Normal file
16
testMod/netlink/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
obj-m += netlink_logger.o
|
||||
|
||||
KDIR := /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KDIR) M=$(PWD) clean
|
||||
|
||||
load:
|
||||
sudo insmod netlink_logger.ko
|
||||
|
||||
unload:
|
||||
sudo rmmod netlink_logger
|
||||
54
testMod/netlink/netlink_logger.c
Normal file
54
testMod/netlink/netlink_logger.c
Normal file
@ -0,0 +1,54 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#define NETLINK_USER_CUSTOM 31
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Leo");
|
||||
MODULE_DESCRIPTION("Netlink message logger for custom protocol");
|
||||
|
||||
static struct sock *nl_sk = NULL;
|
||||
|
||||
static void netlink_recv_msg(struct sk_buff *skb)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
char *payload;
|
||||
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
nlh = nlmsg_hdr(skb);
|
||||
payload = (char *)nlmsg_data(nlh);
|
||||
|
||||
pr_info("[netlink_logger] Received netlink msg: %s\n", payload); //此处打印信息
|
||||
}
|
||||
|
||||
static int __init netlink_logger_init(void)
|
||||
{
|
||||
struct netlink_kernel_cfg cfg = {
|
||||
.input = netlink_recv_msg,
|
||||
};
|
||||
|
||||
nl_sk = netlink_kernel_create(&init_net, NETLINK_USER_CUSTOM, &cfg);
|
||||
if (!nl_sk) {
|
||||
pr_err("[netlink_logger] Failed to create netlink socket\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pr_info("[netlink_logger] Netlink logger module loaded (protocol: %d)\n", NETLINK_USER_CUSTOM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit netlink_logger_exit(void)
|
||||
{
|
||||
if (nl_sk)
|
||||
netlink_kernel_release(nl_sk);
|
||||
pr_info("[netlink_logger] Module unloaded\n");
|
||||
}
|
||||
|
||||
module_init(netlink_logger_init);
|
||||
module_exit(netlink_logger_exit);
|
||||
53
testScripts/frida_hook_libusb_basic_Version2.js
Executable file
53
testScripts/frida_hook_libusb_basic_Version2.js
Executable file
@ -0,0 +1,53 @@
|
||||
const symbol = DebugSymbol.fromName("libusb_bulk_transfer");
|
||||
console.log("libusb_bulk_transfer symbol info:", symbol);
|
||||
|
||||
if (symbol && symbol.address) {
|
||||
Interceptor.replace(symbol.address, new NativeCallback(function(
|
||||
dev_handle, endpoint, data, length, transferred, timeout
|
||||
) {
|
||||
console.log('[!] libusb_bulk_transfer 被阻断');
|
||||
console.log('dev_handle:', dev_handle);
|
||||
console.log('endpoint:', endpoint);
|
||||
console.log('data pointer:', data);
|
||||
console.log('length:', length);
|
||||
console.log('transferred pointer:', transferred);
|
||||
console.log('timeout:', timeout);
|
||||
|
||||
try {
|
||||
var nLen = length.toInt32 ? length.toInt32() : parseInt(length);
|
||||
var bytesToPrint = Math.min(nLen, 64); // 只输出前64字节
|
||||
|
||||
if (data && nLen > 0) {
|
||||
console.log("数据十六进制输出(前" + bytesToPrint + "字节):");
|
||||
|
||||
// 最原始的读取方法
|
||||
var hexOutput = "";
|
||||
for (var i = 0; i < bytesToPrint; i++) {
|
||||
try {
|
||||
// 尝试使用ptr对象的属性
|
||||
var byteValue = data.add(i).readU8();
|
||||
var hexByte = byteValue.toString(16).padStart(2, "0");
|
||||
hexOutput += hexByte + " ";
|
||||
if ((i + 1) % 16 === 0) {
|
||||
hexOutput += "\n";
|
||||
}
|
||||
} catch (readErr) {
|
||||
console.log("读取字节" + i + "时出错:", readErr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.log(hexOutput);
|
||||
} else {
|
||||
console.log('data 指针无效 或 length <= 0');
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('读取data时出错:', e);
|
||||
console.log('错误详情:', e.stack || e.toString());
|
||||
}
|
||||
|
||||
return -1; // 阻断原函数
|
||||
}, 'int', ['pointer', 'uchar', 'pointer', 'int', 'pointer', 'uint']));
|
||||
console.log("已成功 Hook libusb_bulk_transfer at:", symbol.address);
|
||||
} else {
|
||||
console.log("找不到符号 libusb_bulk_transfer,请确认程序未被 strip,且符号可见。");
|
||||
}
|
||||
84
testScripts/frida_hook_libusb_modify_data_Version2.js
Executable file
84
testScripts/frida_hook_libusb_modify_data_Version2.js
Executable file
@ -0,0 +1,84 @@
|
||||
const symbol = DebugSymbol.fromName("libusb_bulk_transfer");
|
||||
console.log("libusb_bulk_transfer symbol info:", symbol);
|
||||
|
||||
if (symbol && symbol.address) {
|
||||
Interceptor.attach(symbol.address, {
|
||||
onEnter: function(args) {
|
||||
this.dev_handle = args[0];
|
||||
this.endpoint = args[1];
|
||||
this.data = args[2];
|
||||
this.length = args[3];
|
||||
this.transferred = args[4];
|
||||
this.timeout = args[5];
|
||||
|
||||
console.log('[+] libusb_bulk_transfer 被拦截');
|
||||
console.log('dev_handle:', this.dev_handle);
|
||||
console.log('endpoint:', this.endpoint);
|
||||
console.log('data pointer:', this.data);
|
||||
console.log('length:', this.length);
|
||||
console.log('transferred pointer:', this.transferred);
|
||||
console.log('timeout:', this.timeout);
|
||||
|
||||
try {
|
||||
var nLen = parseInt(this.length);
|
||||
if (this.data && nLen > 0) {
|
||||
console.log(`[+] 正在修改 ${nLen} 字节数据,全部修改为0`);
|
||||
|
||||
// 先记录前16个字节用于展示修改前后差异
|
||||
var previewBytes = 16;
|
||||
var bytesToPreview = Math.min(nLen, previewBytes);
|
||||
var originalHex = "";
|
||||
|
||||
for (var i = 0; i < bytesToPreview; i++) {
|
||||
try {
|
||||
var byteValue = this.data.add(i).readU8();
|
||||
originalHex += byteValue.toString(16).padStart(2, "0") + " ";
|
||||
} catch (readErr) {
|
||||
console.log("读取原始数据时出错:", readErr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.log("修改前前16字节:", originalHex);
|
||||
|
||||
// 修改数据为全0
|
||||
for (var j = 0; j < nLen; j++) {
|
||||
try {
|
||||
this.data.add(j).writeU8(0);
|
||||
} catch (writeErr) {
|
||||
console.log("写入数据时出错:", writeErr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 校验修改结果
|
||||
var modifiedHex = "";
|
||||
for (var k = 0; k < bytesToPreview; k++) {
|
||||
try {
|
||||
var newByteValue = this.data.add(k).readU8();
|
||||
modifiedHex += newByteValue.toString(16).padStart(2, "0") + " ";
|
||||
} catch (verifyErr) {
|
||||
console.log("验证修改后数据时出错:", verifyErr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.log("修改后前16字节:", modifiedHex);
|
||||
|
||||
console.log('[+] 数据修改完成');
|
||||
} else {
|
||||
console.log('[-] data 指针无效 或 length <= 0,无法修改数据');
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('[-] 处理数据时出错:', e);
|
||||
console.log('错误详情:', e.stack || e.toString());
|
||||
}
|
||||
},
|
||||
|
||||
onLeave: function(retval) {
|
||||
console.log(`[+] libusb_bulk_transfer 返回值: ${retval}`);
|
||||
// 如果想修改返回值,可以使用 retval.replace(0)
|
||||
}
|
||||
});
|
||||
console.log("已成功 Hook libusb_bulk_transfer at:", symbol.address);
|
||||
} else {
|
||||
console.log("找不到符号 libusb_bulk_transfer,请确认程序未被 strip,且符号可见。");
|
||||
}
|
||||
83
testScripts/frida_hook_libusb_replay_Version2.js
Executable file
83
testScripts/frida_hook_libusb_replay_Version2.js
Executable file
@ -0,0 +1,83 @@
|
||||
const symbol = DebugSymbol.fromName("libusb_bulk_transfer");
|
||||
console.log("libusb_bulk_transfer symbol info:", symbol);
|
||||
|
||||
if (symbol && symbol.address) {
|
||||
Interceptor.attach(symbol.address, {
|
||||
onEnter: function(args) {
|
||||
// 保存原始参数
|
||||
this.dev_handle = args[0];
|
||||
this.endpoint = parseInt(args[1]); // 转换为整数
|
||||
this.data = args[2];
|
||||
this.length = parseInt(args[3]); // 转换为整数
|
||||
this.transferred = args[4];
|
||||
this.timeout = parseInt(args[5]); // 转换为整数
|
||||
|
||||
// 记录原始函数和参数,以便后续重放
|
||||
this.original_function = symbol.address;
|
||||
|
||||
console.log('[+] libusb_bulk_transfer 被拦截');
|
||||
console.log('dev_handle:', this.dev_handle);
|
||||
console.log('endpoint:', this.endpoint, '(', args[1], ')');
|
||||
console.log('data pointer:', this.data);
|
||||
console.log('length:', this.length, '(', args[3], ')');
|
||||
console.log('transferred pointer:', this.transferred);
|
||||
console.log('timeout:', this.timeout, '(', args[5], ')');
|
||||
|
||||
// 显示部分原始数据(前16字节)
|
||||
try {
|
||||
if (this.data && this.length > 0) {
|
||||
var bytesToPreview = Math.min(this.length, 16);
|
||||
var originalHex = "";
|
||||
|
||||
for (var i = 0; i < bytesToPreview; i++) {
|
||||
try {
|
||||
var byteValue = this.data.add(i).readU8();
|
||||
originalHex += byteValue.toString(16).padStart(2, "0") + " ";
|
||||
} catch (readErr) {
|
||||
console.log("读取原始数据时出错:", readErr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.log("数据前16字节:", originalHex);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('读取数据时出错:', e, e.stack);
|
||||
}
|
||||
},
|
||||
|
||||
onLeave: function(retval) {
|
||||
console.log(`[+] libusb_bulk_transfer 原始调用返回值: ${retval}`);
|
||||
|
||||
// 重放次数设置
|
||||
const replayCount = 3; // 设置重放次数,这里重放3次
|
||||
console.log(`[*] 开始重放 libusb_bulk_transfer ${replayCount} 次`);
|
||||
|
||||
// 重放函数
|
||||
try {
|
||||
const originalFunction = new NativeFunction(this.original_function, 'int',
|
||||
['pointer', 'int', 'pointer', 'int', 'pointer', 'int']);
|
||||
|
||||
for (let i = 0; i < replayCount; i++) {
|
||||
console.log(`[*] 正在重放第 ${i + 1}/${replayCount} 次`);
|
||||
const replayResult = originalFunction(
|
||||
this.dev_handle,
|
||||
this.endpoint,
|
||||
this.data,
|
||||
this.length,
|
||||
this.transferred,
|
||||
this.timeout
|
||||
);
|
||||
console.log(`[+] 重放 #${i + 1} 返回值: ${replayResult}`);
|
||||
}
|
||||
|
||||
console.log('[+] 重放完成');
|
||||
} catch (err) {
|
||||
console.log('[!] 重放时发生错误: ', err, err.stack);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log("已成功 Hook libusb_bulk_transfer at:", symbol.address);
|
||||
} else {
|
||||
console.log("找不到符号 libusb_bulk_transfer,请确认程序未被 strip,且符号可见。");
|
||||
}
|
||||
226
testScripts/test/exportOpen.js
Normal file
226
testScripts/test/exportOpen.js
Normal file
@ -0,0 +1,226 @@
|
||||
// 详细调试脚本,用于解决 NativeFunction 错误
|
||||
console.log("*** 详细调试脚本开始执行 ***");
|
||||
|
||||
// 调试辅助函数
|
||||
function describeValue(value) {
|
||||
if (value === null) return "null";
|
||||
if (value === undefined) return "undefined";
|
||||
if (typeof value === "object") {
|
||||
if ("isNull" in value && typeof value.isNull === "function") {
|
||||
return value.isNull() ? "NullPointer" : `Pointer(${value})`;
|
||||
}
|
||||
try {
|
||||
return JSON.stringify(value);
|
||||
} catch (e) {
|
||||
return `[对象类型: ${Object.prototype.toString.call(value)}]`;
|
||||
}
|
||||
}
|
||||
return `${typeof value}: ${value}`;
|
||||
}
|
||||
|
||||
function safeStringify(obj) {
|
||||
try {
|
||||
return JSON.stringify(obj);
|
||||
} catch (e) {
|
||||
return `[无法序列化: ${e.message}]`;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行主逻辑
|
||||
try {
|
||||
console.log("1. 检查 Frida 核心 API 可用性");
|
||||
console.log(`- Process 对象类型: ${typeof Process}`);
|
||||
console.log(`- Module 对象类型: ${typeof Module}`);
|
||||
console.log(`- Memory 对象类型: ${typeof Memory}`);
|
||||
console.log(`- NativeFunction 对象类型: ${typeof NativeFunction}`);
|
||||
|
||||
// 步骤 1: 列出所有可用模块
|
||||
console.log("\n2. 列出系统中的一些模块:");
|
||||
var modules = Process.enumerateModules();
|
||||
console.log(`- 找到 ${modules.length} 个模块`);
|
||||
var libcFound = false;
|
||||
|
||||
for (var i = 0; i < Math.min(modules.length, 10); i++) {
|
||||
console.log(`- [${i}] ${modules[i].name} @ ${modules[i].base}`);
|
||||
if (modules[i].name.includes("libc.so")) {
|
||||
libcFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!libcFound) {
|
||||
console.log("* 警告: 前 10 个模块中未发现 libc");
|
||||
|
||||
// 尝试找到 libc
|
||||
for (var i = 0; i < modules.length; i++) {
|
||||
if (modules[i].name.includes("libc.so")) {
|
||||
console.log(`- 在位置 [${i}] 找到 libc: ${modules[i].name} @ ${modules[i].base}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 步骤 2: 全局查找 open 函数
|
||||
console.log("\n3. 尝试全局查找 open 函数:");
|
||||
console.log("- 调用 Module.findExportByName(null, 'open')");
|
||||
var openAddr = Module.findExportByName(null, "open");
|
||||
console.log(`- 结果: ${describeValue(openAddr)}`);
|
||||
|
||||
// 如果找不到 open,尝试其他名称
|
||||
if (!openAddr) {
|
||||
console.log("\n4. 尝试查找替代函数名:");
|
||||
var alternateNames = ["__open", "_open", "open64"];
|
||||
for (var i = 0; i < alternateNames.length; i++) {
|
||||
console.log(`- 尝试: ${alternateNames[i]}`);
|
||||
openAddr = Module.findExportByName(null, alternateNames[i]);
|
||||
console.log(` 结果: ${describeValue(openAddr)}`);
|
||||
if (openAddr) {
|
||||
console.log(`* 找到替代符号: ${alternateNames[i]}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 步骤 3: 尝试在特定模块中查找
|
||||
if (!openAddr) {
|
||||
console.log("\n5. 尝试在特定模块中查找:");
|
||||
for (var i = 0; i < modules.length; i++) {
|
||||
if (modules[i].name.includes("libc.so")) {
|
||||
console.log(`- 在 ${modules[i].name} 中查找 'open'`);
|
||||
try {
|
||||
openAddr = Module.findExportByName(modules[i].name, "open");
|
||||
console.log(` 结果: ${describeValue(openAddr)}`);
|
||||
if (openAddr) break;
|
||||
} catch (e) {
|
||||
console.log(` 错误: ${e.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 步骤 4: 尝试直接枚举导出符号
|
||||
if (!openAddr) {
|
||||
console.log("\n6. 尝试枚举导出符号:");
|
||||
for (var i = 0; i < modules.length; i++) {
|
||||
if (modules[i].name.includes("libc.so")) {
|
||||
console.log(`- 枚举 ${modules[i].name} 的导出`);
|
||||
var found = false;
|
||||
try {
|
||||
Module.enumerateExports(modules[i].name, {
|
||||
onMatch: function(exp) {
|
||||
if (exp.name === "open") {
|
||||
console.log(` 找到: ${exp.name} @ ${exp.address}`);
|
||||
openAddr = exp.address;
|
||||
found = true;
|
||||
}
|
||||
},
|
||||
onComplete: function() {
|
||||
if (!found) {
|
||||
console.log(" 未找到 'open' 符号");
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(` 枚举错误: ${e.message}`);
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 步骤 5: 如果找到地址,尝试创建 NativeFunction
|
||||
if (openAddr) {
|
||||
console.log("\n7. 尝试创建 NativeFunction:");
|
||||
console.log(`- 使用地址: ${openAddr}`);
|
||||
|
||||
// 打印地址的详细信息
|
||||
console.log("- 地址详细信息:");
|
||||
console.log(` 类型: ${typeof openAddr}`);
|
||||
console.log(` toString(): ${openAddr.toString()}`);
|
||||
if (typeof openAddr === 'object') {
|
||||
console.log(` 是否为空: ${openAddr.isNull ? openAddr.isNull() : 'isNull 不可用'}`);
|
||||
}
|
||||
|
||||
try {
|
||||
// 确保地址是一个有效的 NativePointer
|
||||
var openPtr = ptr(openAddr.toString());
|
||||
console.log(`- 转换为 ptr: ${openPtr}`);
|
||||
|
||||
// 创建 NativeFunction
|
||||
console.log("- 创建 NativeFunction 对象...");
|
||||
var open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
|
||||
console.log("* NativeFunction 创建成功!");
|
||||
|
||||
// 测试函数
|
||||
var testPath = Memory.allocUtf8String("/etc/hosts");
|
||||
console.log(`- 打开文件: ${Memory.readUtf8String(testPath)}`);
|
||||
|
||||
var fd = open(testPath, 0);
|
||||
console.log(`- 文件描述符: ${fd}`);
|
||||
|
||||
if (fd >= 0) {
|
||||
console.log("* 文件成功打开!");
|
||||
} else {
|
||||
console.log(`* 打开文件失败,错误码: ${-fd}`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`* 创建 NativeFunction 时出错: ${e.message}`);
|
||||
console.log(`* 错误类型: ${e.name}`);
|
||||
console.log(`* 堆栈: ${e.stack}`);
|
||||
}
|
||||
} else {
|
||||
console.log("\n* 错误: 无法找到 open 函数");
|
||||
}
|
||||
|
||||
// 步骤 6: 尝试手动获取系统调用号
|
||||
console.log("\n8. 尝试系统调用方法 (仅适用于 Linux):");
|
||||
try {
|
||||
console.log("- 识别 CPU 架构:", Process.arch);
|
||||
|
||||
// 只有在 Linux 上才继续
|
||||
if (Process.platform === 'linux') {
|
||||
var syscallNumber = -1;
|
||||
|
||||
// 根据架构确定 open 的系统调用号
|
||||
if (Process.arch === 'x64') {
|
||||
syscallNumber = 2; // x86_64 上 open 的系统调用号
|
||||
} else if (Process.arch === 'arm64') {
|
||||
syscallNumber = 56; // ARM64 上 open 的系统调用号
|
||||
} else if (Process.arch === 'ia32') {
|
||||
syscallNumber = 5; // x86 上 open 的系统调用号
|
||||
}
|
||||
|
||||
if (syscallNumber !== -1) {
|
||||
console.log(`- open 系统调用号: ${syscallNumber}`);
|
||||
console.log("* 注意: 可以使用系统调用直接调用 open,但需要更复杂的设置");
|
||||
} else {
|
||||
console.log("* 未知架构,无法确定系统调用号");
|
||||
}
|
||||
} else {
|
||||
console.log("* 不是 Linux 平台,跳过系统调用方法");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`* 系统调用检查错误: ${e.message}`);
|
||||
}
|
||||
|
||||
console.log("\n9. Frida 会话信息:");
|
||||
try {
|
||||
var sessionInfo = {
|
||||
architecture: Process.arch,
|
||||
platform: Process.platform,
|
||||
pageSize: Process.pageSize,
|
||||
pointerSize: Process.pointerSize,
|
||||
// 添加更多可能有用的信息
|
||||
};
|
||||
console.log(safeStringify(sessionInfo));
|
||||
} catch (e) {
|
||||
console.log(`* 获取会话信息错误: ${e.message}`);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error("*** 主脚本错误 ***");
|
||||
console.error(`- 消息: ${e.message}`);
|
||||
console.error(`- 类型: ${e.name}`);
|
||||
console.error(`- 堆栈: ${e.stack}`);
|
||||
}
|
||||
|
||||
console.log("\n*** 调试脚本执行完毕 ***");
|
||||
59
testScripts/test/listMod.js
Normal file
59
testScripts/test/listMod.js
Normal file
@ -0,0 +1,59 @@
|
||||
console.log("列出所有加载的模块:");
|
||||
|
||||
var modules = Process.enumerateModules();
|
||||
console.log("总模块数量:", modules.length);
|
||||
|
||||
// 查找 libc 相关模块
|
||||
var libcFound = false;
|
||||
for (var i = 0; i < modules.length; i++) {
|
||||
var module = modules[i];
|
||||
console.log((i+1) + ". " + module.name + " @ " + module.base);
|
||||
|
||||
if (module.name.includes("libc") || module.path.includes("libc")) {
|
||||
libcFound = true;
|
||||
console.log("**** 找到 libc 相关模块! ****");
|
||||
// 列出详细信息
|
||||
console.log(" 名称: " + module.name);
|
||||
console.log(" 路径: " + module.path);
|
||||
console.log(" 基址: " + module.base);
|
||||
console.log(" 大小: " + module.size);
|
||||
}
|
||||
}
|
||||
|
||||
if (!libcFound) {
|
||||
console.log("没有找到明确的 libc 相关模块,尝试使用系统加载器...");
|
||||
try {
|
||||
// 尝试直接通过系统加载器查找 open 函数
|
||||
var openPtr = Module.findExportByName(null, "open");
|
||||
if (openPtr) {
|
||||
console.log("通过系统加载器找到 open 函数地址:", openPtr);
|
||||
|
||||
// 确定哪个模块拥有此地址
|
||||
for (var i = 0; i < modules.length; i++) {
|
||||
var m = modules[i];
|
||||
var baseAddr = ptr(m.base.toString());
|
||||
if (openPtr.compare(baseAddr) >= 0 &&
|
||||
openPtr.compare(baseAddr.add(m.size)) < 0) {
|
||||
console.log("open 函数位于模块:", m.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试使用此函数
|
||||
try {
|
||||
var open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
|
||||
var path = Memory.allocUtf8String("/etc/hosts");
|
||||
var fd = open(path, 0);
|
||||
console.log("成功打开文件,文件描述符:", fd);
|
||||
} catch (e) {
|
||||
console.log("调用 open 函数失败:", e);
|
||||
}
|
||||
} else {
|
||||
console.log("无法找到 open 函数");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("尝试通过系统加载器查找函数时出错:", e);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("脚本执行完毕");
|
||||
Reference in New Issue
Block a user