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: ...
随机推荐
- jQuery的弹出窗口插件colorbox
官方网站:http://colorpowered.com/colorbox/ 支持 照片,照片组,幻灯片,ajax,内联 和 iframe 框架. 通过CSS 控制外观,使用用户可以很容易重新定制外观 ...
- 【LCA】CodeForce #326 Div.2 E:Duff in the Army
C. Duff in the Army Recently Duff has been a soldier in the army. Malek is her commander. Their coun ...
- 了解javascript中的事件(一)
本人目录如下: 零.寒暄 一.事件概念 二.事件流 三.事件处理程序 四.总结 零.寒暄 由于刚入职,近期事情繁多,今天好不容易中期答辩完事,晚上有一些时间,来给大家分享一篇博文. 这段时间每天写js ...
- Java多线程程序设计详细解析
一.理解多线程 多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立. 线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线 ...
- 远程数据源Combobox
Ext.define('bookInfo', { extend: 'Ext.data.Model',//新类继承自model fields: [{ name: 'b ...
- JQuery原理及深入解析--转载
总体架构 jQuery是个出色的javascript库,最近结合它写javascript,看了下源码. 先从整体.全局的看,jQuery的源码几乎都在下面的代码中: (function() { //… ...
- CAP定理与RDBMS的ACID
一.分布式领域CAP理论 CAP定理指在设计分布式系统时,一致性(Consistent).可用性(Availability).可靠性(分区容忍性Partition Tolerance)三个属性不可能同 ...
- UVALive6571 It Can Be Arranged(最小路径覆盖)
题意:现在有n个课程,每个课程有一定的参与人数,然后每个课程有开始时间和结束时间ai,bi. 而且给定了一个矩阵clean(ij),表示的是上完i课程需要clean[i][j]的时间打扫卫生才能继续上 ...
- POJ 2182
#include <iostream> #define MAXN 8005 using namespace std; int _m[MAXN]; int main() { //freope ...
- 李洪强iOS开发之- 实现简单的弹窗
李洪强iOS开发之- 实现简单的弹窗 实现的效果: 112222222222223333333333333333