└── framenthook
├── .gitignore
├── src
├── main
│ ├── res
│ │ ├── values
│ │ │ ├── strings.xml
│ │ │ ├── colors.xml
│ │ │ └── styles.xml
│ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── layout
│ │ │ └── activity_main.xml
│ │ ├── drawable-v24
│ │ │ └── ic_launcher_foreground.xml
│ │ └── drawable
│ │ │ └── ic_launcher_background.xml
│ ├── cpp
│ │ ├── jni
│ │ │ ├── hookTool.c
│ │ │ ├── hookTool.h
│ │ │ ├── SnowGOTHook.c
│ │ │ ├── SnowGOTHook.h
│ │ │ ├── SnowInlineHook.c
│ │ │ ├── SnowInlineHook.h
│ │ │ ├── SnowInlineSimpleHook.c
│ │ │ ├── SnowInlineSimpleHook.h
│ │ │ └── common.h
│ │ ├── MSHook
│ │ │ ├── util.h
│ │ │ ├── CydiaSubstrate.h
│ │ │ ├── Hooker.h
│ │ │ ├── SubstrateStruct.h
│ │ │ ├── MSHook.h
│ │ │ ├── PosixMemory.h
│ │ │ ├── MSHook.cpp
│ │ │ ├── Debug.h
│ │ │ ├── Hooker.cpp
│ │ │ ├── PosixMemory.cpp
│ │ │ ├── ARM.h
│ │ │ ├── Log.h
│ │ │ ├── hde64.h
│ │ │ ├── Debug.cpp
│ │ │ ├── x86_64.h
│ │ │ ├── Thumb.h
│ │ │ ├── ARM.cpp
│ │ │ ├── x86.h
│ │ │ ├── x86.cpp
│ │ │ ├── util.cpp
│ │ │ ├── x86_64.cpp
│ │ │ └── Thumb.cpp
│ │ ├── Android-Inline
│ │ │ ├── relocate.h
│ │ │ ├── include
│ │ │ │ └── inlineHook.h
│ │ │ ├── README.md
│ │ │ ├── inlineHook.c
│ │ │ └── relocate.c
│ │ ├── native-lib.cpp
│ │ ├── hook_device.h
│ │ ├── DvmDex.h
│ │ ├── Common.h
│ │ ├── sokect_hook.h
│ │ ├── DexProto.h
│ │ ├── art.h
│ │ └── DexFile.h
│ └── java
│ │ └── com
│ │ └── example
│ │ └── framenthook
│ │ └── MainActivity.java
├── test
│ └── java
│ │ └── com
│ │ └── example
│ │ └── framenthook
│ │ └── ExampleUnitTest.java
└── androidTest
│ └── java
│ └── com
│ └── example
│ └── framenthook
│ └── ExampleInstrumentedTest.java
├── libs
└── armeabi
│ └── libwechatnonmsg.so
├── proguard-rules.pro
├── CMakeLists.txt
└── framenthook.iml
/framenthook/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/framenthook/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | FramentHook
3 |
4 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/jni/hookTool.c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/cpp/jni/hookTool.c
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/jni/hookTool.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/cpp/jni/hookTool.h
--------------------------------------------------------------------------------
/framenthook/libs/armeabi/libwechatnonmsg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/libs/armeabi/libwechatnonmsg.so
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/jni/SnowGOTHook.c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/cpp/jni/SnowGOTHook.c
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/jni/SnowGOTHook.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/cpp/jni/SnowGOTHook.h
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/jni/SnowInlineHook.c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/cpp/jni/SnowInlineHook.c
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/jni/SnowInlineHook.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/cpp/jni/SnowInlineHook.h
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/jni/SnowInlineSimpleHook.c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/cpp/jni/SnowInlineSimpleHook.c
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/jni/SnowInlineSimpleHook.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/cpp/jni/SnowInlineSimpleHook.h
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skyun1314/framenthook/HEAD/framenthook/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/jni/common.h:
--------------------------------------------------------------------------------
1 | #ifndef _COMMON_H
2 | #define _COMMON_H
3 | #include
4 | #define LOG_TAG "snow_soHook"
5 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
6 |
7 | #endif
--------------------------------------------------------------------------------
/framenthook/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/util.h:
--------------------------------------------------------------------------------
1 | #ifndef HOOK_UTIL_H_
2 | #define HOOK_UTIL_H_
3 |
4 | #include
5 |
6 | extern int find_name(pid_t pid, const char *name,const char *libn, unsigned long *addr);
7 | extern int find_libbase(pid_t pid, const char *libn, unsigned long *addr);
8 | #endif
9 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/Android-Inline/relocate.h:
--------------------------------------------------------------------------------
1 | #ifndef _RELOCATE_H
2 | #define _RELOCATE_H
3 |
4 | #include
5 |
6 | void relocateInstruction(uint32_t target_addr, void *orig_instructions, int length, void *trampoline_instructions, int *orig_boundaries, int *trampoline_boundaries, int *count);
7 |
8 | #endif
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/framenthook/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/CydiaSubstrate.h:
--------------------------------------------------------------------------------
1 | #ifndef CYDIASUBSTRATE_H_
2 | #define CYDIASUBSTRATE_H_
3 |
4 | #include
5 | #include
6 |
7 | #define _finline \
8 | inline __attribute__((__always_inline__))
9 | #define _disused \
10 | __attribute__((__unused__))
11 | #define _extern \
12 | extern "C" __attribute__((__visibility__("default")))
13 |
14 | #include "SubstrateStruct.h"
15 | #endif /* CYDIASUBSTRATE_H_ */
16 |
--------------------------------------------------------------------------------
/framenthook/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/Hooker.h:
--------------------------------------------------------------------------------
1 | #ifndef HOOKER_H_
2 | #define HOOKER_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "Debug.h"
10 | #include "Log.h"
11 | #include "PosixMemory.h"
12 | #include "CydiaSubstrate.h"
13 |
14 | namespace Cydia{
15 |
16 | void MSHookFunction(const char *soname, const char *symbol, void *replace_func, void **old_func);
17 | void MSHookFunction(void *symbol, void *replace, void **result);
18 | }
19 | #endif /* HOOKER_H_ */
--------------------------------------------------------------------------------
/framenthook/src/test/java/com/example/framenthook/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.framenthook;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/SubstrateStruct.h:
--------------------------------------------------------------------------------
1 | /*
2 | * SubstrateMacro.h
3 | *
4 | * Author: peng
5 | */
6 |
7 | #ifndef SUBSTRATEMACRO_H_
8 | #define SUBSTRATEMACRO_H_
9 |
10 | #include
11 | typedef struct __SubstrateProcess *SubstrateProcessRef;
12 | typedef void *SubstrateAllocatorRef;
13 | typedef struct SubstrateMemory {
14 | void *address_;
15 | size_t width_;
16 | SubstrateMemory(void *address, size_t width):address_(address), width_(width) {}
17 | }*SubstrateMemoryRef;
18 |
19 | #endif /* SUBSTRATEMACRO_H_ */
20 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/MSHook.h:
--------------------------------------------------------------------------------
1 | #ifndef LIBHOOK_H_
2 | #define LIBHOOK_H_
3 |
4 | #define HOOK_FAILED -1
5 | #define HOOK_SUCCESS 0
6 |
7 | #ifdef __cplusplus
8 | extern "C" {
9 | #endif
10 |
11 | int findSymbol(const char *name, const char *libn,
12 | unsigned long *addr);
13 | int inlineHook(const char *soname, const char *symbol, void *replace_func, void **old_func);
14 | int inlineHookDirect(unsigned int addr, void *replace_func, void **old_func);
15 |
16 | #ifdef __cplusplus
17 | }
18 | #endif
19 | #endif /* LIBHOOK_HOOK2_H_ */
20 |
--------------------------------------------------------------------------------
/framenthook/src/main/java/com/example/framenthook/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.framenthook;
2 |
3 | import android.content.Intent;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.os.Bundle;
6 |
7 | public class MainActivity extends AppCompatActivity {
8 |
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | setContentView(R.layout.activity_main);
13 |
14 |
15 |
16 | }
17 |
18 |
19 | // Used to load the 'native-lib' library on application startup.
20 | static {
21 | System.loadLibrary("sohook");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/PosixMemory.h:
--------------------------------------------------------------------------------
1 | /*
2 | * PosixMemory.h
3 | *
4 | * Author: peng
5 | */
6 |
7 | #ifndef POSIXMEMORY_H_
8 | #define POSIXMEMORY_H_
9 |
10 | #include "CydiaSubstrate.h"
11 |
12 |
13 | extern "C" SubstrateMemoryRef SubstrateMemoryCreate(SubstrateAllocatorRef allocator, SubstrateProcessRef process, void *data, size_t size);
14 | extern "C" void SubstrateMemoryRelease(SubstrateMemoryRef memory);
15 | extern "C" void __clear_cache(void *beg, void *end);
16 |
17 | struct SubstrateHookMemory {
18 | SubstrateMemoryRef handle_;
19 |
20 | SubstrateHookMemory(SubstrateProcessRef process, void *data, size_t size) : handle_(SubstrateMemoryCreate(NULL, NULL, data, size)) {}
21 |
22 | ~SubstrateHookMemory() {
23 | if (handle_ != NULL)
24 | SubstrateMemoryRelease(handle_);
25 | }
26 | };
27 |
28 | #endif /* POSIXMEMORY_H_ */
29 |
--------------------------------------------------------------------------------
/framenthook/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/Android-Inline/include/inlineHook.h:
--------------------------------------------------------------------------------
1 | #ifndef _INLINEHOOK_H
2 | #define _INLINEHOOK_H
3 |
4 | #include
5 |
6 | #ifdef __cplusplus
7 | extern "C" {
8 | #endif
9 |
10 | enum ele7en_status {
11 | ELE7EN_ERROR_UNKNOWN = -1,
12 | ELE7EN_OK = 0,
13 | ELE7EN_ERROR_NOT_INITIALIZED,
14 | ELE7EN_ERROR_NOT_EXECUTABLE,
15 | ELE7EN_ERROR_NOT_REGISTERED,
16 | ELE7EN_ERROR_NOT_HOOKED,
17 | ELE7EN_ERROR_ALREADY_REGISTERED,
18 | ELE7EN_ERROR_ALREADY_HOOKED,
19 | ELE7EN_ERROR_SO_NOT_FOUND,
20 | ELE7EN_ERROR_FUNCTION_NOT_FOUND
21 | };
22 |
23 | enum ele7en_status registerInlineHook(uint32_t target_addr, uint32_t new_addr, uint32_t **proto_addr);
24 | enum ele7en_status inlineUnHook(uint32_t target_addr);
25 | void inlineUnHookAll();
26 | enum ele7en_status inlineHook(uint32_t target_addr);
27 | void inlineHookAll();
28 |
29 | #ifdef __cplusplus
30 | }
31 | #endif
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/framenthook/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/MSHook.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "util.h"
4 |
5 | #include "Hooker.h"
6 | #include "MSHook.h"
7 |
8 |
9 | int inlineHook(const char *soname, const char *symbol, void *replace_func,
10 | void **old_func) {
11 | int ret = -1;
12 | void *addr = NULL;
13 | if (findSymbol(symbol, soname, (unsigned long *) &addr) < 0) {
14 | return -1;
15 | }
16 | Cydia::MSHookFunction(addr, replace_func, old_func);
17 | ret = 0;
18 | return ret;
19 | }
20 |
21 | int findSymbol(const char *name, const char *libn,
22 | unsigned long *addr) {
23 | return find_name(getpid(), name, libn, addr);
24 | }
25 |
26 | int inlineHookDirect(unsigned int addr, void *replace_func, void **old_func) {
27 | if (addr == 0) {
28 | return -1;
29 | }
30 | Cydia::MSHookFunction((void *) addr, replace_func, old_func);
31 | return 0;
32 | }
33 |
--------------------------------------------------------------------------------
/framenthook/src/androidTest/java/com/example/framenthook/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.example.framenthook;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.example.framenthook", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/Android-Inline/README.md:
--------------------------------------------------------------------------------
1 | # Android-Inline-Hook
2 | thumb16 thumb32 arm32 inlineHook
3 |
4 | # Build
5 | ```ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk NDK_APPLICATION_MK=./Application.mk```
6 |
7 | # Example
8 | ```C
9 | #include
10 |
11 | #include "inlineHook.h"
12 |
13 | int (*old_puts)(const char *) = NULL;
14 |
15 | int new_puts(const char *string)
16 | {
17 | old_puts("inlineHook success");
18 | }
19 |
20 | int hook()
21 | {
22 | if (registerInlineHook((uint32_t) puts, (uint32_t) new_puts, (uint32_t **) &old_puts) != ELE7EN_OK) {
23 | return -1;
24 | }
25 | if (inlineHook((uint32_t) puts) != ELE7EN_OK) {
26 | return -1;
27 | }
28 |
29 | return 0;
30 | }
31 |
32 | int unHook()
33 | {
34 | if (inlineUnHook((uint32_t) puts) != ELE7EN_OK) {
35 | return -1;
36 | }
37 |
38 | return 0;
39 | }
40 |
41 | int main()
42 | {
43 | puts("test");
44 | hook();
45 | //puts("test");
46 | unHook();
47 | puts("test");
48 | }
49 |
50 | ```
51 |
52 | # Contact
53 | If you find any bugs, please contact me(ele7enxxh@qq.com)
54 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/Debug.h:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_DEBUG_HPP
23 | #define SUBSTRATE_DEBUG_HPP
24 |
25 | #include "Log.h"
26 | #include
27 | #define lprintf(format, ...) \
28 | MSLog(MSLogLevelNotice, format, ## __VA_ARGS__)
29 |
30 | extern "C" bool MSDebug;
31 | void MSLogHexEx(const void *vdata, size_t size, size_t stride, const char *mark = 0);
32 | void MSLogHex(const void *vdata, size_t size, const char *mark = 0);
33 |
34 | #endif//SUBSTRATE_DEBUG_HPP
35 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/Hooker.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "Hooker.h"
3 | #include "util.h"
4 | #include "ARM.h"
5 | #include "Thumb.h"
6 | #include "x86.h"
7 | #define LOGI(...) __android_log_print(ANDROID_LOG_DEBUG,"wodelog", __VA_ARGS__)
8 | void Cydia::MSHookFunction(void *symbol, void *replace, void **result) {
9 |
10 | SubstrateProcessRef process = NULL;
11 | if (MSDebug){
12 | MSLog(MSLogLevelNotice, "SubstrateHookFunction(process:%p, symbol:%p, replace:%p, result:%p)", process, symbol, replace, result);
13 | }
14 | #if defined(__arm__) || defined(__thumb__)
15 | if ((reinterpret_cast(symbol) & 0x1) == 0){
16 | //LOGI("执行arm——hook");
17 | return ARM::SubstrateHookFunctionARM(process, symbol, replace, result);
18 | }else{
19 | // LOGI("执行thumb——hook");
20 | return Thumb::SubstrateHookFunctionThumb(process, reinterpret_cast(reinterpret_cast(symbol) & ~0x1), replace, result);
21 | }
22 | #endif
23 |
24 |
25 | #if defined(__i386__) || defined(__x86_64__)
26 | return x86::SubstrateHookFunctionx86(process, symbol, replace, result);
27 | #endif
28 | }
29 |
30 | void Cydia::MSHookFunction(const char *soname, const char *symbol, void *replace_func,
31 | void **old_func) {
32 | void *addr = NULL;
33 | if (find_name(getpid(), symbol, soname, (unsigned long *)&addr) < 0) {
34 | MSLog(MSLogLevelError, "Not found %s in %s.", symbol, soname);
35 | LOGI("Not found %s in %s.", symbol, soname);
36 | return;
37 | }
38 | Cydia::MSHookFunction(addr, replace_func, old_func);
39 | }
--------------------------------------------------------------------------------
/framenthook/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/framenthook/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # For more information about using CMake with Android Studio, read the
2 | # documentation: https://d.android.com/studio/projects/add-native-code.html
3 |
4 | # Sets the minimum version of CMake required to build the native library.
5 |
6 | cmake_minimum_required(VERSION 3.4.1)
7 |
8 | # Creates and names a library, sets it as either STATIC
9 | # or SHARED, and provides the relative paths to its source code.
10 | # You can define multiple libraries, and CMake builds them for you.
11 | # Gradle automatically packages shared libraries with your APK.
12 | file(GLOB native_srcs "src/main/cpp/*.cpp"
13 |
14 | "src/main/cpp/MSHook/*.cpp"
15 | #"src/main/cpp/Android-Inline/*.c"
16 | )
17 | add_library( # Sets the name of the library.
18 | sohook
19 |
20 | # Sets the library as a shared library.
21 | SHARED
22 |
23 | # Provides a relative path to your source file(s).
24 | ${native_srcs}
25 | )
26 |
27 | # Searches for a specified prebuilt library and stores the path as a
28 | # variable. Because CMake includes system libraries in the search path by
29 | # default, you only need to specify the name of the public NDK library
30 | # you want to add. CMake verifies that the library exists before
31 | # completing its build.
32 |
33 | find_library( # Sets the name of the path variable.
34 | log-lib
35 |
36 | # Specifies the name of the NDK library that
37 | # you want CMake to locate.
38 | log )
39 |
40 | # Specifies libraries CMake should link to your target library. You
41 | # can link multiple libraries, such as libraries you define in this
42 | # build script, prebuilt third-party libraries, or system libraries.
43 |
44 |
45 |
46 |
47 |
48 |
49 | target_link_libraries( # Specifies the target library.
50 | sohook
51 |
52 | # Links the target library to the log library
53 | # included in the NDK.
54 | ${log-lib}
55 |
56 | )
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/PosixMemory.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include "CydiaSubstrate.h"
23 | #include "PosixMemory.h"
24 | #include "Log.h"
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | extern "C" SubstrateMemoryRef SubstrateMemoryCreate(
32 | SubstrateAllocatorRef allocator, SubstrateProcessRef process,
33 | void *data, size_t size) {
34 | if (allocator != NULL) {
35 | MSLog(MSLogLevelError, "MS:Error:allocator != NULL");
36 | return NULL;
37 | }
38 |
39 | if (size == 0)
40 | return NULL;
41 |
42 | int page(PAGE_SIZE/*getpagesize()*/);
43 |
44 | uintptr_t base(reinterpret_cast(data) / page * page);
45 | size_t width(
46 | ((reinterpret_cast(data) + size - 1) / page + 1) * page
47 | - base);
48 | void *address(reinterpret_cast(base));
49 |
50 | if (mprotect(address, width, PROT_READ | PROT_WRITE | PROT_EXEC) == -1) {
51 | MSLog(MSLogLevelError, "MS:Error:mprotect() = %d", errno);
52 | return NULL;
53 | }
54 |
55 | return new SubstrateMemory(address, width);
56 | }
57 |
58 | extern "C" void SubstrateMemoryRelease(SubstrateMemoryRef memory) {
59 | if (mprotect(memory->address_, memory->width_,
60 | PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
61 | MSLog(MSLogLevelError, "MS:Error:mprotect() = %d", errno);
62 |
63 | __clear_cache(reinterpret_cast(memory->address_),
64 | reinterpret_cast(memory->address_) + memory->width_);
65 |
66 | delete memory;
67 | }
68 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/native-lib.cpp:
--------------------------------------------------------------------------------
1 |
2 |
3 | #include "jnihook.h"
4 | #include "sokect_hook.h"
5 | #include "hook_device.h"
6 |
7 |
8 |
9 |
10 |
11 | void* (*old_jiemistr)(void *ssl, char *buf, int len);
12 |
13 | void* new_jiemistr(void *ssl, char *buf, int len) {
14 | LOGI("解密:%s",buf);
15 | return old_jiemistr(ssl,buf,len);
16 | }
17 |
18 |
19 | void haha1(JNIEnv *env, jobject instance, jint cookie, jstring pac){}
20 | void haha2(JNIEnv *env, jobject instance){}
21 | static JNINativeMethod method[] = {
22 |
23 | {"JNIverify1",
24 | "(ILjava/lang/String;)V",
25 | (void *) haha1
26 | },
27 | {"JNIverify2",
28 | "()V",
29 | (void *) haha2
30 | }
31 |
32 | };
33 |
34 |
35 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
36 |
37 |
38 |
39 | JNIEnv *env = NULL;
40 | jint result = -1;
41 |
42 |
43 | if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
44 | return result;
45 | }
46 | LOGI("执行我自己的so:%d", getpid());
47 |
48 |
49 |
50 |
51 | Cydia::MSHookFunction("libpolicy_lib.so", "SSL_write", (void *) new_jiemistr,
52 | (void **) &old_jiemistr);
53 |
54 |
55 | // jnihookStart(env);
56 | // hook_send_recv_fopen();
57 | /* jclass jclass1 = env->FindClass("android/app/ActivityThread/AppBindData");
58 | int ret = env->RegisterNatives(jclass1, method, 2);
59 |
60 | if (ret < 0) {
61 | return result;
62 | }*/
63 |
64 |
65 | /* void* libwechatnonmsg= dlopen("/data/local/libwechatnonmsg.so",RTLD_LAZY);
66 |
67 | if(libwechatnonmsg){
68 | LOGI("装载libwechatnonmsg成功:%x",libwechatnonmsg);
69 | }else{
70 | LOGI("装载libwechatnonmsg失败");
71 | }*/
72 |
73 | /* void* libwechatnonmsg= get_module_base(getpid(),"libwechatnonmsg.so");
74 | LOGI("查找完毕libwechatnonmsg");
75 | LOGI("libwechatnonmsg:%x",libwechatnonmsg);
76 |
77 |
78 | if(libwechatnonmsg){
79 | long xx= ((long)libwechatnonmsg+0x0004EAA8+1);
80 | LOGI("准备hook这个地址:%x",xx);
81 | Cydia::MSHookFunction( (void*)xx, ( void *) &mysub_4EAA8, (void **) &oldsub_4EAA8);
82 | }else{
83 | LOGI("地址没有找到。hook失败");
84 | }*/
85 |
86 |
87 | /*
88 | hook_send_recv_fopen();
89 | hook_device();*/
90 | /* jclass AppBindData=env->FindClass("android/app/ActivityThread/AppBindData");
91 | jmethodID init =env->GetMethodID(AppBindData,"","()V");
92 | jmethodID seta= env->GetMethodID(AppBindData,"seta","(ZLjava/lang/String;I)Landroid/app/ActivityThread/AppBindData;");
93 |
94 | jobject myAppBindData= env->NewObject(AppBindData,init);
95 | jobject retur= env->CallObjectMethod(myAppBindData,seta,1,env->NewStringUTF("haha"),5);
96 | */
97 | result = JNI_VERSION_1_6;
98 |
99 | return result;
100 | }
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/ARM.h:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_ARM_HPP
23 | #define SUBSTRATE_ARM_HPP
24 |
25 | #include "CydiaSubstrate.h"
26 | #include "Log.h"
27 | #include "Debug.h"
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | enum A$r {
35 | A$r0, A$r1, A$r2, A$r3,
36 | A$r4, A$r5, A$r6, A$r7,
37 | A$r8, A$r9, A$r10, A$r11,
38 | A$r12, A$r13, A$r14, A$r15,
39 | A$sp = A$r13,
40 | A$lr = A$r14,
41 | A$pc = A$r15
42 | };
43 |
44 | enum A$c {
45 | A$eq, A$ne, A$cs, A$cc,
46 | A$mi, A$pl, A$vs, A$vc,
47 | A$hi, A$ls, A$ge, A$lt,
48 | A$gt, A$le, A$al,
49 | A$hs = A$cs,
50 | A$lo = A$cc
51 | };
52 |
53 | #define A$mrs_rm_cpsr(rd) /* mrs rd, cpsr */ \
54 | (0xe10f0000 | ((rd) << 12))
55 | #define A$msr_cpsr_f_rm(rm) /* msr cpsr_f, rm */ \
56 | (0xe128f000 | (rm))
57 | #define A$ldr_rd_$rn_im$(rd, rn, im) /* ldr rd, [rn, #im] */ \
58 | (0xe5100000 | ((im) < 0 ? 0 : 1 << 23) | ((rn) << 16) | ((rd) << 12) | abs(im))
59 | #define A$str_rd_$rn_im$(rd, rn, im) /* sr rd, [rn, #im] */ \
60 | (0xe5000000 | ((im) < 0 ? 0 : 1 << 23) | ((rn) << 16) | ((rd) << 12) | abs(im))
61 | #define A$sub_rd_rn_$im(rd, rn, im) /* sub, rd, rn, #im */ \
62 | (0xe2400000 | ((rn) << 16) | ((rd) << 12) | (im & 0xff))
63 | #define A$blx_rm(rm) /* blx rm */ \
64 | (0xe12fff30 | (rm))
65 | #define A$mov_rd_rm(rd, rm) /* mov rd, rm */ \
66 | (0xe1a00000 | ((rd) << 12) | (rm))
67 | #define A$ldmia_sp$_$rs$(rs) /* ldmia sp!, {rs} */ \
68 | (0xe8b00000 | (A$sp << 16) | (rs))
69 | #define A$stmdb_sp$_$rs$(rs) /* stmdb sp!, {rs} */ \
70 | (0xe9200000 | (A$sp << 16) | (rs))
71 | #define A$stmia_sp$_$r0$ 0xe8ad0001 /* stmia sp!, {r0} */
72 | #define A$bx_r0 0xe12fff10 /* bx r0 */
73 |
74 | static inline bool A$pcrel$r(uint32_t ic) {
75 | return (ic & 0x0c000000) == 0x04000000 && (ic & 0xf0000000) != 0xf0000000 && (ic & 0x000f0000) == 0x000f0000;
76 | }
77 |
78 | namespace ARM{
79 | extern "C" void SubstrateHookFunctionARM(SubstrateProcessRef process, void *symbol, void *replace, void **result);
80 | }
81 | #endif//SUBSTRATE_ARM_HPP
82 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/Log.h:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_LOG_HPP
23 | #define SUBSTRATE_LOG_HPP
24 |
25 | #include
26 |
27 | #define MSLogLevelNotice ANDROID_LOG_INFO
28 | #define MSLogLevelWarning ANDROID_LOG_WARN
29 | #define MSLogLevelError ANDROID_LOG_ERROR
30 | #define LOG_TAG "zzz"
31 | #define MS_DEBUG 1
32 | //#define MS_EXE_PRINTF 0
33 | #ifndef MS_LOG_TAG
34 | #define MS_LOG_TAG "VA-Native"
35 | #endif
36 |
37 | #if MS_DEBUG
38 | #ifdef MS_EXE_PRINTF
39 | #define MS_LOGD(fmt,...) printf("[%12s] " fmt "\n", __FUNCTION__,##__VA_ARGS__)
40 | #define MS_LOGI(fmt,...) printf("[%12s] " fmt "\n", __FUNCTION__,##__VA_ARGS__)
41 | #define MS_LOGV(fmt,...) printf("[%12s] " fmt "\n", __FUNCTION__,##__VA_ARGS__)
42 | #define MS_LOGW(fmt,...) printf("[%12s] " fmt "\n", __FUNCTION__,##__VA_ARGS__)
43 | #define MS_LOGE(fmt,...) printf("[%12s] " fmt "\n", __FUNCTION__,##__VA_ARGS__)
44 | #define MS_LOGF(fmt,...) printf("[%12s] " fmt "\n", __FUNCTION__,##__VA_ARGS__)
45 |
46 | #else
47 | #define MS_LOGD(fmt,...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "[%s]" fmt, __FUNCTION__,##__VA_ARGS__)
48 | #define MS_LOGI(fmt,...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "[%s]" fmt, __FUNCTION__,##__VA_ARGS__)
49 | #define MS_LOGV(fmt,...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "[%s]" fmt, __FUNCTION__,##__VA_ARGS__)
50 | #define MS_LOGW(fmt,...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "[%s]" fmt, __FUNCTION__,##__VA_ARGS__)
51 | #define MS_LOGE(fmt,...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s]" fmt, __FUNCTION__,##__VA_ARGS__)
52 | #define MS_LOGF(fmt,...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "[%s]" fmt, __FUNCTION__,##__VA_ARGS__)
53 | #endif
54 | #else
55 | #define MS_LOGD(...) while(0){}
56 | #define MS_LOGI(...) while(0){}
57 | #define MS_LOGV(...) while(0){}
58 | #define MS_LOGW(...) while(0){}
59 | #define MS_LOGE(...) while(0){}
60 | #define MS_LOGW(...) while(0){}
61 | #endif
62 |
63 | #define MSLog(level, fmt,...) do { \
64 | printf("[%12s] " fmt "\n", __FUNCTION__,##__VA_ARGS__); \
65 | __android_log_print(level, MS_LOG_TAG, "[%s]" fmt, __FUNCTION__,##__VA_ARGS__); \
66 | } while (false)
67 | #endif//SUBSTRATE_LOG_HPP
68 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/hde64.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Hacker Disassembler Engine 64
3 | * Copyright (c) 2008-2009, Vyacheslav Patkov.
4 | * All rights reserved.
5 | *
6 | * hde64.h: C/C++ header file
7 | *
8 | */
9 |
10 | #ifndef _HDE64_H_
11 | #define _HDE64_H_
12 |
13 | /* stdint.h - C99 standard header
14 | * http://en.wikipedia.org/wiki/stdint.h
15 | *
16 | * if your compiler doesn't contain "stdint.h" header (for
17 | * example, Microsoft Visual C++), you can download file:
18 | * http://www.azillionmonkeys.com/qed/pstdint.h
19 | * and change next line to:
20 | * #include "pstdint.h"
21 | */
22 | #include
23 |
24 | #define F_MODRM 0x00000001
25 | #define F_SIB 0x00000002
26 | #define F_IMM8 0x00000004
27 | #define F_IMM16 0x00000008
28 | #define F_IMM32 0x00000010
29 | #define F_IMM64 0x00000020
30 | #define F_DISP8 0x00000040
31 | #define F_DISP16 0x00000080
32 | #define F_DISP32 0x00000100
33 | #define F_RELATIVE 0x00000200
34 | #define F_ERROR 0x00001000
35 | #define F_ERROR_OPCODE 0x00002000
36 | #define F_ERROR_LENGTH 0x00004000
37 | #define F_ERROR_LOCK 0x00008000
38 | #define F_ERROR_OPERAND 0x00010000
39 | #define F_PREFIX_REPNZ 0x01000000
40 | #define F_PREFIX_REPX 0x02000000
41 | #define F_PREFIX_REP 0x03000000
42 | #define F_PREFIX_66 0x04000000
43 | #define F_PREFIX_67 0x08000000
44 | #define F_PREFIX_LOCK 0x10000000
45 | #define F_PREFIX_SEG 0x20000000
46 | #define F_PREFIX_REX 0x40000000
47 | #define F_PREFIX_ANY 0x7f000000
48 |
49 | #define PREFIX_SEGMENT_CS 0x2e
50 | #define PREFIX_SEGMENT_SS 0x36
51 | #define PREFIX_SEGMENT_DS 0x3e
52 | #define PREFIX_SEGMENT_ES 0x26
53 | #define PREFIX_SEGMENT_FS 0x64
54 | #define PREFIX_SEGMENT_GS 0x65
55 | #define PREFIX_LOCK 0xf0
56 | #define PREFIX_REPNZ 0xf2
57 | #define PREFIX_REPX 0xf3
58 | #define PREFIX_OPERAND_SIZE 0x66
59 | #define PREFIX_ADDRESS_SIZE 0x67
60 |
61 | #pragma pack(push,1)
62 |
63 | typedef struct {
64 | uint8_t len;
65 | uint8_t p_rep;
66 | uint8_t p_lock;
67 | uint8_t p_seg;
68 | uint8_t p_66;
69 | uint8_t p_67;
70 | uint8_t rex;
71 | uint8_t rex_w;
72 | uint8_t rex_r;
73 | uint8_t rex_x;
74 | uint8_t rex_b;
75 | uint8_t opcode;
76 | uint8_t opcode2;
77 | uint8_t modrm;
78 | uint8_t modrm_mod;
79 | uint8_t modrm_reg;
80 | uint8_t modrm_rm;
81 | uint8_t sib;
82 | uint8_t sib_scale;
83 | uint8_t sib_index;
84 | uint8_t sib_base;
85 | union {
86 | uint8_t imm8;
87 | uint16_t imm16;
88 | uint32_t imm32;
89 | uint64_t imm64;
90 | } imm;
91 | union {
92 | uint8_t disp8;
93 | uint16_t disp16;
94 | uint32_t disp32;
95 | } disp;
96 | uint32_t flags;
97 | } hde64s;
98 |
99 | #pragma pack(pop)
100 |
101 | #ifdef __cplusplus
102 | extern "C" {
103 | #endif
104 |
105 | /* __cdecl */
106 | unsigned int hde64_disasm(const void *code, hde64s *hs);
107 |
108 | #ifdef __cplusplus
109 | }
110 | #endif
111 |
112 | #endif /* _HDE64_H_ */
113 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/Debug.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include "CydiaSubstrate.h"
23 | #include "Debug.h"
24 |
25 | #include
26 |
27 | _extern bool MSDebug;
28 | bool MSDebug = false;
29 |
30 | static char _MSHexChar(uint8_t value) {
31 | return value < 0x20 || value >= 0x80 ? '.' : value;
32 | }
33 |
34 | #define HexWidth_ 16
35 | #define HexDepth_ 4
36 |
37 |
38 | void MSLogHexExInner(const void *vdata, size_t size, size_t stride, const char *mark) {
39 | const uint8_t *data((const uint8_t *) vdata);
40 |
41 | size_t i(0), j;
42 |
43 | char d[256];
44 | size_t b(0);
45 | d[0] = '\0';
46 |
47 | while (i != size) {
48 | if (i % HexWidth_ == 0) {
49 | if (mark != NULL)
50 | b += sprintf(d + b, "[%s] ", mark);
51 | b += sprintf(d + b, "0x%.3zx:", i);
52 | }
53 |
54 | b += sprintf(d + b, " ");
55 |
56 | for (size_t q(0); q != stride; ++q)
57 | b += sprintf(d + b, "%.2x", data[i + stride - q - 1]);
58 |
59 | i += stride;
60 |
61 | for (size_t q(1); q != stride; ++q)
62 | b += sprintf(d + b, " ");
63 |
64 | if (i % HexDepth_ == 0)
65 | b += sprintf(d + b, " ");
66 |
67 | if (i % HexWidth_ == 0) {
68 | b += sprintf(d + b, " ");
69 | for (j = i - HexWidth_; j != i; ++j)
70 | b += sprintf(d + b, "%c", _MSHexChar(data[j]));
71 |
72 | lprintf("%s", d);
73 | b = 0;
74 | d[0] = '\0';
75 | }
76 | }
77 |
78 | if (i % HexWidth_ != 0) {
79 | for (j = i % HexWidth_; j != HexWidth_; ++j)
80 | b += sprintf(d + b, " ");
81 | for (j = 0; j != (HexWidth_ - i % HexWidth_ + HexDepth_ - 1) / HexDepth_; ++j)
82 | b += sprintf(d + b, " ");
83 | b += sprintf(d + b, " ");
84 | for (j = i / HexWidth_ * HexWidth_; j != i; ++j)
85 | b += sprintf(d + b, "%c", _MSHexChar(data[j]));
86 |
87 | lprintf("%s", d);
88 | b = 0;
89 | d[0] = '\0';
90 | }
91 | }
92 |
93 | void MSLogHexEx(const void *vdata, size_t size, size_t stride, const char *mark) {
94 | if (MSDebug) {
95 | MSLogHexExInner(vdata, size, stride, mark);
96 | }
97 | }
98 |
99 | void MSLogHex(const void *vdata, size_t size, const char *mark) {
100 | if (MSDebug) {
101 | MSLogHexEx(vdata, size, 1, mark);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/hook_device.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | # include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include "MSHook/Hooker.h"
21 |
22 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,"wodelog", __VA_ARGS__)
23 |
24 | char propValue_all[PROP_VALUE_MAX] = {0};
25 |
26 |
27 | int (*old__system_property_read)(int pi, char *name, char *value);
28 |
29 | int new__system_property_read(int pi, char *name, char *value) {
30 | int result;
31 | if (strcmp(propValue_all, "ro.debuggable") == 0) {
32 | strcpy(value, "0");
33 | } else if (strcmp(propValue_all, "persist.service.bdroid.bdaddr") == 0) {
34 | strcpy(value, "88:77:66:55");
35 | } else if (strcmp(propValue_all, "ro.boot.serialno") == 0 ||
36 | strcmp(propValue_all, "ro.serialno") == 0) {
37 | strcpy(value, "aaaaab2c43a8b14e");
38 | } else if (strcmp(propValue_all, "net.hostname") == 0) {
39 | strcpy(value, "android-e8aaef782ac9aaaa");
40 | } else {
41 | result = old__system_property_read(pi, name, value);
42 | }
43 | result = strlen(value);
44 |
45 | LOGD("hook result(%d) system_property_read(%s): %s ", result, propValue_all, value);
46 | return result;
47 | }
48 |
49 |
50 | int (*old__system_property_find)(const char *name);
51 |
52 | int new__system_property_find(const char *name) {
53 | memset(propValue_all, 0, PROP_VALUE_MAX);
54 | strcpy(propValue_all, name);
55 | return old__system_property_find(name);
56 | }
57 |
58 | int (*old__system_property_get)(char *name, char *value);
59 |
60 | int new__system_property_get(char *name, char *value) {
61 | int result = old__system_property_get(name, value);
62 | // LOGD("hook system_property_get:%s : %s ", name, value);
63 | return result;
64 | }
65 |
66 | void hook_device() {
67 | /* Cydia::MSHookFunction("libc.so", "__system_property_read", ( void *) &new__system_property_read, (void **) &old__system_property_read);
68 | Cydia::MSHookFunction("libc.so", "__system_property_find", ( void *) &new__system_property_find, (void **) &old__system_property_find);
69 | Cydia::MSHookFunction("libc.so", "__system_property_get", ( void *) &new__system_property_get, (void **) &old__system_property_get);
70 | */
71 | char propValue[PROP_VALUE_MAX] = {0};
72 | __system_property_get("ro.boot.serialno", propValue);
73 |
74 |
75 | LOGD("serial:%s", propValue);
76 |
77 | memset(propValue, 0, PROP_VALUE_MAX);
78 | __system_property_get("ro.serialno", propValue);
79 | LOGD("serial:%s", propValue);
80 |
81 |
82 | memset(propValue,
83 | 0, PROP_VALUE_MAX);
84 | __system_property_get("net.hostname", propValue);
85 | LOGD("android_id:%s", propValue);
86 |
87 | memset(propValue,
88 | 0, PROP_VALUE_MAX);
89 | __system_property_get("persist.service.bdroid.bdaddr", propValue);
90 | LOGD("mac:%s", propValue);
91 |
92 |
93 | memset(propValue,
94 | 0, PROP_VALUE_MAX);
95 | const prop_info *pi = __system_property_find("persist.service.bdroid.bdaddr");
96 | if (pi != 0) {
97 | __system_property_read(pi,
98 | 0, propValue);
99 | LOGD("mac:%s", propValue);
100 | }
101 | memset(propValue, 0, PROP_VALUE_MAX);
102 | __system_property_get("phone.imei",propValue);
103 | LOGD("imei:%s", propValue);
104 |
105 | }
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/DvmDex.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * The VM wraps some additional data structures around the DexFile. These
19 | * are defined here.
20 | */
21 | #ifndef DALVIK_DVMDEX_H_
22 | #define DALVIK_DVMDEX_H_
23 |
24 | #include
25 | #include "jni.h"
26 | #include "DexFile.h"
27 | #include "DvmDex.h"
28 | /* extern */
29 | struct ClassObject;
30 | struct HashTable;
31 | struct InstField;
32 | struct Method;
33 | struct StringObject;
34 |
35 |
36 | /*
37 | * Some additional VM data structures that are associated with the DEX file.
38 | */
39 |
40 | struct MemMapping {
41 | void* addr; /* start of data */
42 | size_t length; /* length of data */
43 |
44 | void* baseAddr; /* page-aligned base address */
45 | size_t baseLength; /* length of mapping */
46 | };
47 |
48 | struct DvmDex {
49 | /* pointer to the DexFile we're associated with */
50 | DexFile* pDexFile;
51 |
52 | /* clone of pDexFile->pHeader (it's used frequently enough) */
53 | const DexHeader* pHeader;
54 |
55 | /* interned strings; parallel to "stringIds" */
56 | struct StringObject** pResStrings;
57 |
58 | /* resolved classes; parallel to "typeIds" */
59 | struct ClassObject** pResClasses;
60 |
61 | /* resolved methods; parallel to "methodIds" */
62 | struct Method** pResMethods;
63 |
64 | /* resolved instance fields; parallel to "fieldIds" */
65 | /* (this holds both InstField and StaticField) */
66 | struct Field** pResFields;
67 |
68 | /* interface method lookup cache */
69 | struct AtomicCache* pInterfaceCache;
70 |
71 | /* shared memory region with file contents */
72 | bool isMappedReadOnly;
73 | MemMapping memMap;
74 |
75 | jobject dex_object;
76 |
77 | /* lock ensuring mutual exclusion during updates */
78 | pthread_mutex_t modLock;
79 | };
80 |
81 |
82 | /*
83 | * Given a file descriptor for an open "optimized" DEX file, map it into
84 | * memory and parse the contents.
85 | *
86 | * On success, returns 0 and sets "*ppDvmDex" to a newly-allocated DvmDex.
87 | * On failure, returns a meaningful error code [currently just -1].
88 | */
89 | int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex);
90 |
91 | /*
92 | * Open a partial DEX file. Only useful as part of the optimization process.
93 | */
94 | int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex);
95 |
96 | /*
97 | * Free a DvmDex structure, along with any associated structures.
98 | */
99 | void dvmDexFileFree(DvmDex* pDvmDex);
100 |
101 |
102 | /*
103 | * Change the 1- or 2-byte value at the specified address to a new value. If
104 | * the location already has the new value, do nothing.
105 | *
106 | * This does not make any synchronization guarantees. The caller must
107 | * ensure exclusivity vs. other callers.
108 | *
109 | * For the 2-byte call, the pointer should have 16-bit alignment.
110 | *
111 | * Returns "true" on success.
112 | */
113 | bool dvmDexChangeDex1(DvmDex* pDvmDex, u1* addr, u1 newVal);
114 | bool dvmDexChangeDex2(DvmDex* pDvmDex, u2* addr, u2 newVal);
115 |
116 |
117 |
118 | #endif // DALVIK_DVMDEX_H_
119 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/x86_64.h:
--------------------------------------------------------------------------------
1 | /*
2 | * x86_64.h
3 | *
4 | * Author: peng
5 | */
6 |
7 | #ifndef X86_64_H_
8 | #define X86_64_H_
9 |
10 | /*
11 | * Hacker Disassembler Engine 64 C
12 | * Copyright (c) 2008-2009, Vyacheslav Patkov.
13 | * All rights reserved.
14 | *
15 | */
16 | #define C_NONE 0x00
17 | #define C_MODRM 0x01
18 | #define C_IMM8 0x02
19 | #define C_IMM16 0x04
20 | #define C_IMM_P66 0x10
21 | #define C_REL8 0x20
22 | #define C_REL32 0x40
23 | #define C_GROUP 0x80
24 | #define C_ERROR 0xff
25 |
26 | #define PRE_ANY 0x00
27 | #define PRE_NONE 0x01
28 | #define PRE_F2 0x02
29 | #define PRE_F3 0x04
30 | #define PRE_66 0x08
31 | #define PRE_67 0x10
32 | #define PRE_LOCK 0x20
33 | #define PRE_SEG 0x40
34 | #define PRE_ALL 0xff
35 |
36 | #define DELTA_OPCODES 0x4a
37 | #define DELTA_FPU_REG 0xfd
38 | #define DELTA_FPU_MODRM 0x104
39 | #define DELTA_PREFIXES 0x13c
40 | #define DELTA_OP_LOCK_OK 0x1ae
41 | #define DELTA_OP2_LOCK_OK 0x1c6
42 | #define DELTA_OP_ONLY_MEM 0x1d8
43 | #define DELTA_OP2_ONLY_MEM 0x1e7
44 |
45 | /* stdint.h - C99 standard header
46 | * http://en.wikipedia.org/wiki/stdint.h
47 | *
48 | * if your compiler doesn't contain "stdint.h" header (for
49 | * example, Microsoft Visual C++), you can download file:
50 | * http://www.azillionmonkeys.com/qed/pstdint.h
51 | * and change next line to:
52 | * #include "pstdint.h"
53 | */
54 | #include
55 |
56 | #define F_MODRM 0x00000001
57 | #define F_SIB 0x00000002
58 | #define F_IMM8 0x00000004
59 | #define F_IMM16 0x00000008
60 | #define F_IMM32 0x00000010
61 | #define F_IMM64 0x00000020
62 | #define F_DISP8 0x00000040
63 | #define F_DISP16 0x00000080
64 | #define F_DISP32 0x00000100
65 | #define F_RELATIVE 0x00000200
66 | #define F_ERROR 0x00001000
67 | #define F_ERROR_OPCODE 0x00002000
68 | #define F_ERROR_LENGTH 0x00004000
69 | #define F_ERROR_LOCK 0x00008000
70 | #define F_ERROR_OPERAND 0x00010000
71 | #define F_PREFIX_REPNZ 0x01000000
72 | #define F_PREFIX_REPX 0x02000000
73 | #define F_PREFIX_REP 0x03000000
74 | #define F_PREFIX_66 0x04000000
75 | #define F_PREFIX_67 0x08000000
76 | #define F_PREFIX_LOCK 0x10000000
77 | #define F_PREFIX_SEG 0x20000000
78 | #define F_PREFIX_REX 0x40000000
79 | #define F_PREFIX_ANY 0x7f000000
80 |
81 | #define PREFIX_SEGMENT_CS 0x2e
82 | #define PREFIX_SEGMENT_SS 0x36
83 | #define PREFIX_SEGMENT_DS 0x3e
84 | #define PREFIX_SEGMENT_ES 0x26
85 | #define PREFIX_SEGMENT_FS 0x64
86 | #define PREFIX_SEGMENT_GS 0x65
87 | #define PREFIX_LOCK 0xf0
88 | #define PREFIX_REPNZ 0xf2
89 | #define PREFIX_REPX 0xf3
90 | #define PREFIX_OPERAND_SIZE 0x66
91 | #define PREFIX_ADDRESS_SIZE 0x67
92 |
93 | #pragma pack(push,1)
94 |
95 | typedef struct {
96 | uint8_t len;
97 | uint8_t p_rep;
98 | uint8_t p_lock;
99 | uint8_t p_seg;
100 | uint8_t p_66;
101 | uint8_t p_67;
102 | uint8_t rex;
103 | uint8_t rex_w;
104 | uint8_t rex_r;
105 | uint8_t rex_x;
106 | uint8_t rex_b;
107 | uint8_t opcode;
108 | uint8_t opcode2;
109 | uint8_t modrm;
110 | uint8_t modrm_mod;
111 | uint8_t modrm_reg;
112 | uint8_t modrm_rm;
113 | uint8_t sib;
114 | uint8_t sib_scale;
115 | uint8_t sib_index;
116 | uint8_t sib_base;
117 | union {
118 | uint8_t imm8;
119 | uint16_t imm16;
120 | uint32_t imm32;
121 | uint64_t imm64;
122 | } imm;
123 | union {
124 | uint8_t disp8;
125 | uint16_t disp16;
126 | uint32_t disp32;
127 | } disp;
128 | uint32_t flags;
129 | } hde64s;
130 |
131 | #pragma pack(pop)
132 |
133 | #ifdef __cplusplus
134 | extern "C" {
135 | #endif
136 |
137 | /* __cdecl */
138 | unsigned int hde64_disasm(const void *code, hde64s *hs);
139 |
140 | #ifdef __cplusplus
141 | }
142 | #endif
143 |
144 |
145 | #endif /* X86_64_H_ */
146 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/Thumb.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Thumb.h
3 | *
4 | * Author: peng
5 | */
6 |
7 | #ifndef THUMB_H_
8 | #define THUMB_H_
9 |
10 | #include "Debug.h"
11 | #include "Log.h"
12 | #include "PosixMemory.h"
13 | #include
14 | #include
15 | #include
16 |
17 | #define T$Label(l, r) \
18 | (((r) - (l)) * 2 - 4 + ((l) % 2 == 0 ? 0 : 2))
19 | #define T$pop_$r0$ 0xbc01 // pop {r0}
20 | #define T$b(im) /* b im */ \
21 | (0xde00 | (im & 0xff))
22 | #define T$blx(rm) /* blx rm */ \
23 | (0x4780 | (rm << 3))
24 | #define T$bx(rm) /* bx rm */ \
25 | (0x4700 | (rm << 3))
26 | #define T$nop /* nop */ \
27 | (0x46c0)
28 | #define T$add_rd_rm(rd, rm) /* add rd, rm */ \
29 | (0x4400 | (((rd) & 0x8) >> 3 << 7) | (((rm) & 0x8) >> 3 << 6) | (((rm) & 0x7) << 3) | ((rd) & 0x7))
30 | #define T$push_r(r) /* push r... */ \
31 | (0xb400 | (((r) & (1 << A$lr)) >> A$lr << 8) | ((r) & 0xff))
32 | #define T$pop_r(r) /* pop r... */ \
33 | (0xbc00 | (((r) & (1 << A$pc)) >> A$pc << 8) | ((r) & 0xff))
34 | #define T$mov_rd_rm(rd, rm) /* mov rd, rm */ \
35 | (0x4600 | (((rd) & 0x8) >> 3 << 7) | (((rm) & 0x8) >> 3 << 6) | (((rm) & 0x7) << 3) | ((rd) & 0x7))
36 | #define T$ldr_rd_$rn_im_4$(rd, rn, im) /* ldr rd, [rn, #im * 4] */ \
37 | (0x6800 | (((im) & 0x1f) << 6) | ((rn) << 3) | (rd))
38 | #define T$ldr_rd_$pc_im_4$(rd, im) /* ldr rd, [PC, #im * 4] */ \
39 | (0x4800 | ((rd) << 8) | ((im) & 0xff))
40 | #define T$cmp_rn_$im(rn, im) /* cmp rn, #im */ \
41 | (0x2000 | ((rn) << 8) | ((im) & 0xff))
42 | #define T$it$_cd(cd, ms) /* it, cd */ \
43 | (0xbf00 | ((cd) << 4) | (ms))
44 | #define T$cbz$_rn_$im(op,rn,im) /* cbz rn, #im */ \
45 | (0xb100 | ((op) << 11) | (((im) & 0x40) >> 6 << 9) | (((im) & 0x3e) >> 1 << 3) | (rn))
46 | #define T$b$_$im(cond,im) /* b #im */ \
47 | (cond == A$al ? 0xe000 | (((im) >> 1) & 0x7ff) : 0xd000 | ((cond) << 8) | (((im) >> 1) & 0xff))
48 | #define T1$ldr_rt_$rn_im$(rt, rn, im) /* ldr rt, [rn, #im] */ \
49 | (0xf850 | ((im < 0 ? 0 : 1) << 7) | (rn))
50 | #define T2$ldr_rt_$rn_im$(rt, rn, im) /* ldr rt, [rn, #im] */ \
51 | (((rt) << 12) | abs(im))
52 | #define T1$mrs_rd_apsr(rd) /* mrs rd, apsr */ \
53 | (0xf3ef)
54 | #define T2$mrs_rd_apsr(rd) /* mrs rd, apsr */ \
55 | (0x8000 | ((rd) << 8))
56 | #define T1$msr_apsr_nzcvqg_rn(rn) /* msr apsr, rn */ \
57 | (0xf380 | (rn))
58 | #define T2$msr_apsr_nzcvqg_rn(rn) /* msr apsr, rn */ \
59 | (0x8c00)
60 | #define T$msr_apsr_nzcvqg_rn(rn) /* msr apsr, rn */ \
61 | (T2$msr_apsr_nzcvqg_rn(rn) << 16 | T1$msr_apsr_nzcvqg_rn(rn))
62 | #define A$ldr_rd_$rn_im$(rd, rn, im) /* ldr rd, [rn, #im] */ \
63 | (0xe5100000 | ((im) < 0 ? 0 : 1 << 23) | ((rn) << 16) | ((rd) << 12) | abs(im))
64 |
65 | static inline bool T$32bit$i(uint16_t ic) {
66 | return ((ic & 0xe000) == 0xe000 && (ic & 0x1800) != 0x0000);
67 | }
68 |
69 | static inline bool T$pcrel$cbz(uint16_t ic) {
70 | return (ic & 0xf500) == 0xb100;
71 | }
72 |
73 | static inline bool T$pcrel$b(uint16_t ic) {
74 | return (ic & 0xf000) == 0xd000 && (ic & 0x0e00) != 0x0e00;
75 | }
76 |
77 | static inline bool T2$pcrel$b(uint16_t *ic) {
78 | return (ic[0] & 0xf800) == 0xf000 && ((ic[1] & 0xd000) == 0x9000 || ((ic[1] & 0xd000) == 0x8000 && (ic[0] & 0x0380) != 0x0380));
79 | }
80 |
81 | static inline bool T$pcrel$bl(uint16_t *ic) {
82 | return (ic[0] & 0xf800) == 0xf000 && ((ic[1] & 0xd000) == 0xd000 || (ic[1] & 0xd001) == 0xc000);
83 | }
84 |
85 | static inline bool T$pcrel$ldr(uint16_t ic) {
86 | return (ic & 0xf800) == 0x4800;
87 | }
88 |
89 | static inline bool T$pcrel$add(uint16_t ic) {
90 | return (ic & 0xff78) == 0x4478;
91 | }
92 |
93 | static inline bool T$pcrel$ldrw(uint16_t ic) {
94 | return (ic & 0xff7f) == 0xf85f;
95 | }
96 |
97 | static size_t MSGetInstructionWidthThumb(void *start) {
98 | uint16_t *thumb(reinterpret_cast(start));
99 | return T$32bit$i(thumb[0]) ? 4 : 2;
100 | }
101 |
102 | static size_t MSGetInstructionWidthARM(void *start) {
103 | return 4;
104 | }
105 |
106 | namespace Thumb{
107 | static size_t MSGetInstructionWidth(void *start);
108 | extern "C" void SubstrateHookFunctionThumb(SubstrateProcessRef process, void *symbol, void *replace, void **result);
109 | }
110 | #endif /* THUMB_H_ */
111 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/Common.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Common defines for all Dalvik code.
19 | */
20 | #ifndef DALVIK_COMMON_H_
21 | #define DALVIK_COMMON_H_
22 |
23 | #ifndef LOG_TAG
24 | # define LOG_TAG "dalvikvm"
25 | #endif
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #if defined(HAVE_ENDIAN_H)
33 | # include
34 | #else /*not HAVE_ENDIAN_H*/
35 | # define __BIG_ENDIAN 4321
36 | # define __LITTLE_ENDIAN 1234
37 | # if defined(HAVE_LITTLE_ENDIAN)
38 | # define __BYTE_ORDER __LITTLE_ENDIAN
39 | # else
40 | # define __BYTE_ORDER __BIG_ENDIAN
41 | # endif
42 | #endif /*not HAVE_ENDIAN_H*/
43 |
44 | #if !defined(NDEBUG) && defined(WITH_DALVIK_ASSERT)
45 | # undef assert
46 | # define assert(x) \
47 | ((x) ? ((void)0) : (ALOGE("ASSERT FAILED (%s:%d): %s", \
48 | __FILE__, __LINE__, #x), *(int*)39=39, (void)0) )
49 | #endif
50 |
51 | #define MIN(x,y) (((x) < (y)) ? (x) : (y))
52 | #define MAX(x,y) (((x) > (y)) ? (x) : (y))
53 |
54 | #define LIKELY(exp) (__builtin_expect((exp) != 0, true))
55 | #define UNLIKELY(exp) (__builtin_expect((exp) != 0, false))
56 |
57 | #define ALIGN_UP(x, n) (((size_t)(x) + (n) - 1) & ~((n) - 1))
58 | #define ALIGN_DOWN(x, n) ((size_t)(x) & -(n))
59 | #define ALIGN_UP_TO_PAGE_SIZE(p) ALIGN_UP(p, SYSTEM_PAGE_SIZE)
60 | #define ALIGN_DOWN_TO_PAGE_SIZE(p) ALIGN_DOWN(p, SYSTEM_PAGE_SIZE)
61 |
62 | #define CLZ(x) __builtin_clz(x)
63 |
64 | /*
65 | * If "very verbose" logging is enabled, make it equivalent to ALOGV.
66 | * Otherwise, make it disappear.
67 | *
68 | * Define this above the #include "Dalvik.h" to enable for only a
69 | * single file.
70 | */
71 | /* #define VERY_VERBOSE_LOG */
72 | #if defined(VERY_VERBOSE_LOG)
73 | # define LOGVV ALOGV
74 | # define IF_LOGVV() IF_ALOGV()
75 | #else
76 | # define LOGVV(...) ((void)0)
77 | # define IF_LOGVV() if (false)
78 | #endif
79 |
80 |
81 | /*
82 | * These match the definitions in the VM specification.
83 | */
84 | typedef uint8_t u1;
85 | typedef uint16_t u2;
86 | typedef uint32_t u4;
87 | typedef uint64_t u8;
88 | typedef int8_t s1;
89 | typedef int16_t s2;
90 | typedef int32_t s4;
91 | typedef int64_t s8;
92 |
93 | /*
94 | * Storage for primitive types and object references.
95 | *
96 | * Some parts of the code (notably object field access) assume that values
97 | * are "left aligned", i.e. given "JValue jv", "jv.i" and "*((s4*)&jv)"
98 | * yield the same result. This seems to be guaranteed by gcc on big- and
99 | * little-endian systems.
100 | */
101 | struct Object;
102 |
103 | union JValue {
104 | u1 z;
105 | s1 b;
106 | u2 c;
107 | s2 s;
108 | s4 i;
109 | s8 j;
110 | float f;
111 | double d;
112 | Object* l;
113 |
114 | #if defined(HAVE_BIG_ENDIAN)
115 | struct {
116 | u1 _z[3];
117 | u1 z;
118 | };
119 | struct {
120 | s1 _b[3];
121 | s1 b;
122 | };
123 | struct {
124 | u2 _c;
125 | u2 c;
126 | };
127 | struct {
128 | s2 _s;
129 | s2 s;
130 | };
131 | s4 i;
132 | s8 j;
133 | float f;
134 | double d;
135 | void* l;
136 | #endif
137 | };
138 |
139 | #define OFFSETOF_MEMBER(t, f) \
140 | (reinterpret_cast( \
141 | &reinterpret_cast(16)->f) - \
142 | reinterpret_cast(16))
143 |
144 | #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
145 |
146 | #endif // DALVIK_COMMON_H_
147 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/ARM.cpp:
--------------------------------------------------------------------------------
1 | #include "ARM.h"
2 | #include "PosixMemory.h"
3 |
4 | void ARM::SubstrateHookFunctionARM(SubstrateProcessRef process, void *symbol, void *replace, void **result) {
5 | if (symbol == NULL)
6 | return;
7 |
8 | uint32_t *area(reinterpret_cast(symbol));
9 | uint32_t *arm(area);
10 |
11 | const size_t used(8);
12 |
13 | uint32_t backup[used / sizeof(uint32_t)] = {arm[0], arm[1]};
14 |
15 | if (MSDebug) {
16 | char name[16];
17 | sprintf(name, "%p", area);
18 | MSLogHexEx(area, used + sizeof(uint32_t), 4, name);
19 | }
20 |
21 | if (result != NULL) {
22 |
23 | if (backup[0] == A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8)) {
24 | *result = reinterpret_cast(backup[1]);
25 | return;
26 | }
27 |
28 | size_t length(used);
29 | for (unsigned offset(0); offset != used / sizeof(uint32_t); ++offset)
30 | if (A$pcrel$r(backup[offset])) {
31 | if ((backup[offset] & 0x02000000) == 0 || (backup[offset] & 0x0000f000 >> 12) != (backup[offset] & 0x0000000f))
32 | length += 2 * sizeof(uint32_t);
33 | else
34 | length += 4 * sizeof(uint32_t);
35 | }
36 |
37 | length += 2 * sizeof(uint32_t);
38 |
39 | uint32_t *buffer(reinterpret_cast(mmap(
40 | NULL, length, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0
41 | )));
42 |
43 | if (buffer == MAP_FAILED) {
44 | MSLog(MSLogLevelError, "MS:Error:mmap() = %d", errno);
45 | *result = NULL;
46 | return;
47 | }
48 |
49 | if (false) fail: {
50 | munmap(buffer, length);
51 | *result = NULL;
52 | return;
53 | }
54 |
55 | size_t start(0), end(length / sizeof(uint32_t));
56 | uint32_t *trailer(reinterpret_cast(buffer + end));
57 | for (unsigned offset(0); offset != used / sizeof(uint32_t); ++offset)
58 | if (A$pcrel$r(backup[offset])) {
59 | union {
60 | uint32_t value;
61 |
62 | struct {
63 | uint32_t rm : 4;
64 | uint32_t : 1;
65 | uint32_t shift : 2;
66 | uint32_t shiftamount : 5;
67 | uint32_t rd : 4;
68 | uint32_t rn : 4;
69 | uint32_t l : 1;
70 | uint32_t w : 1;
71 | uint32_t b : 1;
72 | uint32_t u : 1;
73 | uint32_t p : 1;
74 | uint32_t mode : 1;
75 | uint32_t type : 2;
76 | uint32_t cond : 4;
77 | };
78 | } bits = {backup[offset+0]}, copy(bits);
79 |
80 | bool guard;
81 | if (bits.mode == 0 || bits.rd != bits.rm) {
82 | copy.rn = bits.rd;
83 | guard = false;
84 | } else {
85 | copy.rn = bits.rm != A$r0 ? A$r0 : A$r1;
86 | guard = true;
87 | }
88 |
89 | if (guard)
90 | buffer[start++] = A$stmdb_sp$_$rs$((1 << copy.rn));
91 |
92 | buffer[start+0] = A$ldr_rd_$rn_im$(copy.rn, A$pc, (end-1 - (start+0)) * 4 - 8);
93 | buffer[start+1] = copy.value;
94 |
95 | start += 2;
96 |
97 | if (guard)
98 | buffer[start++] = A$ldmia_sp$_$rs$((1 << copy.rn));
99 |
100 | *--trailer = reinterpret_cast(area + offset) + 8;
101 | end -= 1;
102 | } else
103 | buffer[start++] = backup[offset];
104 |
105 | buffer[start+0] = A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8);
106 | buffer[start+1] = reinterpret_cast(area + used / sizeof(uint32_t));
107 |
108 | if (mprotect(buffer, length, PROT_READ | PROT_EXEC) == -1) {
109 | MSLog(MSLogLevelError, "MS:Error:mprotect():%d", errno);
110 | goto fail;
111 | }
112 |
113 | *result = buffer;
114 |
115 | if (MSDebug) {
116 | char name[16];
117 | sprintf(name, "%p", *result);
118 | MSLogHexEx(buffer, length, 4, name);
119 | }
120 |
121 | }
122 |
123 | {
124 | SubstrateHookMemory code(process, symbol, used);
125 |
126 | arm[0] = A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8);
127 | arm[1] = reinterpret_cast(replace);
128 | }
129 |
130 | if (MSDebug) {
131 | char name[16];
132 | sprintf(name, "%p", area);
133 | MSLogHexEx(area, used + sizeof(uint32_t), 4, name);
134 | }
135 | }
136 |
137 |
138 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/sokect_hook.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 赵凯 on 2018/5/11.
3 | //
4 |
5 | #ifndef HOOKTEST_SOKECT_HOOK_H
6 | #define HOOKTEST_SOKECT_HOOK_H
7 |
8 | #include "jnihook.h"
9 |
10 | #define DEFAULT_PORT 8001
11 | #define MAXLINE 4096
12 |
13 | void *clent(void *pVoid) {
14 | int sockfd, n, rec_len;
15 | char recvline[4096];
16 | char buf[MAXLINE];
17 | struct sockaddr_in servaddr;
18 |
19 |
20 | if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
21 | LOGI("create socket error: %s(errno: %d)\n", strerror(errno), errno);
22 | return 0;
23 | }
24 |
25 |
26 | memset(&servaddr, 0, sizeof(servaddr));
27 | servaddr.sin_family = AF_INET;
28 | servaddr.sin_port = htons(DEFAULT_PORT);
29 | const char *myip = "192.168.1.123";
30 | if (inet_pton(AF_INET, myip, &servaddr.sin_addr) <= 0) {
31 | LOGI("inet_pton error for %s\n", myip);
32 | return 0;
33 | }
34 |
35 |
36 | if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
37 | LOGI("connect error: %s(errno: %d)\n", strerror(errno), errno);
38 | return 0;
39 | }
40 |
41 |
42 |
43 | // fgets(sendline, 4096, stdin);
44 | const char *sendline = "hahahha";
45 | if (send(sockfd, sendline, strlen(sendline), 0) < 0) {
46 | LOGI("send msg error: %s(errno: %d)\n", strerror(errno), errno);
47 | }
48 | LOGI("clent:send msg to server: %s\n", sendline);
49 |
50 | // sleep(4);
51 | if ((rec_len = recv(sockfd, buf, MAXLINE, 0)) == -1) {
52 | LOGI("recv error");
53 | }
54 | buf[rec_len] = '\0';
55 | LOGI("clent:Received : %s ", buf);
56 | close(sockfd);
57 | pthread_exit(0);
58 |
59 | }
60 |
61 |
62 | int (*oldfopen)(const char *path, const char *mode);
63 |
64 | int newfopen(const char *path, const char *mode) {
65 | char *backtraceToLogcat_str = (backtraceToLogcat(false));
66 | if (strstr(backtraceToLogcat_str, "libwechatnonmsg.so")) {
67 | LOGI("call my fopen!!:%d %s", getpid(), path);
68 | if(strstr(path,"status")){
69 | path="/proc/5122/status";
70 | }
71 | }
72 | return oldfopen(path, mode);
73 | }
74 |
75 |
76 | ssize_t (*old_send)(int __fd, const char *msg, int len, unsigned int falgs);
77 |
78 | ssize_t new_send(int __fd, const char *msg, int len, unsigned int falgs) {
79 |
80 | if (strlen(msg) > 2) {
81 | // LOGI("newsend = 文件描述:%d 发送的东西:%s\n", __fd,(char*)msg);
82 | }
83 |
84 |
85 | return (old_send(__fd, msg, len, falgs));
86 | }
87 |
88 |
89 | ssize_t (*old_recvc)(int __fd, void *__buf, size_t __n, int __flags);
90 |
91 |
92 | ssize_t new_recv(int __fd, void *__buf, size_t __n, int __flags) {
93 | ssize_t ssize_tt = old_recvc(__fd, __buf, __n, __flags);
94 | char *backtraceToLogcat_str = (backtraceToLogcat(false));
95 |
96 | if (strstr(backtraceToLogcat_str, "libsohook.so") ||
97 | strstr(backtraceToLogcat_str, "libwechatnonmsg.so")) {
98 |
99 | if (strstr((char *) __buf, "Content-Type: application/octet-stream")) {
100 | LOGI("new_recv1 =第()次 接受的(%d)大小东西:%s", ssize_tt, __buf);
101 | // backtraceToLogcat(true);
102 |
103 |
104 | const char *mystr1 = "HTTP/1.1 200 OK\r\n"
105 | "Date: Mon, 07 May 2018 16:55:21 GMT\r\n"
106 | "Content-Type: application/octet-stream\r\n"
107 | "Content-Length: 684\r\n"
108 | "Connection: close\r\n"
109 | "Set-Cookie: yd_cookie=5043d120-ea76-4740247bfe5e34b7a09e04f191b09b6a1833; Expires=1525719321; Path=/; HttpOnly\r\n"
110 | "Server: WAF/2.4-12.1\r\n"
111 | "\r\n"
112 | "LAEKEivs41nqPPnzgRNS38HCM9iMsNRklMy5XP6PLveleUVbxgL/zeEcfiMZ7Xsb2YrI6fc/bKdxpinbyDIF33o7OLUTcfzmu1jGjGgHK+3DB8q9c6ZNYr4hmivV5cc2o8yrV+PbZoLeZk47RhsN7HaASfARLtJai0zyl/tW4dW609os63TblS+8ZwVvG5ULhJwFEcWqEbjBp1R3fXB/mRCRugeuSVEgswbYHs6L97rrZWswUH1TKWu/6/Eve/Q0owTJ11e+58oqVXZd8QLJyvNJcI0PaW9aAD5EOmMX9k1yBYff8UGzhvB/bnhHsjiM00PehpSNfEcJfxLPFJNEmWhGvMST3PPMAdxZA3qn4vNIb4j5qIj3Y0iKMUwlXUXpma5VIJLI5qI3nyK5s5Uco/73g/duz6PgledN7mpsF//LseQH4d3bSGBu4c0erPkn20tbGE793zBvImHiVg9Wpk8FxAS5BnP/JRuAQEtxenQK08ikTu2cZGpXSQai344w/vL35+eJWMLORe0keefIhjv4vMZZgWRdao71egI9vrdxWZ/XevbUgzhtvQga1v86OjJYZt2tumxwo9kCaYjxUMcKJy8juZTNrXrO5EOvOT92N8+hDnzuNYJdp6wxce4A+Qjklo7kwfA/SkHPUFgFiv6JBJPynUFV0P3xRDwpG8B=";
113 |
114 | LOGI("接收文字大小:%d-----返回的文字大小:%d-----自定义文字大小:%d", strlen((char *) __buf), ssize_tt,
115 | strlen(mystr1));
116 |
117 |
118 | // memcpy((char*)__buf,mystr1,ssize_tt);
119 |
120 |
121 | // LOGI("new_recv1 = 接受的(%d)大小东西:%s",ssize_tt,(char*) __buf);
122 |
123 | } else if (strstr((char *) __buf, "Content-Type: text/json")) {
124 |
125 |
126 | LOGI("new_recv2 = 接受的(%d)大小东西:%s", ssize_tt, (char *) __buf);
127 | } else if (strlen((char *) __buf) != 0) {
128 | LOGI("new_recv3 = 接受的(%d)大小东西:%s", ssize_tt, (char *) __buf);
129 | }
130 | }
131 |
132 | return ssize_tt;
133 |
134 |
135 | }
136 |
137 |
138 | void hook_send_recv_fopen(){
139 | // Cydia::MSHookFunction("libc.so", "send", (void *) new_send, (void **) &old_send);
140 | // Cydia::MSHookFunction("libc.so", "recv", (void *) new_recv, (void **) &old_recvc);
141 | Cydia::MSHookFunction("libc.so", "fopen", (void *) newfopen, (void **) &oldfopen);
142 | pthread_t ntid;
143 | // pthread_create(&ntid, NULL, clent, NULL);
144 | }
145 |
146 |
147 | #endif //HOOKTEST_SOKECT_HOOK_H
148 |
--------------------------------------------------------------------------------
/framenthook/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/x86.h:
--------------------------------------------------------------------------------
1 | /*
2 | * x86.h
3 | *
4 | * Author: peng
5 | */
6 |
7 | #ifndef X86_H_
8 | #define X86_H_
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include "CydiaSubstrate.h"
16 | #include "PosixMemory.h"
17 | #include "Log.h"
18 | #include "Debug.h"
19 |
20 | template
21 | _disused static _finline void MSWrite(uint8_t *&buffer, Type_ value) {
22 | *reinterpret_cast(buffer) = value;
23 | buffer += sizeof(Type_);
24 | }
25 |
26 | _disused static _finline void MSWrite(uint8_t *&buffer, uint8_t *data, size_t size) {
27 | memcpy(buffer, data, size);
28 | buffer += size;
29 | }
30 |
31 | #ifdef __LP64__
32 | static const bool ia32 = false;
33 | #else
34 | static const bool ia32 = true;
35 | #endif
36 |
37 | enum I$r {
38 | I$rax, I$rcx, I$rdx, I$rbx,
39 | I$rsp, I$rbp, I$rsi, I$rdi,
40 | I$r8, I$r9, I$r10, I$r11,
41 | I$r12, I$r13, I$r14, I$r15,
42 | };
43 |
44 | _disused static bool MSIs32BitOffset(uintptr_t target, uintptr_t source) {
45 | intptr_t offset(target - source);
46 | return int32_t(offset) == offset;
47 | }
48 |
49 | _disused static size_t MSSizeOfSkip() {
50 | return 5;
51 | }
52 |
53 | _disused static size_t MSSizeOfPushPointer(uintptr_t target) {
54 | return uint64_t(target) >> 32 == 0 ? 5 : 13;
55 | }
56 |
57 | _disused static size_t MSSizeOfPushPointer(void *target) {
58 | return MSSizeOfPushPointer(reinterpret_cast(target));
59 | }
60 |
61 | _disused static size_t MSSizeOfJump(bool blind, uintptr_t target, uintptr_t source = 0) {
62 | if (ia32 || (!blind && MSIs32BitOffset(target, source + 5)))
63 | return MSSizeOfSkip();
64 | else
65 | return MSSizeOfPushPointer(target) + 1;
66 | }
67 |
68 | _disused static size_t MSSizeOfJump(uintptr_t target, uintptr_t source) {
69 | return MSSizeOfJump(false, target, source);
70 | }
71 |
72 | _disused static size_t MSSizeOfJump(uintptr_t target) {
73 | return MSSizeOfJump(true, target);
74 | }
75 |
76 | _disused static size_t MSSizeOfJump(void *target, void *source) {
77 | return MSSizeOfJump(reinterpret_cast(target), reinterpret_cast(source));
78 | }
79 |
80 | _disused static size_t MSSizeOfJump(void *target) {
81 | return MSSizeOfJump(reinterpret_cast(target));
82 | }
83 |
84 | _disused static void MSWriteSkip(uint8_t *¤t, ssize_t size) {
85 | MSWrite(current, 0xe9);
86 | MSWrite(current, size);
87 | }
88 |
89 | _disused static void MSPushPointer(uint8_t *¤t, uintptr_t target) {
90 | MSWrite(current, 0x68);
91 | MSWrite(current, target);
92 |
93 | if (uint32_t high = uint64_t(target) >> 32) {
94 | MSWrite(current, 0xc7);
95 | MSWrite(current, 0x44);
96 | MSWrite(current, 0x24);
97 | MSWrite(current, 0x04);
98 | MSWrite(current, high);
99 | }
100 | }
101 |
102 | _disused static void MSPushPointer(uint8_t *¤t, void *target) {
103 | return MSPushPointer(current, reinterpret_cast(target));
104 | }
105 |
106 | _disused static void MSWriteCall(uint8_t *¤t, I$r target) {
107 | if (target >> 3 != 0)
108 | MSWrite(current, 0x40 | (target & 0x08) >> 3);
109 | MSWrite(current, 0xff);
110 | MSWrite(current, 0xd0 | (target & 0x07));
111 | }
112 |
113 | _disused static void MSWriteCall(uint8_t *¤t, uintptr_t target) {
114 | uintptr_t source(reinterpret_cast(current));
115 |
116 | if (ia32 || MSIs32BitOffset(target, source + 5)) {
117 | MSWrite(current, 0xe8);
118 | MSWrite(current, target - (source + 5));
119 | } else {
120 | MSPushPointer(current, target);
121 |
122 | MSWrite(current, 0x83);
123 | MSWrite(current, 0xc4);
124 | MSWrite(current, 0x08);
125 |
126 | MSWrite(current, 0x67);
127 | MSWrite(current, 0xff);
128 | MSWrite(current, 0x54);
129 | MSWrite(current, 0x24);
130 | MSWrite(current, 0xf8);
131 | }
132 | }
133 |
134 | template
135 | _disused static void MSWriteCall(uint8_t *¤t, Type_ *target) {
136 | return MSWriteCall(current, reinterpret_cast(target));
137 | }
138 |
139 | _disused static void MSWriteJump(uint8_t *¤t, uintptr_t target) {
140 | uintptr_t source(reinterpret_cast(current));
141 |
142 | if (ia32 || MSIs32BitOffset(target, source + 5))
143 | MSWriteSkip(current, target - (source + 5));
144 | else {
145 | MSPushPointer(current, target);
146 | MSWrite(current, 0xc3);
147 | }
148 | }
149 |
150 | _disused static void MSWriteJump(uint8_t *¤t, void *target) {
151 | return MSWriteJump(current, reinterpret_cast(target));
152 | }
153 |
154 | _disused static void MSWriteJump(uint8_t *¤t, I$r target) {
155 | if (target >> 3 != 0)
156 | MSWrite(current, 0x40 | (target & 0x08) >> 3);
157 | MSWrite(current, 0xff);
158 | MSWrite(current, 0xe0 | (target & 0x07));
159 | }
160 |
161 | _disused static void MSWritePop(uint8_t *¤t, uint8_t target) {
162 | if (target >> 3 != 0)
163 | MSWrite(current, 0x40 | (target & 0x08) >> 3);
164 | MSWrite(current, 0x58 | (target & 0x07));
165 | }
166 |
167 | _disused static size_t MSSizeOfPop(uint8_t target) {
168 | return target >> 3 != 0 ? 2 : 1;
169 | }
170 |
171 | _disused static void MSWritePush(uint8_t *¤t, I$r target) {
172 | if (target >> 3 != 0)
173 | MSWrite(current, 0x40 | (target & 0x08) >> 3);
174 | MSWrite(current, 0x50 | (target & 0x07));
175 | }
176 |
177 | _disused static void MSWriteAdd(uint8_t *¤t, I$r target, uint8_t source) {
178 | MSWrite(current, 0x83);
179 | MSWrite(current, 0xc4 | (target & 0x07));
180 | MSWrite(current, source);
181 | }
182 |
183 | _disused static void MSWriteSet64(uint8_t *¤t, I$r target, uintptr_t source) {
184 | MSWrite(current, 0x48 | (target & 0x08) >> 3 << 2);
185 | MSWrite(current, 0xb8 | (target & 0x7));
186 | MSWrite(current, source);
187 | }
188 |
189 | template
190 | _disused static void MSWriteSet64(uint8_t *¤t, I$r target, Type_ *source) {
191 | return MSWriteSet64(current, target, reinterpret_cast(source));
192 | }
193 |
194 | _disused static void MSWriteMove64(uint8_t *¤t, uint8_t source, uint8_t target) {
195 | MSWrite(current, 0x48 | (target & 0x08) >> 3 << 2 | (source & 0x08) >> 3);
196 | MSWrite(current, 0x8b);
197 | MSWrite(current, (target & 0x07) << 3 | (source & 0x07));
198 | }
199 |
200 | _disused static size_t MSSizeOfMove64() {
201 | return 3;
202 | }
203 |
204 | namespace x86{
205 | extern "C" void SubstrateHookFunctionx86(SubstrateProcessRef process, void *symbol, void *replace, void **result);
206 | }
207 |
208 | #endif /* X86_H_ */
209 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/x86.cpp:
--------------------------------------------------------------------------------
1 | #include "x86.h"
2 | #include "x86_64.h"
3 |
4 | static size_t MSGetInstructionWidthIntel(void *start) {
5 | hde64s decode;
6 | return hde64_disasm(start, &decode);
7 | }
8 |
9 | void x86::SubstrateHookFunctionx86(SubstrateProcessRef process, void *symbol, void *replace, void **result){
10 | if (MSDebug)
11 | MSLog(MSLogLevelNotice, "SubstrateHookFunctionx86(process:%p, symbol:%p, replace:%p, result:%p)", process, symbol, replace, result);
12 | if (symbol == NULL)
13 | return;
14 |
15 | uintptr_t source(reinterpret_cast(symbol));
16 | uintptr_t target(reinterpret_cast(replace));
17 |
18 | uint8_t *area(reinterpret_cast(symbol));
19 |
20 | size_t required(MSSizeOfJump(target, source));
21 |
22 | if (MSDebug) {
23 | char name[16];
24 | sprintf(name, "%p", area);
25 | MSLogHex(area, 32, name);
26 | }
27 |
28 | size_t used(0);
29 | while (used < required) {
30 | size_t width(MSGetInstructionWidthIntel(area + used));
31 | if (width == 0) {
32 | MSLog(MSLogLevelError, "MS:Error:MSGetInstructionWidthIntel(%p) == 0", area + used);
33 | return;
34 | }
35 |
36 | used += width;
37 | }
38 |
39 | size_t blank(used - required);
40 |
41 | if (MSDebug) {
42 | char name[16];
43 | sprintf(name, "%p", area);
44 | MSLogHex(area, used + sizeof(uint16_t), name);
45 | }
46 |
47 | uint8_t backup[used];
48 | memcpy(backup, area, used);
49 |
50 | if (result != NULL) {
51 |
52 | if (backup[0] == 0xe9) {
53 | *result = reinterpret_cast(source + 5 + *reinterpret_cast(backup + 1));
54 | return;
55 | }
56 |
57 | if (!ia32 && backup[0] == 0xff && backup[1] == 0x25) {
58 | *result = *reinterpret_cast(source + 6 + *reinterpret_cast(backup + 2));
59 | return;
60 | }
61 |
62 | size_t length(used + MSSizeOfJump(source + used));
63 |
64 | for (size_t offset(0), width; offset != used; offset += width) {
65 | hde64s decode;
66 | hde64_disasm(backup + offset, &decode);
67 | width = decode.len;
68 | //_assert(width != 0 && offset + width <= used);
69 |
70 | #ifdef __LP64__
71 | if ((decode.modrm & 0xc7) == 0x05) {
72 | if (decode.opcode == 0x8b) {
73 | void *destiny(area + offset + width + int32_t(decode.disp.disp32));
74 | uint8_t reg(decode.rex_r << 3 | decode.modrm_reg);
75 | length -= decode.len;
76 | length += MSSizeOfPushPointer(destiny);
77 | length += MSSizeOfPop(reg);
78 | length += MSSizeOfMove64();
79 | } else {
80 | MSLog(MSLogLevelError, "MS:Error: Unknown RIP-Relative (%.2x %.2x)", decode.opcode, decode.opcode2);
81 | continue;
82 | }
83 | } else
84 | #endif
85 |
86 | if (backup[offset] == 0xe8) {
87 | int32_t relative(*reinterpret_cast(backup + offset + 1));
88 | void *destiny(area + offset + decode.len + relative);
89 |
90 | if (relative == 0) {
91 | length -= decode.len;
92 | length += MSSizeOfPushPointer(destiny);
93 | } else {
94 | length += MSSizeOfSkip();
95 | length += MSSizeOfJump(destiny);
96 | }
97 | } else if (backup[offset] == 0xeb) {
98 | length -= decode.len;
99 | length += MSSizeOfJump(area + offset + decode.len + *reinterpret_cast(backup + offset + 1));
100 | } else if (backup[offset] == 0xe9) {
101 | length -= decode.len;
102 | length += MSSizeOfJump(area + offset + decode.len + *reinterpret_cast(backup + offset + 1));
103 | } else if (
104 | backup[offset] == 0xe3 ||
105 | (backup[offset] & 0xf0) == 0x70
106 | // XXX: opcode2 & 0xf0 is 0x80?
107 | ) {
108 | length += decode.len;
109 | length += MSSizeOfJump(area + offset + decode.len + *reinterpret_cast(backup + offset + 1));
110 | }
111 | }
112 |
113 | uint8_t *buffer(reinterpret_cast(mmap(
114 | NULL, length, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0
115 | )));
116 |
117 | if (buffer == MAP_FAILED) {
118 | MSLog(MSLogLevelError, "MS:Error:mmap() = %d", errno);
119 | *result = NULL;
120 | return;
121 | }
122 |
123 | if (false) fail: {
124 | munmap(buffer, length);
125 | *result = NULL;
126 | return;
127 | }
128 |
129 | {
130 | uint8_t *current(buffer);
131 |
132 | for (size_t offset(0), width; offset != used; offset += width) {
133 | hde64s decode;
134 | hde64_disasm(backup + offset, &decode);
135 | width = decode.len;
136 | //_assert(width != 0 && offset + width <= used);
137 |
138 | #ifdef __LP64__
139 | if ((decode.modrm & 0xc7) == 0x05) {
140 | if (decode.opcode == 0x8b) {
141 | void *destiny(area + offset + width + int32_t(decode.disp.disp32));
142 | uint8_t reg(decode.rex_r << 3 | decode.modrm_reg);
143 | MSPushPointer(current, destiny);
144 | MSWritePop(current, reg);
145 | MSWriteMove64(current, reg, reg);
146 | } else {
147 | MSLog(MSLogLevelError, "MS:Error: Unknown RIP-Relative (%.2x %.2x)", decode.opcode, decode.opcode2);
148 | goto copy;
149 | }
150 | } else
151 | #endif
152 |
153 | if (backup[offset] == 0xe8) {
154 | int32_t relative(*reinterpret_cast(backup + offset + 1));
155 | if (relative == 0)
156 | MSPushPointer(current, area + offset + decode.len);
157 | else {
158 | MSWrite(current, 0xe8);
159 | MSWrite(current, MSSizeOfSkip());
160 | void *destiny(area + offset + decode.len + relative);
161 | MSWriteSkip(current, MSSizeOfJump(destiny, current + MSSizeOfSkip()));
162 | MSWriteJump(current, destiny);
163 | }
164 | } else if (backup[offset] == 0xeb)
165 | MSWriteJump(current, area + offset + decode.len + *reinterpret_cast(backup + offset + 1));
166 | else if (backup[offset] == 0xe9)
167 | MSWriteJump(current, area + offset + decode.len + *reinterpret_cast(backup + offset + 1));
168 | else if (
169 | backup[offset] == 0xe3 ||
170 | (backup[offset] & 0xf0) == 0x70
171 | ) {
172 | MSWrite(current, backup[offset]);
173 | MSWrite(current, 2);
174 | MSWrite(current, 0xeb);
175 | void *destiny(area + offset + decode.len + *reinterpret_cast(backup + offset + 1));
176 | MSWrite(current, MSSizeOfJump(destiny, current + 1));
177 | MSWriteJump(current, destiny);
178 | } else
179 | #ifdef __LP64__
180 | copy:
181 | #endif
182 | {
183 | MSWrite(current, backup + offset, width);
184 | }
185 | }
186 |
187 | MSWriteJump(current, area + used);
188 | }
189 |
190 | if (mprotect(buffer, length, PROT_READ | PROT_EXEC) == -1) {
191 | MSLog(MSLogLevelError, "MS:Error:mprotect():%d", errno);
192 | goto fail;
193 | }
194 |
195 | *result = buffer;
196 |
197 | if (MSDebug) {
198 | char name[16];
199 | sprintf(name, "%p", *result);
200 | MSLogHex(buffer, length, name);
201 | }
202 |
203 | }
204 |
205 | {
206 | SubstrateHookMemory code(process, area, used);
207 |
208 | uint8_t *current(area);
209 | MSWriteJump(current, target);
210 | for (unsigned offset(0); offset != blank; ++offset)
211 | MSWrite(current, 0x90);
212 | }
213 |
214 | if (MSDebug) {
215 | char name[16];
216 | sprintf(name, "%p", area);
217 | MSLogHex(area, used + sizeof(uint16_t), name);
218 | }
219 | }
220 |
221 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/DexProto.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Functions for dealing with method prototypes
19 | */
20 |
21 | #ifndef LIBDEX_DEXPROTO_H_
22 | #define LIBDEX_DEXPROTO_H_
23 |
24 | #include "DexFile.h"
25 | #include "Common.h"
26 |
27 | /*
28 | * Single-thread single-string cache. This structure holds a pointer to
29 | * a string which is semi-automatically manipulated by some of the
30 | * method prototype functions. Functions which use in this struct
31 | * generally return a string that is valid until the next
32 | * time the same DexStringCache is used.
33 | */
34 | struct DexStringCache {
35 | char* value; /* the latest value */
36 | size_t allocatedSize; /* size of the allocated buffer, if allocated */
37 | char buffer[120]; /* buffer used to hold small-enough results */
38 | };
39 |
40 | /*
41 | * Make sure that the given cache can hold a string of the given length,
42 | * including the final '\0' byte.
43 | */
44 | void dexStringCacheAlloc(DexStringCache* pCache, size_t length);
45 |
46 | /*
47 | * Initialize the given DexStringCache. Use this function before passing
48 | * one into any other function.
49 | */
50 | void dexStringCacheInit(DexStringCache* pCache);
51 |
52 | /*
53 | * Release the allocated contents of the given DexStringCache, if any.
54 | * Use this function after your last use of a DexStringCache.
55 | */
56 | void dexStringCacheRelease(DexStringCache* pCache);
57 |
58 | /*
59 | * If the given DexStringCache doesn't already point at the given value,
60 | * make a copy of it into the cache. This always returns a writable
61 | * pointer to the contents (whether or not a copy had to be made). This
62 | * function is intended to be used after making a call that at least
63 | * sometimes doesn't populate a DexStringCache.
64 | */
65 | char* dexStringCacheEnsureCopy(DexStringCache* pCache, const char* value);
66 |
67 | /*
68 | * Abandon the given DexStringCache, and return a writable copy of the
69 | * given value (reusing the string cache's allocation if possible).
70 | * The return value must be free()d by the caller. Use this instead of
71 | * dexStringCacheRelease() if you want the buffer to survive past the
72 | * scope of the DexStringCache.
73 | */
74 | char* dexStringCacheAbandon(DexStringCache* pCache, const char* value);
75 |
76 | /*
77 | * Method prototype structure, which refers to a protoIdx in a
78 | * particular DexFile.
79 | */
80 | struct DexProto {
81 | const DexFile* dexFile; /* file the idx refers to */
82 | u4 protoIdx; /* index into proto_ids table of dexFile */
83 | };
84 |
85 | /*
86 | * Set the given DexProto to refer to the prototype of the given MethodId.
87 | */
88 | DEX_INLINE void dexProtoSetFromMethodId(DexProto* pProto,
89 | const DexFile* pDexFile, const DexMethodId* pMethodId)
90 | {
91 | pProto->dexFile = pDexFile;
92 | pProto->protoIdx = pMethodId->protoIdx;
93 | }
94 |
95 | /*
96 | * Get the short-form method descriptor for the given prototype. The
97 | * prototype must be protoIdx-based.
98 | */
99 | const char* dexProtoGetShorty(const DexProto* pProto);
100 |
101 | /*
102 | * Get the full method descriptor for the given prototype.
103 | */
104 | const char* dexProtoGetMethodDescriptor(const DexProto* pProto,
105 | DexStringCache* pCache);
106 |
107 | /*
108 | * Get a copy of the descriptor string associated with the given prototype.
109 | * The returned pointer must be free()ed by the caller.
110 | */
111 | char* dexProtoCopyMethodDescriptor(const DexProto* pProto);
112 |
113 | /*
114 | * Get the parameter descriptors for the given prototype. This is the
115 | * concatenation of all the descriptors for all the parameters, in
116 | * order, with no other adornment.
117 | */
118 | const char* dexProtoGetParameterDescriptors(const DexProto* pProto,
119 | DexStringCache* pCache);
120 |
121 | /*
122 | * Return the utf-8 encoded descriptor string from the proto of a MethodId.
123 | */
124 | DEX_INLINE const char* dexGetDescriptorFromMethodId(const DexFile* pDexFile,
125 | const DexMethodId* pMethodId, DexStringCache* pCache)
126 | {
127 | DexProto proto;
128 |
129 | dexProtoSetFromMethodId(&proto, pDexFile, pMethodId);
130 | return dexProtoGetMethodDescriptor(&proto, pCache);
131 | }
132 |
133 | /*
134 | * Get a copy of the utf-8 encoded method descriptor string from the
135 | * proto of a MethodId. The returned pointer must be free()ed by the
136 | * caller.
137 | */
138 | DEX_INLINE char* dexCopyDescriptorFromMethodId(const DexFile* pDexFile,
139 | const DexMethodId* pMethodId)
140 | {
141 | DexProto proto;
142 |
143 | dexProtoSetFromMethodId(&proto, pDexFile, pMethodId);
144 | return dexProtoCopyMethodDescriptor(&proto);
145 | }
146 |
147 | /*
148 | * Get the type descriptor for the return type of the given prototype.
149 | */
150 | const char* dexProtoGetReturnType(const DexProto* pProto);
151 |
152 | /*
153 | * Get the parameter count of the given prototype.
154 | */
155 | size_t dexProtoGetParameterCount(const DexProto* pProto);
156 |
157 | /*
158 | * Compute the number of parameter words (u4 units) required by the
159 | * given prototype. For example, if the method takes (int, long) and
160 | * returns double, this would return 3 (one for the int, two for the
161 | * long, and the return type isn't relevant).
162 | */
163 | int dexProtoComputeArgsSize(const DexProto* pProto);
164 |
165 | /*
166 | * Compare the two prototypes. The two prototypes are compared
167 | * with the return type as the major order, then the first arguments,
168 | * then second, etc. If two prototypes are identical except that one
169 | * has extra arguments, then the shorter argument is considered the
170 | * earlier one in sort order (similar to strcmp()).
171 | */
172 | int dexProtoCompare(const DexProto* pProto1, const DexProto* pProto2);
173 |
174 | /*
175 | * Compare the two prototypes, ignoring return type. The two
176 | * prototypes are compared with the first argument as the major order,
177 | * then second, etc. If two prototypes are identical except that one
178 | * has extra arguments, then the shorter argument is considered the
179 | * earlier one in sort order (similar to strcmp()).
180 | */
181 | int dexProtoCompareParameters(const DexProto* pProto1,
182 | const DexProto* pProto2);
183 |
184 | /*
185 | * Compare a prototype and a string method descriptor. The comparison
186 | * is done as if the descriptor were converted to a prototype and compared
187 | * with dexProtoCompare().
188 | */
189 | int dexProtoCompareToDescriptor(const DexProto* proto, const char* descriptor);
190 |
191 | /*
192 | * Compare a prototype and a concatenation of type descriptors. The
193 | * comparison is done as if the descriptors were converted to a
194 | * prototype and compared with dexProtoCompareParameters().
195 | */
196 | int dexProtoCompareToParameterDescriptors(const DexProto* proto,
197 | const char* descriptors);
198 |
199 | /*
200 | * Single-thread prototype parameter iterator. This structure holds a
201 | * pointer to a prototype and its parts, along with a cursor.
202 | */
203 | struct DexParameterIterator {
204 | const DexProto* proto;
205 | const DexTypeList* parameters;
206 | int parameterCount;
207 | int cursor;
208 | };
209 |
210 | /*
211 | * Initialize the given DexParameterIterator to be at the start of the
212 | * parameters of the given prototype.
213 | */
214 | void dexParameterIteratorInit(DexParameterIterator* pIterator,
215 | const DexProto* pProto);
216 |
217 | /*
218 | * Get the type_id index for the next parameter, if any. This returns
219 | * kDexNoIndex if the last parameter has already been consumed.
220 | */
221 | u4 dexParameterIteratorNextIndex(DexParameterIterator* pIterator);
222 |
223 | /*
224 | * Get the type descriptor for the next parameter, if any. This returns
225 | * NULL if the last parameter has already been consumed.
226 | */
227 | const char* dexParameterIteratorNextDescriptor(
228 | DexParameterIterator* pIterator);
229 |
230 | #endif // LIBDEX_DEXPROTO_H_
231 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/Android-Inline/inlineHook.c:
--------------------------------------------------------------------------------
1 | /*
2 | thumb16 thumb32 arm32 inlineHook
3 | author: ele7enxxh
4 | mail: ele7enxxh@qq.com
5 | website: ele7enxxh.com
6 | modified time: 2015-01-23
7 | created time: 2015-11-30
8 | */
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | // #include
17 | #include
18 | #include
19 |
20 | #include "relocate.h"
21 | #include "include/inlineHook.h"
22 |
23 | #ifndef PAGE_SIZE
24 | #define PAGE_SIZE 4096
25 | #endif
26 |
27 | #define PAGE_START(addr) (~(PAGE_SIZE - 1) & (addr))
28 | #define SET_BIT0(addr) (addr | 1)
29 | #define CLEAR_BIT0(addr) (addr & 0xFFFFFFFE)
30 | #define TEST_BIT0(addr) (addr & 1)
31 |
32 | #define ACTION_ENABLE 0
33 | #define ACTION_DISABLE 1
34 |
35 | enum hook_status {
36 | REGISTERED,
37 | HOOKED,
38 | };
39 |
40 | struct inlineHookItem {
41 | uint32_t target_addr;
42 | uint32_t new_addr;
43 | uint32_t **proto_addr;
44 | void *orig_instructions;
45 | int orig_boundaries[4];
46 | int trampoline_boundaries[20];
47 | int count;
48 | void *trampoline_instructions;
49 | int length;
50 | int status;
51 | int mode;
52 | };
53 |
54 | struct inlineHookInfo {
55 | struct inlineHookItem item[1024];
56 | int size;
57 | };
58 |
59 | static struct inlineHookInfo info = {0};
60 |
61 | static int getAllTids(pid_t pid, pid_t *tids)
62 | {
63 | char dir_path[32];
64 | DIR *dir;
65 | int i;
66 | struct dirent *entry;
67 | pid_t tid;
68 |
69 | if (pid < 0) {
70 | snprintf(dir_path, sizeof(dir_path), "/proc/self/task");
71 | }
72 | else {
73 | snprintf(dir_path, sizeof(dir_path), "/proc/%d/task", pid);
74 | }
75 |
76 | dir = opendir(dir_path);
77 | if (dir == NULL) {
78 | return 0;
79 | }
80 |
81 | i = 0;
82 | while((entry = readdir(dir)) != NULL) {
83 | tid = atoi(entry->d_name);
84 | if (tid != 0 && tid != getpid()) {
85 | tids[i++] = tid;
86 | }
87 | }
88 | closedir(dir);
89 | return i;
90 | }
91 |
92 | static bool doProcessThreadPC(struct inlineHookItem *item, struct pt_regs *regs, int action)
93 | {
94 | int offset;
95 | int i;
96 |
97 | switch (action)
98 | {
99 | case ACTION_ENABLE:
100 | offset = regs->ARM_pc - CLEAR_BIT0(item->target_addr);
101 | for (i = 0; i < item->count; ++i) {
102 | if (offset == item->orig_boundaries[i]) {
103 | regs->ARM_pc = (uint32_t) item->trampoline_instructions + item->trampoline_boundaries[i];
104 | return true;
105 | }
106 | }
107 | break;
108 | case ACTION_DISABLE:
109 | offset = regs->ARM_pc - (int) item->trampoline_instructions;
110 | for (i = 0; i < item->count; ++i) {
111 | if (offset == item->trampoline_boundaries[i]) {
112 | regs->ARM_pc = CLEAR_BIT0(item->target_addr) + item->orig_boundaries[i];
113 | return true;
114 | }
115 | }
116 | break;
117 | }
118 |
119 | return false;
120 | }
121 |
122 | static void processThreadPC(pid_t tid, struct inlineHookItem *item, int action)
123 | {
124 | struct pt_regs regs;
125 |
126 | if (ptrace(PTRACE_GETREGS, tid, NULL, ®s) == 0) {
127 | if (item == NULL) {
128 | int pos;
129 |
130 | for (pos = 0; pos < info.size; ++pos) {
131 | if (doProcessThreadPC(&info.item[pos], ®s, action) == true) {
132 | break;
133 | }
134 | }
135 | }
136 | else {
137 | doProcessThreadPC(item, ®s, action);
138 | }
139 |
140 | ptrace(PTRACE_SETREGS, tid, NULL, ®s);
141 | }
142 | }
143 |
144 | static pid_t freeze(struct inlineHookItem *item, int action)
145 | {
146 | int count;
147 | pid_t tids[1024];
148 | pid_t pid;
149 |
150 | pid = -1;
151 | count = getAllTids(getpid(), tids);
152 | if (count > 0) {
153 | pid = fork();
154 |
155 | if (pid == 0) {
156 | int i;
157 |
158 | for (i = 0; i < count; ++i) {
159 | if (ptrace(PTRACE_ATTACH, tids[i], NULL, NULL) == 0) {
160 | waitpid(tids[i], NULL, WUNTRACED);
161 | processThreadPC(tids[i], item, action);
162 | }
163 | }
164 |
165 | raise(SIGSTOP);
166 |
167 | for (i = 0; i < count; ++i) {
168 | ptrace(PTRACE_DETACH, tids[i], NULL, NULL);
169 | }
170 |
171 | raise(SIGKILL);
172 | }
173 |
174 | else if (pid > 0) {
175 | waitpid(pid, NULL, WUNTRACED);
176 | }
177 | }
178 |
179 | return pid;
180 | }
181 |
182 | static void unFreeze(pid_t pid)
183 | {
184 | if (pid < 0) {
185 | return;
186 | }
187 |
188 | kill(pid, SIGCONT);
189 | wait(NULL);
190 | }
191 |
192 | static bool isExecutableAddr(uint32_t addr)
193 | {
194 | FILE *fp;
195 | char line[1024];
196 | uint32_t start;
197 | uint32_t end;
198 |
199 | fp = fopen("/proc/self/maps", "r");
200 | if (fp == NULL) {
201 | return false;
202 | }
203 |
204 | while (fgets(line, sizeof(line), fp)) {
205 | if (strstr(line, "r-xp") || strstr(line, "rwxp")) {
206 | start = strtoul(strtok(line, "-"), NULL, 16);
207 | end = strtoul(strtok(NULL, " "), NULL, 16);
208 | if (addr >= start && addr <= end) {
209 | fclose(fp);
210 | return true;
211 | }
212 | }
213 | }
214 |
215 | fclose(fp);
216 |
217 | return false;
218 | }
219 |
220 | static struct inlineHookItem *findInlineHookItem(uint32_t target_addr)
221 | {
222 | int i;
223 |
224 | for (i = 0; i < info.size; ++i) {
225 | if (info.item[i].target_addr == target_addr) {
226 | return &info.item[i];
227 | }
228 | }
229 |
230 | return NULL;
231 | }
232 |
233 | static struct inlineHookItem *addInlineHookItem() {
234 | struct inlineHookItem *item;
235 |
236 | if (info.size >= 1024) {
237 | return NULL;
238 | }
239 |
240 | item = &info.item[info.size];
241 | ++info.size;
242 |
243 | return item;
244 | }
245 |
246 | static void deleteInlineHookItem(int pos)
247 | {
248 | info.item[pos] = info.item[info.size - 1];
249 | --info.size;
250 | }
251 |
252 | enum ele7en_status registerInlineHook(uint32_t target_addr, uint32_t new_addr, uint32_t **proto_addr)
253 | {
254 | struct inlineHookItem *item;
255 |
256 | if (!isExecutableAddr(target_addr) || !isExecutableAddr(new_addr)) {
257 | return ELE7EN_ERROR_NOT_EXECUTABLE;
258 | }
259 |
260 | item = findInlineHookItem(target_addr);
261 | if (item != NULL) {
262 | if (item->status == REGISTERED) {
263 | return ELE7EN_ERROR_ALREADY_REGISTERED;
264 | }
265 | else if (item->status == HOOKED) {
266 | return ELE7EN_ERROR_ALREADY_HOOKED;
267 | }
268 | else {
269 | return ELE7EN_ERROR_UNKNOWN;
270 | }
271 | }
272 |
273 | item = addInlineHookItem();
274 |
275 | item->target_addr = target_addr;
276 | item->new_addr = new_addr;
277 | item->proto_addr = proto_addr;
278 |
279 | item->length = TEST_BIT0(item->target_addr) ? 12 : 8;
280 | item->orig_instructions = malloc(item->length);
281 | memcpy(item->orig_instructions, (void *) CLEAR_BIT0(item->target_addr), item->length);
282 |
283 | item->trampoline_instructions = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
284 | relocateInstruction(item->target_addr, item->orig_instructions, item->length, item->trampoline_instructions, item->orig_boundaries, item->trampoline_boundaries, &item->count);
285 |
286 | item->status = REGISTERED;
287 |
288 | return ELE7EN_OK;
289 | }
290 |
291 | static void doInlineUnHook(struct inlineHookItem *item, int pos)
292 | {
293 | mprotect((void *) PAGE_START(CLEAR_BIT0(item->target_addr)), PAGE_SIZE * 2, PROT_READ | PROT_WRITE | PROT_EXEC);
294 | memcpy((void *) CLEAR_BIT0(item->target_addr), item->orig_instructions, item->length);
295 | mprotect((void *) PAGE_START(CLEAR_BIT0(item->target_addr)), PAGE_SIZE * 2, PROT_READ | PROT_EXEC);
296 | munmap(item->trampoline_instructions, PAGE_SIZE);
297 | free(item->orig_instructions);
298 |
299 | deleteInlineHookItem(pos);
300 |
301 | cacheflush(CLEAR_BIT0(item->target_addr), CLEAR_BIT0(item->target_addr) + item->length, 0);
302 | }
303 |
304 | enum ele7en_status inlineUnHook(uint32_t target_addr)
305 | {
306 | int i;
307 |
308 | for (i = 0; i < info.size; ++i) {
309 | if (info.item[i].target_addr == target_addr && info.item[i].status == HOOKED) {
310 | pid_t pid;
311 |
312 | pid = freeze(&info.item[i], ACTION_DISABLE);
313 |
314 | doInlineUnHook(&info.item[i], i);
315 |
316 | unFreeze(pid);
317 |
318 | return ELE7EN_OK;
319 | }
320 | }
321 |
322 | return ELE7EN_ERROR_NOT_HOOKED;
323 | }
324 |
325 | void inlineUnHookAll()
326 | {
327 | pid_t pid;
328 | int i;
329 |
330 | pid = freeze(NULL, ACTION_DISABLE);
331 |
332 | for (i = 0; i < info.size; ++i) {
333 | if (info.item[i].status == HOOKED) {
334 | doInlineUnHook(&info.item[i], i);
335 | --i;
336 | }
337 | }
338 |
339 | unFreeze(pid);
340 | }
341 |
342 | static void doInlineHook(struct inlineHookItem *item)
343 | {
344 | mprotect((void *) PAGE_START(CLEAR_BIT0(item->target_addr)), PAGE_SIZE * 2, PROT_READ | PROT_WRITE | PROT_EXEC);
345 |
346 | if (item->proto_addr != NULL) {
347 | *(item->proto_addr) = TEST_BIT0(item->target_addr) ? (uint32_t *) SET_BIT0((uint32_t) item->trampoline_instructions) : item->trampoline_instructions;
348 | }
349 |
350 | if (TEST_BIT0(item->target_addr)) {
351 | int i;
352 |
353 | i = 0;
354 | if (CLEAR_BIT0(item->target_addr) % 4 != 0) {
355 | ((uint16_t *) CLEAR_BIT0(item->target_addr))[i++] = 0xBF00; // NOP
356 | }
357 | ((uint16_t *) CLEAR_BIT0(item->target_addr))[i++] = 0xF8DF;
358 | ((uint16_t *) CLEAR_BIT0(item->target_addr))[i++] = 0xF000; // LDR.W PC, [PC]
359 | ((uint16_t *) CLEAR_BIT0(item->target_addr))[i++] = item->new_addr & 0xFFFF;
360 | ((uint16_t *) CLEAR_BIT0(item->target_addr))[i++] = item->new_addr >> 16;
361 | }
362 | else {
363 | ((uint32_t *) (item->target_addr))[0] = 0xe51ff004; // LDR PC, [PC, #-4]
364 | ((uint32_t *) (item->target_addr))[1] = item->new_addr;
365 | }
366 |
367 | mprotect((void *) PAGE_START(CLEAR_BIT0(item->target_addr)), PAGE_SIZE * 2, PROT_READ | PROT_EXEC);
368 |
369 | item->status = HOOKED;
370 |
371 | cacheflush(CLEAR_BIT0(item->target_addr), CLEAR_BIT0(item->target_addr) + item->length, 0);
372 | }
373 |
374 | enum ele7en_status inlineHook(uint32_t target_addr)
375 | {
376 | int i;
377 | struct inlineHookItem *item;
378 |
379 | item = NULL;
380 | for (i = 0; i < info.size; ++i) {
381 | if (info.item[i].target_addr == target_addr) {
382 | item = &info.item[i];
383 | break;
384 | }
385 | }
386 |
387 | if (item == NULL) {
388 | return ELE7EN_ERROR_NOT_REGISTERED;
389 | }
390 |
391 | if (item->status == REGISTERED) {
392 | pid_t pid;
393 |
394 | pid = freeze(item, ACTION_ENABLE);
395 |
396 | doInlineHook(item);
397 |
398 | unFreeze(pid);
399 |
400 | return ELE7EN_OK;
401 | }
402 | else if (item->status == HOOKED) {
403 | return ELE7EN_ERROR_ALREADY_HOOKED;
404 | }
405 | else {
406 | return ELE7EN_ERROR_UNKNOWN;
407 | }
408 | }
409 |
410 | void inlineHookAll()
411 | {
412 | pid_t pid;
413 | int i;
414 |
415 | pid = freeze(NULL, ACTION_ENABLE);
416 |
417 | for (i = 0; i < info.size; ++i) {
418 | if (info.item[i].status == REGISTERED) {
419 | doInlineHook(&info.item[i]);
420 | }
421 | }
422 |
423 | unFreeze(pid);
424 | }
425 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/util.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | //#include
7 | #include
8 | #include "Hooker.h"
9 | //#include "../common.h"
10 |
11 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,"wodelog", __VA_ARGS__)
12 | /* memory map for libraries */
13 | #define MAX_NAME_LEN 256
14 | #define MEMORY_ONLY "[memory]"
15 | struct mm {
16 | char name[MAX_NAME_LEN];
17 | unsigned long start, end;
18 | };
19 |
20 | typedef struct symtab *symtab_t;
21 | struct symlist {
22 | Elf32_Sym *sym; /* symbols */
23 | char *str; /* symbol strings */
24 | unsigned num; /* number of symbols */
25 | };
26 | struct symtab {
27 | struct symlist *st; /* "static" symbols */
28 | struct symlist *dyn; /* dynamic symbols */
29 | };
30 |
31 | static void* xmalloc(size_t size) {
32 | void *p;
33 | p = malloc(size);
34 | if (!p) {
35 | printf("Out of memory\n");
36 | exit(1);
37 | }
38 | return p;
39 | }
40 |
41 | static int my_pread(int fd, void *buf, size_t count, off_t offset) {
42 | lseek(fd, offset, SEEK_SET);
43 | return read(fd, buf, count);
44 | }
45 |
46 | static struct symlist* get_syms(int fd, Elf32_Shdr *symh, Elf32_Shdr *strh) {
47 | struct symlist *sl, *ret;
48 | int rv;
49 |
50 | ret = NULL;
51 | sl = (struct symlist *) xmalloc(sizeof(struct symlist));
52 | sl->str = NULL;
53 | sl->sym = NULL;
54 |
55 | /* sanity */
56 | if (symh->sh_size % sizeof(Elf32_Sym)) {
57 | //printf("elf_error\n");
58 | goto out;
59 | }
60 |
61 | /* symbol table */
62 | sl->num = symh->sh_size / sizeof(Elf32_Sym);
63 | sl->sym = (Elf32_Sym *) xmalloc(symh->sh_size);
64 | rv = my_pread(fd, sl->sym, symh->sh_size, symh->sh_offset);
65 | if (0 > rv) {
66 | //perror("read");
67 | goto out;
68 | }
69 | if (rv != symh->sh_size) {
70 | //printf("elf error\n");
71 | goto out;
72 | }
73 |
74 | /* string table */
75 | sl->str = (char *) xmalloc(strh->sh_size);
76 | rv = my_pread(fd, sl->str, strh->sh_size, strh->sh_offset);
77 | if (0 > rv) {
78 | //perror("read");
79 | goto out;
80 | }
81 | if (rv != strh->sh_size) {
82 | //printf("elf error");
83 | goto out;
84 | }
85 |
86 | ret = sl;
87 | out: return ret;
88 | }
89 |
90 | static int do_load(int fd, symtab_t symtab) {
91 | int rv;
92 | size_t size;
93 | Elf32_Ehdr ehdr;
94 | Elf32_Shdr *shdr = NULL, *p;
95 | Elf32_Shdr *dynsymh, *dynstrh;
96 | Elf32_Shdr *symh, *strh;
97 | char *shstrtab = NULL;
98 | int i;
99 | int ret = -1;
100 |
101 | /* elf header */
102 | rv = read(fd, &ehdr, sizeof(ehdr));
103 | if (0 > rv) {
104 | LOGD("read\n");
105 | goto out;
106 | }
107 | if (rv != sizeof(ehdr)) {
108 | LOGD("elf error 1\n");
109 | goto out;
110 | }
111 | if (strncmp((const char *) ELFMAG, (const char *) ehdr.e_ident, SELFMAG)) { /* sanity */
112 | LOGD("not an elf\n");
113 | goto out;
114 | }
115 | if (sizeof(Elf32_Shdr) != ehdr.e_shentsize) { /* sanity */
116 | LOGD("elf error 2\n");
117 | goto out;
118 | }
119 |
120 | /* section header table */
121 | size = ehdr.e_shentsize * ehdr.e_shnum;
122 | shdr = (Elf32_Shdr *) xmalloc(size);
123 | rv = my_pread(fd, shdr, size, ehdr.e_shoff);
124 | if (0 > rv) {
125 | LOGD("read\n");
126 | goto out;
127 | }
128 | if (rv != size) {
129 | LOGD("elf error 3 %d %d\n", rv, size);
130 | goto out;
131 | }
132 |
133 | /* section header string table */
134 | size = shdr[ehdr.e_shstrndx].sh_size;
135 | shstrtab = (char *) xmalloc(size);
136 | rv = my_pread(fd, shstrtab, size, shdr[ehdr.e_shstrndx].sh_offset);
137 | if (0 > rv) {
138 | LOGD("read\n");
139 | goto out;
140 | }
141 | if (rv != size) {
142 | LOGD("elf error 4 %d %d\n", rv, size);
143 | goto out;
144 | }
145 |
146 | /* symbol table headers */
147 | symh = dynsymh = NULL;
148 | strh = dynstrh = NULL;
149 | for (i = 0, p = shdr; i < ehdr.e_shnum; i++, p++)
150 | if (SHT_SYMTAB == p->sh_type) {
151 | if (symh) {
152 | LOGD("too many symbol tables\n");
153 | goto out;
154 | }
155 | symh = p;
156 | } else if (SHT_DYNSYM == p->sh_type) {
157 | if (dynsymh) {
158 | LOGD("too many symbol tables\n");
159 | goto out;
160 | }
161 | dynsymh = p;
162 | } else if (SHT_STRTAB == p->sh_type
163 | && !strncmp(shstrtab + p->sh_name, ".strtab", 7)) {
164 | if (strh) {
165 | LOGD("too many string tables\n");
166 | goto out;
167 | }
168 | strh = p;
169 | } else if (SHT_STRTAB == p->sh_type
170 | && !strncmp(shstrtab + p->sh_name, ".dynstr", 7)) {
171 | if (dynstrh) {
172 | LOGD("too many string tables\n");
173 | goto out;
174 | }
175 | dynstrh = p;
176 | }
177 | /* sanity checks */
178 | if ((!dynsymh && dynstrh) || (dynsymh && !dynstrh)) {
179 | LOGD("bad dynamic symbol table\n");
180 | goto out;
181 | }
182 | if ((!symh && strh) || (symh && !strh)) {
183 | LOGD("bad symbol table\n");
184 | goto out;
185 | }
186 | if (!dynsymh && !symh) {
187 | LOGD("no symbol table\n");
188 | goto out;
189 | }
190 |
191 | /* symbol tables */
192 | if (dynsymh)
193 | symtab->dyn = get_syms(fd, dynsymh, dynstrh);
194 | if (symh)
195 | symtab->st = get_syms(fd, symh, strh);
196 | ret = 0;
197 | out: free(shstrtab);
198 | free(shdr);
199 | return ret;
200 | }
201 |
202 | static symtab_t load_symtab(char *filename) {
203 | int fd;
204 | symtab_t symtab;
205 |
206 | symtab = (symtab_t) xmalloc(sizeof(*symtab));
207 | memset(symtab, 0, sizeof(*symtab));
208 |
209 | fd = open(filename, O_RDONLY);
210 | if (0 > fd) {
211 | LOGD("%s open\n", __func__);
212 | return NULL;
213 | }
214 | if (0 > do_load(fd, symtab)) {
215 | LOGD("Error ELF parsing %s\n", filename);
216 | free(symtab);
217 | symtab = NULL;
218 | }
219 | close(fd);
220 | return symtab;
221 | }
222 |
223 | static int load_memmap(pid_t pid, struct mm *mm, int *nmmp) {
224 | size_t buf_size = 0x40000;
225 | char *p_buf = (char *) malloc(buf_size); // increase this if needed for larger "maps"
226 | char name[MAX_NAME_LEN] = { 0 };
227 | char *p;
228 | unsigned long start, end;
229 | struct mm *m;
230 | int nmm = 0;
231 | int fd, rv;
232 | int i;
233 |
234 | sprintf(p_buf, "/proc/%d/maps", pid);
235 | fd = open(p_buf, O_RDONLY);
236 | if (0 > fd) {
237 | LOGD("Can't open %s for reading\n", p_buf);
238 | free(p_buf);
239 | return -1;
240 | }
241 |
242 | /* Zero to ensure data is null terminated */
243 | memset(p_buf, 0, buf_size);
244 |
245 | p = p_buf;
246 | while (1) {
247 | rv = read(fd, p, buf_size - (p - p_buf));
248 | if (0 > rv) {
249 | LOGD("%s read", __FUNCTION__);
250 | free(p_buf);
251 | return -1;
252 | }
253 | if (0 == rv)
254 | break;
255 | p += rv;
256 | if (p - p_buf >= buf_size) {
257 | LOGD("Too many memory mapping\n");
258 | free(p_buf);
259 | return -1;
260 | }
261 | }
262 | close(fd);
263 |
264 | p = strtok(p_buf, "\n");
265 | m = mm;
266 | while (p) {
267 | /* parse current map line */
268 | rv = sscanf(p, "%08lx-%08lx %*s %*s %*s %*s %s\n", &start, &end, name);
269 |
270 | p = strtok(NULL, "\n");
271 |
272 | if (rv == 2) {
273 | m = &mm[nmm++];
274 | m->start = start;
275 | m->end = end;
276 | memcpy(m->name, MEMORY_ONLY, sizeof(MEMORY_ONLY));
277 | continue;
278 | }
279 |
280 | /* search backward for other mapping with same name */
281 | for (i = nmm - 1; i >= 0; i--) {
282 | m = &mm[i];
283 | if (!strcmp(m->name, name))
284 | break;
285 | }
286 |
287 | if (i >= 0) {
288 | if (start < m->start)
289 | m->start = start;
290 | if (end > m->end)
291 | m->end = end;
292 | } else {
293 | /* new entry */
294 | m = &mm[nmm++];
295 | m->start = start;
296 | m->end = end;
297 | memcpy(m->name, name, strlen(name));
298 | }
299 | }
300 |
301 | *nmmp = nmm;
302 | free(p_buf);
303 | return 0;
304 | }
305 |
306 | /* Find libc in MM, storing no more than LEN-1 chars of
307 | its name in NAME and set START to its starting
308 | address. If libc cannot be found return -1 and
309 | leave NAME and START untouched. Otherwise return 0
310 | and null-terminated NAME. */
311 | static int find_libname(const char *libn, char *name, int len, unsigned long *start,
312 | struct mm *mm, int nmm) {
313 | int i;
314 | struct mm *m;
315 | char *p;
316 | for (i = 0, m = mm; i < nmm; i++, m++) {
317 |
318 | if (!strcmp(m->name, MEMORY_ONLY))
319 | continue;
320 | p = strrchr(m->name, '/');
321 | if (!p)
322 | continue;
323 | p++;
324 | // LOGD("m->name:%s",m->name);
325 | if (strncmp(libn, p, strlen(libn)))
326 | continue;
327 | p += strlen(libn);
328 |
329 | /* here comes our crude test -> 'libc.so' or 'libc-[0-9]' */
330 | if (!strncmp("so", p, 2) || 1) // || (p[0] == '-' && isdigit(p[1])))
331 | break;
332 | }
333 | if (i >= nmm)
334 | /* not found */
335 | return -1;
336 |
337 | *start = m->start;
338 | strncpy(name, m->name, len);
339 | if (strlen(m->name) >= len)
340 | name[len - 1] = '\0';
341 |
342 | mprotect((void*) m->start, m->end - m->start,
343 | PROT_READ | PROT_WRITE | PROT_EXEC);
344 | return 0;
345 | }
346 |
347 | static int lookup2(struct symlist *sl, unsigned char type, char *name,
348 | unsigned long *val) {
349 | Elf32_Sym *p;
350 | int len;
351 | int i;
352 |
353 | len = strlen(name);
354 | for (i = 0, p = sl->sym; i < sl->num; i++, p++) {
355 | //LOGD("name: %s %x\n", sl->str+p->st_name, p->st_value)
356 | if (!strncmp(sl->str + p->st_name, name, len)
357 | && *(sl->str + p->st_name + len) == 0
358 | && ELF32_ST_TYPE(p->st_info) == type) {
359 | //if (p->st_value != 0) {
360 | *val = p->st_value;
361 | return 0;
362 | //}
363 | }
364 | }
365 | return -1;
366 | }
367 |
368 | static int lookup_sym(symtab_t s, unsigned char type, char *name,
369 | unsigned long *val) {
370 | if (s->dyn && !lookup2(s->dyn, type, name, val))
371 | return 0;
372 | if (s->st && !lookup2(s->st, type, name, val))
373 | return 0;
374 | return -1;
375 | }
376 |
377 | static int lookup_func_sym(symtab_t s, char *name, unsigned long *val) {
378 | return lookup_sym(s, STT_FUNC, name, val);
379 | }
380 |
381 | int find_name(pid_t pid, const char *name, const char *libn,
382 | unsigned long *addr) {
383 | struct mm mm[1000] = { 0 };
384 | unsigned long libcaddr;
385 | int nmm;
386 | char libc[1024] = { 0 };
387 | symtab_t s;
388 |
389 | if (0 > load_memmap(pid, mm, &nmm)) {
390 | LOGD("cannot read memory map\n");
391 | return -1;
392 | }
393 | if (0
394 | > find_libname((char *) libn, (char *) libc, sizeof(libc),
395 | &libcaddr, mm, nmm)) {
396 | LOGD("cannot find lib: %s\n", libn);
397 | return -1;
398 | }
399 | //LOGD("lib: >%s<\n", libc)
400 | s = load_symtab(libc);
401 | if (!s) {
402 | LOGD("cannot read symbol table\n");
403 | return -1;
404 | }
405 | if (0 > lookup_func_sym(s, (char *) name, addr)) {
406 | LOGD("cannot find function: %s\n", name);
407 | return -1;
408 | }
409 | *addr += libcaddr;
410 | return 0;
411 | }
412 |
413 | int find_libbase(pid_t pid, const char *libn, unsigned long *addr) {
414 | struct mm mm[1000] = { 0 };
415 | unsigned long libcaddr;
416 | int nmm;
417 | char libc[1024] = { 0 };
418 | symtab_t s;
419 |
420 | if (0 > load_memmap(pid, mm, &nmm)) {
421 | LOGD("cannot read memory map\n");
422 | return -1;
423 | }
424 | if (0 > find_libname(libn, libc, sizeof(libc), &libcaddr, mm, nmm)) {
425 | LOGD("cannot find lib\n");
426 | return -1;
427 | }
428 | *addr = libcaddr;
429 | return 0;
430 | }
431 |
432 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/art.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Jarlene on 2015/9/29.
3 | //
4 |
5 | #ifndef COMMONDEMO_ART_H
6 | #define COMMONDEMO_ART_H
7 |
8 | #include
9 | #include "string.h"
10 | #include
11 | #include
12 | //#include "../../base/log.h"
13 |
14 |
15 |
16 | #ifdef HAVE_STDINT_H
17 | # include /* C99 */
18 | typedef uint8_t u1;
19 | typedef uint16_t u2;
20 | typedef uint32_t u4;
21 | typedef uint64_t u8;
22 | typedef int8_t s1;
23 | typedef int16_t s2;
24 | typedef int32_t s4;
25 | typedef int64_t s8;
26 | #else
27 | typedef unsigned char u1;
28 | typedef unsigned short u2;
29 | typedef unsigned int u4;
30 | typedef unsigned long long u8;
31 | typedef signed char s1;
32 | typedef signed short s2;
33 | typedef signed int s4;
34 | typedef signed long long s8;
35 | #endif
36 |
37 |
38 | namespace art {
39 | namespace mirror {
40 |
41 | class Object {
42 | public:
43 | static constexpr size_t kVTableLength = 11;
44 | static uint32_t hash_code_seed;
45 | // 5.0系统只有以下两个数据,5.1以及6.0多了上面两个。
46 | void* klass_;
47 | uint32_t monitor_;
48 |
49 | };
50 |
51 | class Class: public Object {
52 | public:
53 |
54 |
55 | // 5.1以上系统独有的参数
56 | static constexpr uint32_t kClassWalkSuper = 0xC0000000;
57 |
58 | // Interface method table size. Increasing this value reduces the chance of two interface methods
59 | // colliding in the interface method table but increases the size of classes that implement
60 | // (non-marker) interfaces.
61 | static constexpr size_t kImtSize = 64; //IMT_SIZE;
62 | // defining class loader, or NULL for the "bootstrap" system loader
63 | void* class_loader_;
64 | // For array classes, the component class object for instanceof/checkcast
65 | // (for String[][][], this will be String[][]). NULL for non-array classes.
66 | void* component_type_;
67 | // DexCache of resolved constant pool entries (will be NULL for classes generated by the
68 | // runtime such as arrays and primitive classes).
69 | void* dex_cache_;
70 | // static, private, and methods
71 | void* direct_methods_;
72 | // instance fields
73 | //
74 | // These describe the layout of the contents of an Object.
75 | // Note that only the fields directly declared by this class are
76 | // listed in ifields; fields declared by a superclass are listed in
77 | // the superclass's Class.ifields.
78 | //
79 | // All instance fields that refer to objects are guaranteed to be at
80 | // the beginning of the field list. num_reference_instance_fields_
81 | // specifies the number of reference fields.
82 | void* ifields_;
83 | // The interface table (iftable_) contains pairs of a interface class and an array of the
84 | // interface methods. There is one pair per interface supported by this class. That means one
85 | // pair for each interface we support directly, indirectly via superclass, or indirectly via a
86 | // superinterface. This will be null if neither we nor our superclass implement any interfaces.
87 | //
88 | // Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".
89 | // Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a
90 | // single vtable.
91 | //
92 | // For every interface a concrete class implements, we create an array of the concrete vtable_
93 | // methods for the methods in the interface.
94 | void* iftable_;
95 | // Interface method table (imt), for quick "invoke-interface".
96 | void* imtable_;
97 | // Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName
98 | void* name_;
99 | // Static fields
100 | void* sfields_;
101 | // The superclass, or NULL if this is java.lang.Object, an interface or primitive type.
102 | void* super_class_;
103 | // If class verify fails, we must return same error on subsequent tries.
104 | void* verify_error_class_;
105 | // Virtual methods defined in this class; invoked through vtable.
106 | void* virtual_methods_;
107 | // Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is
108 | // copied in, and virtual methods from our class either replace those from the super or are
109 | // appended. For abstract classes, methods may be created in the vtable that aren't in
110 | // virtual_ methods_ for miranda methods.
111 | void* vtable_;
112 | // Access flags; low 16 bits are defined by VM spec.
113 | uint32_t access_flags_;
114 | // Total size of the Class instance; used when allocating storage on gc heap.
115 | // See also object_size_.
116 | uint32_t class_size_;
117 | // Tid used to check for recursive invocation.
118 | pid_t clinit_thread_id_;
119 | // ClassDef index in dex file, -1 if no class definition such as an array.
120 | // TODO: really 16bits
121 | int32_t dex_class_def_idx_;
122 | // Type index in dex file.
123 | // TODO: really 16bits
124 | int32_t dex_type_idx_;
125 | // Number of instance fields that are object refs.
126 | uint32_t num_reference_instance_fields_;
127 | // Number of static fields that are object refs,
128 | uint32_t num_reference_static_fields_;
129 | // Total object size; used when allocating storage on gc heap.
130 | // (For interfaces and abstract classes this will be zero.)
131 | // See also class_size_.
132 | uint32_t object_size_;
133 | // Primitive type value, or Primitive::kPrimNot (0); set for generated primitive classes.
134 | void* primitive_type_;
135 | // Bitmap of offsets of ifields.
136 | uint32_t reference_instance_offsets_;
137 | // Bitmap of offsets of sfields.
138 | uint32_t reference_static_offsets_;
139 | // State of class initialization.
140 | void* status_;
141 | // TODO: ?
142 | // initiating class loader list
143 | // NOTE: for classes with low serialNumber, these are unused, and the
144 | // values are kept in a table in gDvm.
145 | // InitiatingLoaderList initiating_loader_list_;
146 | // The following data exist in real class objects.
147 | // Embedded Imtable, for class object that's not an interface, fixed size.
148 | void* embedded_imtable_[0];
149 | // Embedded Vtable, for class object that's not an interface, variable size.
150 | void* embedded_vtable_[0];
151 | // Static fields, variable size.
152 | uint32_t fields_[0];
153 | // java.lang.Class
154 | static void* java_lang_Class_;
155 |
156 | };
157 | // art所有的系统都一样
158 | class ArtField: public Object {
159 | void* declaring_class_;
160 | int32_t access_flags_;
161 | int32_t field_dex_idx_;
162 | int32_t offset_;
163 | };
164 |
165 | class ArtMethod : public Object{
166 | public:
167 | // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
168 | // The class we are a part of
169 | Class* declaring_class_;
170 |
171 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
172 | void* dex_cache_initialized_static_storage_;
173 |
174 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
175 | void* dex_cache_resolved_methods_;
176 |
177 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
178 | void* dex_cache_resolved_types_;
179 |
180 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
181 | void* dex_cache_strings_;
182 |
183 | // Access flags; low 16 bits are defined by spec.
184 | uint32_t access_flags_;
185 |
186 | // Offset to the CodeItem.
187 | uint32_t code_item_offset_;
188 |
189 | // Architecture-dependent register spill mask
190 | uint32_t core_spill_mask_;
191 |
192 | // Compiled code associated with this method for callers from managed code.
193 | // May be compiled managed code or a bridge for invoking a native method.
194 | // TODO: Break apart this into portable and quick.
195 | const void* entry_point_from_compiled_code_;
196 |
197 | // Called by the interpreter to execute this method.
198 | void* entry_point_from_interpreter_;
199 |
200 | // Architecture-dependent register spill mask
201 | uint32_t fp_spill_mask_;
202 |
203 | // Total size in bytes of the frame
204 | size_t frame_size_in_bytes_;
205 |
206 | // Garbage collection map of native PC offsets (quick) or dex PCs (portable) to reference bitmaps.
207 | const uint8_t* gc_map_;
208 |
209 | // Mapping from native pc to dex pc
210 | const uint32_t* mapping_table_;
211 |
212 | /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */
213 | // Offset to the CodeItem.
214 | uint32_t dex_code_item_offset_;
215 | // Index into method_ids of the dex file associated with this method.
216 | uint32_t dex_method_index_;
217 |
218 | // Index into method_ids of the dex file associated with this method
219 | uint32_t method_dex_index_;
220 |
221 | // For concrete virtual methods, this is the offset of the method in Class::vtable_.
222 | //
223 | // For abstract methods in an interface class, this is the offset of the method in
224 | // "iftable_->Get(n)->GetMethodArray()".
225 | //
226 | // For static and direct methods this is the index in the direct methods table.
227 | uint32_t method_index_;
228 |
229 | // The target native method registered with this method
230 | const void* native_method_;
231 |
232 | // When a register is promoted into a register, the spill mask holds which registers hold dex
233 | // registers. The first promoted register's corresponding dex register is vmap_table_[1], the Nth
234 | // is vmap_table_[N]. vmap_table_[0] holds the length of the table.
235 | const uint16_t* vmap_table_;
236 |
237 | static void* java_lang_reflect_ArtMethod_;
238 |
239 | struct PtrSizedFields {
240 | // Method dispatch from the interpreter invokes this pointer which may cause a bridge into
241 | // compiled code.
242 | void* entry_point_from_interpreter_;
243 | // Pointer to JNI function registered to this method, or a function to resolve the JNI function.
244 | void* entry_point_from_jni_;
245 | // Method dispatch from quick compiled code invokes this pointer which may cause bridging into
246 | // the interpreter.
247 | void* entry_point_from_quick_compiled_code_;
248 | } ptr_sized_fields_;
249 | };
250 |
251 | }
252 | }
253 |
254 | typedef void* (*artVerifyClass_func) (art::mirror::Class * ,bool, std::string*);
255 |
256 | artVerifyClass_func artVerifyClass_fnPtr;
257 |
258 |
259 | #endif //COMMONDEMO_ART_H
260 |
--------------------------------------------------------------------------------
/framenthook/framenthook.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | generateDebugSources
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/x86_64.cpp:
--------------------------------------------------------------------------------
1 | #ifndef X86_64_CPP_
2 | #define X86_64_CPP_
3 |
4 | #include
5 | #include
6 | #include "x86_64.h"
7 |
8 | unsigned char hde64_table[] = {
9 | 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5,
10 | 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1,
11 | 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea,
12 | 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0,
13 | 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab,
14 | 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92,
15 | 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90,
16 | 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b,
17 | 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,
18 | 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc,
19 | 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20,
20 | 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff,
21 | 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00,
22 | 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01,
23 | 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10,
24 | 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00,
25 | 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00,
26 | 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00,
27 | 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00,
28 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
29 | 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,
30 | 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40,
31 | 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43,
32 | 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
33 | 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40,
34 | 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06,
35 | 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07,
36 | 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
37 | 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10,
38 | 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00,
39 | 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb,
40 | 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff,
41 | 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09,
42 | 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff,
43 | 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08,
44 | 0x00,0xf0,0x02,0x00
45 | };
46 |
47 | /*
48 | * Hacker Disassembler Engine 64 C
49 | * Copyright (c) 2008-2009, Vyacheslav Patkov.
50 | * All rights reserved.
51 | *
52 | */
53 | unsigned int hde64_disasm(const void *code, hde64s *hs)
54 | {
55 | uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
56 | uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0;
57 | uint8_t op64 = 0;
58 |
59 | memset(hs,0,sizeof(hde64s));
60 |
61 | for (x = 16; x; x--)
62 | switch (c = *p++) {
63 | case 0xf3:
64 | hs->p_rep = c;
65 | pref |= PRE_F3;
66 | break;
67 | case 0xf2:
68 | hs->p_rep = c;
69 | pref |= PRE_F2;
70 | break;
71 | case 0xf0:
72 | hs->p_lock = c;
73 | pref |= PRE_LOCK;
74 | break;
75 | case 0x26: case 0x2e: case 0x36:
76 | case 0x3e: case 0x64: case 0x65:
77 | hs->p_seg = c;
78 | pref |= PRE_SEG;
79 | break;
80 | case 0x66:
81 | hs->p_66 = c;
82 | pref |= PRE_66;
83 | break;
84 | case 0x67:
85 | hs->p_67 = c;
86 | pref |= PRE_67;
87 | break;
88 | default:
89 | goto pref_done;
90 | }
91 | pref_done:
92 |
93 | hs->flags = (uint32_t)pref << 23;
94 |
95 | if (!pref)
96 | pref |= PRE_NONE;
97 |
98 | if ((c & 0xf0) == 0x40) {
99 | hs->flags |= F_PREFIX_REX;
100 | if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8)
101 | op64++;
102 | hs->rex_r = (c & 7) >> 2;
103 | hs->rex_x = (c & 3) >> 1;
104 | hs->rex_b = c & 1;
105 | if (((c = *p++) & 0xf0) == 0x40) {
106 | opcode = c;
107 | goto error_opcode;
108 | }
109 | }
110 |
111 | if ((hs->opcode = c) == 0x0f) {
112 | hs->opcode2 = c = *p++;
113 | ht += DELTA_OPCODES;
114 | } else if (c >= 0xa0 && c <= 0xa3) {
115 | op64++;
116 | if (pref & PRE_67)
117 | pref |= PRE_66;
118 | else
119 | pref &= ~PRE_66;
120 | }
121 |
122 | opcode = c;
123 | cflags = ht[ht[opcode / 4] + (opcode % 4)];
124 |
125 | if (cflags == C_ERROR) {
126 | error_opcode:
127 | hs->flags |= F_ERROR | F_ERROR_OPCODE;
128 | cflags = 0;
129 | if ((opcode & -3) == 0x24)
130 | cflags++;
131 | }
132 |
133 | x = 0;
134 | if (cflags & C_GROUP) {
135 | uint16_t t;
136 | t = *(uint16_t *)(ht + (cflags & 0x7f));
137 | cflags = (uint8_t)t;
138 | x = (uint8_t)(t >> 8);
139 | }
140 |
141 | if (hs->opcode2) {
142 | ht = hde64_table + DELTA_PREFIXES;
143 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
144 | hs->flags |= F_ERROR | F_ERROR_OPCODE;
145 | }
146 |
147 | if (cflags & C_MODRM) {
148 | hs->flags |= F_MODRM;
149 | hs->modrm = c = *p++;
150 | hs->modrm_mod = m_mod = c >> 6;
151 | hs->modrm_rm = m_rm = c & 7;
152 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
153 |
154 | if (x && ((x << m_reg) & 0x80))
155 | hs->flags |= F_ERROR | F_ERROR_OPCODE;
156 |
157 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
158 | uint8_t t = opcode - 0xd9;
159 | if (m_mod == 3) {
160 | ht = hde64_table + DELTA_FPU_MODRM + t*8;
161 | t = ht[m_reg] << m_rm;
162 | } else {
163 | ht = hde64_table + DELTA_FPU_REG;
164 | t = ht[t] << m_reg;
165 | }
166 | if (t & 0x80)
167 | hs->flags |= F_ERROR | F_ERROR_OPCODE;
168 | }
169 |
170 | if (pref & PRE_LOCK) {
171 | if (m_mod == 3) {
172 | hs->flags |= F_ERROR | F_ERROR_LOCK;
173 | } else {
174 | uint8_t *table_end, op = opcode;
175 | if (hs->opcode2) {
176 | ht = hde64_table + DELTA_OP2_LOCK_OK;
177 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
178 | } else {
179 | ht = hde64_table + DELTA_OP_LOCK_OK;
180 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
181 | op &= -2;
182 | }
183 | for (; ht != table_end; ht++)
184 | if (*ht++ == op) {
185 | if (!((*ht << m_reg) & 0x80))
186 | goto no_lock_error;
187 | else
188 | break;
189 | }
190 | hs->flags |= F_ERROR | F_ERROR_LOCK;
191 | no_lock_error:
192 | ;
193 | }
194 | }
195 |
196 | if (hs->opcode2) {
197 | switch (opcode) {
198 | case 0x20: case 0x22:
199 | m_mod = 3;
200 | if (m_reg > 4 || m_reg == 1)
201 | goto error_operand;
202 | else
203 | goto no_error_operand;
204 | case 0x21: case 0x23:
205 | m_mod = 3;
206 | if (m_reg == 4 || m_reg == 5)
207 | goto error_operand;
208 | else
209 | goto no_error_operand;
210 | }
211 | } else {
212 | switch (opcode) {
213 | case 0x8c:
214 | if (m_reg > 5)
215 | goto error_operand;
216 | else
217 | goto no_error_operand;
218 | case 0x8e:
219 | if (m_reg == 1 || m_reg > 5)
220 | goto error_operand;
221 | else
222 | goto no_error_operand;
223 | }
224 | }
225 |
226 | if (m_mod == 3) {
227 | uint8_t *table_end;
228 | if (hs->opcode2) {
229 | ht = hde64_table + DELTA_OP2_ONLY_MEM;
230 | table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM;
231 | } else {
232 | ht = hde64_table + DELTA_OP_ONLY_MEM;
233 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
234 | }
235 | for (; ht != table_end; ht += 2)
236 | if (*ht++ == opcode) {
237 | if (*ht++ & pref && !((*ht << m_reg) & 0x80))
238 | goto error_operand;
239 | else
240 | break;
241 | }
242 | goto no_error_operand;
243 | } else if (hs->opcode2) {
244 | switch (opcode) {
245 | case 0x50: case 0xd7: case 0xf7:
246 | if (pref & (PRE_NONE | PRE_66))
247 | goto error_operand;
248 | break;
249 | case 0xd6:
250 | if (pref & (PRE_F2 | PRE_F3))
251 | goto error_operand;
252 | break;
253 | case 0xc5:
254 | goto error_operand;
255 | }
256 | goto no_error_operand;
257 | } else
258 | goto no_error_operand;
259 |
260 | error_operand:
261 | hs->flags |= F_ERROR | F_ERROR_OPERAND;
262 | no_error_operand:
263 |
264 | c = *p++;
265 | if (m_reg <= 1) {
266 | if (opcode == 0xf6)
267 | cflags |= C_IMM8;
268 | else if (opcode == 0xf7)
269 | cflags |= C_IMM_P66;
270 | }
271 |
272 | switch (m_mod) {
273 | case 0:
274 | if (pref & PRE_67) {
275 | if (m_rm == 6)
276 | disp_size = 2;
277 | } else
278 | if (m_rm == 5)
279 | disp_size = 4;
280 | break;
281 | case 1:
282 | disp_size = 1;
283 | break;
284 | case 2:
285 | disp_size = 2;
286 | if (!(pref & PRE_67))
287 | disp_size <<= 1;
288 | }
289 |
290 | if (m_mod != 3 && m_rm == 4) {
291 | hs->flags |= F_SIB;
292 | p++;
293 | hs->sib = c;
294 | hs->sib_scale = c >> 6;
295 | hs->sib_index = (c & 0x3f) >> 3;
296 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
297 | disp_size = 4;
298 | }
299 |
300 | p--;
301 | switch (disp_size) {
302 | case 1:
303 | hs->flags |= F_DISP8;
304 | hs->disp.disp8 = *p;
305 | break;
306 | case 2:
307 | hs->flags |= F_DISP16;
308 | hs->disp.disp16 = *(uint16_t *)p;
309 | break;
310 | case 4:
311 | hs->flags |= F_DISP32;
312 | hs->disp.disp32 = *(uint32_t *)p;
313 | }
314 | p += disp_size;
315 | } else if (pref & PRE_LOCK)
316 | hs->flags |= F_ERROR | F_ERROR_LOCK;
317 |
318 | if (cflags & C_IMM_P66) {
319 | if (cflags & C_REL32) {
320 | if (pref & PRE_66) {
321 | hs->flags |= F_IMM16 | F_RELATIVE;
322 | hs->imm.imm16 = *(uint16_t *)p;
323 | p += 2;
324 | goto disasm_done;
325 | }
326 | goto rel32_ok;
327 | }
328 | if (op64) {
329 | hs->flags |= F_IMM64;
330 | hs->imm.imm64 = *(uint64_t *)p;
331 | p += 8;
332 | } else if (!(pref & PRE_66)) {
333 | hs->flags |= F_IMM32;
334 | hs->imm.imm32 = *(uint32_t *)p;
335 | p += 4;
336 | } else
337 | goto imm16_ok;
338 | }
339 |
340 |
341 | if (cflags & C_IMM16) {
342 | imm16_ok:
343 | hs->flags |= F_IMM16;
344 | hs->imm.imm16 = *(uint16_t *)p;
345 | p += 2;
346 | }
347 | if (cflags & C_IMM8) {
348 | hs->flags |= F_IMM8;
349 | hs->imm.imm8 = *p++;
350 | }
351 |
352 | if (cflags & C_REL32) {
353 | rel32_ok:
354 | hs->flags |= F_IMM32 | F_RELATIVE;
355 | hs->imm.imm32 = *(uint32_t *)p;
356 | p += 4;
357 | } else if (cflags & C_REL8) {
358 | hs->flags |= F_IMM8 | F_RELATIVE;
359 | hs->imm.imm8 = *p++;
360 | }
361 |
362 | disasm_done:
363 |
364 | if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) {
365 | hs->flags |= F_ERROR | F_ERROR_LENGTH;
366 | hs->len = 15;
367 | }
368 |
369 | return (unsigned int)hs->len;
370 | }
371 |
372 |
373 |
374 | #endif /* X86_64_CPP_ */
375 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/MSHook/Thumb.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "ARM.h"
3 | #include "Thumb.h"
4 |
5 | static size_t Thumb::MSGetInstructionWidth(void *start) {
6 | if ((reinterpret_cast(start) & 0x1) == 0)
7 | return MSGetInstructionWidthARM(start);
8 | else
9 | return MSGetInstructionWidthThumb(reinterpret_cast(reinterpret_cast(start) & ~0x1));
10 | }
11 |
12 | void Thumb::SubstrateHookFunctionThumb(SubstrateProcessRef process, void *symbol, void *replace, void **result){
13 | if (symbol == NULL)
14 | return;
15 |
16 | uint16_t *area(reinterpret_cast(symbol));
17 |
18 | unsigned align((reinterpret_cast(area) & 0x2) == 0 ? 0 : 1);
19 | uint16_t *thumb(area + align);
20 |
21 | uint32_t *arm(reinterpret_cast(thumb + 2));
22 | uint16_t *trail(reinterpret_cast(arm + 2));
23 |
24 | if (
25 | (align == 0 || area[0] == T$nop) &&
26 | thumb[0] == T$bx(A$pc) &&
27 | thumb[1] == T$nop &&
28 | arm[0] == A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8)
29 | ) {
30 | if (result != NULL)
31 | *result = reinterpret_cast(arm[1]);
32 |
33 | SubstrateHookMemory code(process, arm + 1, sizeof(uint32_t) * 1);
34 |
35 | arm[1] = reinterpret_cast(replace);
36 |
37 | return;
38 | }
39 |
40 | size_t required((trail - area) * sizeof(uint16_t));
41 |
42 | size_t used(0);
43 | while (used < required)
44 | used += MSGetInstructionWidthThumb(reinterpret_cast(area) + used);
45 | used = (used + sizeof(uint16_t) - 1) / sizeof(uint16_t) * sizeof(uint16_t);
46 |
47 | size_t blank((used - required) / sizeof(uint16_t));
48 |
49 | uint16_t backup[used / sizeof(uint16_t)];
50 | memcpy(backup, area, used);
51 |
52 | if (MSDebug) {
53 | char name[16];
54 | sprintf(name, "%p", area);
55 | MSLogHexEx(area, used + sizeof(uint16_t), 2, name);
56 | }
57 |
58 | if (result != NULL) {
59 |
60 | size_t length(used);
61 | for (unsigned offset(0); offset != used / sizeof(uint16_t); ++offset)
62 | if (T$pcrel$ldr(backup[offset]))
63 | length += 3 * sizeof(uint16_t);
64 | else if (T$pcrel$b(backup[offset]))
65 | length += 6 * sizeof(uint16_t);
66 | else if (T2$pcrel$b(backup + offset)) {
67 | length += 5 * sizeof(uint16_t);
68 | ++offset;
69 | } else if (T$pcrel$bl(backup + offset)) {
70 | length += 5 * sizeof(uint16_t);
71 | ++offset;
72 | } else if (T$pcrel$cbz(backup[offset])) {
73 | length += 16 * sizeof(uint16_t);
74 | } else if (T$pcrel$ldrw(backup[offset])) {
75 | length += 4 * sizeof(uint16_t);
76 | ++offset;
77 | } else if (T$pcrel$add(backup[offset]))
78 | length += 6 * sizeof(uint16_t);
79 | else if (T$32bit$i(backup[offset]))
80 | ++offset;
81 |
82 | unsigned pad((length & 0x2) == 0 ? 0 : 1);
83 | length += (pad + 2) * sizeof(uint16_t) + 2 * sizeof(uint32_t);
84 |
85 | uint16_t *buffer(reinterpret_cast(mmap(
86 | NULL, length, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0
87 | )));
88 |
89 | if (buffer == MAP_FAILED) {
90 | MSLog(MSLogLevelError, "MS:Error:mmap() = %d", errno);
91 | *result = NULL;
92 | return;
93 | }
94 |
95 | if (false) fail: {
96 | munmap(buffer, length);
97 | *result = NULL;
98 | return;
99 | }
100 |
101 | size_t start(pad), end(length / sizeof(uint16_t));
102 | uint32_t *trailer(reinterpret_cast(buffer + end));
103 | for (unsigned offset(0); offset != used / sizeof(uint16_t); ++offset) {
104 | if (T$pcrel$ldr(backup[offset])) {
105 | union {
106 | uint16_t value;
107 |
108 | struct {
109 | uint16_t immediate : 8;
110 | uint16_t rd : 3;
111 | uint16_t : 5;
112 | };
113 | } bits = {backup[offset+0]};
114 |
115 | buffer[start+0] = T$ldr_rd_$pc_im_4$(bits.rd, T$Label(start+0, end-2) / 4);
116 | buffer[start+1] = T$ldr_rd_$rn_im_4$(bits.rd, bits.rd, 0);
117 |
118 | // XXX: this code "works", but is "wrong": the mechanism is more complex than this
119 | *--trailer = ((reinterpret_cast(area + offset) + 4) & ~0x2) + bits.immediate * 4;
120 |
121 | start += 2;
122 | end -= 2;
123 | } else if (T$pcrel$b(backup[offset])) {
124 | union {
125 | uint16_t value;
126 |
127 | struct {
128 | uint16_t imm8 : 8;
129 | uint16_t cond : 4;
130 | uint16_t /*1101*/ : 4;
131 | };
132 | } bits = {backup[offset+0]};
133 |
134 | intptr_t jump(bits.imm8 << 1);
135 | jump |= 1;
136 | jump <<= 23;
137 | jump >>= 23;
138 |
139 | buffer[start+0] = T$b$_$im(bits.cond, (end-6 - (start+0)) * 2 - 4);
140 |
141 | *--trailer = reinterpret_cast(area + offset) + 4 + jump;
142 | *--trailer = A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8);
143 | *--trailer = T$nop << 16 | T$bx(A$pc);
144 |
145 | start += 1;
146 | end -= 6;
147 | } else if (T2$pcrel$b(backup + offset)) {
148 | union {
149 | uint16_t value;
150 |
151 | struct {
152 | uint16_t imm6 : 6;
153 | uint16_t cond : 4;
154 | uint16_t s : 1;
155 | uint16_t : 5;
156 | };
157 | } bits = {backup[offset+0]};
158 |
159 | union {
160 | uint16_t value;
161 |
162 | struct {
163 | uint16_t imm11 : 11;
164 | uint16_t j2 : 1;
165 | uint16_t a : 1;
166 | uint16_t j1 : 1;
167 | uint16_t : 2;
168 | };
169 | } exts = {backup[offset+1]};
170 |
171 | intptr_t jump(1);
172 | jump |= exts.imm11 << 1;
173 | jump |= bits.imm6 << 12;
174 |
175 | if (exts.a) {
176 | jump |= bits.s << 24;
177 | jump |= (~(bits.s ^ exts.j1) & 0x1) << 23;
178 | jump |= (~(bits.s ^ exts.j2) & 0x1) << 22;
179 | jump |= bits.cond << 18;
180 | jump <<= 7;
181 | jump >>= 7;
182 | } else {
183 | jump |= bits.s << 20;
184 | jump |= exts.j2 << 19;
185 | jump |= exts.j1 << 18;
186 | jump <<= 11;
187 | jump >>= 11;
188 | }
189 |
190 | buffer[start+0] = T$b$_$im(exts.a ? A$al : bits.cond, (end-6 - (start+0)) * 2 - 4);
191 |
192 | *--trailer = reinterpret_cast(area + offset) + 4 + jump;
193 | *--trailer = A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8);
194 | *--trailer = T$nop << 16 | T$bx(A$pc);
195 |
196 | ++offset;
197 | start += 1;
198 | end -= 6;
199 | } else if (T$pcrel$bl(backup + offset)) {
200 | union {
201 | uint16_t value;
202 |
203 | struct {
204 | uint16_t immediate : 10;
205 | uint16_t s : 1;
206 | uint16_t : 5;
207 | };
208 | } bits = {backup[offset+0]};
209 |
210 | union {
211 | uint16_t value;
212 |
213 | struct {
214 | uint16_t immediate : 11;
215 | uint16_t j2 : 1;
216 | uint16_t x : 1;
217 | uint16_t j1 : 1;
218 | uint16_t : 2;
219 | };
220 | } exts = {backup[offset+1]};
221 |
222 | int32_t jump(0);
223 | jump |= bits.s << 24;
224 | jump |= (~(bits.s ^ exts.j1) & 0x1) << 23;
225 | jump |= (~(bits.s ^ exts.j2) & 0x1) << 22;
226 | jump |= bits.immediate << 12;
227 | jump |= exts.immediate << 1;
228 | jump |= exts.x;
229 | jump <<= 7;
230 | jump >>= 7;
231 |
232 | buffer[start+0] = T$push_r(1 << A$r7);
233 | buffer[start+1] = T$ldr_rd_$pc_im_4$(A$r7, ((end-2 - (start+1)) * 2 - 4 + 2) / 4);
234 | buffer[start+2] = T$mov_rd_rm(A$lr, A$r7);
235 | buffer[start+3] = T$pop_r(1 << A$r7);
236 | buffer[start+4] = T$blx(A$lr);
237 |
238 | *--trailer = reinterpret_cast(area + offset) + 4 + jump;
239 |
240 | ++offset;
241 | start += 5;
242 | end -= 2;
243 | } else if (T$pcrel$cbz(backup[offset])) {
244 | union {
245 | uint16_t value;
246 |
247 | struct {
248 | uint16_t rn : 3;
249 | uint16_t immediate : 5;
250 | uint16_t : 1;
251 | uint16_t i : 1;
252 | uint16_t : 1;
253 | uint16_t op : 1;
254 | uint16_t : 4;
255 | };
256 | } bits = {backup[offset+0]};
257 |
258 | intptr_t jump(1);
259 | jump |= bits.i << 6;
260 | jump |= bits.immediate << 1;
261 |
262 | //jump <<= 24;
263 | //jump >>= 24;
264 |
265 | unsigned rn(bits.rn);
266 | unsigned rt(rn == A$r7 ? A$r6 : A$r7);
267 |
268 | buffer[start+0] = T$push_r(1 << rt);
269 | buffer[start+1] = T1$mrs_rd_apsr(rt);
270 | buffer[start+2] = T2$mrs_rd_apsr(rt);
271 | buffer[start+3] = T$cbz$_rn_$im(bits.op, rn, (end-10 - (start+3)) * 2 - 4);
272 | buffer[start+4] = T1$msr_apsr_nzcvqg_rn(rt);
273 | buffer[start+5] = T2$msr_apsr_nzcvqg_rn(rt);
274 | buffer[start+6] = T$pop_r(1 << rt);
275 |
276 | *--trailer = reinterpret_cast(area + offset) + 4 + jump;
277 | *--trailer = A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8);
278 | *--trailer = T$nop << 16 | T$bx(A$pc);
279 | *--trailer = T$nop << 16 | T$pop_r(1 << rt);
280 | *--trailer = T$msr_apsr_nzcvqg_rn(rt);
281 |
282 | #if 0
283 | if ((start & 0x1) == 0)
284 | buffer[start++] = T$nop;
285 | buffer[start++] = T$bx(A$pc);
286 | buffer[start++] = T$nop;
287 |
288 | uint32_t *arm(reinterpret_cast(buffer + start));
289 | arm[0] = A$add(A$lr, A$pc, 1);
290 | arm[1] = A$ldr_rd_$rn_im$(A$pc, A$pc, (trailer - arm) * sizeof(uint32_t) - 8);
291 | #endif
292 |
293 | start += 7;
294 | end -= 10;
295 | } else if (T$pcrel$ldrw(backup[offset])) {
296 | union {
297 | uint16_t value;
298 |
299 | struct {
300 | uint16_t : 7;
301 | uint16_t u : 1;
302 | uint16_t : 8;
303 | };
304 | } bits = {backup[offset+0]};
305 |
306 | union {
307 | uint16_t value;
308 |
309 | struct {
310 | uint16_t immediate : 12;
311 | uint16_t rt : 4;
312 | };
313 | } exts = {backup[offset+1]};
314 |
315 | buffer[start+0] = T1$ldr_rt_$rn_im$(exts.rt, A$pc, T$Label(start+0, end-2));
316 | buffer[start+1] = T2$ldr_rt_$rn_im$(exts.rt, A$pc, T$Label(start+0, end-2));
317 |
318 | buffer[start+2] = T1$ldr_rt_$rn_im$(exts.rt, exts.rt, 0);
319 | buffer[start+3] = T2$ldr_rt_$rn_im$(exts.rt, exts.rt, 0);
320 |
321 | // XXX: this code "works", but is "wrong": the mechanism is more complex than this
322 | *--trailer = ((reinterpret_cast(area + offset) + 4) & ~0x2) + (bits.u == 0 ? -exts.immediate : exts.immediate);
323 |
324 | ++offset;
325 | start += 4;
326 | end -= 2;
327 | } else if (T$pcrel$add(backup[offset])) {
328 | union {
329 | uint16_t value;
330 |
331 | struct {
332 | uint16_t rd : 3;
333 | uint16_t rm : 3;
334 | uint16_t h2 : 1;
335 | uint16_t h1 : 1;
336 | uint16_t : 8;
337 | };
338 | } bits = {backup[offset+0]};
339 |
340 | if (bits.h1) {
341 | MSLog(MSLogLevelError, "MS:Error:pcrel(%u):add (rd > r7)", offset);
342 | goto fail;
343 | }
344 |
345 | unsigned rt(bits.rd == A$r7 ? A$r6 : A$r7);
346 |
347 | buffer[start+0] = T$push_r(1 << rt);
348 | buffer[start+1] = T$mov_rd_rm(rt, (bits.h1 << 3) | bits.rd);
349 | buffer[start+2] = T$ldr_rd_$pc_im_4$(bits.rd, T$Label(start+2, end-2) / 4);
350 | buffer[start+3] = T$add_rd_rm((bits.h1 << 3) | bits.rd, rt);
351 | buffer[start+4] = T$pop_r(1 << rt);
352 | *--trailer = reinterpret_cast(area + offset) + 4;
353 |
354 | start += 5;
355 | end -= 2;
356 | } else if (T$32bit$i(backup[offset])) {
357 | buffer[start++] = backup[offset];
358 | buffer[start++] = backup[++offset];
359 | } else {
360 | buffer[start++] = backup[offset];
361 | }
362 | }
363 |
364 | buffer[start++] = T$bx(A$pc);
365 | buffer[start++] = T$nop;
366 |
367 | uint32_t *transfer = reinterpret_cast(buffer + start);
368 | transfer[0] = A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8);
369 | transfer[1] = reinterpret_cast(area + used / sizeof(uint16_t)) + 1;
370 |
371 | if (mprotect(buffer, length, PROT_READ | PROT_EXEC) == -1) {
372 | MSLog(MSLogLevelError, "MS:Error:mprotect():%d", errno);
373 | return;
374 | }
375 |
376 | *result = reinterpret_cast(buffer + pad) + 1;
377 |
378 | if (MSDebug) {
379 | char name[16];
380 | sprintf(name, "%p", *result);
381 | MSLogHexEx(buffer, length, 2, name);
382 | }
383 |
384 | }
385 |
386 | {
387 | SubstrateHookMemory code(process, area, used);
388 |
389 | if (align != 0)
390 | area[0] = T$nop;
391 |
392 | thumb[0] = T$bx(A$pc);
393 | thumb[1] = T$nop;
394 |
395 | arm[0] = A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8);
396 | arm[1] = reinterpret_cast(replace);
397 |
398 | for (unsigned offset(0); offset != blank; ++offset)
399 | trail[offset] = T$nop;
400 | }
401 |
402 | if (MSDebug) {
403 | char name[16];
404 | sprintf(name, "%p", area);
405 | MSLogHexEx(area, used + sizeof(uint16_t), 2, name);
406 | }
407 | }
408 |
409 |
--------------------------------------------------------------------------------
/framenthook/src/main/cpp/Android-Inline/relocate.c:
--------------------------------------------------------------------------------
1 | /*
2 | relocate instruction
3 | author: ele7enxxh
4 | mail: ele7enxxh@qq.com
5 | website: ele7enxxh.com
6 | modified time: 2016-10-17
7 | created time: 2015-01-17
8 | */
9 |
10 | #include "relocate.h"
11 |
12 | #define ALIGN_PC(pc) (pc & 0xFFFFFFFC)
13 |
14 | enum INSTRUCTION_TYPE {
15 | // B