Android下so注入汇总
/*
* 作者:蟑螂一号
* 原文链接:http://www.sanwho.com/133.html
* 转载请注明出处
*/
Android下so注入是基于ptrace系统调用,因此要想学会android下的so注入,首先需要了解ptrace的用法。
ptrace用法可以参考博客:http://blog.sina.com.cn/s/blog_4ac74e9a0100n7w1.html,也可以在ubuntu下输入man ptrace命令,查看具体描述。
android中进程系统调用劫持可参考博客:http://www.kanxue.com/bbs/showthread.php?t=180461,这是一个android简单的ptrace监控远程进程监控调用的例子。
Android系统是基于Linux系统,在linux系统中可以通过ptrace系统调用实现进程注入。ptrace注入过程大致过程如下:
(1)基于shellcode加载
[1]编写shellcode,shellcode是使用汇编语言写一段汇编程序,该程序实现so库的加载、so库函数查找以及执行库中的函数。
[2]通过远程进程pid,ATTACH到远程进程。
[3]获取远程进程寄存器值,并保存,以便注入完成后恢复进程原有状态。
[4]获取远程进程系统调用mmap、dlopen、dlsym调用地址。
[5]调用远程进程mmap分配一段存储空间,并在空间中写入shellcode、so库路径以及函数调用参数。
[6]执行远程进程shellcode代码。
[7]恢复远程进程寄存器。
[8]detach远程进程。
基于shellcode注入可看雪古河大哥写的libInject,网址: http://bbs.pediy.com/showthread.php?t=141355
其中,dlopen和dlsym是用于打开动态链接库中的函数,将动态链接库中的函数或类导入到本程序中。
dlopen函数定义:
void * dlopen( const char * pathname, int mode );
函数描述:
dlopen()函数以指定模式打开指定的动态链接库文件,并返回一个句柄给dlsym()的调用进程。使用dlclose()来卸载打开的库。 dlsym函数原型是 void* dlsym(void* handle,const char* symbol) 该函数在<dlfcn.h>文件中。 handle是由dlopen打开动态链接库后返回的指针,symbol就是要求获取的函数的名称,函数返回值是void*,指向函数的地址,供调用使用。
(2)直接加载
[1]通过远程进程pid,ATTACH到远程进程。
[2]获取远程进程寄存器值,并保存,以便注入完成后恢复进程原有状态。
[3]获取远程进程系统调用mmap、dlopen、dlsym调用地址。
[4]调用远程进程mmap分配一段存储空间,并在空间中写入so库路径以及函数调用参数。
[5]执行远程进程dlopen,加载so库。
[6]执行远程进程dlsym,获取so库中需要执行的函数地址。
[7]执行远程进程中的函数。
[7]恢复远程进程寄存器。
[8]DETACH远程进程。
目前android so注入的版本基本上都是基于古河大哥的libInject修改而来。关于so注入的项目,还可以参考洗大师的一个开源项目,网址:https://code.google.com/p/libandroidinjector/downloads/list。洗大师注入需要修改elf文件。
提供一个方便测试so注入成功与否的小测试库,代码如下:
1 #include <unstd.h>
2
3 #include <stdio.h>
4
5 #include <android/log.h>
6
7 #define LOG_TAG "test"
8
9 __attribute__((constructor)) void inject () {
10
11 __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,"Hello,I am injected.");
12
13 }
说明:若函数被设定为constructor属性,则该函数会在main()函数执行之前被自动的执行。因此,so注入测试中,只需注入以上代码编译的so库,无需调用注入so的相关函数,即可测试是否注入到远程进程。
补充说明——实现方式
转自:http://ele7enxxh.com/Android-Shared-Library-Injection.html
0x01 获取目标进程的pid,关联目标进程:
通过遍历查找/proc/pid/cmdline文件中是否含有目标进程名process_name,若有则进程名对应的进程号即为pid。接着,直接调用函数ptrace_attach(pid)即可完成关联。
0x02 获取并保存目标进程寄存器值:
直接调用ptrace(PTRACE_GETREGS, pid, NULL, &saved_regs),当然saved_regs要定义为全局变量。
0x03 获取目标进程的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同理,不再详述。
0x04 获取并保存目标进程的堆栈,设置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存放,超过四个参数则压入堆栈。
0x05 调用dlopen函数:
参数设置好后,设置ARM_pc = dlopen_addr, ARM_lr = 0。调用ptrace_setregs(pid, regs)写入修改后的寄存器值,调用ptrace_continue( pid )使目标进程继续运行。(注:dlopen_addr为0x03获取到的目标进程dlopen函数的绝对地址,ARM_lr = 0的目的在于当目标进程执行完dlopen函数,使目标进程发生异常,从而让本进程重新获得控制权)
0x06 调用dlsym函数,获取SO中要执行的函数地址:
实现方式与调用dlopen函数类似,不再详述。
0x07 调用要执行的函数:
实现方式与调用dlopen函数类似,不再详述。
0x08 恢复目标进程的堆栈,恢复目标进程寄存器值,解除关联,完成SO动态库注入:
调用ptrace_writedata(pid, (uint8_t *)saved_regs.ARM_sp, (uint8_t *)sbuf, sizeof(sbuf))恢复堆栈,调用ptrace_setregs(pid, &saved_regs)恢复寄存器值,调用ptrace_detach(pid)解除关联,完成SO动态库注入。
Android下so注入汇总的更多相关文章
- Android下so注入和hook
一.前言 总结一下这两天学习的Android注入so文件,通过遍历got表hook函数调用 1.注入so文件 2.so文件中遍历got表hook函数 二.注入so文件 1)注入进程 1.编程思路分为以 ...
- GitHub上史上最全的Android开源项目分类汇总 (转)
GitHub上史上最全的Android开源项目分类汇总 标签: github android 开源 | 发表时间:2014-11-23 23:00 | 作者:u013149325 分享到: 出处:ht ...
- GitHub上史上最全的Android开源项目分类汇总
今天在看博客的时候,无意中发现了 @Trinea 在GitHub上的一个项目 Android开源项目分类汇总 ,由于类容太多了,我没有一个个完整地看完,但是里面介绍的开源项目都非常有参考价值,包括很炫 ...
- Android 开源项目分类汇总(转)
Android 开源项目分类汇总(转) ## 第一部分 个性化控件(View)主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Galler ...
- Android 开源项目分类汇总
Android 开源项目分类汇总 Android 开源项目第一篇——个性化控件(View)篇 包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView ...
- Android开源项目分类汇总【畜生级别】[转]
Android开源项目分类汇总 欢迎大家推荐好的Android开源项目,可直接Commit或在 收集&提交页 中告诉我,欢迎Star.Fork :) 微博:Trinea 主页:www.t ...
- Android开源项目分类汇总[转]
Android开源项目分类汇总 如果你也对开源实现库的实现原理感兴趣,欢迎 Star 和 Fork Android优秀开源项目实现原理解析欢迎加入 QQ 交流群:383537512(入群理由需要填写群 ...
- Android开源项目分类汇总【畜生级别】
From :http://blog.csdn.net/forlong401/article/details/25459403?c=6c4cd677a617db4655988e41ee081691#t7 ...
- Android开源项目分类汇总-转载
太长了,还是转载吧...今天在看博客的时候,无意中发现了@Trinea在GitHub上的一个项目Android开源项目分类汇总,由于类容太多了,我没有一个个完整地看完,但是里面介绍的开源项目都非常有参 ...
随机推荐
- onkeydown小练习
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [原创.数据可视化系列之八]使用等d3进行灰度图转伪彩色
对灰度图进行彩色化是数据可视化中常见的需求,使用d3在客户端比较容易实现,本文使用d3生成图片,并显示: 代码如下: 代码中首先下载数据文件,然后设定d3的色带信息,生成一个空白的canvas元素,并 ...
- KCF跟踪算法 入门详解
一.算法介绍 KCF全称为Kernel Correlation Filter 核相关滤波算法.是在2014年由Joao F. Henriques, Rui Caseiro, Pedro Martins ...
- SQLServer 学习笔记之超详细基础SQL语句 Part 8
Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 7------------------- --触发器str_trigge ...
- 并发容器(四)ConcurrentHashMap 深入解析(JDK1.6)
这篇文章深入分析的是 JDK1.6的 ConcurrentHashMap 的实现原理,但在JDK1.8中又改进了 ConcurrentHashMap 的实现,废弃了 segments.虽然是已经被 ...
- 【转】CentOS 6.6 升级GCC G++ (当前最新版本为v6.1.0) (完整)
原文地址:https://www.cnblogs.com/lzpong/p/5755678.html 我这里是centos7 升级到gcc8.1,过程差不多,参考这篇文章,记录一下. ---原文--- ...
- As3截图转换为ByteArray传送给后台node的一种方法
最近将以前用As3+Php做的一个画板拿出来改成了As3+nodejs(expressjs4). Node: 1. 将图片存放的路径设置为静态公开的路径. app.use(express.static ...
- Sqlserver数据库中,跨权限执行语句
问题来源:最近有同事需要执行批量删除语句.根据他提供的业务需求,推荐他使用“TRUNCATE TABLE”语句.但使用该语句需要 ALTER权限,这与执行用户的角色不符. 解决办法:使用EXECUTE ...
- 转:C# lock用法
lock 的目的很明确:就是不想让别人使用这段代码,体现在多线程情况下,只允许当前线程执行该代码区域,其他线程等待直到该线程执行结束:这样可以多线程避免同时使用某一方法造成数据混乱. 一般定义如下: ...
- 转:ASP.NET前台代码绑定后台变量方法总结
经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题.一般有<%= str%>和<%# str %>两种方式,这里简单总结一下.如有错误或异议之处,敬请各位指教. 一方 ...