android逆向奇技淫巧九:frida常见java层的加密/hash算法自吐

  逆向分析X东时,遇到了狠角色,通过fidderl抓包如下:登陆的包和返回包的body全都不是明文!这是我分析了这么多app以来头一次遇到这种情况!

     

 

   以前抓包分析,遇到最多的情况就是某些字段加密,x东时我遇到第一个数据包的body都加密的app;以前可以根据字段名称在java层或so层查找加密的方法,这次body的字段都加密了,字段名称都不知道,怎么找?

  有同学就会说了:既然加密了,先解密呗! 没错,思路是这样的,但是加密算法是啥呀? 密钥又是啥了? 这些都不知道,怎么解密?

  可能又有同学会说:那就静态分析呗,肯定能找到加密的方法和密钥!理论上是这样的,但x东怎么说也是大厂,技术实例杠杠滴,(1)代码都做过了很严重的混淆,静态分析有那么容易?如果静态分析很容易了,还要动态调试干嘛了? (2)参考之前tls1.3的分析,这里双方对称加密的密钥有可能是动态协商出来的,并不是在客户端内置写死的,静态分析没任何用!这里又要用到frida了!

  先说说加解密算法:常见的加解密/hash算法,都是顶级数学家发明的!哪怕就是顶尖的码农,他也是码农,要想设计安全的加密算法是不现实的,所以互联网公司的码农知道各种加密算法的适用场景已经很不错了,绝对不会有设计加密算法的实力!具体到工程实现,肯定是调用现有的API来加解密,突破口就在这里了!但是在x东这里逆向,我也不知道登陆时用了那种加密算法,只能广撒网了:把所有已知的加密算法都hook,看看到底是哪些被调用了,以及传入的参数都是啥!下面是frida的js代码:

Java.perform(function() {
    //Base64
    var base64=Java.use('android.util.Base64');
    var string=Java.use('java.lang.String');
    /*base64.encode.overload('[B', 'int', 'int', 'int').implementation = function(){
        send("=================base64 encode====================");
        send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
        send(arguments[0]);
        send(arguments[1]);
        send(arguments[2]);
        send(arguments[3]);
        var data=this.encode(arguments[0],arguments[1],arguments[2],arguments[3])
        send("base64:"+string.$new(data));
        return data;
    }*/
    
    /*base64.decode.overload('[B', 'int', 'int', 'int').implementation = function(){
        send("=================base64 decode====================");
        send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
        send(arguments[0]);
        send(arguments[1]);
        send(arguments[2]);
        send(arguments[3]);
        var data=this.decode(arguments[0],arguments[1],arguments[2],arguments[3])
        send("base64:"+string.$new(data));
        return data;
    }*/
   

    // MD SHA 
    var messageDigest=Java.use('java.security.MessageDigest');
    // update
    for(var i = 0; i < messageDigest.update.overloads.length; i++){
        messageDigest.update.overloads[i].implementation = function(){
            var name=this.getAlgorithm()
            send("================="+name+"====================");
            send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
            if(arguments.length == 1){
                send(arguments[0]);
                this.update(arguments[0]);
            }else if(arguments.length == 3){
                send(arguments[0]);
                send(arguments[1]);
                send(arguments[2]);
                this.update(arguments[0],arguments[1],arguments[2]);
            }
        }
    }
    // digest
    for(var i = 0; i < messageDigest.digest.overloads.length; i++){
        messageDigest.digest.overloads[i].implementation = function(){
            var name=this.getAlgorithm()
            send("================="+name+"====================");
            send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
            if(arguments.length == 0){
                var data=this.digest();
                send(data);
                return data;
            }else if(arguments.length == 1){
                send(arguments[0]);
                var data=this.digest(arguments[0]);
                send(data);
                return data;
            }else if(arguments.length == 3){
                send(arguments[0]);
                send(arguments[1]);
                send(arguments[2]);
                var data=this.digest(arguments[0],arguments[1],arguments[2]);
                send(data);
                return data;
            }
        }
    }

    //MAC
    var mac=Java.use('javax.crypto.Mac');
    for(var i = 0; i < mac.doFinal.overloads.length; i++){
        mac.doFinal.overloads[i].implementation = function(){
            var name=this.getAlgorithm()
            send("================="+name+"====================");
            send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
            if(arguments.length == 0){
                var data=this.doFinal();
                send(data);
                return data;
            }else if(arguments.length == 1){
                send(arguments[0]);
                var data=this.doFinal(arguments[0]);
                send(data);
                return data;
            }else if(arguments.length == 2){
                send(arguments[0]);
                send(arguments[1]);
                var data=this.doFinal(arguments[0],arguments[1]);
                send(data);
                return data;
            }
        }
    }
    
    // DES DESede AES PBE RSA
    var cipher=Java.use('javax.crypto.Cipher');
     for(var i = 0; i < cipher.doFinal.overloads.length; i++){
        cipher.doFinal.overloads[i].implementation = function(){
            var name=this.getAlgorithm()
            send("================="+name+"====================");
            send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
            if(arguments.length == 0){
                var data=this.doFinal();
                send(data);
                return data;
            }else if(arguments.length == 1){
                send(arguments[0]);
                var data=this.doFinal(arguments[0]);
                send(data);
                return data;
            }else if(arguments.length == 2){
                send(arguments[0]);
                send(arguments[1]);
                var data=this.doFinal(arguments[0],arguments[1]);
                send(data);
                return data;
            }else if(arguments.length == 3){
                send(arguments[0]);
                send(arguments[1]);
                send(arguments[2]);
                var data=this.doFinal(arguments[0],arguments[1],arguments[2]);
                send(data);
                return data;
            }else if(arguments.length == 5){
                send(arguments[0]);
                send(arguments[1]);
                send(arguments[2]);
                send(arguments[3]);
                send(arguments[4]);
                var data=this.doFinal(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]);
                send(data);
                return data;
            }else{
                send(arguments[0]);
                send(arguments[1]);
                send(arguments[2]);
                send(arguments[3]);
                var data=this.doFinal(arguments[0],arguments[1],arguments[2],arguments[3]);
                send(data);
                return data;
            }
        }
    }
    
    //KEY
    var secretKey=Java.use('javax.crypto.spec.SecretKeySpec');
    for(var i = 0; i < secretKey.$init.overloads.length; i++){
        secretKey.$init.overloads[i].implementation = function(){
            var name=this.getAlgorithm()
            send("=================KEY====================");
            //send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
            if(arguments.length == 2){
                send(arguments[0]);
                send(arguments[1]);
                this.$init(arguments[0],arguments[1]);
            }else if(arguments.length == 4){
                send(arguments[0]);
                send(arguments[1]);
                send(arguments[2]);
                send(arguments[3]);
                this.$init(arguments[0],arguments[1],arguments[2],arguments[3]);
            }
        }
    }
    //IV
    //DES KEY  
    //DESede KEY
    //PBE KEY salt
}); 

  如上所示:其实就是把java层所有涉及编码、加解密、hash的函数都hook,看看传参、函数的调用栈等!用这个脚本去hook x东登陆时的加密算法调用,打印的日志如下:

  (1)我输入的密码是123456,这里明显在用md5转化:jd.wjlogin_sdk.util.MD5.encrypt32 这个方法可以重点研究下(比如用objection hook一下,看看参数都是啥)!

[*] =================MD5====================
[*] java.lang.Throwable
	at java.security.MessageDigest.digest(Native Method)
	at jd.wjlogin_sdk.util.MD5.encrypt32(Proguard:36)
	at com.jd.lib.login.unit.a.b.f(AccountFragment.java:605)
	at com.jd.lib.login.unit.a.b.onClick(AccountFragment.java:8346)
	at android.view.View.performClick(View.java:5637)
	at android.view.View$PerformClick.run(View.java:22429)
	at android.os.Handler.handleCallback(Handler.java:751)
	at android.os.Handler.dispatchMessage(Handler.java:95)
	at android.os.Looper.loop(Looper.java:154)
	at android.app.ActivityThread.main(ActivityThread.java:6153)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
[*] [49, 50, 51, 52, 53, 54]

  (2)这里还用SHA1,不知道在干嘛,所以com.jd.sec.utils.LoadDoor.getToken、jd.wjlogin_sdk.common.a.b.j值得好好研究!

[*] =================SHA1====================
[*] java.lang.Throwable
	at java.security.MessageDigest.digest(Native Method)
	at com.jd.sec.utils.LoadDoor.getToken(Native Method)
	at com.jd.sec.utils.LoadDoor.a(LoadDoor.java:69)
	at com.jd.sec.logo.TokenManager.getToken(TokenManager.java:13)
	at com.jingdong.common.login.LoginUserBase.getDeviceJson(LoginUserBase.java:288)
	at com.jingdong.common.utils.gf.getDeviceFinger(UserUtil.java:220)
	at jd.wjlogin_sdk.common.a.b.j(Proguard:1000)
	at jd.wjlogin_sdk.common.a.a.b(Proguard:25)
	at jd.wjlogin_sdk.c.d.a(Proguard:708)
	at jd.wjlogin_sdk.common.inland.WJLoginInland.getCaptchaSid(Proguard:2848)
	at com.jd.lib.login.unit.a.n.a(AccountPresenter.java:108)
	at com.jd.lib.login.unit.a.b.onClick(AccountFragment.java:8346)
	at android.view.View.performClick(View.java:5637)
	at android.view.View$PerformClick.run(View.java:22429)
	at android.os.Handler.handleCallback(Handler.java:751)
	at android.os.Handler.dispatchMessage(Handler.java:95)
	at android.os.Looper.loop(Looper.java:154)
	at android.app.ActivityThread.main(ActivityThread.java:6153)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
[*] [101, 105, 100, 65, 48, 56, 52, 48, 56, 49, 50, 51, 51, 97, 115, 57, 80, 68, 121, 115, 57, 56, 112, 79, 83, 66, 79, 79, 118, 83, 76, 65, 107, 47, 117, 102, 118, 122, 119, 56, 114, 110, 71, 75, 121, 99, 86, 102, 47, 55, 55, 109, 85, 87, 88, 114, 98, 54, 112, 111, 78, 80, 66, 81, 121, 113, 119, 102, 72, 68, 82, 52, 113, 73, 53, 68, 84, 100, 111, 57, 109, 82, 56, 75, 85, 120, 73, 83, 87, 56, 98, 73, 105, 111, 79, 48, 107, 76, 83, 106, 103, 70, 72, 70, 102, 86, 110, 73, 106, 100, 101, 113, 111, 106, 77, 122, 50, 48, 50, 49, 54, 53, 49, 49, 52, 54, 51, 54, 57, 57, 50, 52, 56, 50, 97, 38, 48, 33, 91, 42, 55, 81, 49, 86]

  (3)这里用上key了,还用HMAC的散列:目的是为了防止加密数据被删改!

[*] =================KEY====================
[*] [51, 52, 54, 54, 57, 99, 54, 54, 97, 101, 56, 51, 52, 53, 55, 97, 57, 97, 56, 101, 55, 98, 52, 100, 48, 52, 49, 55, 102, 48, 50, 102]
[*] HmacSHA256
[*] =================HmacSHA256====================
[*] java.lang.Throwable
	at javax.crypto.Mac.doFinal(Native Method)
	at com.jingdong.sdk.jdhttpdns.core.SignatureHelper.HMACSHA256(SignatureHelper.java:90)
	at com.jingdong.sdk.jdhttpdns.core.SignatureHelper.signature(SignatureHelper.java:62)
	at com.jingdong.sdk.jdhttpdns.core.ParamHelper.getDnsQueryStr(ParamHelper.java:54)
	at com.jingdong.sdk.jdhttpdns.core.Request.getUrl(Request.java:137)
	at com.jingdong.sdk.jdhttpdns.core.NetworkHandler.performRequest(NetworkHandler.java:75)
	at com.jingdong.sdk.jdhttpdns.core.NetworkHandler.requests(NetworkHandler.java:46)
	at com.jingdong.sdk.jdhttpdns.core.WorkRunnable.run(WorkRunnable.java:39)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
	at java.util.concurrent.FutureTask.run(FutureTask.java:237)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
	at java.lang.Thread.run(Thread.java:761)
[*] [106, 100, 109, 111, 98, 105, 108, 101, 38, 119, 108, 109, 111, 110, 105, 116, 111, 114, 46, 109, 46, 106, 100, 46, 99, 111, 109, 38, 119, 105, 102, 105, 38, 97, 110, 100, 114, 111, 105, 100, 38, 49, 54, 50, 50, 56, 54, 52, 55, 57, 55, 51, 51, 54, 38, 98, 56, 51, 101, 99, 54, 97, 54, 55, 53, 97, 100, 98, 97, 54, 97, 38, 57, 46, 53, 46, 52, 95, 56, 56, 49, 51, 54]

  (4)这里貌似找到了关键函数:jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew

[*] =================SHA1====================
[*] java.lang.Throwable
	at java.security.MessageDigest.digest(Native Method)
	at java.security.MessageDigest.digest(MessageDigest.java:426)
	at java.security.MessageDigest.digest(Native Method)
	at com.jd.sec.utils.LoadDoor.getToken(Native Method)
	at com.jd.sec.utils.LoadDoor.a(LoadDoor.java:69)
	at com.jd.sec.logo.TokenManager.getToken(TokenManager.java:13)
	at com.jingdong.common.login.LoginUserBase.getDeviceJson(LoginUserBase.java:288)
	at com.jingdong.common.utils.gf.getDeviceFinger(UserUtil.java:220)
	at jd.wjlogin_sdk.common.a.b.j(Proguard:1000)
	at jd.wjlogin_sdk.common.a.a.b(Proguard:25)
	at jd.wjlogin_sdk.c.d.a(Proguard:708)
	at jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew(Proguard:131)
	at com.jd.lib.login.unit.a.n.a(AccountPresenter.java:145)
	at com.jd.lib.login.unit.a.e.onSuccess(AccountFragment.java:570)
	at com.jd.verify.common.a.run(Proguard:13)
	at android.os.Handler.handleCallback(Handler.java:751)
	at android.os.Handler.dispatchMessage(Handler.java:95)
	at android.os.Looper.loop(Looper.java:154)
	at android.app.ActivityThread.main(ActivityThread.java:6153)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
[*] [-126, -106, -116, 66, 57, -90, -31, -58, 80, 65, 44, -84, -60, 94, -102, -24, -102, -40, -86, -37]
[*] [-126, -106, -116, 66, 57, -90, -31, -58, 80, 65, 44, -84, -60, 94, -102, -24, -102, -40, -86, -37]

  用objection hook上面列举的几个关键函数:

com.jingdong.app.mall on (samsung: 7.1.2) [usb] # android hooking watch class_method  jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew --dump-args --dump-backtrac
e --dump-return
(agent) Attempting to watch class jd.wjlogin_sdk.common.inland.WJLoginInland and method JDLoginWithPasswordNew.
(agent) Hooking jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew(java.lang.String, java.lang.String, java.lang.String, java.lang.String, jd.wjlogin_sdk.common.listener.OnLoginCallback)
(agent) Registering job 463404. Type: watch-method for: jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew
com.jingdong.app.mall on (samsung: 7.1.2) [usb] # android hooking watch class_method  com.jd.sec.utils.LoadDoor.getToken --dump-args --dump-backtrace --dump-return
(agent) Attempting to watch class com.jd.sec.utils.LoadDoor and method getToken.
(agent) Hooking com.jd.sec.utils.LoadDoor.getToken(java.lang.Object)
(agent) Registering job 063371. Type: watch-method for: com.jd.sec.utils.LoadDoor.getToken
com.jingdong.app.mall on (samsung: 7.1.2) [usb] # android hooking watch class_method  jd.wjlogin_sdk.common.a.b.j --dump-args --dump-backtrace --dump-return
(agent) Attempting to watch class jd.wjlogin_sdk.common.a.b and method j.
(agent) Hooking jd.wjlogin_sdk.common.a.b.j()
(agent) Registering job 063544. Type: watch-method for: jd.wjlogin_sdk.common.a.b.j
com.jingdong.app.mall on (samsung: 7.1.2) [usb] # android hooking watch class_method  jd.wjlogin_sdk.util.MD5.encrypt32 --dump-args --dump-backtrace --dump-return
(agent) Attempting to watch class jd.wjlogin_sdk.util.MD5 and method encrypt32.
(agent) Hooking jd.wjlogin_sdk.util.MD5.encrypt32(java.lang.String)
(agent) Registering job 184672. Type: watch-method for: jd.wjlogin_sdk.util.MD5.encrypt32
com.jingdong.app.mall on (samsung: 7.1.2) [usb] # (agent) [184672] Called jd.wjlogin_sdk.util.MD5.encrypt32(java.lang.String)

  打印的日志如下:

com.jingdong.app.mall on (samsung: 7.1.2) [usb] # (agent) [184672] Called jd.wjlogin_sdk.util.MD5.encrypt32(java.lang.String)
(agent) [184672] Backtrace:
        jd.wjlogin_sdk.util.MD5.encrypt32(Native Method)
        com.jd.lib.login.unit.a.b.f(AccountFragment.java:605)
        com.jd.lib.login.unit.a.b.onClick(AccountFragment.java:8346)
        android.view.View.performClick(View.java:5637)
        android.view.View$PerformClick.run(View.java:22429)
        android.os.Handler.handleCallback(Handler.java:751)
        android.os.Handler.dispatchMessage(Handler.java:95)
        android.os.Looper.loop(Looper.java:154)
        android.app.ActivityThread.main(ActivityThread.java:6153)
        java.lang.reflect.Method.invoke(Native Method)
        com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)

(agent) [184672] Arguments jd.wjlogin_sdk.util.MD5.encrypt32(123456)
(agent) [184672] Return Value: e10adc3949ba59abbe56e057f20f883e
(agent) [063544] Called jd.wjlogin_sdk.common.a.b.j()
(agent) [063544] Backtrace:
        jd.wjlogin_sdk.common.a.b.j(Native Method)
        jd.wjlogin_sdk.common.a.a.b(Proguard:25)
        jd.wjlogin_sdk.c.d.a(Proguard:708)
        jd.wjlogin_sdk.common.inland.WJLoginInland.getCaptchaSid(Proguard:2848)
        com.jd.lib.login.unit.a.n.a(AccountPresenter.java:108)
        com.jd.lib.login.unit.a.b.onClick(AccountFragment.java:8346)
        android.view.View.performClick(View.java:5637)
        android.view.View$PerformClick.run(View.java:22429)
        android.os.Handler.handleCallback(Handler.java:751)
        android.os.Handler.dispatchMessage(Handler.java:95)
        android.os.Looper.loop(Looper.java:154)
        android.app.ActivityThread.main(ActivityThread.java:6153)
        java.lang.reflect.Method.invoke(Native Method)
        com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)

(agent) [063371] Called com.jd.sec.utils.LoadDoor.getToken(java.lang.Object)
(agent) [063371] Backtrace:
        com.jd.sec.utils.LoadDoor.getToken(Native Method)
        com.jd.sec.utils.LoadDoor.a(LoadDoor.java:69)
        com.jd.sec.logo.TokenManager.getToken(TokenManager.java:13)
        com.jingdong.common.login.LoginUserBase.getDeviceJson(LoginUserBase.java:288)
        com.jingdong.common.utils.gf.getDeviceFinger(UserUtil.java:220)
        jd.wjlogin_sdk.common.a.b.j(Proguard:1000)
        jd.wjlogin_sdk.common.a.b.j(Native Method)
        jd.wjlogin_sdk.common.a.a.b(Proguard:25)
        jd.wjlogin_sdk.c.d.a(Proguard:708)
        jd.wjlogin_sdk.common.inland.WJLoginInland.getCaptchaSid(Proguard:2848)
        com.jd.lib.login.unit.a.n.a(AccountPresenter.java:108)
        com.jd.lib.login.unit.a.b.onClick(AccountFragment.java:8346)
        android.view.View.performClick(View.java:5637)
        android.view.View$PerformClick.run(View.java:22429)
        android.os.Handler.handleCallback(Handler.java:751)
        android.os.Handler.dispatchMessage(Handler.java:95)
        android.os.Looper.loop(Looper.java:154)
        android.app.ActivityThread.main(ActivityThread.java:6153)
        java.lang.reflect.Method.invoke(Native Method)
        com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)

(agent) [063371] Arguments com.jd.sec.utils.LoadDoor.getToken(com.jingdong.app.mall.JDApp@56edf59)
(agent) [063371] Return Value: 3506QJLNHI545OL22KN764E0KL3F01D16OO229923124CPP3467LLLK6DCQ1VCF12D
(agent) [063544] Return Value: {"eid":"eidA084081233as9PDys98pOSBOOvSLAk\/ufvzw8rnGKycVf\/77mUWXrb6poNPBQyqwfHDR4qI5DTdo9mR8KUxISW8bIioO0kLSjgFHFfVnIjdeqojMz","token":"3506QJLNHI545OL22KN764E0KL3F01D16OO229923124CPP3467LLLK6DCQ1VCF12D","unionwsws":"{\"devicefinger\":\"eidA084081233as9PDys98pOSBOOvSLAk\\\/ufvzw8rnGKycVf\\\/77mUWXrb6poNPBQyqwfHDR4qI5DTdo9mR8KUxISW8bIioO0kLSjgFHFfVnIjdeqojMz\",\"jmafinger\":\"ebMdecnT8fvsTrLtkO9NXqp6tTZhAGGjpEOgxuDg8ULxB5gIhoqNZX266wOt+0Ed8NrcDmKTQHBkAyH+Fe5745Q==\"}"}
(agent) [184672] Called jd.wjlogin_sdk.util.MD5.encrypt32(java.lang.String)
(agent) [184672] Backtrace:
        jd.wjlogin_sdk.util.MD5.encrypt32(Native Method)
        com.jd.lib.login.unit.a.b.f(AccountFragment.java:605)
        com.jd.lib.login.unit.a.b.m(AccountFragment.java:61)
        com.jd.lib.login.unit.a.e.onSuccess(AccountFragment.java:570)
        com.jd.verify.common.a.run(Proguard:13)
        android.os.Handler.handleCallback(Handler.java:751)
        android.os.Handler.dispatchMessage(Handler.java:95)
        android.os.Looper.loop(Looper.java:154)
        android.app.ActivityThread.main(ActivityThread.java:6153)
        java.lang.reflect.Method.invoke(Native Method)
        com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)

(agent) [184672] Arguments jd.wjlogin_sdk.util.MD5.encrypt32(123456)
(agent) [184672] Return Value: e10adc3949ba59abbe56e057f20f883e
(agent) [463404] Called jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew(java.lang.String, java.lang.String, java.lang.String, java.lang.String, jd.wjlogin_sdk.common.listener.OnLoginCallback)
(agent) [463404] Backtrace:
        jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew(Native Method)
        com.jd.lib.login.unit.a.n.a(AccountPresenter.java:145)
        com.jd.lib.login.unit.a.e.onSuccess(AccountFragment.java:570)
        com.jd.verify.common.a.run(Proguard:13)
        android.os.Handler.handleCallback(Handler.java:751)
        android.os.Handler.dispatchMessage(Handler.java:95)
        android.os.Looper.loop(Looper.java:154)
        android.app.ActivityThread.main(ActivityThread.java:6153)
        java.lang.reflect.Method.invoke(Native Method)
        com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)

(agent) [463404] Arguments jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew(18888888888, eacadc3949ba59abbe56e057f20f883e, WIQAxQABAAAAAAAAAAAAMO2PcCPs73q8Ab1lswJ94Kvv3e2lwE8c-mu8Wy6Qom21i0WRSiUZKlC6c_vEU5rA4gAAAAA, LEZAEgABAAABedp0U0IAgBxTXfHLWqEFODZP8KIupy_HB945JxIcQJOj4W_nMHNp6cnfdFjX7JJoShRJYjY74L5B863OOSDWrNFxBpBd0FUKyWbSY1qzEPG18CQ6oaY8vBbyWpoR-uW2XP3vR_eDGFMzs_5iEetZlsrpMrPq2ctmHTF5vvXJkwb41MWRzItC, com.jd.lib.login.unit.a.q@91765f8)
(agent) [063544] Called jd.wjlogin_sdk.common.a.b.j()
(agent) [063544] Backtrace:
        jd.wjlogin_sdk.common.a.b.j(Native Method)
        jd.wjlogin_sdk.common.a.a.b(Proguard:25)
        jd.wjlogin_sdk.c.d.a(Proguard:708)
        jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew(Proguard:131)
        jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew(Native Method)
        com.jd.lib.login.unit.a.n.a(AccountPresenter.java:145)
        com.jd.lib.login.unit.a.e.onSuccess(AccountFragment.java:570)
        com.jd.verify.common.a.run(Proguard:13)
        android.os.Handler.handleCallback(Handler.java:751)
        android.os.Handler.dispatchMessage(Handler.java:95)
        android.os.Looper.loop(Looper.java:154)
        android.app.ActivityThread.main(ActivityThread.java:6153)
        java.lang.reflect.Method.invoke(Native Method)
        com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)

(agent) [063371] Called com.jd.sec.utils.LoadDoor.getToken(java.lang.Object)
(agent) [063371] Backtrace:
        com.jd.sec.utils.LoadDoor.getToken(Native Method)
        com.jd.sec.utils.LoadDoor.a(LoadDoor.java:69)
        com.jd.sec.logo.TokenManager.getToken(TokenManager.java:13)
        com.jingdong.common.login.LoginUserBase.getDeviceJson(LoginUserBase.java:288)
        com.jingdong.common.utils.gf.getDeviceFinger(UserUtil.java:220)
        jd.wjlogin_sdk.common.a.b.j(Proguard:1000)
        jd.wjlogin_sdk.common.a.b.j(Native Method)
        jd.wjlogin_sdk.common.a.a.b(Proguard:25)
        jd.wjlogin_sdk.c.d.a(Proguard:708)
        jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew(Proguard:131)
        jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew(Native Method)
        com.jd.lib.login.unit.a.n.a(AccountPresenter.java:145)
        com.jd.lib.login.unit.a.e.onSuccess(AccountFragment.java:570)
        com.jd.verify.common.a.run(Proguard:13)
        android.os.Handler.handleCallback(Handler.java:751)
        android.os.Handler.dispatchMessage(Handler.java:95)
        android.os.Looper.loop(Looper.java:154)
        android.app.ActivityThread.main(ActivityThread.java:6153)
        java.lang.reflect.Method.invoke(Native Method)
        com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)

(agent) [063371] Arguments com.jd.sec.utils.LoadDoor.getToken(com.jingdong.app.mall.JDApp@56edf59)
(agent) [063371] Return Value: 8906OHHHMJ829PRC4LO7F05DKL1C87463OO9656DF403EPPE287LLLK797Q1V3417B
(agent) [063544] Return Value: {"eid":"eidA084081233as9PDys98pOSBOOvSLAk\/ufvzw8rnGKycVf\/77mUWXrb6poNPBQyqwfHDR4qI5DTdo9mR8KUxISW8bIioO0kLSjgFHFfVnIjdeqojMz","token":"8906OHHHMJ829PRC4LO7F05DKL1C87463OO9656DF403EPPE287LLLK797Q1V3417B","unionwsws":"{\"devicefinger\":\"eidA084081233as9PDys98pOSBOOvSLAk\\\/ufvzw8rnGKycVf\\\/77mUWXrb6poNPBQyqwfHDR4qI5DTdo9mR8KUxISW8bIioO0kLSjgFHFfVnIjdeqojMz\",\"jmafinger\":\"ebMdecnT8fvsTrLtkO9NXqp6tTZhAGGjpEOgxuDg8ULxB5gIhoqNZX266wOt+0Ed8NrcDmKTQHBkAyH+Fe5745Q==\"}"}
(agent) [463404] Return Value: (none)

  我输入的电话号码18888888888和密码123456一览无遗!jd.wjlogin_sdk.common.inland.WJLoginInland.JDLoginWithPasswordNew这个就是登陆函数实锤了!这里话说回来,这么明显的函数,为啥不混淆了?

 

===================================分割线=================================

   Java层因为加密函数名称没法混淆,所以很容易找到并hook,so层的加密算法怎么识别了?有一个简单的常量特征识别法:一般来说,这些加密算法都会使用一些固定的常量用来异或(注意不是用来做if判断),比如:

  • MD5的常量
Context->a = 0x67452301;
Context->b = 0xefcdab89;
Context->c = 0x98badcfe;
Context->d = 0x10325476;
  • sha256的常量
#define    K_00_19        0x5a827999UL
#define    K_20_39        0x6ed9eba1UL
#define    K_40_59        0x8f1bbcdcUL
#define    K_60_79        0xca62c1d6UL
  • AES的常量(太多了,这里只放一部分,详细的常量建议参考链接2)
static const uint32_t TE0[256] =
{
    0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
    0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
    0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL, 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL,
    0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL, 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL,
    0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL, 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL,
    0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL, 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL,
    0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL, 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL,
    0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL, 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL,
    0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL, 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL,
    0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL, 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL,
    0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL, 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL,
    0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL, 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL,
    0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL, 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL,
    0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL, 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL,
    0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL, 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL,
    0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL, 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL,
    0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL, 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL,
    0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL, 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL,
    0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL, 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL,
    0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL, 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL,
    0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL, 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL,
    0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL, 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL,
    0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL, 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL,
    0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL, 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL,
    0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL, 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL,
    0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL, 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL,
    0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL, 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL,
    0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL, 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL,
    0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL, 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL,
    0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL, 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL,
    0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL, 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL,
    0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL, 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL,
};
  •  base64的字符集
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

  其他自定义的加密算法可能没有固定的套路,只能hook可疑函数,打印函数的参数和返回值来判断,参数或返回值一般有这三种:

  •   指针/地址:这个是一段字符串的buf或类的对象;建议用hexdump查看内容
  •        数值:一般是字符串的长度
  •        有些函数可能没有返回值,就要重点观察参数了;因为函数一旦执行,结果肯定要保存的,否则就失去了函数调用的意义;没有返回值就只能把结果保存在参数了

 

  最后就是找一些标准的加密算法so库,hook其导出函数了,从导出的符号名称大致判断是哪种加密算法!

 

参考:

1、https://opensource.apple.com/source/  这里有很多加密算法的c实现

2、https://github.com/WaterJuice/WjCryptLib/tree/master/lib  同上

  

posted @ 2021-06-05 12:39  第七子007  阅读(6402)  评论(0编辑  收藏  举报