package com.hujiang.
cctalk;
import unicorn.UnicornException;
import unicorn.Unicorn;
import unicorn.CodeHook;
import unicorn.Arm64Const;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Emulator;
import com.github.unidbg.Module;
import com.github.unidbg.debugger.BreakPointCallback;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.AbstractJni;
import com.github.unidbg.linux.android.dvm.BaseVM;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.DvmObject;
import com.github.unidbg.linux.android.dvm.StringObject;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.memory.Memory;
import com.github.unidbg.pointer.UnidbgPointer;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
class JNIDecryptModel {
public byte[] byteMing;
public String data;
public String dataVerion;
public String encrypt;
public int errorCode;
public boolean isEncrypt;
public String key;
public String path;
public long period;
public String priKey;
public String pubKey;
public long systemTime;
JNIDecryptModel(byte[] byteMing_, String data_, String dataVerion_, String
encrypt_, int errorCode_, boolean isEncrypt_, String key_, String path_, long
period_, String priKey_, String pubKey_, long systemTime_) {
this.byteMing = byteMing_;
this.data = data_;
this.dataVerion = dataVerion_;
this.encrypt = encrypt_;
this.errorCode = errorCode_;
this.isEncrypt = isEncrypt_;
this.key = key_;
this.path = path_;
this.period = period_;
this.priKey = priKey_;
this.pubKey = pubKey_;
this.systemTime = systemTime_;
}
}
class ReadFileToList {
ReadFileToList() {
}
public static List<String> readLines(String fileName) {
ArrayList lines = new ArrayList();
try {
Scanner scanner = new Scanner(new File(fileName));
while(scanner.hasNextLine()) {
lines.add(scanner.nextLine());
}
scanner.close();
} catch (Exception var3) {
var3.printStackTrace();
}
return lines;
}
}
class WriteFileToList {
WriteFileToList() {
}
public static void testFileWriter(String dirPath, String content) throws
IOException {
File file0 = new File(dirPath);
String fileName = file0.getName();
String Path = file0.getParent();
String filePath = Path + File.separator + fileName;
File file = new File(filePath);
System.out.println(file.createNewFile() ? "成功创建文件!" : "文件已存在!");
FileWriter fw = new FileWriter(file);
fw.write(content);
System.out.println("成功写入内容");
fw.close();
}
}
class StringReader {
public static String readString(UnidbgPointer pointer) {
final int READ_BLOCK_SIZE = 16; // 每次读取的块大小
ArrayList<Byte> byteList = new ArrayList<>();
int offset = 0;
boolean foundNullTerminator = false;
while (!foundNullTerminator) {
byte[] buffer = pointer.getByteArray(offset, READ_BLOCK_SIZE);
for (int i = 0; i < buffer.length; i++) {
if (buffer[i] == 0) {
foundNullTerminator = true;
break;
}
byteList.add(buffer[i]);
}
offset += READ_BLOCK_SIZE;
}
byte[] stringBytes = new byte[byteList.size()];
for (int i = 0; i < byteList.size(); i++) {
stringBytes[i] = byteList.get(i);
}
return new String(stringBytes, StandardCharsets.UTF_8);
}
}
public class cctalk extends AbstractJni {
private final AndroidEmulator emulator;
private final VM vm;
private final Module module;
byte[] byteMing_ = new byte[0];
String data_ = null;
String dataVerion_ = null;
int errorCode_ = 0;
boolean isEncrypt_ = true;
String path_ = null;
long period_ = 0L;
String dirPath = System.getProperty("user.dir");
String fileName;
List<String> lines;
String encrypt_;
String pubKey_;
String priKey_;
String key_;
String systemTimestr;
long systemTime_;
long startTime;
public String getPath() {
String path =
this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
if (System.getProperty("os.name").contains("dows")) {
path = path.substring(1, path.length());
}
if (path.contains("jar")) {
path = path.substring(0, path.lastIndexOf("."));
return path.substring(0, path.lastIndexOf("/"));
} else {
return path.replace("/target/test-classes/", "");
}
}
cctalk() {
this.fileName = this.dirPath + "\\config.txt";
this.lines = ReadFileToList.readLines(this.fileName);
this.encrypt_ = ((String)this.lines.get(2)).trim();
this.pubKey_ = ((String)this.lines.get(0)).trim();
this.priKey_ = ((String)this.lines.get(1)).trim();
this.key_ = ((String)this.lines.get(3)).trim();
this.systemTimestr = ((String)this.lines.get(4)).trim();
this.systemTime_ = Long.parseLong(this.systemTimestr);
//this.systemTime_ = ((String)this.lines.get(5)).trim();
this.startTime = System.nanoTime();
this.emulator =
(AndroidEmulator)AndroidEmulatorBuilder.for64Bit().setProcessName("com.xianghu.orga
nization").build();
Memory memory = this.emulator.getMemory();
memory.setLibraryResolver(new AndroidResolver(23, new String[0]));
this.vm = this.emulator.createDalvikVM(new File(this.getPath() + "\\src\\
test\\java\\com\\hujiang\\cctalk\\MDDClass_1.2.5.950.apk"));
DalvikModule dm = this.vm.loadLibrary(new File(this.getPath() + "\\src\\
test\\java\\com\\hujiang\\cctalk\\libocsdecrypt.so"), false);
this.module = dm.getModule();
this.vm.setJni(this);
dm.callJNI_OnLoad(this.emulator);
}
public static void main(String[] args) {
long startTime = System.nanoTime();
cctalk cct = new cctalk();
JNIDecryptModel decryptModel = new JNIDecryptModel(cct.byteMing_,
cct.data_, cct.dataVerion_, cct.encrypt_, cct.errorCode_, cct.isEncrypt_, cct.key_,
cct.path_, cct.period_, cct.priKey_, cct.pubKey_, cct.systemTime_);
System.out.println("chuint>>>>>>>>>>>>>>>>" +
cct.HJDCDoDecrypt(decryptModel));
}
public String HJDCGenerateKey(JNIDecryptModel decryptModel) {
List<Object> list = new ArrayList();
list.add(this.vm.getJNIEnv());
list.add(0);
DvmObject<?> JNIDecryptModel =
this.vm.resolveClass("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel", new
DvmClass[0]).newObject(decryptModel);
list.add(this.vm.addLocalObject(JNIDecryptModel));
this.emulator.attach().addBreakPoint(this.module, 1388440L, new
BreakPointCallback() {
public boolean onHit(Emulator<?> emulator, long address) {
UnidbgPointer pointer = UnidbgPointer.register(emulator, 200);
String string1 = pointer.getString(0L);
System.out.println("miyao>>>>>>>>>>>>>>>>>>>>>\n" +
string1.substring(0, 32));
String filePath = "z:\\config.txt";
String content = string1;
try {
if (!Files.exists(Paths.get(filePath), new LinkOption[0])) {
Files.createFile(Paths.get(filePath));
}
Files.write(Paths.get(filePath), (content + "\n").getBytes(),
new OpenOption[]{StandardOpenOption.APPEND});
} catch (IOException var9) {
var9.printStackTrace();
}
return true;
}
});
this.emulator.attach().addBreakPoint(this.module, 1388488L, new
BreakPointCallback() {
public boolean onHit(Emulator<?> emulator, long address) {
UnidbgPointer pointer = UnidbgPointer.register(emulator, 200);
String string2 = pointer.getString(0L);
System.out.println("miyao2>>>>>>>>>>>>>>>>>>>>>\n" +
string2.substring(0, 32));
String filePath = "z:\\config.txt";
String content = string2;
try {
if (!Files.exists(Paths.get(filePath), new LinkOption[0])) {
Files.createFile(Paths.get(filePath));
}
Files.write(Paths.get(filePath), (content + "\n").getBytes(),
new OpenOption[]{StandardOpenOption.APPEND});
} catch (IOException var9) {
var9.printStackTrace();
}
return true;
}
});
Number number = this.module.callFunction(this.emulator, 1388104L,
list.toArray());
return "gen end!";
}
public int HJDCDoDecrypt(JNIDecryptModel decryptModel) {
List<Object> list = new ArrayList();
list.add(this.vm.getJNIEnv());
list.add(0);
DvmObject<?> JNIDecryptModel =
this.vm.resolveClass("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel", new
DvmClass[0]).newObject(decryptModel);
list.add(this.vm.addLocalObject(JNIDecryptModel));
emulator.attach().addBreakPoint(module,0x14ec8c);
//emulator.getBackend().reg_write(ArmConst.UC_ARM_REG_PC, 0x14ec60);
this.emulator.attach().addBreakPoint(this.module, 1369848L, new
BreakPointCallback() {
public boolean onHit(Emulator<?> emulator, long address) {
UnidbgPointer pointer4 = UnidbgPointer.register(emulator, 220);
String value = StringReader.readString(pointer4);
System.out.println(value);
try {
WriteFileToList.testFileWriter(cctalk.this.dirPath + "\\
out.txt", value);
} catch (IOException var12) {
var12.printStackTrace();
}
long endTime = System.nanoTime();
long duration = endTime - cctalk.this.startTime;
double seconds = (double)duration / 1.0E9D;
System.out.println("执行时间: " + seconds + " 秒");
System.exit(0);
return false;
}
});
Number number = this.module.callFunction(this.emulator, 0x14EBF0,
list.toArray());
return 0;
}
public DvmObject<?> getObjectField(BaseVM vm, DvmObject<?> dvmObject, String
signature) {
if
(signature.equals("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel-
>priKey:Ljava/lang/String;")) {
System.out.println("+++++++++++1++++++++++++");
return new StringObject(vm, this.priKey_);
} else if
(signature.equals("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel-
>key:Ljava/lang/String;")) {
System.out.println("+++++++++++2++++++++++++");
return new StringObject(vm, this.key_);
} else if
(signature.equals("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel-
>encrypt:Ljava/lang/String;")) {
System.out.println("+++++++++++3++++++++++++");
return new StringObject(vm, this.encrypt_);
} else {
System.out.println("out1>>>>>>>>>>>>>>");
return super.getObjectField(vm, dvmObject, signature);
}
}
public long getLongField(BaseVM vm, DvmObject<?> dvmObject, String signature) {
if
(signature.equals("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel-
>period:J")) {
System.out.println("+++++++++++4++++++++++++");
return this.period_;
} else if
(signature.equals("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel-
>systemTime:J")) {
System.out.println("+++++++++++5++++++++++++");
return this.systemTime_;
} else {
System.out.println("out2>>>>>>>>>>>>>>");
throw new UnsupportedOperationException(signature);
}
}
public void setIntField(BaseVM vm, DvmObject<?> dvmObject, String signature,
int value) {
if
(signature.equals("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel-
>errorCode:I")) {
System.out.println("+++++++++++6++++++++++++");
} else {
System.out.println("out3>>>>>>>>>>>>>>");
throw new UnsupportedOperationException(signature);
}
}
public void setObjectField(BaseVM vm, DvmObject<?> dvmObject, String signature,
DvmObject<?> value) {
if
(signature.equals("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel-
>pubKey:Ljava/lang/String;")) {
System.out.println("+++++++++++7++++++++++++");
} else if
(signature.equals("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel-
>priKey:Ljava/lang/String;")) {
System.out.println("+++++++++++8++++++++++++");
} else if
(signature.equals("com/techedux/makerx/hjdecrypt/sdk/model/JNIDecryptModel-
>byteMing:[B")) {
System.out.println("+++++++++++9++++++++++++");
} else {
System.out.println("out4>>>>>>>>>>>>>>");
throw new UnsupportedOperationException(signature);
}
}
}