Skip to content

Commit

Permalink
4.3
Browse files Browse the repository at this point in the history
  • Loading branch information
rdbo committed Aug 4, 2020
1 parent f01c53d commit 44b8d2c
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 20 deletions.
1 change: 1 addition & 0 deletions examples/linux/compile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
clang++ -g main.cpp ../Memory/mem/mem.cpp -o main -ldl
159 changes: 159 additions & 0 deletions examples/linux/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#include "../Memory/mem/mem.hpp"
#define PROCESS_NAME MEM_STR("main")

bool test_pid(mem::string_t process_name, mem::pid_t& pid)
{
mem::pid_t pid_in = mem::in::get_pid();
mem::pid_t pid_ex = mem::ex::get_pid(process_name);
pid = pid_in;

std::cout << "PID (in): " << pid_in << std::endl;
std::cout << "PID (ex): " << pid_ex << std::endl;

return pid_in != (mem::pid_t)MEM_BAD_RETURN && pid_in == pid_ex;
}

bool test_process_name(mem::pid_t pid, mem::string_t& process_name)
{
mem::string_t process_name_in = mem::in::get_process_name();
mem::string_t process_name_ex = mem::ex::get_process_name(pid);
process_name = process_name_in;

std::cout << "Process Name (in): " << process_name_in << std::endl;
std::cout << "Process Name (ex): " << process_name_ex << std::endl;

return (
process_name_in == process_name_ex &&
process_name_in != ""
);
}

bool test_process(mem::string_t process_name, mem::process_t& process)
{
mem::process_t process_in = mem::in::get_process();
mem::process_t process_ex = mem::ex::get_process(process_name);
process = process_in;

std::cout << "Process ID (in): " << process_in.pid << std::endl;
std::cout << "Process ID (ex): " << process_ex.pid << std::endl;
std::cout << "Process Name (in): " << process_in.name << std::endl;
std::cout << "Process Name (ex): " << process_ex.name << std::endl;

return (
process_in.is_valid() &&
process_in == process_ex
);
}

bool function(bool ret)
{
asm(
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
);

std::cout << "the return is: " << ret << std::endl;
return ret;
}

typedef bool(* function_t)(bool ret);
function_t o_function;

bool hk_function(bool ret)
{
std::cout << "the old ret was: " << ret << std::endl;
ret = true;
std::cout << "ret set to true" << std::endl;
return o_function(ret);
}

bool test_hook()
{
mem::detour_int method = mem::detour_int::method0;
o_function = (function_t)mem::in::detour_trampoline((mem::voidptr_t)&function, (mem::voidptr_t)&hk_function, mem::in::detour_length(method));
bool ret = function(false);
return ret;
}

bool test_module(mem::process_t process)
{
mem::string_t mod_name = mem::string_t("/" + process.name + "\n");
mem::module_t mod_in = mem::in::get_module(mod_name);
mem::module_t mod_ex = mem::ex::get_module(process, mod_name);

std::cout << "Module Name (in): " << mod_in.name << std::endl;
std::cout << "Module Name (ex): " << mod_ex.name << std::endl;
std::cout << "Module Path (in): " << mod_in.path << std::endl;
std::cout << "Module Path (ex): " << mod_ex.path << std::endl;
std::cout << "Module Base (in): " << mod_in.base << std::endl;
std::cout << "Module Base (ex): " << mod_ex.base << std::endl;
std::cout << "Module Size (in): " << std::hex << mod_in.size << std::endl;
std::cout << "Module Size (ex): " << std::hex << mod_ex.size << std::endl;
std::cout << "Module End (in): " << mod_in.end << std::endl;
std::cout << "Module End (ex): " << mod_ex.end << std::endl;
std::cout << "Module Handle (in): " << mod_in.handle << std::endl;
mod_ex.handle = mod_in.handle;

return (
mod_in.is_valid() &&
mod_ex.is_valid() &&
mod_in == mod_ex
);
}

void separator()
{
std::cout << "-------------------" << std::endl;
}

int main()
{
mem::pid_t pid;
mem::string_t process_name;
mem::process_t process;

std::cout << "test pid" << std::endl;
bool btest_pid = test_pid(PROCESS_NAME, pid);
separator();

std::cout << "test process name" << std::endl;
bool btest_process_name = test_process_name(pid, process_name);
separator();

std::cout << "test process" << std::endl;
bool btest_process = test_process(process_name, process);
separator();

std::cout << "test module" << std::endl;
bool btest_module = test_module(process);
separator();

std::cout << "test hook" << std::endl;
bool btest_hook = test_hook();
separator();

std::cout << "<< Results >>" << std::endl;
std::cout << "Test PID: " << btest_pid << std::endl;
std::cout << "Test Process Name: " << btest_process_name << std::endl;
std::cout << "Test Process: " << btest_process << std::endl;
std::cout << "Test Module: " << btest_module << std::endl;
std::cout << "Test Hook: " << btest_hook << std::endl;

return 0;
}
55 changes: 41 additions & 14 deletions mem/mem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ mem::string_t mem::ex::get_process_name(pid_t pid)
mem::module_t mem::ex::get_module(process_t process, string_t module_name)
{
module_t modinfo;
if(!process.is_valid()) return modinfo;
# if defined(MEM_WIN)
HMODULE hMod;
char_t modpath[MAX_PATH];
Expand All @@ -171,10 +172,23 @@ mem::module_t mem::ex::get_module(process_t process, string_t module_name)
std::stringstream ss;
ss << file.rdbuf();

std::size_t module_name_pos = ss.str().rfind('/', ss.str().find('\n', ss.str().find(module_name.c_str(), 0))) + 1;
std::size_t module_name_end = ss.str().find('\n', module_name_pos);
if(module_name_pos == (std::size_t)-1 || module_name_end == (std::size_t)-1) return modinfo;
std::string module_name_str = ss.str().substr(module_name_pos, module_name_end - module_name_pos);
std::size_t module_name_pos = 0;
std::size_t module_name_end = 0;
std::size_t next = 0;
std::string module_name_str = "";
while((next = ss.str().find(module_name.c_str(), module_name_end)) != ss.str().npos && (module_name_pos = ss.str().find('/', next)))
{
module_name_end = ss.str().find('\n', module_name_pos);
module_name_pos = ss.str().rfind('/', module_name_end) + 1;
module_name_str = ss.str().substr(module_name_pos, module_name_end - module_name_pos);
if(module_name_str.length() >= module_name.length())
{
if(!MEM_STR_N_CMP(module_name_str.c_str(), module_name.c_str(), module_name.length()))
break;
}
}

if(module_name_pos == 0 || module_name_pos == -1 || module_name_pos == ss.str().npos || module_name_end == 0 || module_name_end == -1 || module_name_end == ss.str().npos) return modinfo;

std::size_t base_address_pos = ss.str().rfind('\n', ss.str().find(mem::string_t('/' + module_name_str + '\n').c_str(), 0)) + 1;
std:size_t base_address_end = ss.str().find('-', base_address_pos);
Expand All @@ -200,14 +214,15 @@ mem::module_t mem::ex::get_module(process_t process, string_t module_name)
mem::uintptr_t end_address = strtoull(end_address_str.c_str(), NULL, 16);
# endif

module_handle_t handle = (module_handle_t)dlopen(module_path_str.c_str(), RTLD_LAZY);
module_handle_t handle = (module_handle_t)MEM_BAD_RETURN;
if(MEM_STR_CMP(process.name.c_str(), module_name_str.c_str()))
handle = (module_handle_t)dlopen(module_path_str.c_str(), RTLD_LAZY);

if(
module_name_pos == (std::size_t)-1 || module_name_end == (std::size_t)-1 ||
base_address_pos == (std::size_t)-1 || base_address_end == (std::size_t)-1 ||
end_address_pos == (std::size_t)-1 || end_address_end == (std::size_t)-1 ||
module_path_pos == (std::size_t)-1 || module_path_end == (std::size_t)-1 ||
handle == (module_handle_t)MEM_BAD_RETURN
module_path_pos == (std::size_t)-1 || module_path_end == (std::size_t)-1
) return modinfo;

modinfo.name = module_name_str;
Expand All @@ -226,6 +241,7 @@ mem::module_t mem::ex::get_module(process_t process, string_t module_name)

mem::bool_t mem::ex::is_process_running(process_t process)
{
if(!process.is_valid()) return (bool_t)false;
# if defined(MEM_WIN)
DWORD exit_code;
GetExitCodeProcess(process.handle, &exit_code);
Expand All @@ -242,41 +258,48 @@ mem::bool_t mem::ex::is_process_running(process_t process)

mem::int_t mem::ex::read(process_t process, voidptr_t src, voidptr_t dst, size_t size)
{
int_t ret = (int_t)MEM_BAD_RETURN;
if(!process.is_valid()) return ret;
# if defined(MEM_WIN)
return (int_t)ReadProcessMemory(process.handle, (LPCVOID)src, (LPVOID)dst, (SIZE_T)size, NULL);
ret = (int_t)ReadProcessMemory(process.handle, (LPCVOID)src, (LPVOID)dst, (SIZE_T)size, NULL);
# elif defined(MEM_LINUX)
struct iovec iosrc;
struct iovec iodst;
iodst.iov_base = dst;
iodst.iov_len = size;
iosrc.iov_base = src;
iosrc.iov_len = size;
return process_vm_readv(process.pid, &iodst, 1, &iosrc, 1, 0);
ret = process_vm_readv(process.pid, &iodst, 1, &iosrc, 1, 0);
# endif
return MEM_BAD_RETURN;
return ret;
}

mem::int_t mem::ex::write(process_t process, voidptr_t src, voidptr_t data, size_t size)
{
int_t ret = (int_t)MEM_BAD_RETURN;
if(!process.is_valid()) return ret;
# if defined(MEM_WIN)
return (int_t)WriteProcessMemory(process.handle, (LPVOID)src, (LPCVOID)data, (SIZE_T)size, NULL);
ret = (int_t)WriteProcessMemory(process.handle, (LPVOID)src, (LPCVOID)data, (SIZE_T)size, NULL);
# elif defined(MEM_LINUX)
struct iovec iosrc;
struct iovec iodst;
iosrc.iov_base = data;
iosrc.iov_len = size;
iodst.iov_base = src;
iodst.iov_len = size;
return process_vm_writev(process.pid, &iosrc, 1, &iodst, 1, 0);
ret = process_vm_writev(process.pid, &iosrc, 1, &iodst, 1, 0);
# endif
return MEM_BAD_RETURN;
return ret;
}

mem::int_t mem::ex::set(process_t process, voidptr_t src, byte_t byte, size_t size)
{
int_t ret = MEM_BAD_RETURN;
byte_t* data = new byte_t[size];
mem::in::set(data, byte, size);
return write(process, src, data, size);
ret = write(process, src, data, size);
delete[] data;
return ret;
}

mem::int_t mem::ex::protect(process_t process, voidptr_t src, size_t size, prot_t protection)
Expand Down Expand Up @@ -310,6 +333,7 @@ mem::voidptr_t mem::ex::allocate(process_t process, size_t size, alloc_t allocat
mem::voidptr_t mem::ex::scan(process_t process, voidptr_t data, voidptr_t base, voidptr_t end, size_t size)
{
voidptr_t ret = (voidptr_t)MEM_BAD_RETURN;
if(!process.is_valid()) return ret;
for(uintptr_t i = 0; (uintptr_t)base + i < (uintptr_t)end; i += size)
{
voidptr_t read_bytes = malloc(size);
Expand All @@ -329,6 +353,7 @@ mem::voidptr_t mem::ex::pattern_scan(process_t process, bytearray_t pattern, str
mask = parse_mask(mask);
voidptr_t ret = (mem::voidptr_t)MEM_BAD_RETURN;
uintptr_t scan_size = (uintptr_t)end - (uintptr_t)base;
if(!process.is_valid()) return ret;

for (uintptr_t i = 0; i < scan_size; i++)
{
Expand Down Expand Up @@ -358,6 +383,7 @@ mem::voidptr_t mem::ex::pattern_scan(process_t process, bytearray_t pattern, str
mem::int_t mem::ex::load_library(process_t process, lib_t lib)
{
int_t ret = (int_t)MEM_BAD_RETURN;
if(!lib.is_valid()) return ret;
# if defined(MEM_WIN)
if (lib.path.length() == 0 || process.handle == NULL) return ret;
size_t buffer_size = (size_t)((lib.path.length() + 1) * sizeof(char_t));
Expand Down Expand Up @@ -678,6 +704,7 @@ mem::voidptr_t mem::in::pattern_scan(bytearray_t pattern, string_t mask, voidptr
mem::int_t mem::in::load_library(lib_t lib, module_t* mod)
{
int_t ret = (int_t)MEM_BAD_RETURN;
if(!lib.is_valid()) return ret;
# if defined(MEM_WIN)
HMODULE h_mod = LoadLibrary(lib.path.c_str());
ret = (h_mod == NULL ? MEM_BAD_RETURN : !MEM_BAD_RETURN);
Expand Down
16 changes: 10 additions & 6 deletions mem/mem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,12 @@ namespace mem
typedef uint32_t pid_t;
typedef uint32_t prot_t;
typedef HMODULE module_handle_t;
typedef uint32_t alloc_type_t;
# elif defined(MEM_LINUX)
typedef int32_t pid_t;
typedef int32_t prot_t;
typedef void* module_handle_t;
typedef int32_t alloc_type_t;
# endif

# if defined(MEM_86)
Expand Down Expand Up @@ -270,6 +272,8 @@ namespace mem
HANDLE handle = (HANDLE)NULL;
# elif defined(MEM_LINUX)
# endif

public:
bool_t is_valid()
{
return (
Expand All @@ -296,16 +300,14 @@ namespace mem
{
public:
prot_t protection = (prot_t)NULL;
# if defined(MEM_WIN)
uint32_t type = MEM_RESERVE | MEM_COMMIT;
# elif defined(MEM_LINUX)
int32_t type = MAP_ANON | MAP_PRIVATE;
# endif
alloc_type_t type = (alloc_type_t)NULL;

public:
bool_t is_valid()
{
return (
protection != (prot_t)NULL &&
(int32_t)type != (int_t)NULL
type != (alloc_type_t)NULL
);
}

Expand All @@ -327,6 +329,8 @@ namespace mem
int_t mode = (int_t)RTLD_LAZY;
# endif

public:

bool_t is_valid()
{
return (bool_t)(
Expand Down

0 comments on commit 44b8d2c

Please sign in to comment.