Skip to content

Instantly share code, notes, and snippets.

@Lanchon
Last active July 7, 2023 12:39
Show Gist options
  • Save Lanchon/78854e97dc8f1d2a6b11a0a134d06c6c to your computer and use it in GitHub Desktop.
Save Lanchon/78854e97dc8f1d2a6b11a0a134d06c6c to your computer and use it in GitHub Desktop.
Sample DexPatcher framework patch to implement microG-style signature spoofing
/*
* Copyright (C) 2014 Marvin W <https://github.com/mar-v-in>
* Copyright (C) 2016 Lanchon <https://github.com/Lanchon>
*
* This is Marvin's work converted to a DexPatcher patch by Lanchon.
*
* https://gerrit.omnirom.org/#/c/8672/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.content.pm;
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashSet;
import lanchon.dexpatcher.annotation.*;
// Lets modify the PackageParser class.
@DexEdit(onlyEditMembers = true)
public class PackageParser {
// We need to declare these framework symbols so that the compiler will find
// them when building the patch.
@DexIgnore
public final static class Package {
public final ArrayList<String> requestedPermissions = new ArrayList<String>();
public Bundle mAppMetaData = null;
}
// Wrap the existing generatePackageInfo(...) method with this new method.
// The new method calls the original, modifies its return value if needed,
// and passes it back to the caller.
@DexWrap
public static PackageInfo generatePackageInfo(PackageParser.Package p,
int gids[], int flags, long firstInstallTime, long lastUpdateTime,
HashSet<String> grantedPermissions, PackageUserState state, int userId) {
// This recursive call gets converted to an invocation of the original
// method being wrapped.
PackageInfo pi = generatePackageInfo(p, gids, flags, firstInstallTime,
lastUpdateTime, grantedPermissions, state, userId);
if (pi != null) {
if ((flags & PackageManager.GET_SIGNATURES) != 0) {
try {
if (p.requestedPermissions.contains("android.permission.FAKE_PACKAGE_SIGNATURE") &&
p.mAppMetaData != null) {
Object fakeSignatureMetaData = p.mAppMetaData.get("fake-signature");
if (fakeSignatureMetaData instanceof String) {
pi.signatures = new Signature[] { new Signature((String) fakeSignatureMetaData) };
}
}
} catch (Throwable t) {
// We should never die because of any failures, this is system code!
// Eating up instances of Error might seem excessive, but they can be
// the result of improperly applied patches so we will handle them here.
Log.e("PackageParser_FakePackageSignature", "hook exception", t);
}
}
}
return pi;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment