[Android Apps and Games] Luminger:
Sure I can tell you about the inner workings of this "exploit". I'll split it into 4 parts. A general part about "what it does and why it works", second is the current LD_PRELOAD implementation, third I'll talk a little about the inner workings of the 1.1.0 release (which will come soon btw, had no time the last days to work on it sadly) and last about the library.

The whole thing bases on the linux capabilities and the inner workings about the android process spawning model. On Linux root is most of the times misunderstood (at least somehow). People think the mighty powers of root derive from the fact that the user id and group id is zero, but this doesn't grant root any special abilities. The real power from root comes from the capabilities granted to this user.

The kernel knows a lot of them, they are listed in man 7 capabilities. Most of them are not that interesting for users, but CAP_NET_ADMIN and CAP_FOWNER are for example what people have in mind when it comes to root.

Capabilities are normally only granted to root, but here come the different capabilitie sets into the game. If you take a look at man 2 capset, there are 3 of them. 'effective' is the set which is used when it comes to checking if the process has those capabilities. A process may drop them at any point in time by setting them to zero. A process is also able to "regain" all of the capabilities from the 'permitted' set. The 'inheritable' set is the set which will be inherited by a child of this thread and it's not really relevant in our case.

If you want to know which capabilities a process has take a look into /proc/<pid>/status, it lists all 3 capability sets.

Okay, we have talked about the capabilities and why they really are the power of root. Next is the Android process spawning. There are some resources on the net, I will just talk about the relevant parts here.

The zygote is spawned very early in the boot process of any Android system and preloads a huge pile of resources and libraries which are used by all parts of the later system. After this has finished, the zygote is utilized by the system to spawn of new app processes (hence the name zygote, it's the parent of all app processes). This is done by forking a new child (all the loaded resources will be shared with it in a copy on write manner to save RAM) which is in the begining nothing more than a direct clone of the zygote. A crutial thing I forgot to mention till now: zygote runs as root and has all/nearly all capabilities available on a system. After the fork has taken place the zygote will begin to specialize its new child (drop root, drop capabilities, setup the app) which will form the new app process.

And here comes the trick I used with AnJaRoot:

When the zygote specializes the child it will drop its capabilities from 0xFFFFFFFF (everything) to 0x00000000 (none). This drop is intercepted and will leave the child with a 'permitted' capability set of 0xFFFFFFFF and 'effective' 0x00000000 - as I described above those can be regained later, the child will remain 'root' this way.

The intercept is realized with LD_PRELOAD. You can read on google about it - it forces the dynamic linker to load a library into the process before any other dynamic library will be loaded. This way a dynamic symbol resolve will at first try to find the asked symbol from this library, then it will proceed to other libraries (libc is queried after LD_PRELOADed libraries). The AnJaRoot Library provides a replacement for capset (which is called by the zygote to drop capabilities). This replacement will look into the AnJaRoot database and does the capabilities drop if the process is not a AnJaRoot enabled process or it will not drop the capabilities and signal a successfull capability drop to the zygote. This way the library can later aid the process to regain capabilities.

The new AnJaRoot 1.1.0 release adds compatibility to Xposed which was a problem in the 1.0.0 release. It does so by utilitzing ptrace to basicaly "debug" the zygote (it's the main debug interface, used by gdb for example, on Linux). It does't need to change the app_process this way (which is the binary which spawns the zygote initialy) but is completely transparent to Xposed.

The AnJaRoot Library adds the capset, capget, setresuid, getresuid, setresgid, getresgid calls to the Android Java land (those functions all have manual pages, you can look them up on the net). When you request capabilities via the Library it will utilize capset to set the 'effective' capabilities set to the previously preserved 'permitted' capabilities and also set your uid/gid to 0. And now the process is magicaly root again.

This way nobody ever again has to use the su binary to gain root via setuid to call some shellscripts. You can now use the Android Java API to fiddle arround with the filesystem, sockets and even Android services (you could claim to be a system process and do otherwise not permitted action to the system).

Hope this helps, if anything is not clear please feel free to ask =)