把frida的脚本可以通过实例类跑出来,同时获取占用pid也正常了,可能未来会有bug,到时候根据实际情况调整
This commit is contained in:
parent
f095b5836b
commit
a5dc2d9578
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
upper/build
|
||||
upper/upper.pro.*
|
||||
upper/upper.pro.*
|
||||
.vscode
|
||||
BIN
idapro_90_x64linux.run
Executable file
BIN
idapro_90_x64linux.run
Executable file
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
FILE* log_output=stdout;
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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.
|
||||
|
||||
367
usbFilter.cpp
367
usbFilter.cpp
@ -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
|
||||
}
|
||||
16
usbFilter.h
16
usbFilter.h
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user