NDK(7)NDK debugging without root access
from : http://ian-ni-lewis.blogspot.com/2011/05/ndk-debugging-without-root-access.html
NDK debugging without root access
This isn't meant as a criticism of either NVidia or the WinGDB folks. WinGDB has explicitly said they're only supporting emulators right now, and NVidia is targeting its own devkits that have AFAIK always shipped rooted. I highly doubt that they tried and failed to debug without root, I just don't think that they've had any real reason to try. But I was surprised to see just how small of a change needs to be made in order to enable debugging on unrooted devices.
The short answer to the question "how can I debug a process if I'm not root?" is simple: the debugger needs to run under the same account as the process it's debugging, and it can't do things (e.g. create sockets) which might be forbidden to that account. The long answer is more involved, because running under the same account isn't quite as simple as it sounds. To understand why this is tricky, let's first revisit how accounts and privileges work on Android.
When it comes to restricting privilege, desktop OSes have nothing on Android. Windows, OSX, and Linux all have the concept of root and non-root accounts, but they apply these concepts mostly to users (although both consumer OSes have followed *nix's lead in allowing sudo-style temporary privilege escalation, which while sometimes annoying, at least prevents everyone fromrunning as root all the time). In general, every process the user runs has access to the same files and settings as any other process, give or take. Which means that "OpenOffice.exe" and "MalwareRiddenToolbarInstalledWithSomePornMyRoommateDownloaded.exe" have approximately equal ability to read, write and delete your stuff.
Android takes a different tack, one that's more common in mobile systems: it creates a different account for each app. This has two immediate advantages. First, every app gets its own "home directory" that other apps can't access, so it's harder for programs to screw with each other. Second, it makes it easy for the system to customize a set of privileges for each application. Some apps need to access the Internet, write to your contacts list, and send SMS texts; others don't.
But this compartmentalized security model makes life hard for gdbserver. While the underlying Linux permission model for debugging is pretty reasonable--as a normal user, you're allowed to debug any app that's running under the same account--that model assumes that accounts are tied to users or roles, not individual apps. What works on the desktop fails on Android because by default the app and the debugger will run under separate identities.
As an example, here's me trying to run the command line that WinGDB issued for my most recent debugging session. I'm running it against an unrooted Xperia Play. (I extracted the command line using ProcMon.)
>adb shell /data/data/com.example.testwingdb/lib/gdbserver :1001 --attach 1221
Cannot attach to process 1221: Operation not permitted (1)
No dice. The process I want to debug is running under the identity that's been assigned to com.example.testwingdb. But gdbserver is running under a different account--in this case, the default shell identity.
So what to do? Well, it turns out that there is a simple way out of this mess. Android ships with a utility called run-as. The run-as command takes a package name and a command line, then turns around and executes that command line under the security identity of the package you named. It's just like sudo, except run-as lets you specify which identity you want to run under while sudo always uses root. [Edited to add: Some Android device builds have issues with run-as. See my comment (comment #3 below this post).]
Here's me running the unix "id" command first without, then with "run-as". (For this example and the ones that follow, I'm using a package called com.example.testwingdb. If you're playing along at home, substitute your own package name.)
>adb shell id
uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)
>adb shell run-as com.example.testwingdb id
uid=10117(app_117) gid=10117(app_117) groups=1003(graphics),1004(input),1007(log
),1009(mount),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)
So we use run-as and all is dandy, right? Not quite yet. The last part of the trick is that the executable we want to run with run-as, in this case gdbserver, needs to be in a place where our app uid has permission to execute. Sharp-eyed readers may have noted that my instance of gdbserver lives in /data/data/com.example.testwingdb/lib. Fortunately for the lazier programmers among us, it's not there by accident. It got there because ndk-build automatically puts it there when it makes a debug build. It puts it there because that's where it needs to be if you want to run it under com.example.testwingdb's uid.
With this in mind, we can make a very small tweak to the command line:
>adb shell run-as com.example.testwingdb /data/data/com.example.testwingdb/lib/gdbserver :1001 --attach 1221
Attached; pid = 1221
Woohoo!! Gdbserver is launched and has successfully attached to my process. All is perfect.... well, until this happens:
Can't bind address: Permission denied.
Exiting
Here we see the second consequence of the Android security model: apps have fine grained permissions. In this case, my app never asked for Internet permissions, so it's unable to open a socket--and because gdbserver is running under my app's uid, it can't open sockets either.
There's two ways to solve this. We could just modify our app manifest to request Internet permission. But that would suck: we don't need that permission for anything else, so we'd be making a significant change to our app's capabilities just to make it debuggable. A better solution is to do what ndk-gdb does: create a named pipe that gdbserver can use instead of a socket. Communication over named pipes doesn't require special permission as long as the pipe itself is accessible to the app, and adb includes the "forward" command that magically turns a device-side named pipe into a host-side socket:
>adb forward tcp:5039 localfilesystem:/data/data/com.example.testwingdb/debug-pipe
To use the named pipe, we launch gdbserver like this:
>adb shell run-as com.example.testwingdb /data/da
ta/com.example.testwingdb/lib/gdbserver +debug-pipe --attach 1221
Attached; pid = 1221
Listening on sockaddr socket debug-socket
And BAM. We can now connect up our favorite gdb client to port 5039 on the host, and it will communicate with the device-side instance of gdbserver over the named pipe /data/data/com.example.testwingdb/debug-pipe.
As far as I can tell, that's all it takes to enable rootless debugging. Let's review:
- Launch gdbserver under the uid of the process to be debugged, using run-as.
- Tell gdbserver to use a named pipe instead of a socket to communicate with the host.
- Use adb forward to forward the device-side named pipe to a host-side tcp socket.
NDK(7)NDK debugging without root access的更多相关文章
- A very cool thing: Install MYSQL from source without root access on LINUX
最近由于工作的需要,要在centos上安装MYSQL服务器.作为一名小兵中的小兵,当然是没有root权限的,为了能够使用mysql,只能使用源码安装了(因为binary安装方式似乎需要root acc ...
- kylin cube测试时,报错:org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode="/user":hdfs:supergroup:drwxr-xr-x
异常: org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, i ...
- hadoop 权限错误 Permission denied: user=root, access=WRITE, inode="/":hdfs:super
关于不能执行Hadoop命令 并报权限问题执行错误1.Permission denied: user=root, access=WRITE, inode="/":hdfs:supe ...
- How do I copy files that need root access with scp
server - How do I copy files that need root access with scp? - Ask Ubuntuhttps://askubuntu.com/quest ...
- 不同用户操作hadoop,Permission denied: user=root, access=WRITE, inode="/user"
关于不能执行Hadoop命令 并报权限问题执行错误1.Permission denied: user=root, access=WRITE, inode="/":hdfs:supe ...
- CDH:cdh5环境mkdir: Permission denied: user=root, access=WRITE, inode="/user":hdfs:hadoop:drwxr-xr-x
产生问题原因: 环境hadoop2,cdh5创建 使用hadoop fs -mdkir /use/xxx创建文件路径时,出现权限问题 前提我们已经把当前用户zhangsan和root放到/etc/su ...
- hive之权限问题AccessControlException Permission denied: user=root, access=WR
问题描述:在集群上,用hive分析数据出现如下错误 FAILED: Execution Error, return code from org.apache.hadoop.hive.ql.exec.D ...
- Android:JNI与NDK(三)NDK构建的脚本文件配置
友情提示:欢迎关注本人公众号,那里有更好的阅读体验以及第一时间获取最新文章 本文目录 一.前言 本篇我们介绍Android.mk与CMakeLists.txt构建NDK的配置文件,我们知道目前NDK的 ...
- 报错:HDFS IO error org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode="/yk/dl/alarm_his":hdfs:supergroup:drwxr-xr-x
报错背景: CDH集成了Flume服务,准备通过Flume将kafka中的数据放到HDFS中, 启动Flume的时候报错. 报错现象: // :: INFO hdfs.HDFSDataStream: ...
随机推荐
- IDA*
模拟退火 基本思路(Main Thoughts): IDA*是一种优秀的搜索法,在一般的实际问题中,它比普通的搜索更快. 通过迭代加深和估价函数剪枝来搜索. 通常处理没有层数上界或上界很多大的搜索. ...
- JAVA Hashmap不能用基本的数据类型
今天开始学习Java... 转载:http://moto0421.iteye.com/blog/1143777 今天试了一下HahsMap, 采用如下形似定义 (这个下面是用了csdn的一位同仁的文章 ...
- 聊一聊js中的null、undefined与NaN
零.寒暄 翻翻自己的博客,上一篇竟然是六月26号的,说好的更新呢?回顾刚刚过去的这个七月,整天都是公司的入职培训加上自己的小论文,每天奋战到凌晨1点多,这是要挂的节奏啊!但是不论怎么说,自己的时间管理 ...
- 女性社区TOP10
“女性和孩子的钱是世界上最好赚的”并不是一句空话.据统计,女性掌管着家庭70%的支出,如果你能让女性为你掏出腰包,那么你基本就掌控了一个家庭的大部分的消费. 有趣的是,女性还是一个喜欢分享的群体,他们 ...
- vector内存分配
vector,map 这些容器还是在堆上分配的内存,在析构时是释放空间 vector在提高性能可以先reserve在push_back() reserve:决定capacity,但没有真正的分配内存, ...
- windows phone MVVM开发心得第一天
之前刚刚学了asp.net网站的三层架构,为其中的优点着迷,可惜寒假本来决定学下MVC的计划泡汤了,刚开学,学了下windows phone 的MVVM模式的开发,在此留下点心得和脚印,第一天只是学了 ...
- Base64编解码Android和ios的例子,补充JNI中的例子
1.在Android中java层提供了工具类:android.util.Base64; 里面都是静态方法,方便直接使用: 使用方法如下: // Base64 编码: byte [] encode = ...
- 疯狂java讲义——多态
父类 f = new 子类(); 引用变量f,在编译时类型是父类,在运行时类型是子类类型.当这个引用变量调用子类重写父类的那个方法的时候,实际执行的是子类中重写后的那个方法.当运行的时候调用该变量的方 ...
- javascript设计模式--状态模式(State)
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 3(Sorting/Searching)
第一题:340 - Master-Mind Hints UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Item ...