Skip to content

Commit

Permalink
Add some new features
Browse files Browse the repository at this point in the history
1.Compile with cmake
2.Support for fixing codeItem
3.Optimisation de l'espace de stockage
  • Loading branch information
nnjun committed Jun 7, 2021
1 parent 095ad94 commit 27660d7
Show file tree
Hide file tree
Showing 160 changed files with 28,402 additions and 622 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import androidx.annotation.Keep;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

@Keep
Expand Down Expand Up @@ -39,6 +40,18 @@ public static String getDesc(final Method method) {
return buf.toString();
}

// native call
public static String getDesc(final Constructor<?> method) {
final StringBuffer buf = new StringBuffer();
buf.append("(");
final Class<?>[] types = method.getParameterTypes();
for (int i = 0; i < types.length; ++i) {
buf.append(getDesc(types[i]));
}
buf.append(")V");
return buf.toString();
}

private static String getDesc(final Class<?> returnType) {
if (returnType.isPrimitive()) {
return getPrimitiveLetter(returnType);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package top.niunaijun.jnihook.jni;

/**
* Created by Milk on 2021/6/5.
* * ∧_∧
* (`・ω・∥
* 丶 つ0
* しーJ
* 此处无Bug
*/
public class ArtMethod {

public static final native void nativeOffset();

public static final native void nativeOffset2();
}

This file was deleted.

5 changes: 2 additions & 3 deletions Bcore/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ android {
}
}
externalNativeBuild {
ndkBuild {
path file('src/main/jni/Android.mk')
cmake {
path file('./src/main/cpp/CMakeLists.txt')
}
}
dexOptions {
Expand Down Expand Up @@ -62,7 +62,6 @@ tasks.withType(Javadoc) {
options.addStringOption('charSet', 'UTF-8')
}


dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
Expand Down
66 changes: 66 additions & 0 deletions Bcore/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
include_directories( dex )
include_directories( base )
include_directories( ./ )

aux_source_directory(./ SRC7)
aux_source_directory(xhook SRC6)
aux_source_directory(ziparchive SRC1)
aux_source_directory(dex SRC2)
aux_source_directory(android-base SRC3)
aux_source_directory(utils SRC4)
aux_source_directory(hook SRC5)
aux_source_directory(jnihook SRC6)
add_compile_options(-w)
add_library( # Sets the name of the library.
blackdex

# Sets the library as a shared library.
SHARED

# Provides a relative path to your source file(s).
VmCore.cpp
${SRC3}
${SRC1}
${SRC2}
${SRC4}
${SRC5}
${SRC6}
${SRC7}
)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
log-lib

# Specifies the name of the NDK library that
# you want CMake to locate.
log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
blackdex

# Links the target library to the log library
# included in the NDK.
${log-lib}
z
)
174 changes: 174 additions & 0 deletions Bcore/src/main/cpp/DexDump.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
//
// Created by Milk on 2021/5/16.
//

#include "DexDump.h"
#include "utils/HexDump.h"
#include "utils/Log.h"
#include "VmCore.h"
#include "utils/PointerCheck.h"
#include "jnihook/Art.h"
#include "jnihook/ArtM.h"

#include <cstdio>
#include <fcntl.h>
#include <cstring>
#include <cstdlib>
#include <map>
#include "unistd.h"

#include "dex/dex_file.h"
#include "dex/dex_file_loader.h"
#include "jnihook/JniHook.h"
#include "xhook/xhook.h"

using namespace std;
static int beginOffset = -2;

HOOK_JNI(int, kill, pid_t __pid, int __signal) {
ALOGE("hooked so kill");
return 0;
}

HOOK_JNI(int, killpg, int __pgrp, int __signal) {
ALOGE("hooked so killpg");
return 0;
}

void init(JNIEnv *env) {
const char *soName = ".*\\.so$";
xhook_register(soName, "kill", (void *) new_kill,
(void **) (&orig_kill));
xhook_register(soName, "killpg", (void *) new_killpg,
(void **) (&orig_killpg));
xhook_refresh(0);

jlongArray emptyCookie = VmCore::loadEmptyDex(env);
jsize arrSize = env->GetArrayLength(emptyCookie);
if (env->ExceptionCheck() == JNI_TRUE) {
return;
}
jlong *long_data = env->GetLongArrayElements(emptyCookie, nullptr);

for (int i = 0; i < arrSize; ++i) {
jlong cookie = long_data[i];
if (cookie == 0) {
continue;
}
auto dex = reinterpret_cast<char *>(cookie);
for (int ii = 0; ii < 10; ++ii) {
auto value = *(size_t *) (dex + ii * sizeof(size_t));
if (value == 1872) {
beginOffset = ii - 1;
// auto dexBegin = *(size_t *) (dex + beginOffset * sizeof(size_t));
// HexDump(reinterpret_cast<char *>(dexBegin), 10, 0);
env->ReleaseLongArrayElements(emptyCookie, long_data, 0);
return;
}
}
}
env->ReleaseLongArrayElements(emptyCookie, long_data, 0);
beginOffset = -1;
}

void fixCodeItem(JNIEnv *env, const art_lkchan::DexFile *dex_file_, size_t begin) {
for (size_t classdef_ctr = 0;classdef_ctr < dex_file_->NumClassDefs(); ++classdef_ctr) {
const art_lkchan::DexFile::ClassDef &cd = dex_file_->GetClassDef(classdef_ctr);
const uint8_t *class_data = dex_file_->GetClassData(cd);
auto &classTypeId = dex_file_->GetTypeId(cd.class_idx_);
std::string class_name = dex_file_->GetTypeDescriptor(classTypeId);

if (class_data != nullptr) {
art_lkchan::ClassDataItemIterator cdit(*dex_file_, class_data);
cdit.SkipAllFields();
while (cdit.HasNextMethod()) {
if (cdit.GetMemberIndex() > dex_file_->NumMethodIds())
continue;
const art_lkchan::DexFile::MethodId &method_id_item = dex_file_->GetMethodId(
cdit.GetMemberIndex());
auto method_name = dex_file_->GetMethodName(method_id_item);
auto method_signature = dex_file_->GetMethodSignature(
method_id_item).ToString().c_str();
auto java_method = VmCore::findMethod(env, class_name.c_str(), method_name,
method_signature);
if (java_method) {
auto artMethod = ArtM::GetArtMethod(env, java_method);
const art_lkchan::DexFile::CodeItem *orig_code_item = cdit.GetMethodCodeItem();
if (cdit.GetMethodCodeItemOffset() && orig_code_item) {
auto codeItemSize = dex_file_->GetCodeItemSize(*orig_code_item);
auto new_code_item =
begin + ArtM::GetArtMethodDexCodeItemOffset(artMethod);
memcpy((void *) orig_code_item,
(void *) new_code_item,
codeItemSize);
}
} else {
env->ExceptionClear();
}
cdit.Next();
}
}
}
}

void DexDump::dumpDex(JNIEnv *env, jlong cookie, jstring dir, jboolean fix) {
if (beginOffset == -2) {
init(env);
}
if (beginOffset == -1) {
ALOGD("dumpDex not support!");
return;
}
char magic[8] = {0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00};
auto base = reinterpret_cast<char *>(cookie);
auto begin = *(size_t *) (base + beginOffset * sizeof(size_t));
if (!PointerCheck::check(reinterpret_cast<void *>(begin))) {
return;
}
auto dirC = env->GetStringUTFChars(dir, 0);

auto dexSizeOffset = ((unsigned long) begin) + 0x20;
int size = *(size_t *) dexSizeOffset;

void *buffer = malloc(size);
if (buffer) {
memcpy(buffer, reinterpret_cast<const void *>(begin), size);
// fix magic
memcpy(buffer, magic, sizeof(magic));

const bool kVerifyChecksum = false;
const bool kVerify = true;
const art_lkchan::DexFileLoader dex_file_loader;
std::string error_msg;
std::vector<std::unique_ptr<const art_lkchan::DexFile>> dex_files;
if (!dex_file_loader.OpenAll(reinterpret_cast<const uint8_t *>(buffer),
size,
"",
kVerify,
kVerifyChecksum,
&error_msg,
&dex_files)) {
// Display returned error message to user. Note that this error behavior
// differs from the error messages shown by the original Dalvik dexdump.
ALOGE("Open dex error %s", error_msg.c_str());
return;
}

if (fix) {
fixCodeItem(env, dex_files[0].get(), begin);
}
char path[1024];
sprintf(path, "%s/dex_%d.dex", dirC, size);
auto fd = open(path, O_CREAT | O_WRONLY, 0600);
ssize_t w = write(fd, buffer, size);
fsync(fd);
if (w > 0) {
ALOGE("dump dex ======> %s", path);
} else {
remove(path);
}
close(fd);
free(buffer);
env->ReleaseStringUTFChars(dir, dirC);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class DexDump {
public:
static void dumpDex(JNIEnv *env, jlong cookie, jstring dir);
static void dumpDex(JNIEnv *env, jlong cookie, jstring dir, jboolean fix);
};


Expand Down
2 changes: 1 addition & 1 deletion Bcore/src/main/jni/IO.cpp → Bcore/src/main/cpp/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//

#include "IO.h"
#include "Log.h"
#include "utils/Log.h"

jmethodID getAbsolutePathMethodId;

Expand Down
File renamed without changes.
Loading

0 comments on commit 27660d7

Please sign in to comment.