Skip to content

Commit

Permalink
Merge pull request #1 from Genei-Inc/dev
Browse files Browse the repository at this point in the history
fix c++ exports
  • Loading branch information
luadebug authored Oct 12, 2024
2 parents 07eb2e4 + 6341ba1 commit e24e417
Show file tree
Hide file tree
Showing 3 changed files with 327 additions and 5 deletions.
320 changes: 320 additions & 0 deletions packages/l/libmem/patches/cxxexport.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,320 @@
diff --git a/include/libmem/libmem.hpp b/include/libmem/libmem.hpp
index bce9484..31bcacf 100644
--- a/include/libmem/libmem.hpp
+++ b/include/libmem/libmem.hpp
@@ -28,6 +28,7 @@
#include <string>
#include <optional>
#include <vector>
+#include "libmem.h"

struct lm_process_t;
struct lm_thread_t;
@@ -195,108 +219,108 @@ namespace libmem {
// Process API

/// Searches for a process by its name
- std::optional<std::vector<Process>> EnumProcesses();
+ LM_API std::optional<std::vector<Process>> LM_CALL EnumProcesses();

/// Gets the current process
- std::optional<Process> GetProcess();
+ LM_API std::optional<Process> LM_CALL GetProcess();

/// Gets a process by its process ID
- std::optional<Process> GetProcess(Pid pid);
+ LM_API std::optional<Process> LM_CALL GetProcess(Pid pid);

/// Finds a process by its name
- std::optional<Process> FindProcess(const char *process_name);
+ LM_API std::optional<Process> LM_CALL FindProcess(const char *process_name);

/// Checks if a process is alive or not
- bool IsProcessAlive(const Process *process);
+ LM_API bool LM_CALL IsProcessAlive(const Process *process);

/// Gets the process architecture bits
- size_t GetBits();
+ LM_API size_t LM_CALL GetBits();

/// Gets the system architecture bits
- size_t GetSystemBits();
+ LM_API size_t LM_CALL GetSystemBits();

// Thread API

/// Enumerates the thread of the current process
- std::optional<std::vector<Thread>> EnumThreads();
+ LM_API std::optional<std::vector<Thread>> LM_CALL EnumThreads();

/// Enumerates the thread of a remote process
- std::optional<std::vector<Thread>> EnumThreads(const Process *process);
+ LM_API std::optional<std::vector<Thread>> LM_CALL EnumThreads(const Process *process);

/// Gets the current thread
- std::optional<Thread> GetThread();
+ LM_API std::optional<Thread> LM_CALL GetThread();

/// Gets a thread in a remote process
- std::optional<Thread> GetThread(const Process *process);
+ LM_API std::optional<Thread> LM_CALL GetThread(const Process *process);

/// Gets the process that owns a thread
- std::optional<Process> GetThreadProcess(const Thread *thread);
+ LM_API std::optional<Process> LM_CALL GetThreadProcess(const Thread *thread);

// Module API

/// Enumerates modules in the current process
- std::optional<std::vector<Module>> EnumModules();
+ LM_API std::optional<std::vector<Module>> LM_CALL EnumModules();

/// Enumerates modules in a remote process
- std::optional<std::vector<Module>> EnumModules(const Process *process);
+ LM_API std::optional<std::vector<Module>> LM_CALL EnumModules(const Process *process);

/// Searches for a module in the current process
- std::optional<Module> FindModule(const char *name);
+ LM_API std::optional<Module> LM_CALL FindModule(const char *name);

/// Searches for a module in a remote process
- std::optional<Module> FindModule(const Process *process, const char *name);
+ LM_API std::optional<Module> LM_CALL FindModule(const Process *process, const char *name);

/// Loads a module into the current process
- std::optional<Module> LoadModule(const char *path);
+ LM_API std::optional<Module> LM_CALL LoadModule(const char *path);

/// Loads a module into a remote process
- std::optional<Module> LoadModule(const Process *process, const char *path);
+ LM_API std::optional<Module> LM_CALL LoadModule(const Process *process, const char *path);

/// Unloads a module from the current process
- bool UnloadModule(const Module *module);
+ LM_API bool LM_CALL UnloadModule(const Module *module);

/// Unloads a module from a remote process
- bool UnloadModule(const Process *process, const Module *module);
+ LM_API bool LM_CALL UnloadModule(const Process *process, const Module *module);

// Symbol API

/// Enumerates the symbols from a module
- std::optional<std::vector<Symbol>> EnumSymbols(const Module *module);
+ LM_API std::optional<std::vector<Symbol>> LM_CALL EnumSymbols(const Module *module);

/// Finds the address of a symbol within a module
- std::optional<Address> FindSymbolAddress(const Module *module, const char *symbol_name);
+ LM_API std::optional<Address> LM_CALL FindSymbolAddress(const Module *module, const char *symbol_name);

/// Demangles a mangled symbol name
- std::optional<std::string> DemangleSymbol(const char *symbol_name);
+ LM_API std::optional<std::string> LM_CALL DemangleSymbol(const char *symbol_name);

/// Enumerates the symbols from a module and demangles them
- std::optional<std::vector<Symbol>> EnumSymbolsDemangled(const Module *module);
+ LM_API std::optional<std::vector<Symbol>> LM_CALL EnumSymbolsDemangled(const Module *module);

/// Finds the address of a demangled symbol within a module
- std::optional<Address> FindSymbolAddressDemangled(const Module *module, const char *symbol_name);
+ LM_API std::optional<Address> LM_CALL FindSymbolAddressDemangled(const Module *module, const char *symbol_name);

// Segment API

/// Enumerates the memory segments in the current process
- std::optional<std::vector<Segment>> EnumSegments();
+ LM_API std::optional<std::vector<Segment>> LM_CALL EnumSegments();

/// Enumerates the memory segments in a remote process
- std::optional<std::vector<Segment>> EnumSegments(const Process *process);
+ LM_API std::optional<std::vector<Segment>> LM_CALL EnumSegments(const Process *process);

/// Searches for a memory segment that a given address is within in the current process
- std::optional<Segment> FindSegment(Address address);
+ LM_API std::optional<Segment> LM_CALL FindSegment(Address address);

/// Searches for a memory segment that a given address is within in a remote process
- std::optional<Segment> FindSegment(const Process *process, Address address);
+ LM_API std::optional<Segment> LM_CALL FindSegment(const Process *process, Address address);

// Memory API

/// Reads memory from a source address in the current process
- size_t ReadMemory(Address source, uint8_t *dest, size_t size);
+ LM_API size_t LM_CALL ReadMemory(Address source, uint8_t *dest, size_t size);

/// Reads memory from a source address in the current process
template <typename T>
- inline T ReadMemory(Address source)
+ LM_API inline T LM_CALL ReadMemory(Address source)
{
T dest;
ReadMemory(source, reinterpret_cast<uint8_t *>(&dest), sizeof(dest));
@@ -304,11 +328,11 @@ namespace libmem {
}

/// Reads memory from a source address in a remote process
- size_t ReadMemory(const Process *process, Address source, uint8_t *dest, size_t size);
+ LM_API size_t LM_CALL ReadMemory(const Process *process, Address source, uint8_t *dest, size_t size);

/// Reads memory from a source address in a remote process
template <typename T>
- inline std::optional<T> ReadMemory(const Process *process, Address source)
+ LM_API inline std::optional<T> LM_CALL ReadMemory(const Process *process, Address source)
{
T dest;
if (ReadMemory(process, source, reinterpret_cast<uint8_t *>(&dest), sizeof(dest)) != sizeof(dest))
@@ -317,121 +341,121 @@ namespace libmem {
}

/// Writes memory into a destination address in the current process
- size_t WriteMemory(Address dest, uint8_t *source, size_t size);
+ LM_API size_t LM_CALL WriteMemory(Address dest, uint8_t *source, size_t size);

/// Writes memory into a destination address in the current process
template <typename T>
- inline void WriteMemory(Address dest, T source)
+ LM_API inline void LM_CALL WriteMemory(Address dest, T source)
{
WriteMemory(dest, reinterpret_cast<uint8_t *>(&source), sizeof(T));
}

/// Writes memory into a destination address in a remote process
- size_t WriteMemory(const Process *process, Address dest, uint8_t *source, size_t size);
+ LM_API size_t LM_CALL WriteMemory(const Process *process, Address dest, uint8_t *source, size_t size);

/// Writes memory into a destination address in a remote process
template <typename T>
- inline void WriteMemory(const Process *process, Address dest, T source)
+ LM_API inline void LM_CALL WriteMemory(const Process *process, Address dest, T source)
{
WriteMemory(process, dest, reinterpret_cast<uint8_t *>(&source), sizeof(T));
}

/// Sets a memory region to a specific byte in the current process
- size_t SetMemory(Address dest, uint8_t byte, size_t size);
+ LM_API size_t LM_CALL SetMemory(Address dest, uint8_t byte, size_t size);

/// Sets a memory region to a specific byte in a remote process
- size_t SetMemory(const Process *process, Address dest, uint8_t byte, size_t size);
+ LM_API size_t LM_CALL SetMemory(const Process *process, Address dest, uint8_t byte, size_t size);

/// Changes the memory protection flags of a memory region in the current process
- std::optional<Prot> ProtMemory(Address address, size_t size, Prot prot);
+ LM_API std::optional<Prot> LM_CALL ProtMemory(Address address, size_t size, Prot prot);

/// Changes the memory protection flags of a memory region in a remote process
- std::optional<Prot> ProtMemory(const Process *process, Address address, size_t size, Prot prot);
+ LM_API std::optional<Prot> LM_CALL ProtMemory(const Process *process, Address address, size_t size, Prot prot);

/// Allocates memory in the current process (page-aligned)
- std::optional<Address> AllocMemory(size_t size, Prot prot);
+ LM_API std::optional<Address> LM_CALL AllocMemory(size_t size, Prot prot);

/// Allocates memory in a remote process (page-aligned)
- std::optional<Address> AllocMemory(const Process *process, size_t size, Prot prot);
+ LM_API std::optional<Address> LM_CALL AllocMemory(const Process *process, size_t size, Prot prot);

/// Frees memory allocated in the current process (page-aligned)
- bool FreeMemory(Address address, size_t size);
+ LM_API bool LM_CALL FreeMemory(Address address, size_t size);

/// Frees memory allocated in a remote process (page-aligned)
- bool FreeMemory(const Process *process, Address address, size_t size);
+ LM_API bool LM_CALL FreeMemory(const Process *process, Address address, size_t size);

/// Resolves a deep pointer (also known as pointer scan or pointer map) in the current process
- Address DeepPointer(Address base, const std::vector<Address> &offsets);
+ LM_API Address LM_CALL DeepPointer(Address base, const std::vector<Address> &offsets);

/// Resolves a deep pointer (also known as pointer scan or pointer map) in the current process
template <typename T>
- inline T *DeepPointer(Address base, const std::vector<Address> &offsets)
+ LM_API inline T LM_CALL *DeepPointer(Address base, const std::vector<Address> &offsets)
{
return reinterpret_cast<T *>(DeepPointer(base, offsets));
}

/// Resolves a deep pointer (also known as pointer scan or pointer map) in a remote process
- std::optional<Address> DeepPointer(const Process *process, Address base, const std::vector<Address> &offsets);
+ LM_API std::optional<Address> LM_CALL DeepPointer(const Process *process, Address base, const std::vector<Address> &offsets);

// Scan API

/// Scans for some data in the current process
- std::optional<Address> DataScan(std::vector<uint8_t> data, Address address, size_t scansize);
+ LM_API std::optional<Address> LM_CALL DataScan(std::vector<uint8_t> data, Address address, size_t scansize);

/// Scans for some data in a remote process
- std::optional<Address> DataScan(const Process *process, std::vector<uint8_t> data, Address address, size_t scansize);
+ LM_API std::optional<Address> LM_CALL DataScan(const Process *process, std::vector<uint8_t> data, Address address, size_t scansize);

/// Scans for a byte pattern with a mask in the current process
- std::optional<Address> PatternScan(std::vector<uint8_t> pattern, const char *mask, Address address, size_t scansize);
+ LM_API std::optional<Address> LM_CALL PatternScan(std::vector<uint8_t> pattern, const char *mask, Address address, size_t scansize);

/// Scans for a byte pattern with a mask in a remote process
- std::optional<Address> PatternScan(const Process *process, std::vector<uint8_t> pattern, const char *mask, Address address, size_t scansize);
+ LM_API std::optional<Address> LM_CALL PatternScan(const Process *process, std::vector<uint8_t> pattern, const char *mask, Address address, size_t scansize);

/// Scans for a byte signature in the current process (e.g "DE AD ?? BE EF")
- std::optional<Address> SigScan(const char *signature, Address address, size_t scansize);
+ LM_API std::optional<Address> LM_CALL SigScan(const char *signature, Address address, size_t scansize);

/// Scans for a byte signature in a remote process (e.g "DE AD ?? BE EF")
- std::optional<Address> SigScan(const Process *process, const char *signature, Address address, size_t scansize);
+ LM_API std::optional<Address> LM_CALL SigScan(const Process *process, const char *signature, Address address, size_t scansize);

// Assemble/Disassemble API

/// Gets the current process architecture
- Arch GetArchitecture();
+ LM_API Arch LM_CALL GetArchitecture();

/// Assembles an instruction in the current architecture into machine code
- std::optional<Inst> Assemble(const char *code);
+ LM_API std::optional<Inst> LM_CALL Assemble(const char *code);

/// Assembles one or more instructions into machine code
- std::optional<std::vector<uint8_t>> Assemble(const char *code, Arch arch, Address runtime_address);
+ LM_API std::optional<std::vector<uint8_t>> LM_CALL Assemble(const char *code, Arch arch, Address runtime_address);

/// Disassembles a single instruction from machine code in the current architecture
- std::optional<Inst> Disassemble(Address machine_code);
+ LM_API std::optional<Inst> LM_CALL Disassemble(Address machine_code);

/// Disassembles one or more instructions from machine code
/// NOTE: 'max_size' and 'instruction_count' can't both be 0, choose one if you want to
- std::optional<std::vector<Inst>> Disassemble(Address machine_code, Arch arch, size_t max_size, size_t instruction_count, Address runtime_address);
+ LM_API std::optional<std::vector<Inst>> LM_CALL Disassemble(Address machine_code, Arch arch, size_t max_size, size_t instruction_count, Address runtime_address);

/// Calculates the instruction aligned length based on a minimum size in the current process
- size_t CodeLength(Address machine_code, size_t min_length);
+ LM_API size_t LM_CALL CodeLength(Address machine_code, size_t min_length);

/// Calculates the instruction aligned length based on a minimum size in a remote process
- size_t CodeLength(const Process *process, Address machine_code, size_t min_length);
+ LM_API size_t LM_CALL CodeLength(const Process *process, Address machine_code, size_t min_length);

// Hook API

/// Places a hook in the address 'from', jumping to the address 'to' in the current process
- std::optional<Trampoline> HookCode(Address from, Address to);
+ LM_API std::optional<Trampoline> LM_CALL HookCode(Address from, Address to);

/// Places a hook in the address 'from', jumping to the address 'to' in a remote process
- std::optional<RemoteTrampoline> HookCode(const Process *process, Address from, Address to);
+ LM_API std::optional<RemoteTrampoline> LM_CALL HookCode(const Process *process, Address from, Address to);

/// Removes the hook/detour placed in the address 'from', restoring the original code in the current process
/// NOTE: the trampoline will become unusable after this operation
- bool UnhookCode(Address from, Trampoline &trampoline);
+ LM_API bool LM_CALL UnhookCode(Address from, Trampoline &trampoline);

/// Removes the hook/detour placed in the address 'from', restoring the original code in a remote process
/// NOTE: the trampoline will become unusable after this operation
- bool UnhookCode(const Process *process, Address from, RemoteTrampoline &trampoline);
+ LM_API bool LM_CALL UnhookCode(const Process *process, Address from, RemoteTrampoline &trampoline);
}

#endif
5 changes: 2 additions & 3 deletions packages/l/libmem/port/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,5 @@ target("libmem")
add_files("internal/winutils/*.c")
add_files("src/win/*.c")
end
if is_plat("windows") then
add_defines("LM_EXPORT")
end

add_defines("LM_EXPORT")
7 changes: 5 additions & 2 deletions packages/l/libmem/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ package("libmem")
"https://github.com/rdbo/libmem/archive/refs/tags/$(version).tar.gz",
"https://github.com/rdbo/libmem.git")
add_versions("5.0.2", "99adea3e86bd3b83985dce9076adda16968646ebd9d9316c9f57e6854aeeab9c")

add_patches("5.0.2", path.join(os.scriptdir(), "patches", "cxxexport.patch"), "3b6184cfd3fbc6698c1027f70c6d50890b9c5ed7a689a414cd1b42173fd179e3")

add_deps("capstone", "keystone")

if is_plat("windows", "mingw") then
Expand All @@ -20,8 +23,8 @@ package("libmem")
add_syslinks("dl", "kvm", "procstat", "elf", "stdc++", "m")
end

on_load(function (package)
if package:is_plat("windows") then
on_load(function(package)
if not package:config("shared") then
package:add("defines", "LM_EXPORT")
end
end)
Expand Down

0 comments on commit e24e417

Please sign in to comment.