模拟执行libtiny.so计算x-mini相关的参数。
先搭建基础框架, 代码如下:
运行结果:

按照hook顺序调用初始化函数,
运行需要补充的环境:

这是主要需要补充的函数之一,也是开始比较重要的点, 先简单补充如下,通过第一个参数int来写分支补充不同的功能。
这样补充,有报错,需要把DvmMethod类的构造函数权限改成public, 接着给DvmClass函数中增加一个setMethodId的函数,
仿造DvmClass中getMethodID相关的函数,简单粗暴的给添加到对应的map中。

补充之后报错如上所示

进入第一层报错信息,代码如上所示,这里没有实现,直接抛出异常,接下来尝试补全这里的实现,

大致仿造函数_ToReflectedMethod函数的实现和需要补充的函数,猜测这里可能需要从DvmMethod对象获取到MethodIDlong类型。所以补充如下:

补充之后运行结果如上,第一个初始化函数成功执行完成。
继续第二个初始化函数
运行

开补:
运行

补
运行

补

第二个初始化函数执行完成。
第三个初始化函数
运行

不用补,直接能执行。
初始化函数调用完成之后,正式进入参数计算相关的调用。
运行

补
运行

补
运行

补, DvmField类构造函数权限public
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补,这里注意有特殊情况
运行

补
运行

补
运行

补,这里注意输入参数
运行

补
运行

补
运行

进入报错位置,看到报错是因为dvmMehtod是null,并且根据前面的日志,大概率是和android/content/Intent相关的问题,但是并没有补充过,这个类相关的环境,继续向前看,应该是分支环境没有补充,

看到309143350情况没有补全,顺带将其他没有补全的情况也都给补全。
运行

补
运行

补
运行

补, 注意这里的调用又是有参数的
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补
运行

补
运行

从上图中可以看出,出错的位置是prctl系统调用中有不支持的option类型,简单粗暴无脑补全即可,网上搜索prctl.h对应头文件简单看一下对应的值,

运行

补

运行

补
运行

补
运行

完成。
一切都以能跑出结果为主。
public class Xhs859Tiny extends AbstractJni {
private final AndroidEmulator emulator;
private final VM vm;
private final Module module;
private final DvmClass tinyT;
Xhs859Tiny() {
emulator = AndroidEmulatorBuilder.for64Bit()
.setProcessName("com.xingin.xhs")
.addBackendFactory(new Unicorn2Factory(true))
.build();
final Memory memory = emulator.getMemory();
memory.setLibraryResolver(new AndroidResolver(23));
vm = emulator.createDalvikVM(new File("data/xhs8_59_0.apk"));
vm.setVerbose(true);
vm.setJni(this);
new MediaNdkModule(emulator, vm).register(memory);
new AndroidModule(emulator, vm).register(memory);
new JniGraphics(emulator, vm).register(memory);
DalvikModule dm = vm.loadLibrary("tiny", true);
module = dm.getModule();
dm.callJNI_OnLoad(emulator);
tinyT = vm.resolveClass("com/xingin/tiny/internal/t");
}
public static void main(String[] args) {
Xhs859Tiny demo = new Xhs859Tiny();
}
}
public class Xhs859Tiny extends AbstractJni {
private final AndroidEmulator emulator;
private final VM vm;
private final Module module;
private final DvmClass tinyT;
Xhs859Tiny() {
emulator = AndroidEmulatorBuilder.for64Bit()
.setProcessName("com.xingin.xhs")
.addBackendFactory(new Unicorn2Factory(true))
.build();
final Memory memory = emulator.getMemory();
memory.setLibraryResolver(new AndroidResolver(23));
vm = emulator.createDalvikVM(new File("data/xhs8_59_0.apk"));
vm.setVerbose(true);
vm.setJni(this);
new MediaNdkModule(emulator, vm).register(memory);
new AndroidModule(emulator, vm).register(memory);
new JniGraphics(emulator, vm).register(memory);
DalvikModule dm = vm.loadLibrary("tiny", true);
module = dm.getModule();
dm.callJNI_OnLoad(emulator);
tinyT = vm.resolveClass("com/xingin/tiny/internal/t");
}
public static void main(String[] args) {
Xhs859Tiny demo = new Xhs859Tiny();
}
}
public void callInit() {
String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
int i = 1853701372;
ArrayObject objArr = new ArrayObject();
DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
System.out.println(result);
}
public void callInit() {
String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
int i = 1853701372;
ArrayObject objArr = new ArrayObject();
DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
System.out.println(result);
}
@Override
public DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
switch (signature) {
case "com/xingin/tiny/internal/t->b(I[Ljava/lang/Object;)Ljava/lang/Object;": {
int i = vaList.getIntArg(0);
System.out.println("Tiny.t.b i=" + i);
switch (i) {
case -1939572706: {
ArrayObject arrayObject = vaList.getObjectArg(1);
DvmClass clazz = (DvmClass) arrayObject.getValue()[0];
String methodName = (String) arrayObject.getValue()[1].getValue();
DvmObject[] signatureArgs = (DvmObject[]) arrayObject.getValue()[2].getValue();
System.out.println(signatureArgs);
StringBuilder methodSignature = new StringBuilder("(");
for (DvmObject signatureArg : signatureArgs) {
if (signatureArg.getValue().getClass() == String.class) {
System.out.println(signatureArg.getValue().getClass().getName());
methodSignature.append("L")
.append(signatureArg.getValue().getClass().getName().replaceAll("\\.", "/"))
.append(";");
} else {
methodSignature.append(signatureArg.getValue().getClass().getName());
}
}
methodSignature.append(")Ljava/lang/Object;");
System.out.println(methodName + " " + methodSignature);
DvmMethod dvmMethod = new DvmMethod(clazz, methodName, methodSignature.toString(), true);
DvmObject result = vm.resolveClass("java/lang/reflect/Method").newObject(dvmMethod);
clazz.setMethodId(result.hashCode(), dvmMethod);
System.out.println("setMethodId " + Integer.toHexString(result.hashCode()));
return result;
}
}
}
}
return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList);
}
@Override
public DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
switch (signature) {
case "com/xingin/tiny/internal/t->b(I[Ljava/lang/Object;)Ljava/lang/Object;": {
int i = vaList.getIntArg(0);
System.out.println("Tiny.t.b i=" + i);
switch (i) {
case -1939572706: {
ArrayObject arrayObject = vaList.getObjectArg(1);
DvmClass clazz = (DvmClass) arrayObject.getValue()[0];
String methodName = (String) arrayObject.getValue()[1].getValue();
DvmObject[] signatureArgs = (DvmObject[]) arrayObject.getValue()[2].getValue();
System.out.println(signatureArgs);
StringBuilder methodSignature = new StringBuilder("(");
for (DvmObject signatureArg : signatureArgs) {
if (signatureArg.getValue().getClass() == String.class) {
System.out.println(signatureArg.getValue().getClass().getName());
methodSignature.append("L")
.append(signatureArg.getValue().getClass().getName().replaceAll("\\.", "/"))
.append(";");
} else {
methodSignature.append(signatureArg.getValue().getClass().getName());
}
}
methodSignature.append(")Ljava/lang/Object;");
System.out.println(methodName + " " + methodSignature);
DvmMethod dvmMethod = new DvmMethod(clazz, methodName, methodSignature.toString(), true);
DvmObject result = vm.resolveClass("java/lang/reflect/Method").newObject(dvmMethod);
clazz.setMethodId(result.hashCode(), dvmMethod);
System.out.println("setMethodId " + Integer.toHexString(result.hashCode()));
return result;
}
}
}
}
return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList);
}
public void setMethodID(int methodID, DvmMethod dvmMethod) {
if (!staticMethodMap.containsKey(methodID)) {
staticMethodMap.put(methodID, dvmMethod);
}
if (!methodMap.containsKey(methodID)) {
methodMap.put(methodID, dvmMethod);
}
}
public void setMethodID(int methodID, DvmMethod dvmMethod) {
if (!staticMethodMap.containsKey(methodID)) {
staticMethodMap.put(methodID, dvmMethod);
}
if (!methodMap.containsKey(methodID)) {
methodMap.put(methodID, dvmMethod);
}
}
Pointer _FromReflectedMethod = svcMemory.registerSvc(new Arm64Svc() {
@Override
public long handle(Emulator<?> emulator) {
RegisterContext context = emulator.getContext();
UnidbgPointer jmethodID = context.getPointerArg(1);
return jmethodID.toIntPeer();
}
});
Pointer _FromReflectedMethod = svcMemory.registerSvc(new Arm64Svc() {
@Override
public long handle(Emulator<?> emulator) {
RegisterContext context = emulator.getContext();
UnidbgPointer jmethodID = context.getPointerArg(1);
return jmethodID.toIntPeer();
}
});
public void callInit2() {
String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
int i = -1681571521;
ArrayObject objArr = new ArrayObject(
new StringObject(vm, "ECFAAF01"),
new StringObject(vm, "vivo"),
DvmInteger.valueOf(vm, 0),
DvmBoolean.valueOf(vm, true),
DvmBoolean.valueOf(vm, false),
DvmBoolean.valueOf(vm, false),
vm.resolveClass("java/lang/Float").newObject(1.0),
DvmBoolean.valueOf(vm, false),
DvmBoolean.valueOf(vm, false),
DvmBoolean.valueOf(vm, false),
DvmBoolean.valueOf(vm, false),
DvmBoolean.valueOf(vm, false)
);
DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
System.out.println(result);
}
public void callInit2() {
String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
int i = -1681571521;
ArrayObject objArr = new ArrayObject(
new StringObject(vm, "ECFAAF01"),
new StringObject(vm, "vivo"),
DvmInteger.valueOf(vm, 0),
DvmBoolean.valueOf(vm, true),
DvmBoolean.valueOf(vm, false),
DvmBoolean.valueOf(vm, false),
vm.resolveClass("java/lang/Float").newObject(1.0),
DvmBoolean.valueOf(vm, false),
DvmBoolean.valueOf(vm, false),
DvmBoolean.valueOf(vm, false),
DvmBoolean.valueOf(vm, false),
DvmBoolean.valueOf(vm, false)
);
DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
System.out.println(result);
}
@Override
public float callFloatMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
switch (signature) {
case "java/lang/Float->floatValue()F":{
return ((Double) dvmObject.getValue()).floatValue();
}
}
return super.callFloatMethodV(vm, dvmObject, signature, vaList);
}
@Override
public float callFloatMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
switch (signature) {
case "java/lang/Float->floatValue()F":{
return ((Double) dvmObject.getValue()).floatValue();
}
}
return super.callFloatMethodV(vm, dvmObject, signature, vaList);
}
@Override
public boolean callBooleanMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
switch (signature) {
case "java/lang/Boolean->booleanValue()Z": {
return (boolean) dvmObject.getValue();
}
}
return super.callBooleanMethodV(vm, dvmObject, signature, vaList);
}
@Override
public boolean callBooleanMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
switch (signature) {
case "java/lang/Boolean->booleanValue()Z": {
return (boolean) dvmObject.getValue();
}
}
return super.callBooleanMethodV(vm, dvmObject, signature, vaList);
}
case 1004337890: {
return new StringObject(vm, "/data/user/0/com.xingin.xhs");
}
case 1004337890: {
return new StringObject(vm, "/data/user/0/com.xingin.xhs");
}
public void callInit3() {
String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
int i = 830009223;
ArrayObject objArr = new ArrayObject();
DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
System.out.println(result);
}
public void callInit3() {
String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
int i = 830009223;
ArrayObject objArr = new ArrayObject();
DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
System.out.println(result);
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!