Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Art #1

Merged
merged 69 commits into from
Jun 5, 2016
Merged

Art #1

merged 69 commits into from
Jun 5, 2016

Conversation

palmzeed
Copy link
Owner

@palmzeed palmzeed commented Jun 5, 2016

Art

rovo89 and others added 30 commits February 13, 2015 20:52
In case no suitable libxposed_*.so was found or the initialization failed,
the native methods are not registered, so make sure that this situation
doesn't crash the system.

Also retrieve the current runtime and use a different entry point for
non-Zygote executions.

Requires changes in the binary.
With enforced SELinux, Zygote usually cannot read/execute files in /data/data.
By locating XposedBridge.jar next to the system code, we can be pretty
sure that access is always possible.

This might also help to avoid issues where the system partition is wiped,
but /data still holds an older version of XposedBridge.jar.
Some internal methods have changed, so hooks need to be adjusted.

Also, the code for the system_server process is now stored in a separate
file and accessed with a separate classloader (not the boot classloader),
so the hook needs to be placed in two steps.
Due to SELinux, it's pretty much impossible to open file for writing in
the Zygote process and keep writing to it from application and system
processes. On 64-bit ROMs, it's even more complicated because there are
two Zygote processes.

Messages will still be written to logcat and are captured from there in
native coding.
Only one of these processes starts the system_server process, so it only
makes sense to place some hooks or trigger certain actions for this
primary process.

Modules can check this in initZygote() via a new flag in the parameters.
Generally, it's strongly recommended to place any hooks for system_server
in handleLoadPackage() for the "android" package instead.
This commit introduces various classes and helpers to access files even
when SELinux is active and enforcing. Depending on the process/context
(Zygote, system_server, normal app), different approaches have to be used,
most of them realized via native services.

The intention is to abstract the very complex logic and the choice of the
right service by providing a common interface for them. XSharedPreferences
is adapted to handle this in the background, so modules loading their
preferences via this class shouldn't need to be updated at all (provided
they store the preferences world-readable, which has been a requirement
already in most cases).

Modules are free to use the SELinuxHelper class and the services retrieved
from it to access files in /data/data/ themselves. The API is pretty much
finished, although breaking changes are still possible until the first
stable version of Xposed for Lollipop has been published.
v60
Let's skip some numbers due to the big changes.
Otherwise, the installer will show an error message to the user.

Also, make sure that stack traces are logged with ERROR priority.
The actual package name from the activity info is "android". However, the
same name is also used for the system_server. It has been a common pattern
to check for this package name before hooking any system services. Now,
this check would also be true for certain system dialogues and break
existing modules (causing ClassNotFoundExceptions).

For the very few cases where a module needs to hook into this process, it
can simply check for package name "system" instead.
The android:ui process is running with the same UID, but in the system_app
context, so it should be treated like a normal app.
CM11 has introduced this method with Change-Id
If04e82a13250f520d70b58991586c8ce38f0ecb1.

Especially on CM12+, the SystemUI (and possibly other parts of the system)
use this method to retrieve a Resources object. We need to hook it and
replace the result with an XResources object.
This can be useful to determine at which depth we are in recursive/similar
methods and perform certain actions only for e.g. the outer call.
Instead of using a file retrieved from a compiled AOSP tree, just use
stubs of those classes and methods that are actually needed by
Xposed. This allows to add ROM-specific and version-specific methods.
These methods have been introduced in Android 5.0 and need to be
overridden in order to ensure proper resource replacement.
There might be recursive calls, but it's enough to check for replacements
in the first call.
The method signature has changed, taking a File instead of a String as the
first argument. Both signatures are present in the HiddenAPIStubs.jar, so
no reflection is required.

Fixes #34.
This should fix some cases when a ROM is set to enforcing later.
The native daemons are running anyway whenever SELinux is detected.

See #33.
See the native part for details.
They have implemented low-level resource class replacements themselves,
which conflict with Xposed's.

Fixes rovo89/Xposed#54.
Android has (at least) five points in time where apps are compiled:
  1) Quite early when the PackageManagerService is started.
  2) Once the UI comes up ("Android is upgrading" screen).
  3) In a background service called "BackgroundDexOptService".
  4) When an app is installed.
  5) When the app is actually started.

Phase 1) is used for /system/framework and other non-app "libraries".
At this time, the system also scans the app directories and identifies
apps that need to be (re-)compiled. These apps are then handled in
phase 2). After that, all apps are usually compiled, with the exception
of builds with type "eng", where only recently used apps are compiled
immediately and the remaining ones are compiled in phases 3) or 5).
Phase 5) is usually not needed because the app has been compiled in one
of the previous phases.

Unfortunately, there is at least one category of apps that is needed
early during the boot process, the System Content Providers. They're
loaded between phase 1) and 2), but aren't compiled at that time yet,
which leads to errors. Actually that's not completely true: On most ROMs,
side-effects of other early package processing seem to compile them.
But even if not, phase 5) kicks in and should compile the app.

However, that doesn't work correctly. The phase assumes that it's only
needed for "eng" builds, when not all apps have been compiled in phase 2).
It quits early if it doesn't detect such a situation.

This patch hooks into the methods that triggers the compilation of the app
and pretends that the call came from phase 3) if it detects that phase 2)
hasn't run yet. This ensures that the System Content Providers are
compiled shortly before they're required.

Not sure why this doesn't seem to occur without Xposed - maybe the
circumstances are slightly different.

Fixes rovo89/Xposed#53.
For now, this limits the changes done in 01c324 to Android 5.x.
The PackageManagerService methods have changed since then and it's
unclear whether this workaround is still needed for 6.0.
rovo89 added 24 commits April 1, 2016 19:38
There's not much value of having methods like XResources.getDrawable()
in the Javadoc. Let's concentrate on the added methods instead, which
are more visible now.
Previous API levels have been reconstructed from the Git history.
Internal classes/methods that should have never been used by any module
(and which were therefore hidden later) were removed.
All classes implementing this interface already had this method.
XC_LoadPackage and XC_InitPackageResources already had the same
abstract method that the corresponding interface defines, so there is
no effective change.
Modules should always use the IXUnhook instances that are returned from
the hooking methods. Also hooking LoadPackage and InitPackageResources
should be done using the interfaces for the method class, not with
stand-alone classes. This will need further cleanup in the future.

Remove/hide unused methods, deprecate unhookMethod() to give the very
few modules using it a chance to switch.
Less is more, having just two instead of three variants makes the docs
easier to read. There's another variant which can be used without logic
changes. The methods are deprecated now and will be removed completely
in the future.
They make it easier to place hooks conditionally.
They have added several checks that disable the recompiliation of
pre-optimized APKs. This must be undone when Xposed is active.

Fixes rovo89/Xposed#72.
This change reverts the following commits:
  01c3244
  f5967d5

They have become obsolete by a change in Xposed's ART libraries which
allows the system to use the dex from .odex files in interpret-only mode
(i.e. the compiled code is ignored).

This works out-of-the-box on stock ROMs where the image checksums match
(because the image hasn't been recompiled) and no Xposed version check
prevents the usage of the .odex file.
Just a warning for now, even though this can cause strange behavior.
However, quite a lot of modules are compiled incorrectly and I want to
give the developers time to react.
The whole code block is only executed for SDK21+, no need to check it again.
Gradle wrapper:          2.10 ->   2.13
Android Gradle Plugin:  1.5.0 ->  2.1.0
Android Build Tools:   23.0.2 -> 23.0.3
Instant Run replaces the application with a bootstrap application that
can communicate with Android Studio and dynamically exchange methods
In order to achieve this, actual classes are not stored directly in the
APK's classes.dex, but within a file called instant-run.zip in the APK.
Therefore, these classes can't be found by Xposed unless it would
simulate the same bootstrapping that takes place when the app is started.

Let's avoid the misleading ClassNotFoundException and instead print a
proper error message asking the user to disable Instant Run.
@palmzeed palmzeed closed this Jun 5, 2016
@palmzeed palmzeed deleted the art branch June 5, 2016 12:31
@palmzeed palmzeed restored the art branch June 5, 2016 12:31
@palmzeed palmzeed reopened this Jun 5, 2016
@palmzeed
Copy link
Owner Author

palmzeed commented Jun 5, 2016

Art

@palmzeed palmzeed merged commit ffb95d3 into master Jun 5, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants