Android逆向-Android基础逆向8

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36869808/article/details/79319712

0X00 前言

说明

感谢蛋总栽培,本文章首发于I春秋,未经本人允许严禁转载。
夜已深,人未眠。
smali层也差不多了,Native层也该开始了。希望可以尽早学习完毕。

导航

博客导航戳这里
练习资源戳这里

时间

开始:2018年2月13日01:55:30

内容

1.简单的NDK编程。
2.demo反编译分析。
3.smali层和Native交互。
4.IDA 简单应用。
5.实例分析。

0x01 简单的NDK编程

说明

之前因为就是没有点自动生成,所以一直是在手动生成,出了很多的问题。现在学聪明了,使用Android Studio自动生成简单又方便。

生成方式

这里写图片描述

选择include c++support

然后一直点击下一步,下一步。即可。

要点:

第一个要点:

这里写图片描述
这个是调用Native层的原生库。

第二个要点:

这里写图片描述
这个是调用原生函数。

第三个要点:

这里写图片描述
这里就是我们写c语言的地方。框框里的就是我们交互的函数。

0x02 IDA 简要说明

IDA 界面

这里写图片描述

我的IDA是7.0版本

首先来说说这个头像。是一个女人。这个是历史上第一个程序员。

使用方法

这里写图片描述
拖进去就可以了,有一本好像是IDA指南的书,有兴趣可以去看一下。
点确定就可以。

布局说明

file目录

对文件进行基本操作。
这里写图片描述

搜索目录

这里写图片描述

窗口说明

反汇编窗口

这里写图片描述

16进制窗口

这里写图片描述

导出函数窗口(重要窗口)

这里写图片描述

string窗口(重要窗口)

这里写图片描述

区段窗口(重要窗口)

这里写图片描述

0x03 demo分析

目的

更改so文件的数据。

第一步

首先我们在输出窗口中找到一个java开头的函数,就是和我们相交互的界面。

这里写图片描述

第二步

鼠标双击在反汇编窗口查看,因为我们的demo只有一个交互方法所以我们就不对demo进行反编译分析了。
这里写图片描述

第三步

着这里我们发现了我们demo中的字符串。双击进行导航。
这里写图片描述

导航之后。就会发现一个data段。

这里写图片描述

第四步

找到相对应的16进制的编码。、
这里写图片描述

第五步

用FlexHEX对字符串进行修改

把++改成了hh。但是要记得所有的文件夹里的so文件都要进行更改。
这里写图片描述

回编译

这个是原来demo的展示
这里写图片描述
现在是更改后的demo
这里写图片描述

总结

1.其实ARM汇编我也不是很熟悉,但是根据8086汇编来说,还是可以进行简单的猜测,然后进行一些操作。
2.demo分析的意义是
(1)打开so文件。
(2)修改so文件16进制码之后也可以修改判断逻辑等。
(3)修改后进行回编译。

0x04 java层和Native层交互

重点部分

1.定义Native层方法。

public native String stringFromJNI();
    public native String getHelloJni();
    public native void updateFile(String path);

2.调用Native层方法。

  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(getHelloJni());
        updateFile("boys.txt");
    }

3. .cpp文件

#include <jni.h>
#include <string>
#include <android/log.h>
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
#define TAG "hai"

JNIEXPORT jstring

JNICALL
Java_com_example_hanlei_myapplication_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_hanlei_myapplication_MainActivity_getHelloJni(JNIEnv *env, jobject instance) {

    // TODO


    return env->NewStringUTF("Hello");
}extern "C"
JNIEXPORT void JNICALL
Java_com_example_hanlei_myapplication_MainActivity_updateFile(JNIEnv *env, jobject instance,
                                                              jstring path_) {
    const char *path = env->GetStringUTFChars(path_, 0);

    // TODO
    if(path!=NULL)
    {
        LOGV("from c file_path  %s",path);
    }
    env->ReleaseStringUTFChars(path_, path);
}

逻辑分析

通过env->GetStringUTFChars(path_, 0)进行访问java层传入的代码。

0x05 实例分析

工具

IDA 7.0
Android killer 1.3.0
夜神模拟器

样品

霸哥磁力搜索

start

第一步 测试

首先先对app进行反编译然后回编译运行监测。

这里写图片描述

这里发现出现了问题,肯定是因为有验证。那么我们现在需要判断的就是样本是什么验证。

现在重新签名app。
这里写图片描述

问题出现。样本弹出了问题。

我们就此判断出现的是签名验证。

第二步 java层分析

首先来看下java层的逻辑。

首先关注的就是onCreate。

这里写图片描述

 @Override
  public void onCreate(Bundle paramBundle)
  {
    ADRTLogCatReader.onContext(this, "com.aide.ui");
    super.onCreate(paramBundle);
    setContentView(2130903041);
    qian(226776851);

首先是 setContentView(2130903041);加载界面。
然后调用了一个叫做qian的函数。

 public void qian(int paramInt)
  {
    try
    {
      if (getPackageManager().getPackageInfo(getPackageName(), 64).signatures[0].hashCode() != paramInt) {
        Toast.makeText(this, 1, 1).show();
      }
      return;
    }
    catch (PackageManager.NameNotFoundException localNameNotFoundException)
    {
      for (;;) {}
    }
  }

这个函数一看就知道是签名验证的。

然后在smali代码中找到qian函数。

然后我们直接删除了qian函数的调用。就可以跳过验证。

这里写图片描述

当然这种方法值对java层进行了签名验证的有效。

回编译测试。

反编译之后发现还是不能正常运行。所以很有可能是在Native层进行了签名验证。

第三步 Native层分析

我们在MainActivity里找到了一个 Native调用。

这里写图片描述

我们在逻辑层搜索bug。

这里写图片描述

发现这两句代码中有bug

    MainActivity.this.bug();
            Object localObject1 = MainActivity.this.bug() + URLEncoder.encode(MainActivity.this.����.getText().toString());

如果之后的bug在之后没有参与函数的运算的时候那么直接删除这两行调用就可以了。

但是这个bug参与了运算,所以我们就要去so文件里进行分析。

打开IDA,找到bug函数

这里写图片描述

双击跳转,F5查看伪c代码。当然仅仅是提供一个参考。

这里写图片描述

int __fastcall Java_com_bug_bt_MainActivity_bug(int a1)
{
  int v1; // r4

  v1 = a1;
  getSignHashCode();
  return (*(int (__fastcall **)(int, const char *))(*(_DWORD *)v1 + 668))(v1, "http://www.btsou.org/web?q=");
}

这个就是函数的调用部分。

整个代码的意思就是说,首先调用getSignHashCode();,然后返回一个字符串,字符串就是之前我们在java层进行使用的字符串。
那么我们的破解方式就有两种。

第一种破解方式

第一种就是把getSignHashCode();这个函数的调用删掉。
我们现在来进行操作,由于之前进行了一个demo的修改与分析,这里使用的方式是一样的。

首先找到 16进制编码。

这里写图片描述

然后用FlexHEX打开。然后找到具体的位置。

这里写图片描述

然后清空即可。

这里写图片描述

然后覆盖 回编译进行测试

运行成功。

第二种破解方式。

就是我们处理到退出函数就可以了 一般来说就是exit。

首先是getSignHashCode函数

这里写图片描述

F5查看伪c代码。

这里写图片描述

我们根本看不懂这些鬼东西。接着向下看,然后发现了这样一段代码。

 if ( result != 226776851 )
    exit(0);
  return result;
}

这个代码就是判断的部分。然后我们只要更改就可以了。

有两种方法。

第一个就是更改判断,第二个就是删除掉exit函数。

我们先来进行删除exit函数。

方法和上面的一样。

这里写图片描述

删除16进制码。

这里写图片描述

反编译即可

测试通过,当然也可以更改一下if语句。

结束

收获

1.通过对java层签名验证的分析。我可以通过反馈的字符串来进行签名验证,这样就可以保证在简单的删除下是不能对我的签名验证造成威胁的,然后我还可以通过各种加密算法,来隐藏我的字符串。
2.Native层代码编写
3.Native层代码逆向分析
4.Native层逆向修改
5.过签名验证。

时间

2018年2月13日18:56:05

以上。

没有更多推荐了,返回首页