目前主流 APP ,都会把加密算法放入 SO 文件中,以防止用户逆向。所以研究 APP 算法,最简单的办法就是新建一个 Android 项目,并引入该 SO 进行调试 ( 需要该 SO 文件没有验证机制 ) 。
本文分为 3 篇,简要介绍怎样研究一个 APP 的 SO 算法。第一篇主要介绍 Android NDK 的开发流程,让读者对于 SO 开发有一个直观理解。第二篇讲述怎样引入一个没有源文件的 SO,进行编译运行。第三篇则会介绍通过 IDA Pro 调试 SO 文件。
这是第一篇,分为两个部分,第一部分是建立一个基础的 Android 项目,第二部分是引入 C 文件并运行。
首先新建一个没有 NDK 的 Android 的项目,完全参考安卓 官方教程
其次新建一个输入框,一个按键和一个文本输出框,Android 程序的布局如下图所示:
紧接着在 MainActivity 中添加 calMessage 函数并关联到 Button 上
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void calMessage(View view) {
TextView editText = findViewById(R.id.editText);
String msg = editText.getText().toString();
msg = "trans msg: " + msg;
TextView showText = findViewById(R.id.textView);
showText.setText(msg);
editText.setText("");
}
}
最后运行,结果如下:
现在我们来改造一下这个 APP,使得按下按钮的时候,可以调用 C 语言将字符串反转。
Android 目前有两种引入方式,分别是通过 CMake 和 ndk-build。官方推荐使用 CMake,因此我们这里也使用 CMake 进行引入。
首先在项目中新建一个 CPP 目录 app/src/main/cpp
,并在其中添加两个文件
第一个是用于 CMake 的 CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
add_library(translib SHARED translib.c)
target_link_libraries(translib)
第二个就是用于反转字符串的 translib.c
#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
char *trans(char *);
JNIEXPORT jstring JNICALL
Java_com_example_sodemo_MainActivity_transMsg(JNIEnv *env, jobject obj, jstring inputMsg) {
char *inputStr = (char *) (*env)->GetStringUTFChars(env, inputMsg, 0);
char *outputStr = trans(inputStr);
(*env)->ReleaseStringUTFChars(env, inputMsg, inputStr);
return (*env)->NewStringUTF(env, outputStr);
}
char *trans(char *msg) {
size_t msg_len = strlen(msg);
char *result = malloc(msg_len + 1); //+1 for the zero-terminator
for (int i = 0; i < msg_len; i++) {
result[i] = msg[msg_len - i - 1];
}
return result;
}
注意: 其中的函数命名 Java_com_example_sodemo_MainActivity_transMsg 需要符合 JNI 的命名规范,也就是必须包含 Android 包名。以本项目为例,包名为 com.example.sodemo, 所以函数名称必须以 Java_com_example_sodemo 开头
然后在 Android Studio -> File 中选择 Link C++ Project,如下图所示:
然后选择 app/src/main/cpp/CMakeLists.txt
即可
添加成功后,可以在 MainActivity.java 中加入如下代码,以引入 translib
的 SO 库。
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("translib");
}
public native String transMsg(String msg);
}
最终代码如下所示:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("translib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void calMessage(View view) {
TextView editText = findViewById(R.id.editText);
String msg = editText.getText().toString();
msg = "trans msg: " + transMsg(msg);
TextView showText = findViewById(R.id.textView);
showText.setText(msg);
editText.setText("");
}
public native String transMsg(String msg);
}
通过点击 CAL 按钮,可以看到程序调用了 translib
库,最终运行结果如下:
至此,我们就成功的在一个 Android 项目中,引入了包含源文件的 SO 库。下一篇中,我们将继续讲述怎样引入没有源文件的 SO 库。