实现对第三方应用任意SO注入
0x01
应用在Android中运行,从外部对该进程可以进行任意SO文件动态注入,就是应用动态运行我们的SO文件
0x02
基本的逻辑是:
1. 获取目标进程的pid,关联目标进程:通过遍历查找/proc/pid/cmdline文件中是否含有目标进程名process_name,若有则进程名对应的进程号即为pid。接着,直接调用函数ptrace_attach(pid)即可完成关联。
2. 获取并保存目标进程寄存器值:用ptrace(PTRACE_GETREGS, pid, NULL, &saved_regs)
3. 获取目标进程的dlopen,dlsym函数的绝对地址:首先通过遍历/proc/pid/maps文件分别得到本进程中dlopen函数所在动态库的基地址local_module_base和目标进程dlopen函数所在动态库的基地址remote_module_base,接着获取本进程dlopen函数的绝对地址local_addr = (void*)dlopen。需要明白的是,不同进程中相同的动态库中的同一个函数的偏移地址一定是一样的,所以目标进程dlopen函数的绝对地址为:local_addr – local_module_base + remote_module_base。dlsym同理
4. 获取并保存目标进程的堆栈,设置dlopen函数的相关参数,将要注入的SO的绝对路径压栈:当我们的要执行的函数的某些参数需要压入堆栈的时候,就需要提前保存堆栈状态,调用ptrace_readdata(pid, (void *)regs.ARM_sp, (void *)sbuf, sizeof(sbuf)),其中sbuf为char数组,用来存放堆栈。调用ptrace_writedata(pid, (void *)regs.ARM_sp, (void *)so_path, strlen(so_path) + 1),其中so_path为SO的绝对路径。函数传参规则:前四个参数分别由寄存器r0、r1、r2、r3存放,超过四个参数则压入堆栈。
5. 调用dlopen函数:参数设置好后,设置ARM_pc = dlopen_addr, ARM_lr = 0。调用ptrace_setregs(pid, regs)写入修改后的寄存器值,调用ptrace_continue( pid )使目标进程继续运行。(注:dlopen_addr为0x03获取到的目标进程dlopen函数的绝对地址,ARM_lr = 0的目的在于当目标进程执行完dlopen函数,使目标进程发生异常,从而让本进程重新获得控制权)
6. 调用dlsym函数,获取SO中要执行的函数地址:实现方式与调用dlopen函数类似,不再详述
7. 调用要执行的函数:实现方式与调用dlopen函数类似
8. 恢复目标进程的堆栈,恢复目标进程寄存器值,解除关联,完成SO动态库注:调用ptrace_writedata(pid, (uint8_t *)saved_regs.ARM_sp, (uint8_t *)sbuf, sizeof(sbuf))恢复堆栈,调用ptrace_setregs(pid, &saved_regs)恢复寄存器值,调用ptrace_detach(pid)解除关联,完成SO动态库注入
0x03
我知道都不爱看上边原理,下面直接开始吧
首先我有一个可以root机器(没有别玩了,我是自己买的5儿子)
Linux下安装NDK 在环境变量里配好(kali /etc/profile),加上解压后的NDK路径


下面我们需要编译两个文件 xxxx.so(你的SO),nject(用来注入的)
为了编译我们需要创建两个文件夹在任意目录下

两个文件夹都是xxx.c+jni(文件夹) ,jni下放的是Android.mk文件
1.hello 下的 hello.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <android/log.h>
#include <elf.h>
#include <fcntl.h>
#define LOG_TAG “DEBUG”
#define LOGD(fmt, args…) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##args)
int hook_entry(char * a){
LOGD(“Hook success, pid = %d\n”, getpid());
LOGD(“Hello %s\n”, a);
return 0;
}
hello/jni/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog #增加了对android log 库的链接
LOCAL_MODULE := hello
LOCAL_SRC_FILES := ../hello.c
include $(BUILD_SHARED_LIBRARY) #指定编译为动态库
2.libinject2下的ject.c (太长了加个链接)
http://blog.csdn.net/jinzhuojun/article/details/9900105
找不到asm/user.h 请改为sys/user.h

libinject2/jni/Android.mk
OCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := inject
LOCAL_SRC_FILES := ../inject.c
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
include $(BUILD_EXECUTABLE)
下面就是进行编译这两个文件


一个是so文件一个可执行文件
把他俩push到手机的/data/local/tmp文件夹下 chmod 777 即可
随便PS找到一个进程(我用的com.android.phone)找到进程号,执行./inject

这里要先把libhello文件移动到上面的路径,运行,监控logcat

这里的Hook success 和Hello就是SO内容了,到此SO动态注入成功了
感谢:
http://blog.csdn.net/jinzhuojun/article/details/9900105
http://www.cnblogs.com/jiayy/p/4286828.html
实现对第三方应用任意SO注入的更多相关文章
- Vue导入非模块化的第三方插件功能无效解决方案
一.问题: 最近在写vue项目时,想引入某些非模块化的第三方插件时,总是发现会有报错.且在与本地运行插件测试对比时发现插件根本没有注入到jQuery中(console.log($.fn)查看当前jq有 ...
- 控制反转IOC的依赖注入方式
引言: 项目中遇到关于IOC的一些内容,因为和正常的逻辑代码比较起来,IOC有点反常.因此本文记录IOC的一些基础知识,并附有相应的简单实例,而在实际项目中再复杂的应用也只是在基本应用的基础上扩展而来 ...
- spring boot servlet 注入
spring boot 注入servlet的方法是借助ServletRegistrationBean这个类 例子如下: 先建一个servlet import java.io.IOException; ...
- NetCore+Dapper WebApi架构搭建(四):仓储的依赖注入
上一节我们讲到实体,仓储接口和仓储接口的实现需要遵循约定的命名规范,不仅是规范,而且为了依赖注入,现在我们实现仓储的依赖注入 在NetCore WebApi项目中新添加一个文件夹(Unit),当然你也 ...
- SQL注入工具实践
程序简介 超级SQL注入工具(SSQLInjection)是一款基于HTTP协议自组包的SQL注入工具,支持出现在HTTP协议任意位置的SQL注入,支持各种类型的SQL注入,支持HTTPS模式注入. ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(7):装配SpringBean·依赖注入装配
一.依赖注入的三种方式 在实际环境中实现IoC容器的方式主要分为两大类,一类是依赖查找,依赖查找是通过资源定位,把对应的资源查找回来.另一类则是依赖注入.一般而言,依赖注入可分为3中方式: ...
- C++代码注入
一.C++代码注入原则: 在注入代码中不允许使用API. 在注入代码中不允许使用全局变量. 在注入代码中不允许使用字符串(编译时也被当做全局变量). 在注入代码中不允许使用函数嵌套. 二.注入代码编写 ...
- 重新整理 .net core 实践篇————依赖注入应用[二]
前言 这里介绍一下.net core的依赖注入框架,其中其代码原理在我的另一个整理<<重新整理 1400篇>>中已经写了,故而专门整理应用这一块. 以下只是个人整理,如有问题, ...
- 【转载】Android app 安全测试调研及执行
本文来源于:http://testerhome.com/topics/2209 一.通过在线工具进行测试 1.腾讯金刚审计系统http://service.security.tencent.com 优 ...
随机推荐
- placehoder修改
<textarea class="layui-input description" name="description" lay-verify=" ...
- WebLogic配置自己定义密钥库和SSL的操作手冊
WebLogic配置自己定义密钥库和SSL的操作手冊 (定制标识和定制信任&Keytool&TLS1.0) 1.启用SSLport 保存.重新启动受管Server watermark/ ...
- 【LeetCode】 Rotate List 循环链表
题目:rotate list 解法1: <span style="font-size:18px;">/**LeetCode Rotate List:Given a li ...
- django 类通用视图详解
view() : 该类为所有类视图的父类,处于最底层,仅仅只对请求参数做校验后,给特定请求方法做特定调用. 用法: url中定位到类方法:Aa.as_view() ——> View.as ...
- Material design之Material Theme
Material Theme提供了三方面的内容: 系统组件的颜色可以自定义更改 系统组件添加了触摸反馈动画效果 Activity切换动画效果 系统主题默认被定义在以下三个样式中: 使用Material ...
- Quartz.NET 作业调度
Quartz 简介: Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调 ...
- IOS学习笔记(五)——UI基础UIWindow、UIView
在PC中,应用程序多是使用视窗的形式显示内容,手机应用也不例外,手机应用中要在屏幕上显示内容首先要创建一个窗口承载内容,iOS应用中使用UIWindow.UIView来实现内容显示. UIWindow ...
- jQuery EasyUI介绍
官方定义:http://www.jeasyui.com/ what is JQuery EasyUI ? jQuery EasyUI framework helps you build your we ...
- python学习【第五篇】python函数 (二)
一.装饰器 装饰器:本质就是函数,功能是为其它函数添加附加功能 装饰器的原则: 不修改被修饰函数的源代码 不修改被修饰函数的调用方式 装饰器的知识储备: 装饰器 = 高阶函数 + 函数嵌套 + 闭包 ...
- F - 简单计算器(栈)
F - 简单计算器 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Descripti ...