Java层加密
- 将加密的java代码复制粘贴出来到自己写的java文件中,这里假设java文件为Sign.java
- 新建一个manifest.txt文件,文件内容
Main-Class: Sign - 使用以下代码将java文件打包成jar包
javac Sign.javajar cvf Sign.jar Sign.class
- python使用
subprocess.run(['java', '-cp', '.;', '包名', '参数'], capture_output=True, text=True)调用
So层加密
使用unidbg工具。在unidbg-android/src/main/java/com下新建文件。
以下为示例代码
package com.yuanrenxue.match2022.fragment.challenge;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.memory.Memory;
import com.github.unidbg.memory.MemoryBlock;
import com.github.unidbg.pointer.UnidbgPointer;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ChallengeEightFragment {
private final AndroidEmulator emulator;
private final VM vm;
private final Module module;
private final DvmClass ChallengeEightFragment;
private final boolean logging;
public ChallengeEightFragment(boolean logging) {
this.logging = logging;
emulator = AndroidEmulatorBuilder.for64Bit().setProcessName("com.yuanrenxue.match2022").build();
final Memory memory = emulator.getMemory();
memory.setLibraryResolver(new AndroidResolver(23));
/*
创建DalvikVM,可以载入apk,也可以为null
vm = emulator.createDalvikVM(new File("yuanrenxuem1010.apk"));
vm = emulator.createDalvikVM((File) null);
*/
vm = emulator.createDalvikVM((File) null);
vm.setVerbose(logging);
/*
载入要执行的 so,可以是本地so文件,也能是apk中的so文件
DalvikModule dm = vm.loadLibrary(new File("libmatch08.so"), false);
DalvikModule dm = vm.loadLibrary("match08", true);
*/
DalvikModule dm = vm.loadLibrary(new File("libmatch08.so"), false);
dm.callJNI_OnLoad(emulator);
module = dm.getModule();
ChallengeEightFragment = vm.resolveClass("com/yuanrenxue/match2022/fragment/challenge/ChallengeEightFragment");
}
public void destroy() throws IOException {
emulator.close();
}
public static void main(String[] args) throws Exception {
ChallengeEightFragment challengeEightFragment = new ChallengeEightFragment(true);
System.out.println(challengeEightFragment.getData(2));
challengeEightFragment.destroy();
}
/*
使用方法名称调用so文件内的方法
*/
public String getData(int page) {
StringObject data = ChallengeEightFragment.newObject(null).callJniMethodObject(
emulator,
"data(I)Ljava/lang/String;",
page
);
return data.getValue();
}
/*
使用地址调用,并传参数
*/
public String getDeviceId() {
/*
第一个参数是随机值
第二个参数是时间戳加mac地址
第三个参数是第二个参数的长度
*/
String arg1 = "C5A6D4F9B38E0721";
String arg2 = System.currentTimeMillis() + "$E6:CA:E3:4D:6A:08";
int arg3 = arg2.getBytes().length;
/*
emulator.getMemory().malloc(size, isZeroInitialized);
在模拟器(emulator)的内存中分配一个新的内存块,并设置其大小和初始化是否为0.
emulator.getMemory() 获取模拟器的内存操作接口
.malloc(size, isZeroInitialized):是一个内存分配方法,其中size指定了要分配的内存块的大小,isZeroInitialized指定了是否将分配的内存初始化为零。
UnidbgPointer input_ptr1 = memoryBlock1.getPointer(); 从memoryBlock1内存块中获取一个指针input_ptr1
input_ptr1.write(arg1.getBytes());将arg1字符串的字节数据写入到input_ptr1指针所指向的内存地址中。
*/
MemoryBlock memoryBlock1 = emulator.getMemory().malloc(arg1.getBytes().length, false);
UnidbgPointer input_ptr1 = memoryBlock1.getPointer();
input_ptr1.write(arg1.getBytes());
MemoryBlock memoryBlock2 = emulator.getMemory().malloc(arg3, false);
UnidbgPointer input_ptr2 = memoryBlock2.getPointer();
input_ptr2.write(arg2.getBytes());
MemoryBlock memoryBlock3 = emulator.getMemory().malloc(32, false);
UnidbgPointer output_buffer = memoryBlock3.getPointer();
/*
在so文件中0x49E68方法需要传入4个参数,
以下代码将4个参数都添加到数组中,并实现传递
*/
List<Object> list1 = new ArrayList<>();
list1.add(input_ptr1);
list1.add(input_ptr2);
list1.add(arg3);
list1.add(output_buffer);
module.callFunction(emulator, 0x49E68, list1.toArray());
// System.out.println("结果存放地址:" + output_buffer);
// Inspector.inspect(output_buffer.getByteArray(0, 32), "output");
return byte2HexString(output_buffer.getByteArray(0, 32)) + arg1;
}
public static String byte2HexString(byte[] b) {
String r = "";
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
r += hex.toUpperCase();
}
return r;
}
}
调试好代码后使用IDEA将代码打包成jar包给python调用
- 点击 File–Project Structure–Artifacts
- 点击 添加–JAR–From Modules
- Module选择unidbg-android
- Main Class选择你写的java文件
- 选择
extract to the target JAR - 点击OK
- 记住Output directory地址,这是文件输出目录
- 再次点击OK
- 点击 Bulid–Bulid Artifacts–Bulid
python代码调用 pip install JPype1
import jpype
# path后面是导出的jar包
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=./unidbg-android.jar")
# JPackage的参数为java文件顶部的package。后面解类名
jclass = jpype.JPackage("com.yuanrenxue.match2022.fragment.challenge").ChallengeEightFragment
encrypt = jclass(False)
# 使用.方法名(参数)的方式进行调用
print(encrypt.getData(1))