一、前言

当我们对某个使用原生库(native library)的恶意软件或者应用进行分析或渗透测试时,如果能够对库函数进行隔离和执行是再好不过的事情,这样做我们就可以使用其自身的代码来调试对抗恶意软件。举个例子,如果恶意软件包含加密字符串,并使用原生函数完成解密过程,你可以选择花大量时间逆向分析算法来编写自己的解密函数,也可以选择直接利用这个函数来处理任意输入数据。如果使用后一种方法,即使恶意软件作者完全改变了软件的加密算法,你也可能不需要做任何修改即可完成任务。在这篇文章中,我将向读者介绍如何利用并执行原生库函数,即使调用这些函数时需要传入JVM实例作为参数也没问题。

在之前的一篇文章中,我介绍了如何从Android原生代码中创建一个Java虚拟机,但我没有给出一个具体的例子。因此,我会在本文中给出一个具体的例子来说明这一点。

我们至少可以使用两种方法来调用原生函数。第一种方法是对应用进行修改,使应用接受你的输入数据并传递给原生函数。例如,你可以写一个intent filter,将其转化为Smali语言,将代码添加到目标应用中,修改manifest文件,运行应用,使用adb命令将带有参数的intent发送给目标应用即可。另一种方法更好,你可以添加一个小型socket或web服务器,使用curl向其发送请求,这种方法不需要修改manifest文件。

第二种方法的目标是创建一个通过命令行运行的小型原生可执行工具,用来加载库文件、调用目标函数、传递我们输入的任意参数。这样我们就可以单独运行一个可执行文件,而不需要运行整个应用程序,因此调试起来也就更为方便。

二、目标应用

我创建了一个示例应用,方便读者按照教程学习,应用名为“native-harness-target”。你可以使用以下命令将工程文件复制到本地并完成编译(记得修改其中的“$ANDROID_*”变量)。

git clone https://github.com/CalebFenton/native-harness-target.git

cd native-harness-target

echo 'ndk.dir=$ANDROID_NDK' > local.properties

echo 'sdk.dir=$ANDROID_SDK' >> local.properties

./gradlew build

APK文件最终生成在“app/build/outputs/apk/”目录。这篇文章中,我使用的是一个x86模拟器镜像以及一个名为“app-universal-debug.apk”的应用。

该应用程序包含一个加密字符串,并会在运行时使用原生库对字符串进行解密。以下是在Smail中字符串的解密过程:

const/16 v3, 0x57

new-array v1, v3, [B

fill-array-data v1, :array_2a

.local v1, "encryptedStringBytes":[B

invoke-static {}, Lorg/cf/nativeharness/Cryptor;->getInstance()Lorg/cf/nativeharness/Cryptor;

move-result-object v0

.line 21

.local v0, "c":Lorg/cf/nativeharness/Cryptor;

# v3 contains a String made from encrypted bytes

new-instance v3, Ljava/lang/String;

invoke-direct {v3, v1}, Ljava/lang/String;->([B)V

# Call the decryption method, move result back to v3

invoke-virtual {v0, v3}, Lorg/cf/nativeharness/Cryptor;->decryptString(Ljava/lang/String;)Ljava/lang/String;

move-result-object v3

三、构建Harness工具

我使用的是Tim 'diff' Strazzere开发的一款名为“native-shim”的工具(Tim是RedNaga的一名成员)作为整套利用工具的基础,我将这个工具命名为“Harness”。在Android中,shim就像一个中间垫片,作用是加载一个库,并调用其“JNI_OnLoad”方法。它可以使调试工作更加简单,我们只需要使用调试器启动shim,并将具体路径以参数形式传递给目标库即可。我们可以设置调试器的断点,在库加载时触发断点,这样就能进入“JNI_OnLoad”函数的处理流程。此外,native-shim还可以加载库文件(.so文件)、获取函数的引用并调用函数,这一切对我们来说都非常实用。

首先,我添加了部分代码以初始化一个Java虚拟机实例,并将该实例传递给JNI_OnLoad函数,这样处理可以使JNI的初始化过程更为准确。如果没有真实的虚拟机实例,JNI库的内部状态看起来可能会有些奇怪。不同库文件的JNI_OnLoad的实现可能不尽相同,但这并不重要,重要的是这些实现都会检查JNI版本,如这段代码所示。因此我们需要创建一个虚拟机实例。

printf(" [+] Initializing JavaVM Instance\n");

JavaVM *vm = NULL;

JNIEnv *env = NULL;

int status = init_jvm(&vm, &env);

if (status == 0) {

printf(" [+] Initialization success (vm=%p, env=%p)\n", vm, env);

} else {

printf(" [!] Initialization failure (%i)\n", status);

return -1;

}

printf(" [+] Calling JNI_OnLoad\n");

onLoadFunc(vm, NULL);

我们的最终目标是通过harness工具,开启一个socket服务器,读取socket上传输的参数,使用这些参数来调用函数。这样一来,解密函数就会变成一个服务,我们可以简单使用一个Python脚本与其通信。

四、理解目标函数

在调用函数前,我们需要了解函数的签名(即参数个数和参数类型)及函数的返回类型。我们可以先看一下org.cf.nativeharness.Cryptor类的反编译代码,类中包含decryptString原生方法的声明,如下所示:

public class Cryptor {

private static Cryptor instance = null;

public static Cryptor getInstance() {

if (instance == null) {

instance = new Cryptor();

}

return instance;

}

android java调用参数,如何从命令行调用Android JNI函数并传递Java对象参数相关推荐

  1. Android日志[进阶篇]三-Logcat 命令行工具

    Android日志[进阶篇]一-使用 Logcat 写入和查看日志 Android日志[进阶篇]二-分析堆栈轨迹(调试和外部堆栈) Android日志[进阶篇]三-Logcat命令行工具 Androi ...

  2. Electron-vue开发实战7——命令行调用与系统级别右键菜单项的实现

    原文首发在我的博客,欢迎关注! 前言 前段时间,我用electron-vue开发了一款跨平台(目前支持主流三大桌面操作系统)的免费开源的图床上传应用--PicGo,在开发过程中踩了不少的坑,不仅来自应 ...

  3. java调用jar并传参,Java项目导出为jar包+导出第三方jar包+使用命令行调用+传参

    Java项目导出为jar包+导出第三方jar包+使用命令行调用+传参 一.打包 情况1:不需要向程序传参数,并且程序没有使用第三方jar包 Eclipse上导出jar: 然后选择一个java文件作为入 ...

  4. java main命令行参数_java使用命令行参数

    有时你想在运行程序时将信息传递到一个程序中.这通过将命令行参数(command-line arguments )传递给main() 来实现.命令行参数是程序执行时在命令行中紧跟在程序名后的信息.在Ja ...

  5. Java中命令行调用大坑

    Java中命令行调用大坑 背景 我司有一个查询服务接口机,QPS大概40~50,调用方式是Java调用Shell命令行的方式,核心代码如下: Process ps = Runtime.getRunti ...

  6. Java word转pdf Linux/windows跨平台 格式完美(利用命令行调用libreoffice)

    参考了里面的libreoffice的用法:https://blog.csdn.net/qwert678000/article/details/72770109 需求描述 最近在做word报表的自动生成 ...

  7. VB6 实现命令行调用时附着到原控制台

    Public Declare Function AttachConsole Lib "kernel32.dll" (ByVal ProcessID As Integer) As B ...

  8. 使用命令行对Android应用签名

    基于命令行的方式对APK文件进行签名.  第一步:生成RSA密钥对  keytool -genkeypair -alias magick.keystore -keyalg RSA -validity ...

  9. python命令行参数作用_Python命令行参数解析模块argparse

    前言 更多内容,请访问我的 个人博客. 以前 optparse 比较火,但是在python2.7版本后,官方不再维护这个模块,转而大力支持 argparse . argparse 模块可以让人轻松编写 ...

最新文章

  1. Springboot解决IDEA读取properties配置文件的中文乱码问题
  2. C#之 VS2008 之 Extension Methods
  3. rust营火为什么放不下去_为什么大蒜头在超市里不发芽,买回家放几天后就发芽了?...
  4. 6行代码!用Python将PDF转为word
  5. 基于Native Client的编程框架
  6. RocketMQ错误消息重试策略之重试情况的分析
  7. MySql命令行基本操作
  8. 掌握这些Android开发热门前沿知识,跳槽薪资翻倍
  9. java各个版本的特性_Java各个版本的新特性
  10. python基础:os.path的相关操作
  11. [记录]Python的master-worker和epoll模式
  12. Python3 发票导出XML转Excel
  13. 安装loadrunner,缺少VC2005_sp1_with_atl的错
  14. linux在服务器压缩文件夹,Linux服务器压缩文件夹
  15. matlab中求特征值的eig函数说明
  16. oracle驱动包下载
  17. U盘显示0字节怎么恢复完整解决教程
  18. 如何使用磁性套索工具进行抠图
  19. Cadence Allegro 鼠标轨迹快捷键的设置图文教程及视频演示
  20. 智安网络丨第一次听人把云计算讲这么明白!

热门文章

  1. 最近发现有很多人一直在问苹果ID双重认证怎么关闭。
  2. 学C的第一天(初识C语言、VS创建C语言程序、数据类型简单了解、简单了解变量)
  3. php开发中常用字符串函数总结
  4. js如何往数组Array中添加删除元素
  5. 助力武汉抗击疫情,湖北科研资料共享
  6. AD PCB打印1:1
  7. 本土回忆! 即使你走的再远,也不能忘了让你生长的老家文化~
  8. 哪款蓝牙耳机音质好又耐用?便宜耐用的蓝牙耳机
  9. 全民美颜时代中,美颜SDK担任着什么角色?
  10. NVIDIA Jetson官网资料整理