├── .gitignore ├── README.md ├── TODO.md ├── example ├── hooker.cpp └── jni │ ├── Android.mk │ └── Application.mk ├── includes └── Liberation.h ├── liberation └── source ├── Memory.h ├── Patch.cpp ├── Patch.h ├── jni ├── Android.mk └── Application.mk └── liberation.h /.gitignore: -------------------------------------------------------------------------------- 1 | libs/ 2 | obj/ 3 | *.sublime-project 4 | *.sublime-workspace 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Liberation-android 2 | ======== 3 | Liberation-android by [Liberation](https://github.com/Razzile/Liberation). 4 | 5 | ## Usage 6 | To use Liberation, follow these steps: 7 | * Clone repo `git clone https://github.com/circleous/Liberation-android`, 8 | * [Build static library](#building-liberation), 9 | * Include `` in your c++ file, 10 | * Link static library (liberation.a) in your project, example of use at [example/](../blob/master/example/). 11 | 12 | ## Synopsis 13 | ```Logos 14 | #include 15 | 16 | Patch *Patch::Setup(void* _target, char *data, size_t len); 17 | Patch *Patch::Setup(void* _target, uint32_t data); 18 | Patch *Patch::Setup(void* _target, std::string data); 19 | void Apply(); 20 | void Reset(); 21 | ``` 22 | 23 | ## Example 24 | Example of use at [example/](../blob/master/example/) folder. 25 | 26 | ## Building Liberation 27 | Using build script: 28 | * `./liberation build` to build project (static library) 29 | * `./liberation clean` to clean project 30 | 31 | When built, there should be a `liberation.a` file in the `source/obj/local/$(TARGET_ARCH_ABI)` folder. 32 | 33 | ## License 34 | 35 | ```Logos 36 | //Copyright (c) 2017, circleous 37 | 38 | //Permission to use, copy, modify, and/or distribute this software for any purpose 39 | //with or without fee is hereby granted, provided that the above copyright notice 40 | //and this permission notice appear in all copies. 41 | 42 | //THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 43 | //REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 44 | //FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 45 | //INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 46 | //OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 47 | //TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 48 | //THIS SOFTWARE. 49 | ``` 50 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | ### TODO, eta (never) 2 | - [ ] Use keystone for create Instruction Patch 3 | - [ ] Add inline hook 4 | - [ ] ARM 5 | - [ ] x86 6 | - [ ] Saner inline hook method -------------------------------------------------------------------------------- /example/hooker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "Liberation.h" 5 | 6 | char const *getMoney = "giveMeMoneyRealFast"; 7 | 8 | void doHook() 9 | { 10 | void *imagehandle = dlopen("libebelac.so", RTLD_GLOBAL | RTLD_NOW); 11 | void *pGetMoney = dlsym(imagehandle, getMoney); 12 | 13 | Patch *gold = Patch::Setup(pGetMoney, "38467047"); // MOV R0, R7; BX LR; 14 | gold->Apply(); 15 | } 16 | 17 | jint JNI_OnLoad(JavaVM* vm, void* reserved) 18 | { 19 | jint result = -1; 20 | 21 | doHook(); 22 | 23 | result = JNI_VERSION_1_4; 24 | bail: 25 | return result; 26 | } 27 | -------------------------------------------------------------------------------- /example/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := liberation 6 | LOCAL_SRC_FILES := ../../source/obj/local/$(TARGET_ARCH_ABI)/liberation.a 7 | 8 | include $(PREBUILT_STATIC_LIBRARY) 9 | 10 | include $(CLEAR_VARS) 11 | 12 | LOCAL_MODULE := demon 13 | LOCAL_SRC_FILES := \ 14 | ../hooker.cpp 15 | LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../includes/ 16 | LOCAL_LDLIBS := -llog -latomic -ldl 17 | LOCAL_STATIC_LIBRARIES := liberation 18 | 19 | include $(BUILD_SHARED_LIBRARY) -------------------------------------------------------------------------------- /example/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := armeabi-v7a armeabi x86 2 | APP_PLATFORM := android-21 3 | APP_STL := c++_static 4 | APP_CPPFLAGS += -std=c++11 5 | -------------------------------------------------------------------------------- /includes/Liberation.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using bytes = std::vector; 9 | 10 | class Patch 11 | { 12 | public: 13 | static Patch *Setup(void* _target, char *data, size_t len); 14 | static Patch *Setup(void* _target, uint32_t data); 15 | static Patch *Setup(void* _target, std::string data); 16 | 17 | virtual void Apply(); 18 | virtual void Reset(); 19 | 20 | private: 21 | Patch() = default; 22 | Patch(void* _target, char *data, size_t len); 23 | ~Patch(); 24 | 25 | protected: 26 | void* _t_addr; 27 | size_t _patchSize; 28 | bytes _patchBytes; 29 | bytes _origBytes; 30 | }; -------------------------------------------------------------------------------- /liberation: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | current_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | function help { 6 | echo -e "Help:\t$0 build - build liberation" 7 | echo -e "\t$0 clean - clean project" 8 | } 9 | 10 | MODE=$1 11 | 12 | if [[ "$MODE" == "build" ]]; then 13 | if ! type "ndk-build" > /dev/null 2>&1; then 14 | echo "Install Android NDK and add it to \$PATH" 15 | echo "Aborting..." 16 | exit 17 | fi 18 | echo "NDK_PROJECT_PATH=${current_dir}/source/ ndk-build" 19 | NDK_PROJECT_PATH=${current_dir}/source/ ndk-build 20 | 21 | elif [[ "$MODE" == "clean" ]]; then 22 | echo "rm -rf ${current_dir}/source/obj/*" 23 | rm -rf ${current_dir}/source/obj/* 24 | 25 | else 26 | help 27 | fi 28 | -------------------------------------------------------------------------------- /source/Memory.h: -------------------------------------------------------------------------------- 1 | #include "liberation.h" 2 | 3 | namespace Memory 4 | { 5 | inline bool Protect(void *addr, size_t length) 6 | { 7 | size_t pagesize = sysconf(_SC_PAGESIZE); 8 | uintptr_t start = (uintptr_t) addr; 9 | uintptr_t end = start + length; 10 | uintptr_t pagestart = start & -pagesize; 11 | return mprotect((void*)pagestart, end - pagestart, PROT_READ|PROT_EXEC) < 0; 12 | } 13 | 14 | inline bool UnProtect(void *addr, size_t length) 15 | { 16 | size_t pagesize = sysconf(_SC_PAGESIZE); 17 | uintptr_t start = (uintptr_t) addr; 18 | uintptr_t end = start + length; 19 | uintptr_t pagestart = start & -pagesize; 20 | return mprotect((void*)pagestart, end - pagestart, PROT_READ|PROT_WRITE|PROT_EXEC) < 0; 21 | } 22 | 23 | template inline void Write(T1 memaddr, T2 bytes, size_t length) 24 | { 25 | if (UnProtect((void*) memaddr, length)) { 26 | return; 27 | } 28 | memcpy((void*) memaddr, (void*) bytes, length); 29 | Protect((void*) memaddr, length); 30 | } 31 | 32 | template inline void Read(T1 memaddr, T2 dest, size_t length) 33 | { 34 | memcpy((void*) dest, (void*) memaddr, length); 35 | } 36 | } -------------------------------------------------------------------------------- /source/Patch.cpp: -------------------------------------------------------------------------------- 1 | #include "Patch.h" 2 | #include "Memory.h" 3 | 4 | Patch *Patch::Setup(void* _target, uint32_t data) 5 | { 6 | size_t target = (size_t)_target & (~1); 7 | size_t size = 0; 8 | if (data < INT_MAX) { 9 | size = sizeof(unsigned short); 10 | data = __swap16(data); 11 | } else { 12 | size = sizeof(int); 13 | data = __swap32(data); 14 | } 15 | 16 | return new Patch((void*)target, (char *)&data, size); 17 | } 18 | 19 | Patch *Patch::Setup(void* _target, std::string data) { 20 | Patch *patch = nullptr; 21 | 22 | std::string::iterator end_pos = std::remove(data.begin(), data.end(), ' '); 23 | data.erase(end_pos, data.end()); 24 | 25 | const char *tempHex = data.c_str(); 26 | size_t patchSize = data.length() / 2; 27 | uint8_t *patchData = new uint8_t[patchSize]; 28 | 29 | /* convert string to hex array */ 30 | int n; 31 | for (int i = 0; i < patchSize; i++) { 32 | sscanf(tempHex + 2 * i, "%2X", &n); 33 | patchData[i] = (unsigned char)n; 34 | } 35 | 36 | // sanitize address 37 | size_t target = (size_t)_target & (~1); 38 | patch = new Patch((void*)target, (char *)patchData, patchSize); 39 | delete[] patchData; 40 | 41 | return patch; 42 | } 43 | 44 | Patch *Patch::Setup(void* _target, char *data, size_t len){ 45 | return new Patch(_target, data, len); 46 | } 47 | 48 | Patch::Patch(void* addr, char *data, size_t len) 49 | : _t_addr(addr), _patchSize(len) { 50 | uint8_t *orig = new uint8_t[len]; 51 | Memory::Read(addr, orig, len); 52 | 53 | this->_patchBytes.assign(data, data + len); 54 | this->_origBytes.assign(orig, orig + len); 55 | 56 | delete[] orig; 57 | } 58 | 59 | Patch::~Patch() 60 | { 61 | 62 | } 63 | 64 | void Patch::Apply() 65 | { 66 | Memory::Write(_t_addr, _patchBytes.data(), _patchSize); 67 | } 68 | 69 | void Patch::Reset() 70 | { 71 | Memory::Write(_t_addr, _origBytes.data(), _patchSize); 72 | } 73 | -------------------------------------------------------------------------------- /source/Patch.h: -------------------------------------------------------------------------------- 1 | #include "liberation.h" 2 | 3 | using bytes = std::vector; 4 | 5 | class Patch 6 | { 7 | public: 8 | static Patch *Setup(void* _target, char *data, size_t len); 9 | static Patch *Setup(void* _target, uint32_t data); 10 | static Patch *Setup(void* _target, std::string data); 11 | 12 | virtual void Apply(); 13 | virtual void Reset(); 14 | 15 | private: 16 | Patch() = default; 17 | Patch(void* _target, char *data, size_t len); 18 | ~Patch(); 19 | 20 | protected: 21 | void* _t_addr; 22 | size_t _patchSize; 23 | bytes _patchBytes; 24 | bytes _origBytes; 25 | }; -------------------------------------------------------------------------------- /source/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := liberation 6 | LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/../*.cpp)) 7 | 8 | include $(BUILD_STATIC_LIBRARY) -------------------------------------------------------------------------------- /source/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := armeabi-v7a armeabi x86 2 | APP_PLATFORM := android-21 3 | APP_STL := c++_static 4 | APP_CPPFLAGS += -std=c++11 5 | -------------------------------------------------------------------------------- /source/liberation.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include --------------------------------------------------------------------------------