Code Monkey home page Code Monkey logo

rdbo / libmem Goto Github PK

View Code? Open in Web Editor NEW
685.0 12.0 83.0 2.15 MB

Advanced Game Hacking Library for C/C++, Rust and Python (Windows/Linux/FreeBSD) (Process/Memory Hacking) (Hooking/Detouring) (Cross Platform) (x86/x64/ARM/ARM64) (DLL/SO Injection) (Internal/External) (Assembler/Disassembler)

License: GNU Affero General Public License v3.0

C 67.45% C++ 0.49% CMake 4.38% Python 8.05% Shell 2.62% Rust 16.39% Dockerfile 0.39% Makefile 0.05% Lua 0.17%
memory c code-injection syscall process c-plus-plus python function-call hook detour-hook

libmem's Issues

mem_string_replace not working

I just noticed there's a problem in mem_string_replace and I'm working on it. Just opening this issue to let you know.

Pattern Scan Problems (External)

Problem 1: Slow scan if the scanned memory length is too big
Problem 2: Returns the wrong value on Windows when scanning big chunks of memory
Thanks to @karliky for pointing the issues

libmem examples/shared library won't build in bsd

The build scripts are made for bash and it might not be installed or it might not be at /bin. Run the following commands as root:
pkg install bash
ln -s /usr/local/bin/bash /bin/bash
The build scripts should work fine now.

Remove internal.h

The file internal.h was useful when there were helpers; now they're gone so the file seems useless. I will keep it until I manage to solve most of the other issues just to make sure I really won't use it. If I can manage to solve the other issues and the file remains useless, it will be deleted.

Use LIEF library to parse ELF and PE symbols

LIEF is a C++ library that can parse multiple types of binaries and among other features, dump their debug symbols.
As mentioned in the issue #26, libmem has to become more modular. Maintaining all of these features by myself is not a good idea, especially since there are libraries out there that will do a better job.
I have been trying to use LIEF on libmem, but because it is a C++ library, I've had a few problems integrating it. Nonetheless, I still think it's important to use it.

Give proper names to APIs, types, etc

Some things in libmem are not properly named. For example, LM_GetProcessIdEx. It should be something like LM_FindProcessId, since it has no guarantee that it will be got or not - on the other side LM_GetProcessId is always going to succeed by returning the current process ID.

Tests should test everything

The tests cover a lot of libmem's surface area, but they still don't test everything, like LM_HookCodeEx. That should change.

Subroutine hooking

How do you go about doing subroutine hooks, like how zeex/subhook does it?

I almost figured out how all of libmem's API works, which is awesome ๐Ÿ˜

I wish to document it sometime in the future, to better hope those who may need it. libmem is definitely a fantastic replacement to doing this stuff other ways.

process_vm_readv & process_vm_writev for android

process_vm_readv & process_vm_writev methods not found in android

Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16.
Android NDK:
[armeabi-v7a] Compile thumb  : mem <= libmem.c
jni/libmem.c:3020:24: warning: implicit declaration of function 'process_vm_readv' is invalid in C99 [-Wimplicit-function-declaration]
                rdsize = (lm_size_t) process_vm_readv(proc.pid, &iodst, 1,
                                     ^
jni/libmem.c:3086:23: warning: implicit declaration of function 'process_vm_writev' is invalid in C99 [-Wimplicit-function-declaration]
                wrsize = (lm_size_t)process_vm_writev(proc.pid, &iosrc, 1,
                                    ^
2 warnings generated.
[armeabi-v7a] SharedLibrary  : libmem.so
ld: error: undefined symbol: process_vm_writev
>>> referenced by libmem.c:3086 (jni\libmem.c:3086)
>>>               ./obj/local/armeabi-v7a/objs/mem/libmem.o:(LM_WriteMemoryEx)

ld: error: undefined symbol: process_vm_readv
>>> referenced by libmem.c:3020 (jni\libmem.c:3020)
>>>               ./obj/local/armeabi-v7a/objs/mem/libmem.o:(LM_ReadMemoryEx)
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [C:/Users/Unknow/AppData/Local/Android/Sdk/ndk/23.0.7123448/build//../build/core/build-binary.mk:718: obj/local/armeabi-v7a/libmem.so] Error 1```

Does mem_ex_get_module work?

So, I'm working on adding Node.js bindings to this library to use it with JavaScript. ๐Ÿš€

While working on this I found something weird, looks like mem_ex_get_module doesn't work:

    PID:                8020
    Process Name:       explorer.exe
    Process ID:         8020
    Module Name:
    Module Path:
    Module Base:        0000000000000000
    Module Size:        0000000000000000
    Module End:         0000000000000000

The first 3 lines are from mem_ex_get_pid and mem_ex_get_process and they do work fine ๐Ÿ‘ . Then comes process_mod_ex and they look empty or filled with 0000000000000000. The process name I'm using it's explorer.exe

Here is the source code, which I copied from https://github.com/rdbo/libmem/blob/master/example/example.cpp:

	mem_pid_t pid_ex = mem_ex_get_pid(mem_string_new(PROCESS_NAME));
	tprint("PID:                %i", pid_ex);

	//-- Get Process Information
	mem_process_t process_ex = mem_ex_get_process(pid_ex);
	tprint("Process Name:       %s", mem_string_c_str(&process_ex.name));
	tprint("Process ID:         %i", process_ex.pid);

	//-- Get Process Module
	mem_module_t process_mod_ex = mem_ex_get_module(process_ex, mem_string_new(PROCESS_NAME));
	tprint("Module Name:        %s", mem_string_c_str(&process_mod_ex.name));
	tprint("Module Path:        %s", mem_string_c_str(&process_mod_ex.path));
	tprint("Module Base:        %p", process_mod_ex.base);
	tprint("Module Size:        %p", (mem_voidptr_t)process_mod_ex.size);
	tprint("Module End:         %p", process_mod_ex.end);

Am I doing something wrong? ๐Ÿง‘โ€๐Ÿ’ป

Here is the whole source code just in case it helps:
bindings.txt

Does this work with arm ?

Hi,

I would like to use mem.read for reading android memory simple functions like
so it will be basically
long addressreturn=Read(address);
string stringreturn=ReadString(address,ize,bytesToRead);

#if defined (arm)
//arm read syscall for process_vm_writev 377
int syscallWrite = 377;
//arm read syscall for process_vm_readv 376
int syscallRead = 376;

Problem with me is i get read data error because entity might be removed and i try to read it it cause the memory stack crouption. and i get detected.

if you build that class for me i can pay you
i know its quick work for you but it will support your time.
please do let me know my discord is Hammad2224#9851

Thanks
Regards,
Hammad

Reduce/Fix Warnings

It gets a bit hard to find useful information from the compiler when it's generating hundreds of lines of warnings. They have to either be fixed or disabled.

Add Rust Language support

I have learned Rust a while ago, and I want to (at some point) port libmem to Rust. I can't promise anything though, since I've never ported any C APIs to Rust and since I have to solve all of the other issues first.

TODO: fix libmem

libmem is a project I have work on and off for a very long time. It has had many different versions, one completely different than the other, because the more I got better at programming, the more ideas I had to make it better.
Unfortunately, libmem has become practically unmaintainable, mainly for the following reasons:

  • It is not modular: everything is on libmem.h and libmem.c, including the code for all different platforms and architectures, making it a mess with all the preprocessor directives.
  • It has too many features: libmem should have followed the KISS process (Keep It Simple Stupid), instead of adding too many features, such as multiple different hooking methods, debugger functions, overly-complicated code injection (such as the LM_FunctionCallEx).

So how to fix it?
My plan is to do the following:

  • Modulate libmem: I could do that by separating the OS-specific and Arch-specific code, and rely on better written third-party libraries, such as the addition of the capstone and keystone libraries instead of writing my own assembler/disassembler. I'm not sure yet how am I going to modulate it in practice because everything is so entangled together, but I'm sure there is a way.
  • Remove overkill features: offer only one hooking method per architecture, no debugging functions as they're not the main focus of libmem, etc.
  • Follow a Unix-like directory structure for the project: instead of putting everything under the libmem folder, there should be a include and source folders (like in capstone and keystone, similar to the Unix /usr directory), since the library should be compiled first and then included into your project, and not compiled along with your project.
  • Make it 'installable': At least on Unix-like systems, there should be a way to install the libmem shared library into /usr/local/lib to make it easier for linking the library.
  • Add better documentation: there used to be a documentation, but since the project started changing very often, I deleted the old one. After all of other points are fixed, there should be a very detailed documentation about all libmem APIs to make developer's lives easier.

These are only the stuff I could remember right now, and I hope I can close this issue in the future.
If you want to contribute, make a pull request.
There's a lot of work ahead of libmem.

libmem very slow on bsd

Working on it. It's taking a long time to read the /proc/<pid>/map file. I'll try different approaches.

Are gateway's on the mem::in::detour_trampoline functional?

I have a project where this library was needed for taskmanager(thank you!) and while working on it, I found something rather strange with mem::in::detour_trampoline (or I am using it incorrectly) as the trampoline executes but the returning gateway fails to return.
this is how the detour was created:
o_function= (function_t) mem::in::detour_trampoline(IsServer, (void *)IsServerHook, mem::in::detour_size(MEM_ASM_x86_JMP64), MEM_ASM_x86_JMP64);
and here is the respective hook:

typedef bool(* function_t)(void *ret);
bool __fastcall IsServerHook(void *ret)
{
    GlobalSettings = ret;
    std::cout << "exe" << std::endl;
    return o_function(ret);
}

it prints out the exe string and then upon return, process crashes.
before jumping(executes):
image

returning back(crashes on 'ret' instruction):
image

Assemble/Disassemble multiple instructions

The LM_Assemble and LM_Disassemble functions can only do operations with one instruction at a time right now, but the Capstone and Keystone libraries offer support for doing things with multiple instructions.
The idea is to find a way of adding an API that can take/write multiple instructions, but avoiding memory allocations and memory leaks somehow. If avoiding those things isn't possible, then the developer will be responsible for freeing the memory later.

Simplify Detour API

Instead of having LM_MakeTrampoline, LM_DestroyTrampoline, etc, what could be done is have a single LM_Detour function that has a parameter which would be the pointer to a trampoline. If that pointer is not null, generate the trampoline. If it is null, don't do anything.
Prototype:

LM_API lm_size_t
LM_Detour(lm_address_t src, lm_address_t dst, lm_address_t *ptrampoline);

LM_API lm_bool_t
LM_RestoreDetour(lm_address_t ptrampoline, lm_size_t size);

*nix: don't read the whole files at once

It would be more optimized to read a section of the /proc/<pid>/maps file at a time and parse it; if the results were found, free the buffer and return; else, just read once again. This might be applicable to other files, such as /proc/<pid>/status, but since they're not so big, it might not be necessary for performance increase. Instead, it might be a good idea to read until the end of life and pass the read line to a function.

Minimize includes in libmem.h

Since the library is being modulated, there's no need to include every single required header on libmem.h and import all of that stuff into the other programmer's source code; instead, move them to headers or source files in src/.

Deprecate v3 API

There's no need to keep the old v3 API on the code, it just adds more mess and trouble to maintain.

Full code review

After most of the current issues (mainly #26) have been solved, there should be a full code review to find flaws in the code before proceeding.

Change Free/Destroy/Etc parameter to pointer

The "object" that will be freed/destroyed should be passed in as a pointer, and its value should become NULL.
For example, LM_UnhookCode does not take the trampoline as a pointer, but it should, because the trampoline will be freed.

Code injection problem on Linux

I found out that external functions related to code injection on Linux might cause the target program to crash.
The functions doing code injection are:

mem_ex_protect
mem_ex_allocate
mem_ex_deallocate
mem_ex_load_library

Freeing invalid pointer

Somewhere in the code, an invalid address is being free'd. I'm still looking for this problem and it might take some time to even identify where is this occurring

[TUT] What should it looks like of mem::in::detour_trampoline in current version?

Hi, by referencing your AssaultCube-Multihack of this line:

Data::oSwapBuffers = (SwapBuffers_t)mem::in::detour_trampoline(Data::pSwapBuffers, (mem::voidptr_t)Hooks::SwapBuffers, Data::szSwapBuffers, mem::MEM_DT_M1);

see here

What should it looks like in current version of libmem?

This is the code what I've made:

lm_module_t opengl32;
namespace gl
{
  void* SwapBuffers;
}
using SwapBuffers_t = BOOL(__stdcall*)(_In_ HDC hDC);
namespace hook
{
  namespace gl
  {
    SwapBuffers_t SwapBuffers;
  }
}

// idk why crashed...
void Init(HMODULE hModule)
{
  LM_GetModule(LM_MOD_BY_STR, (void*)LM_STR("OPENGL32.dll"), &opengl32);

  gl::SwapBuffers = LM_GetSymbol(opengl32, (lm_cstring_t)"wglSwapBuffers");
  hook::gl::SwapBuffers=(SwapBuffers_t)LM_MakeTrampoline(gl::SwapBuffers, 5);
  LM_DetourCode(gl::SwapBuffers, &hook::gl::SwapBuffers, LM_DETOUR_JMP32);
}

Store process bits on lm_process_t struct

There's no need to keep calling LM_GetProcessBitsEx all the time you want to do a bits-dependent operation. It should be stored when the process handle is opened with LM_OpenProcessEx.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.