一次还原算法的另类途径——动态库引用

一次还原算法的另类途径

一般来说我们还原算法,就要老老实实的静态分析,动态分析,有反调试就国反调试。不过我现在发现,现在的反调试越来越不好过了,加上还有部分签名验证等乱七八糟的东西。就真的让人苦闷了。本次我们另辟蹊径,我们不过反调试和签名验证。直接把关键算法的库给他扒出来,在我们自己的应用中分析。你这回没辙了吧。

关键算法位置

这个比较容易,静态分析直接上,没啥好说的,直接上代码

int __fastcall Java_com_xxxxxxxx_generateCheckToken(int a1, int a2, int a3, int a4)
{
  int v4; // r7
  int v5; // r4
  int v6; // r6
  int result; // r0
  int v8; // r5
  int v9; // ST00_4
  int v10; // [sp+4h] [bp-1Ch]

  v10 = a4;
  v4 = a3;
  v5 = a1;
  v6 = (*(int (**)(void))(*(_DWORD *)a1 + 676))();
  result = (*(int (__fastcall **)(int, int, _DWORD))(*(_DWORD *)v5 + 676))(v5, v10, 0);
  v8 = result;
  if ( !v6 )
    return 0;
  if ( result )
  {
    v9 = generate_checktoken(v6, result);
    (*(void (__fastcall **)(int, int, int))(*(_DWORD *)v5 + 680))(v5, v4, v6);
    (*(void (__fastcall **)(int, int, int))(*(_DWORD *)v5 + 680))(v5, v10, v8);
    result = (*(int (__fastcall **)(int, int))(*(_DWORD *)v5 + 668))(v5, v9);
  }
  return result;
}

中间过程

这里省略了我是如果寻找签名验证和反调试过程的,一句话总结,千万不要一股脑的静态分析。先要把思路理清,让我的程序吐出终端程序相关信息。

柳暗花明

正当我苦苦寻找绕过限制方法的时候,转念一向。既然关键算法都在so的库里,那我自己造个小程序来分析算法不久行了。干嘛非要在源程序里。于是有了一下的分析。
这里写图片描述
我们开始了工程,如图把动态库放到libs文件夹,这里我还造过jniLibs文件夹,在java目录下,但没有成功,所以就不说了。
app目录build.gradle改成这样

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.example.administrator.testcso"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        ndk{
            moduleName "MathKit"

            ldLibs "log"

            abiFilters "armeabi","armeabi-v7a","x86"
        }
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        sourceSets{
            main{
                jniLibs.srcDirs = ['libs']
            }
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

gradle.properties添加一句
org.gradle.jvmargs=-Xmx1536m
android.useDeprecatedNdk=true
上面一句本来就有。

package com.sxxx.wxxxxx;

/**
 * Created by Administrator on 2017/12/12.
 */

public class Wxxxxxxxxtion {
    static {
        System.loadLibrary("utility");
    }
    public  native String generateCheckToken(String paramString1, String paramString2);
    public  String getchecktoken() {
        String result = "";
        return generateCheckToken("6140757656", "3C734D407E22A7B7DB0EBAFC8755D647A071CC80");
    }

}

自己造个类如图,要符合ndk调用规则。
主类很简单,

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView calview;
        Button calbutton;
        calbutton=(Button)findViewById(R.id.bt_calc);
        calview=(TextView)findViewById(R.id.tv_calc);
        calbutton.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v){
                String str="点击事件";
                WeiboApplication tokenob=new WeiboApplication();
                str=tokenob.getchecktoken();
                calview.setText(str);
            }
        });
    // Example of a call to a native method
    TextView tv = (TextView) findViewById(R.id.sample_text);
    tv.setText(stringFromJNI());
    }

添加成这样。

好编译,安装,成功。别急,还没完。

修改库文件的出事化函数

虽然似乎大功告成,但事实告诉我,我的程序在点击了按钮时间后,并没有成功运行。这里写图片描述
这里是调试信息,经过这次我感悟到,凡是异常退出,必须要找类似这种信息,瞎猜根本没用。
我们看下:其实这里是因为加载不到动态库,我们的动态库函数还没调用,也就是肯定在jni_load函数开始的地方就发生了异常。
其实这里的异常信息并没有截取全面,因为是后来截取的:

.text:0000306C 20 1C                       MOVS    R0, R4
.text:0000306E 79 44                       ADD     R1, PC          ; "com/sina/weibo/WeiboApplication"
.text:00003070 2A 1C                       MOVS    R2, R5
.text:00003072 06 23                       MOVS    R3, #6
.text:00003074 FF F7 CE FF                 BL      registerWeiboNativeMethods
.text:00003078 00 28                       CMP     R0, #0
.text:0000307A 0B D0                       BEQ     loc_3094
.text:0000307C 0A 49                       LDR     R1, =(aComSinaWeiboDa - 0x3088)
.text:0000307E 2A 1C                       MOVS    R2, R5
.text:00003080 48 32                       ADDS    R2, #0x48 ; 'H'
.text:00003082 20 1C                       MOVS    R0, R4
.text:00003084 79 44                       ADD     R1, PC          ; "com/sina/weibo/data/sp/EncryptSharedPre"...
.text:00003086 02 23                       MOVS    R3, #2
.text:00003088 FF F7 C4 FF                 BL      registerWeiboNativeMethods
.text:0000308C 00 28                       CMP     R0, #0
.text:0000308E 01 D0           
signed int __fastcall JNI_OnLoad(int a1, int a2, int a3)
{
  int v3; // r4
  signed int result; // r0
  int v5; // [sp+4h] [bp-14h]
  int v6; // [sp+8h] [bp-10h]

  v6 = a3;
  v5 = 0;
  if ( !(*(int (**)(void))(*(_DWORD *)a1 + 24))()
    && (v3 = v5, registerWeiboNativeMethods(v5, "com/sina/weibo/WeiboApplication", off_9044, 6))
    && registerWeiboNativeMethods(v3, "com/sina/weibo/data/sp/EncryptSharedPreferences", off_908C, 2) )
  {
    result = 65540;
  }
  else
  {
    result = -1;
  }
  return result;
}

进过不断的实验,发现有两点可疑,函数的返回值。可能错误返回-1就没法加载了。
用010edit把这里改一下,其实这里分析了半天不知怎么改:

ext:00003080 48 32                       ADDS    R2, #0x48 ; 'H'
.text:00003082 20 1C                       MOVS    R0, R4
.text:00003084 79 44                       ADD     R1, PC          ; "com/sina/weibo/data/sp/EncryptSharedPre"...
.text:00003086 02 23                       MOVS    R3, #2
.text:00003088 FF F7 C4 FF                 BL      registerWeiboNativeMethods
.text:0000308C 00 28                       CMP     R0, #0
.text:0000308E 01 D0                       BEQ     loc_3094
.text:00003090 02 48                       LDR     R0, =0x10004
.text:00003092 01 E0                       B       locret_3098
.text:00003094             ; ---------------------------------------------------------------------------
.text:00003094
.text:00003094             loc_3094                                ; CODE XREF: JNI_OnLoad+12↑j
.text:00003094                                                     ; JNI_OnLoad+2A↑j ...
.text:00003094 01 20                       MOVS    R0, #1
.text:00003096 40 42                       NEGS    R0, R0
.text:00003098
.text:00003098             locret_3098                             ; CODE XREF: JNI_OnLoad+42↑j
.text:00003098 3E BD                       POP     {R1-R5,PC}
.text:00003098             ; End of function JNI_OnLoad

这个函数错误会往下跳到loc_3094,如何才能不让它执行。把他改成movs r0,#1改成ldr r0,=0x10004
事实证明,汇编不是我想怎么改都可以的,这里的代码很难直接改成其他复制语句,偶然发现0000连续4个零,是mov r0,r0
来点暴力的,把所有B loc_3094 都改成mov r0,r0;
哈哈。保存。
运行,哈市不行。这次的提示不贴了,但大致是说找不到库com.sixx.xxxx.wxxxxxxxplication里面的scalcutes函数,这是啥函数,我保证我没掉过。后来发现这个函数是jni_load里面的registerWeiboNativeMethods(v5, “com/sina/weibo/WeiboApplication”, off_9044, 6)里调用的,而这个off_9044就是这个函数的名字,反编译没直接替换过来。

带着很多的无望,我把调用registerWeiboNativeMethods的函数全部,全部换成mov r0,r0

经过更改,最终编程了这样

signed int __fastcall JNI_OnLoad(int a1, int a2, int a3)
{
  int v4; // [sp+4h] [bp-14h]
  int v5; // [sp+8h] [bp-10h]

  v5 = a3;
  v4 = 0;
  (*(void (**)(void))(*(_DWORD *)a1 + 24))();
  return 65540;
}

010保存一下,放到libs下每个文件夹里,ok.
重编译,成功。算法运行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值