Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ flight_profiler_agent.${SHARED_LIB_SUFFIX}:
@mv build/libfrida-gum.* build/lib/
@echo "compiling flight_profiler_agent.${SHARED_LIB_SUFFIX}"
@${CC} ${CFLAGS} ${LDFLAGS} -I${PY_HEADER_PATH} -Ibuild/include -Icsrc \
csrc/code_inject.cpp csrc/frida_profiler.cpp \
csrc/profiler_attach.cpp csrc/frida_profiler.cpp \
csrc/time_util.cpp csrc/symbol_util.cpp csrc/python_util.cpp \
csrc/py_gil_intercept.cpp csrc/py_gil_stat.cpp csrc/stack/py_stack.cpp \
-o build/lib/flight_profiler_agent.${SHARED_LIB_SUFFIX} -Lbuild/lib -lfrida-gum -ldl
@if [ "$(IS_DARWIN)" != "Darwin" ]; then \
$(CC) $(INJECT_CFLAGS) -Icsrc/inject/ -o build/lib/inject csrc/inject/ProcessTracer.cpp csrc/inject/ProcessUtils.cpp csrc/inject/LibraryInjector.cpp csrc/inject/inject.cpp -ldl;\
cp build/lib/inject flight_profiler/lib/inject;\
$(CC) $(INJECT_CFLAGS) -Icsrc/attach/ -o build/lib/attach csrc/attach/ProcessTracer.cpp csrc/attach/ProcessUtils.cpp csrc/attach/AttachAgent.cpp csrc/attach/attach.cpp -ldl;\
cp build/lib/attach flight_profiler/lib/attach;\
fi
@cp build/lib/flight_profiler_agent.${SHARED_LIB_SUFFIX} flight_profiler/lib/flight_profiler_agent.${SHARED_LIB_SUFFIX}

Expand Down
242 changes: 116 additions & 126 deletions csrc/inject/LibraryInjector.cpp → csrc/attach/AttachAgent.cpp

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions csrc/attach/AttachAgent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#ifndef ATTACH_AGENT_H
#define ATTACH_AGENT_H

#include "ExitCode.h"
#include "ProcessTracer.h"
#include "ProcessUtils.h"
#include <memory>
#include <string>
#include <sys/user.h>
#include <vector>

/**
* @brief Manages the attaching of profiler agent into target processes
*
* This class implements a comprehensive solution for attaching profiler agent
* into target processes using advanced ptrace-based techniques. It handles
* all aspects of the attach process including preparation, execution, and
* verification.
*/
class AttachAgent {
public:
/**
* @brief Constructs an AttachAgent instance
* @param target_process_id PID of the process to attach the agent into
* @param shared_library_file_path File path of the shared library to load
* @param debug_mode Enable debug logging
*/
AttachAgent(pid_t target_process_id,
const std::string &shared_library_file_path,
bool debug_mode = false);

/**
* @brief Cleans up resources used by the AttachAgent
*/
~AttachAgent();

/**
* @brief Performs the complete agent attach process
* @return ExitCode indicating success or failure
*/
ExitCode performAttach();

private:
// Core instance attributes
pid_t target_process_id_;
std::string library_file_path_;
ProcessTracer process_tracer_;

// Attach workflow methods
ExitCode initializeAttachEnvironment(long &code_attach_address,
REG_TYPE *original_registers,
REG_TYPE *working_registers);
ExitCode orchestrateAttachSequence(long attach_address,
long malloc_function_address,
long free_function_address,
long dlopen_function_address,
int library_path_string_length,
REG_TYPE *initial_registers);
ExitCode confirmAttachSuccess(long attach_memory_location,
const std::vector<char> &backup_memory_data,
size_t shellcode_byte_size,
REG_TYPE *original_register_state);

// Shellcode generation methods
std::vector<char> createShellcodePayload(size_t &payload_size,
intptr_t &return_instruction_offset);

// Path manipulation utilities
void getParentDirectoryPath(std::string &file_path);
};

#endif // ATTACH_AGENT_H
File renamed without changes.
19 changes: 9 additions & 10 deletions csrc/inject/ProcessTracer.cpp → csrc/attach/ProcessTracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,28 +272,27 @@ bool ProcessTracer::verifySignalStatus() {
}

/**
* @brief Restore the process state after a failed injection attempt
* @brief Restore the process state after a failed attach attempt
*
* This function performs the three required steps to restore the process state:
* 1. Write the original memory data back to the injection address
* 1. Write the original memory data back to the attach address
* 2. Restore the original register state
* 3. Detach from the process
*
* @param injection_address Address where the shellcode was injected
* @param backup_data Pointer to the original data at the injection address
* @param attach_address Address where the shellcode was loaded
* @param backup_data Pointer to the original data at the attach address
* @param data_length Length of the backup data
* @param registers Pointer to the original register state
* @return true if restoration was successful, false otherwise
*/
bool ProcessTracer::recoverInjection(long injection_address,
const void *backup_data,
size_t data_length, REG_TYPE *registers) {
// Step 1: Write the original memory data back to the injection address
if (!writeMemory(injection_address, backup_data, data_length)) {
bool ProcessTracer::recoverAttach(long attach_address, const void *backup_data,
size_t data_length, REG_TYPE *registers) {
// Step 1: Write the original memory data back to the attach address
if (!writeMemory(attach_address, backup_data, data_length)) {
if (debug_mode_) {
std::cerr << "[ERROR] PyFlightProfiler: Failed to recover original "
"memory data at address 0x"
<< std::hex << injection_address << std::dec << std::endl;
<< std::hex << attach_address << std::dec << std::endl;
}
return false;
}
Expand Down
10 changes: 5 additions & 5 deletions csrc/inject/ProcessTracer.h → csrc/attach/ProcessTracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ class ProcessTracer {

// Failure recovery
/**
* @brief Restore the process state after a failed injection attempt
* @param injection_address Address where the shellcode was injected
* @param backup_data Pointer to the original data at the injection address
* @brief Restore the process state after a failed attach attempt
* @param attach_address Address where the shellcode was loaded
* @param backup_data Pointer to the original data at the attach address
* @param data_length Length of the backup data
* @param registers Pointer to the original register state
* @return true if restoration was successful, false otherwise
*/
bool recoverInjection(long injection_address, const void *backup_data,
size_t data_length, REG_TYPE *registers);
bool recoverAttach(long attach_address, const void *backup_data,
size_t data_length, REG_TYPE *registers);

// Accessor for debug mode
/**
Expand Down
File renamed without changes.
File renamed without changes.
23 changes: 11 additions & 12 deletions csrc/inject/inject.cpp → csrc/attach/attach.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "LibraryInjector.h"
#include "AttachAgent.h"
#include "ProcessUtils.h"
#include <cstdio>
#include <cstdlib>
Expand Down Expand Up @@ -26,22 +26,22 @@ void extractParentDirectoryFromPath(std::string &file_system_path) {
}

/**
* @brief Main entry point for the library injection utility
* @brief Main entry point for the profiler attach utility
*
* This program injects the flight_profiler_agent.so library into a target
* process using advanced ptrace-based injection techniques.
* This program attaches the flight_profiler_agent.so library into a target
* process using advanced ptrace-based techniques.
*
* Usage: ./inject <process_identifier>
* Usage: ./attach <process_identifier>
*
* @param argument_count Number of command line arguments
* @param argument_values Array of command line arguments
* @return 0 on successful injection, 1 on failure
* @return 0 on successful attach, 1 on failure
*/
int main(int argument_count, char **argument_values) {
// Validate command line arguments
if (argument_count < 2) {
std::cout << "Invalid inject command without target process identifier "
"provided, USAGE: ./inject process_id!"
std::cout << "Invalid attach command without target process identifier "
"provided, USAGE: ./attach process_id!"
<< std::endl;
return 1;
}
Expand Down Expand Up @@ -86,9 +86,8 @@ int main(int argument_count, char **argument_values) {
std::string library_file_path(library_file_path_cstring);
free(library_file_path_cstring);

// Create and execute the injector
LibraryInjector library_injector(target_process_id, library_file_path,
debug_mode);
// Create and execute the attach agent
AttachAgent attach_agent(target_process_id, library_file_path, debug_mode);

return static_cast<int>(library_injector.performInjection());
return static_cast<int>(attach_agent.performAttach());
}
16 changes: 0 additions & 16 deletions csrc/code_inject.h

This file was deleted.

6 changes: 2 additions & 4 deletions csrc/frida_profiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,25 @@ int init_frida_gum() {
pthread_mutex_lock(&mutex);
if (inited != 0) {
pthread_mutex_unlock(&mutex);
fprintf(stderr, "[*] frida gum already inited\n");
return 0;
}
gum_init_embedded();
inited = 1;
pthread_mutex_unlock(&mutex);
g_print("[*] init frida gum successfully\n");
fprintf(stdout, "[PyFlightProfiler] Native profiler initialized.\n");
return 0;
}

int deinit_frida_gum() {
pthread_mutex_lock(&mutex);
if (inited != 1) {
// pthread_mutex_unlock(&mutex);
fprintf(stderr, "[*] frida gum not inited\n");
return 0;
}
gum_deinit_embedded();
inited = 0;
pthread_mutex_unlock(&mutex);
g_print("[*] deinit frida gum successfully\n");
fprintf(stdout, "[PyFlightProfiler] Native profiler deinitialized.\n");
return 0;
}

Expand Down
72 changes: 0 additions & 72 deletions csrc/inject/LibraryInjector.h

This file was deleted.

Loading
Loading