把frida的脚本可以通过实例类跑出来,同时获取占用pid也正常了,可能未来会有bug,到时候根据实际情况调整

This commit is contained in:
lumos 2025-06-28 22:52:38 +08:00
parent f095b5836b
commit a5dc2d9578
10 changed files with 442 additions and 16 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
upper/build
upper/upper.pro.*
upper/upper.pro.*
.vscode

BIN
idapro_90_x64linux.run Executable file

Binary file not shown.

2
log.cpp Normal file
View File

@ -0,0 +1,2 @@
#include "log.h"
FILE* log_output = stdout; // 只定义一次

View File

@ -1,7 +1,7 @@
#include "mainwindow.h"
#include <QApplication>
FILE* log_output=stdout;
int main(int argc, char *argv[])
{

View File

@ -1,6 +1,5 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QDateTime"
MainWindow::MainWindow(QWidget *parent)
@ -26,5 +25,19 @@ void MainWindow::on_pushButton_3_clicked()
{
string tmp =uf->EnumDriversAndDevices();
this->onPrint(QString::fromStdString(tmp));
auto jsonList = json::parse(tmp);
ui->comboBox->clear();
for(auto i :jsonList){
if(i.contains("DevPath")){
ui->comboBox->addItem(QString::fromStdString(i["DevPath"].get<string>()));
}
}
}
void MainWindow::on_pushButton_4_clicked()
{
QString tmp = ui->comboBox->currentText();
uf->open(tmp.toStdString());
}

View File

@ -4,6 +4,10 @@
#include <QMainWindow>
#include "../usbFilter.h"
#include "QDebug"
#include "QDateTime"
#include "../json.hpp"
using json = nlohmann::json;
QT_BEGIN_NAMESPACE
namespace Ui {
@ -25,6 +29,8 @@ public slots:
private slots:
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
private:
Ui::MainWindow *ui;
usbFilter *uf;

View File

@ -15,21 +15,45 @@
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QPushButton" name="pushButton_2">
<item row="4" column="1">
<widget class="QPushButton" name="pushButton_4">
<property name="text">
<string>Stop Srv</string>
<string>Open</string>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="4" column="0">
<widget class="QComboBox" name="comboBox"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Start Srv</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Stop Srv</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>Enum Drivers And Devices</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QPushButton" name="pushButton_5">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Log</string>
@ -41,13 +65,6 @@
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>Enum Drivers And Devices</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">

View File

@ -11,15 +11,19 @@ CONFIG += c++17
SOURCES += \
../usbFilter.cpp \
main.cpp \
../log.cpp \
mainwindow.cpp
HEADERS += \
../json.hpp \
../usbFilter.h \
mainwindow.h
mainwindow.h\
../log.h
FORMS += \
mainwindow.ui
LIBS += -ludev
# Default rules for deployment.

View File

@ -99,3 +99,370 @@ string usbFilter::EnumDriversAndDevices()
return list.dump();
}
bool usbFilter::open(const string &devPath)
{
// 检查设备路径是否为空
if (devPath.empty()) {
return false;
}
// 检查设备路径是否存在
string devPathTrans = sysfsToDevPath(devPath);
if (devPathTrans.empty()) {
LOG_ERROR("Device path does not exist" );
return false;
}else{
LOG_DEBUG("Opening device: %s", devPathTrans.c_str());
}
int pid = getDeviceUserPID(devPathTrans);
if (pid < 0) {
LOG_ERROR("No process is using the device: %s", devPathTrans.c_str());
return false;
} else {
LOG_DEBUG("Device %s is being used by process with PID: %d", devPathTrans.c_str(), pid);
}
//获取当前目录
string currendDir = CURRENTDIR;
// string scriptPath = currentDir + "/scripts";
string scriptPath = currendDir + "/testScripts";
LOG_INFO("Ready to run frida scripts. The scripts are located in %s.",scriptPath.c_str());
// 构造命令行
// string cmd = "frida -p " + to_string(pid) + " -l " + scriptPath + "/frida_hook_libusb_basic_Version2.js &";
string cmd = "frida -p " + to_string(pid) + " -l " + scriptPath + "/frida_hook_libusb_basic_Version2.js &";
LOG_DEBUG("Running command: %s", cmd.c_str());
// 执行命令
int result = system(cmd.c_str());
if (result != 0) {
LOG_ERROR("Failed to run command: %s", cmd.c_str());
return false;
}
LOG_INFO("Command executed successfully.");
return true;
}
string usbFilter::sysfsToDevPath(const string& sysfs_path) {
struct stat st;
// Check if the sysfs path exists
if (stat(sysfs_path.c_str(), &st) != 0 || !S_ISDIR(st.st_mode)) {
return ""; // Path doesn't exist or is not a directory
}
// Check if this is a USB device path
if (sysfs_path.find("/usb") != string::npos) {
return convertUsbSysfsPath(sysfs_path);
}
// Check if this is a PCI/PCIe device path
if (sysfs_path.find("/pci") != string::npos) {
return convertPciSysfsPath(sysfs_path);
}
// Unknown device type
return "";
}
// Helper function to convert USB sysfs path
string usbFilter::convertUsbSysfsPath(const string& sysfs_path) {
// Construct paths to busnum and devnum files
string busnum_path = sysfs_path + "/busnum";
string devnum_path = sysfs_path + "/devnum";
// Read bus number
ifstream bus_file(busnum_path);
if (!bus_file.is_open()) {
return "";
}
int busnum = 0;
bus_file >> busnum;
bus_file.close();
if (busnum <= 0) {
return "";
}
// Read device number
ifstream dev_file(devnum_path);
if (!dev_file.is_open()) {
return "";
}
int devnum = 0;
dev_file >> devnum;
dev_file.close();
if (devnum <= 0) {
return "";
}
// Construct the /dev path with proper zero-padding
ostringstream dev_path;
dev_path << "/dev/bus/usb/"
<< setfill('0') << setw(3) << busnum
<< "/"
<< setfill('0') << setw(3) << devnum;
string result = dev_path.str();
// Check if the /dev node actually exists
if (access(result.c_str(), F_OK) != 0) {
return ""; // Device node doesn't exist
}
return result;
}
// Helper function to convert PCI/PCIe sysfs path
string usbFilter::convertPciSysfsPath(const string& sysfs_path) {
// First check if there are any special device nodes (e.g., for graphics cards, network cards)
// 1. Check for graphics card
string device_path = sysfs_path + "/drm";
DIR* dir = opendir(device_path.c_str());
if (dir) {
// Found DRM device (likely a graphics card)
closedir(dir);
// Look for card* entries in /dev/dri/
dir = opendir("/dev/dri");
if (dir) {
struct dirent *entry;
regex card_regex("card[0-9]+");
while ((entry = readdir(dir)) != NULL) {
string name = entry->d_name;
if (regex_match(name, card_regex)) {
// For each card, check if it corresponds to our PCI device
string cardpath = "/dev/dri/" + name;
// Need to check if this card corresponds to our PCI device
// One way is to check the device node major/minor numbers against sys/dev entries
struct stat card_stat;
if (stat(cardpath.c_str(), &card_stat) == 0) {
ostringstream dev_path;
dev_path << sysfs_path << "/drm/" << name << "/dev";
ifstream dev_file(dev_path.str());
if (dev_file.is_open()) {
string dev_numbers;
getline(dev_file, dev_numbers);
dev_file.close();
// Format is major:minor
size_t colon_pos = dev_numbers.find(':');
if (colon_pos != string::npos) {
int major = stoi(dev_numbers.substr(0, colon_pos));
int minor = stoi(dev_numbers.substr(colon_pos + 1));
if (major == major(card_stat.st_rdev) &&
minor == minor(card_stat.st_rdev)) {
closedir(dir);
return cardpath;
}
}
}
}
}
}
closedir(dir);
}
}
// 2. Check for network interfaces
device_path = sysfs_path + "/net";
dir = opendir(device_path.c_str());
if (dir) {
// Found network interface
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR &&
strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, "..") != 0) {
closedir(dir);
// Network interfaces don't have /dev entries, but we can return the interface name
return "/sys/class/net/" + string(entry->d_name);
}
}
closedir(dir);
}
// 3. Check for NVMe devices
if (sysfs_path.find("nvme") != string::npos) {
// Extract the NVMe controller number (e.g., nvme0)
regex nvme_regex("nvme([0-9]+)");
smatch match;
if (regex_search(sysfs_path, match, nvme_regex) && match.size() > 1) {
string nvme_num = match[1].str();
string nvme_dev = "/dev/nvme" + nvme_num;
if (access(nvme_dev.c_str(), F_OK) == 0) {
return nvme_dev;
}
}
}
// 4. Check for SCSI/SATA devices that might be connected via PCIe
string block_path = sysfs_path + "/block";
dir = opendir(block_path.c_str());
if (dir) {
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR &&
strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, "..") != 0) {
string dev_name = entry->d_name;
string block_dev = "/dev/" + dev_name;
if (access(block_dev.c_str(), F_OK) == 0) {
closedir(dir);
return block_dev;
}
}
}
closedir(dir);
}
// 5. Generic way to find PCI device - try to use the device's resource file
ifstream resource_file(sysfs_path + "/resource");
if (resource_file.is_open()) {
// This is more complex and would require parsing the resource file
// and checking if it maps to any character device
resource_file.close();
}
// 6. Check for udev links in /dev/char/ directory
string dev_content;
ifstream dev_file(sysfs_path + "/dev");
if (dev_file.is_open()) {
getline(dev_file, dev_content); // Format is "major:minor"
dev_file.close();
if (!dev_content.empty()) {
// Check in /dev/char/ directory
string char_dev_path = "/dev/char/" + dev_content;
if (access(char_dev_path.c_str(), F_OK) == 0) {
// This is a character device
return char_dev_path;
}
// Check in /dev/block/ directory
string block_dev_path = "/dev/block/" + dev_content;
if (access(block_dev_path.c_str(), F_OK) == 0) {
// This is a block device
return block_dev_path;
}
}
}
// If we reach here, couldn't find a corresponding /dev node
return "";
}
// 修复getDeviceUserPID函数中的错误和警告
int usbFilter::getDeviceUserPID(const string& devpath) {
// First check if the device path exists
struct stat st;
if (stat(devpath.c_str(), &st) != 0) {
return -1; // Device path doesn't exist
}
// Use lsof command to find processes using this device
string cmd = "lsof -t " + devpath + " 2>/dev/null";
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
if (!pipe) {
return -1; // Failed to run command
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
// Trim whitespace and newlines
result.erase(result.find_last_not_of(" \n\r\t") + 1);
// If result is empty, no process is using the device
if (result.empty()) {
return -1;
}
// Parse the PID from the result (may have multiple lines if multiple processes)
regex pid_regex("^(\\d+)$", regex::multiline);
smatch match;
if (regex_search(result, match, pid_regex) && match.size() > 1) {
try {
return stoi(match[1].str());
} catch (const invalid_argument& e) {
return -1;
} catch (const out_of_range& e) {
return -1;
}
}
// Alternative approach using /proc filesystem if lsof fails or isn't available
if (access("/proc", F_OK) == 0) {
// Iterate through all processes
string proc_dir = "/proc";
array<char, 256> cmd;
// 修复这行错误
FILE* fp = popen("ls -d /proc/[0-9]*", "r");
if (fp) {
while (fgets(cmd.data(), cmd.size(), fp) != nullptr) {
string pid_dir = cmd.data();
pid_dir.erase(pid_dir.find_last_not_of("\n\r") + 1);
// Check process fd directory
string fd_dir = pid_dir + "/fd";
FILE* fd_fp = popen(("ls -l " + fd_dir + " 2>/dev/null").c_str(), "r");
if (fd_fp) {
array<char, 512> fd_info;
bool found = false;
while (fgets(fd_info.data(), fd_info.size(), fd_fp) != nullptr) {
string line = fd_info.data();
// Check if this fd points to our device
if (line.find(devpath) != string::npos) {
found = true;
break;
}
}
pclose(fd_fp);
if (found) {
pclose(fp);
// Extract PID from path /proc/[0-9]*
regex proc_regex("/proc/(\\d+)");
if (regex_search(pid_dir, match, proc_regex) && match.size() > 1) {
try {
return stoi(match[1].str());
} catch (...) {
return -1;
}
}
}
}
}
pclose(fp);
}
}
return -1; // No process found using the device
}

View File

@ -8,6 +8,14 @@
#include <sstream>
#include <regex>
#include <libudev.h>
#include <fstream>
#include <iomanip>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <cstring>
#include <fcntl.h>
#define CURRENTDIR "/home/leo/devCode/outer/USBFilter_30/usbFilter"
using namespace std;
@ -23,5 +31,13 @@ public:
void StartSrv();
void StopSrv();
string EnumDriversAndDevices();
bool open(const string &devPath);
private:
string sysfsToDevPath(const string& sysfs_path);
string convertUsbSysfsPath(const string& sysfs_path);
string convertPciSysfsPath(const string& sysfs_path);
int getDeviceUserPID(const string& devpath);
};