经常在一些地方看到类似于这样的介绍:「一些重要的字段不要放在Java代码中,需要放在native。」 但是事实上,并没有绝对的安全,即使是将数据放在native,我们也可以使用IDA等工具进行查看,对于未加密的常量字段数据,我们可以在.rodata数据段直接看到数据内容,即使是通过插入花指令等方式使数据看着没那么容易理解,有经验的逆向者也可以通过代码阅读、调试动态库等方式了解原数据内容。

一、编译一个动态库

先写一个动态库,CMakeLists.txt内容如下:cmake_minimum_required(VERSION 3.6)

add_library(reversetest

SHARED

reverse.cpp)

find_library(

log-lib

log)

target_link_libraries(reversetest ${log-lib})

reverse.cpp中的代码内容如下:#include

#include

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,"reservetest" ,__VA_ARGS__)

extern "C" JNIEXPORT void

JNICALL

Java_com_wsy_jnidemo_test_ReverseTest_reverseData(

JNIEnv

*env,

jclass){

const char *content = "content";

LOGI("content is: %s", content);

}

extern "C" JNIEXPORT void

JNICALL

Java_com_wsy_jnidemo_test_ReverseTest_reverseJudge(

JNIEnv

*env,

jclass,

jint count

){

if (count > 1000) {

LOGI("count is %d, count > 1000", count);

} else {

LOGI("count is %d, count <= 1000", count);

}

}

Java调用:public class ReverseTest{

static {

System.loadLibrary("reversetest");

}

public static native void reverseData();

public static native void reverseJudge(int count);

}private void doReverseTest() {

ReverseTest.reverseData();

ReverseTest.reverseJudge(10000);

}

点击externalNativeBuildRelease,将生成的动态库复制到jniLibs目录下,运行。

输出日志如下,很正常:format,png

二、修改动态库

首先我们需要了解的是,无论是exe、so、dll、txt、doc,还是其他格式的文件,它们都只是文件,都是二进制数据,只是生成和解析方式不同。比如我们可以使用文本编辑器将txt解析成我们能够理解的文本内容,也可以将我们输入的文本内容保存成txt;我们可以使用Word将doc解析成我们能够理解的内容,也可以将我们输入的内容保存成doc...

对于so文件,我们可以使用IDA Pro进行解析、修改。

1. IDA界面简介

IDA Pro在安装完成后,会分别有64位和32位的可执行文件。对于刚才生成的libreversetest.so这个动态库文件,使用64位的程序打开,打开后界面如下:format,png

2. 修改函数内容「修改常量字符串」

在左边的函数表中,我们可以使用CTRL + F寻找我们需要查看的函数:

format,png

双击函数名,可查看其汇编指令,再按F5,得到反汇编后的C代码:format,png

双击右边的content,即可跳转到其定义处:format,png

这个时候我们可以使用IDA Pro自带的编辑器修改其内容,也可以根据其偏移地址0x6E0使用其他二进制编辑器修改,或者自己写个代码修改文件的内容。

这里选择用IDA自带的功能修改:点击Edit->Patch program->Changebytes...

format,png 将其修改为61 - 67(也就是a-g):

format,png

确认后可以看到,这个字段的内容已经被我们成功修改了

format,png

但是这个时候并没有保存数据至原动态库中,我们点击Edit->Patch program->Apply patches to input file..即可保存至原文件。

「修改指令」

双击另一个函数,看到以下源码:format,png

这个动态库里的指令反汇编得到的代码和编写时的内容不是完全一致,但是不影响,表达的含义相同。

对于指令的修改,汇编视图会更友好,切换到汇编视图,内容如下:format,png

我们知道,LT代表less than,GT代表greater than,GE代表greater or equals,只要我们将LT修改为GE即可进入判断的另一个分支:

选中这行指令,点击Edit->Patch program->Assemble...,对于arm架构的动态库,我的电脑会报Sorry, this processor module doesn't support the assembler,但是直接改数据是没问题的,修改指令为以下内容:format,pngformat,png

和刚才一样的操作,点击Apply patches to input file..保存修改至原文件。

对于x86_64的动态库,我的设备点击Edit->Patch program->Assemble...是没问题的,所以这里也对x86_64架构的动态库操作一遍:

原指令如下,我们将jl修改为jge即可进入另一个逻辑分支:

原指令:

format,png

修改后:

format,png

format,png

format,png

三、运行验证

刚才我们修改了一处常量字符串和一处判断指令,现在将修改好的arm64-v8a的动态库放进工程对应目录,运行,结果如下:format,png

四、如何加固

程序本身就是相当于可阅读的东西,因此,无论如何加固,都只是增加攻破的难度,我们可以通过添加花指令、隐藏符号等方式来达到加固的作用,比如我们尝试

format,png

用IDA Pro反汇编支付宝中的一个动态库: 可以看到,打开后发现函数名都被修改成了这种让人看不下去的名字,大大增加逆向的难度。

作者:省油的灯

来源:https://juejin.cn/post/6943521608858337293

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐