A, goals,

Recently, I started studying Unidbg again, but with great effort, I didn’t run. Let’s start with a soft touch today.

Today’s target is the calculation method of a sub-APP signature studied before (I)

  • A certain App version 5.5.10

Second, the steps

Let’s put up the frame

Create a new com/fenfei/test package under /unidbg/unidbg-android/ SRC /test/ Java /.

Then create a RunZy class

Public class RunZy extends AbstractJni {public static void main(String[] args) throws IOException {// 1 String apkFilePath = "/ Users/fenfei/Desktop/zy/cn xxxxchuanxxxx. Tieba_5. 5.10 _505100. The apk"; // 2, the full path of the Java class where the function is called, such as a/b/c/d, etc. String classPath = "com/izxxyxx/network/NetCrypto"; // 3, you need to call the method, find the corresponding method in jadx, then click Smail below, copy the Smail code of the method. String methodSign = "sign(Ljava/lang/String; [B)Ljava/lang/String;"; RunZy runZyObj = new RunZy(apkFilePath, ClassPath); runzyobj.destroy ();} // ARM emulator private final ARMEmulator emulator Private Final Module Module; private Final DvmClass TTEncryptUtils; /** ** @param apkFilePath Path of the APK file to be executed * @param ClassPath Java classPath of the function to be executed * @throws IOException */ public RunZy(String apkFilePath, String classPath) throws IOException {// Create app process, Package names can be arbitrary write emulator. = AndroidEmulatorBuilder for32Bit () setProcessName (" com. Fenfei. RunZy "). The build (); / / create instances, simulator to simulate the 32 bit or 64 bit, Here to distinguish the final Memory Memory = emulator. GetMemory (); / / simulator of Memory operation interface / / author support 19 and 23 two SDK Memory. SetLibraryResolver (new // Create DalvikVM, using apK itself, Null vm = ((AndroidARMEmulator) emulator).createdAlviKVM (new File(apkFilePath)); vm.setVerbose(true); Vm. setJni(this); new AndroidModule(emulator, vm).register(memory); DalvikModule dm = vm.loadLibrary("net_crypto", // call jni dm.calljni_onload (emulator); module = dm.getModule(); // emulator.tracecode (module.base, Module.base + module.size); // TTEncryptUtils = vm.resolveclass (classPath);} /** * Close the simulator * @throws IOException */ private void destroy() throws IOException { emulator.close(); System.out.println("emulator destroy..."); } }Copy the code

Run native_init

From our previous analysis, we know that native_init needs to be executed before executing the sign function

// runZyObj.initCall();
    private void initCall(){
        TTEncryptUtils.callStaticJniMethod(emulator,"native_init()V");
    }
Copy the code

To perform a

java.lang.UnsupportedOperationException: com/izxxyxx/common/base/BaseApplication->getAppContext()Landroid/content/Context;
	at com.github.unidbg.linux.android.dvm.AbstractJni.callStaticObjectMethodV(AbstractJni.java:402)

Copy the code

This error is easy to fix, so let’s override callStaticObjectMethodV to implement this function

@Override public DvmObject<? > callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) { switch (signature) { case "com/izxxyxx/common/base/BaseApplication->getAppContext()Landroid/content/Context;" : return vm.resolveClass("android/content/Context", vm.resolveClass("android/content/ContextWrapper", vm.resolveClass("android/content/Context"))).newObject(signature); return super.callStaticObjectMethodV(vm,dvmClass,signature,vaList); }Copy the code

This getAppContext we implemented in the previous article, so we’re going to follow suit.

Let me run it again. Ok, native_init is done.

Perform sign

As we know from the previous analysis, the input parameter of sign has two parameters. The first parameter is a string, which is actually a URL. The second parameter is also the encryption result in the so, which is a BUf. Let’s play around with an entry from the hook result.

String InBuf = "50027f7f7f7f8e8e8e8e8e1......" ; String ret = runZyObj.getSign(methodSign ,new StringObject(runZyObj.vm, "https://zyadapi.izxxyxx.com/ad/popup_ad") ,hexStringToBytes(InBuf)); // Out Rc=v2-1ff7402d2b4fa9a4c39b3853262f18fd System.out.printf("ret:%s\n", ret); @param methodSign passes in information about the function you want to execute, Function signature requiring full smALI syntax format * @param args is the argument required by the function to be called * @return function call result */ private String getSign(String methodSign, Object... The args) {/ / using jni calls incoming function signatures corresponding method () Object value = TTEncryptUtils. CallStaticJniMethodObject (emulator, methodSign, args).getValue(); return value.toString(); }Copy the code

Then run up

java.lang.UnsupportedOperationException: android/content/Context->getClass()Ljava/lang/Class;
	at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:349)
Copy the code

GetClass = getClass; getClass = getClass

@Override public DvmObject<? > callObjectMethodV(BaseVM vm, DvmObject<? > dvmObject, String signature, VaList vaList) { switch (signature) { case "android/content/Context->getClass()Ljava/lang/Class;" : return vm.resolveClass("java/lang/Class"); } return super.callObjectMethodV(vm, dvmObject, signature, vaList); }Copy the code

Continue to run

java.lang.UnsupportedOperationException: java/lang/Class->getSimpleName()Ljava/lang/String;
	at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:349)
Copy the code

This time we need a getSimpleName what is this value? I don’t know, and I’m going to show you how to find this value, but let me write a value here.

case "java/lang/Class->getSimpleName()Ljava/lang/String;" : return new StringObject(vm, "izxxyxx");Copy the code

Keep running,

java.lang.UnsupportedOperationException: cn/xiaochuankeji/tieba/common/debug/AppLogReporter->reportAppRuntime(Ljava/lang/String; Ljava/lang/String;) V at com.github.unidbg.linux.android.dvm.AbstractJni.callStaticVoidMethodV(AbstractJni.java:576)Copy the code

Debug and other sensitive, this error will be used in the later analysis. So let’s just do reportAppRuntime

@Override public void callStaticVoidMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) { switch (signature) { case "cn/xiaochuankeji/tieba/common/debug/AppLogReporter->reportAppRuntime(Ljava/lang/String; Ljava/lang/String;) V": return; } throw new UnsupportedOperationException(signature); }Copy the code

Since this function does not return a value, we simply return. Continue to run…

java.lang.UnsupportedOperationException: android/content/Context->getFilesDir()Ljava/io/File;
	at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:349)
Copy the code

Want to read a file? Let’s implement one

case "android/content/Context->getFilesDir()Ljava/io/File;" : return vm.resolveClass("java/io/File");Copy the code

Continue to run

java.lang.UnsupportedOperationException: java/lang/Class->getAbsolutePath()Ljava/lang/String;
	at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:349)
Copy the code

Get path? We’ll give him one, too

case "java/lang/Class->getAbsolutePath()Ljava/lang/String;" : return new StringObject(vm, "/sdcard");Copy the code

Come again

java.lang.UnsupportedOperationException: android/os/Debug->isDebuggerConnected()Z
	at com.github.unidbg.linux.android.dvm.AbstractJni.callStaticBooleanMethodV(AbstractJni.java:154)
Copy the code

Is it debugged? I’m not gonna let you do that

@Override
public boolean callStaticBooleanMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
    switch (signature) {
        case "android/os/Debug->isDebuggerConnected()Z":
            return Boolean.FALSE;
    }
    return super.callStaticBooleanMethodV(vm,dvmClass,signature,vaList);
}
Copy the code

I have to tell you that I’m not debugging at all.

java.lang.UnsupportedOperationException: android/os/Process->myPid()I
	at com.github.unidbg.linux.android.dvm.AbstractJni.callStaticIntMethodV(AbstractJni.java:174)
Copy the code

Pid? To give you one

@Override
public int callStaticIntMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
    switch (signature) {
        case "android/os/Process->myPid()I":
            return 123;
    }

    return super.callStaticIntMethodV(vm,dvmClass,signature,vaList);
}
Copy the code

The ultimate a run

ret:v2-ABC1ff7402d2b4fa9a4c39b3853262f18fd
emulator destroy...
Copy the code

Oh yeah, the results are in.

The result is sad

Before we Hook ff7402d2b4fa9a4c39b3853262f18fd ran out now as a result of the v2-1 is the result of the v2 – ABC1ff7402d2b4fa9a4c39b3853262f18fd, not yourself.

With the result round hero, we can run several groups, if we are sure that the simulation results are executed with a fixed ABC, that is easy to do, directly filter out the line.

But we’re writing a tutorial. We have to figure it out. How do you figure that out? What if there is something wrong with the results of the simulation execution? We’ll do that next time.

Third, summary

Unidbg performs a pure algorithm, and the effect is just that. It is these impure so, all play C, but also insist on hooking up with the Jave layer, deliberately embarrass us.

Cloth clothes warm root fragrant poetry book taste long

TIP: The purpose of this article is only one is learning more backward techniques and train of thought, if anyone use this technology to get illegal commercial interests the legal liabilities are their operators, and the author and it doesn’t matter, this paper involves the knowledge of code project can go to my friends to fly star come undone, welcome to join star learn together to explore technology knowledge. Have a problem can add me WX: FENfei331 discussion.

Wechat public account: Fenfei safety, the latest technology dry goods real-time push