実装の原則は、アプリの AndroidManifest ファイルを逆コンパイルすることです。アプリ全体をコンパイルするのではなく、アプリのリソース ファイルが逆コンパイルされることに注意してください。この操作は、アプリの dex に触れる必要がなく、次の点ではるかに簡単です。困難。リソース ファイルをデコードするにはいくつかのツールが必要ですが、Android の場合は ARSCLib が推奨されます。次のステップは、ターゲット アプリケーションに再署名することです。ターゲット アプリケーションは、他のパーティと同じアクセス許可を確実に持つように、独自のキーストア ファイルで署名する必要があります。このステップが最も重要で、最後のステップは次のとおりです。データを取得します。
ステップ 1: Android Studio 3.5.2 と WeChat のエクスポートを例として、まずテスト アプリを作成し、依存ライブラリをインポートし、アプリの build.gradle の下に次のコードを追加するか、jar パッケージをインポートします。
依存関係 { ... 実装("io.github.reandroid:ARSCLib:+") }
次に、構成共有 ID を AndroidManifest に追加します:
android:sharedUserId="test.com" //値は任意に設定できます
次に、次のコードをアプリに追加します。
private void generateApk() {
ApkModule module = null;
try {
module = ApkModule.loadApkFile(new File("/sdcard/微信原始.apk")); //源apk文件,这里直接放在了存储根目录
AndroidManifestBlock manifestBlock = module.getAndroidManifestBlock();
ResXmlElement mfElement = manifestBlock.getManifestElement();
//添加共享用户id
ResXmlAttribute sharedAttr = mfElement.createAndroidAttribute("sharedUserId", 16842763);
//要和上面自己的id一样,这里是test.com
sharedAttr.setValueAsString("test.com");
//生成的apk文件
module.writeApk(new File("/sdcard/微信修改.apk"));
ToastUtils.show(this, "操作完成");
} catch (Exception e) {
e.printStackTrace();
ToastUtils.show(this, "操作失败");
} finally {
if (module != null) module.destroy();
}
}
次に、上記のコードを実行し、ストレージ許可を忘れずに適用してから、上で指定したディレクトリにソース ファイルを配置します。実行後に最終ファイルが生成されます。
ステップ 2: テスト アプリケーションと同じ署名を使用して、生成されたファイルに再署名します。
android-sdk directory\build-tools\29.0.3\apksigner signed --ks キーストア ファイル パス --ks-pass pass:keystore パスワード --key-pass pass:key パスワード --v1-signer-name cert --v1 -signing-enabled true --v2-signing-enabled true --v3-signing-enabled false --in WeChat Modified.apk --out WeChat Final.apk
次に、アプリケーション情報アシスタントを使用して WeChat と独自の APK を確認し、2 つのアプリの uid が同じであることを確認します。
ステップ 3: 既存の WeChat をアンインストールし、WeChat の最終 .apk と独自のテスト デモを再インストールします。インストール プロセスは、メーカーのセキュリティ ソフトウェアによってインターセプトされる可能性があります。そのままにしておきます。インストールが完了すると、WeChat を共有できます。 . データが保存されます。
WeChat 内部データ コードをエクスポートします。
new Thread() {
@Override
public void run() {
super.run();
exportData(MainActivity.this, "com.tencent.mm", "/sdcard/wxData");
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "微信数据导出完成", Toast.LENGTH_SHORT).show();
}
});
}
}.start();
public static void exportData(Context context, String packageName, String outputDir) {
try {
ApplicationInfo info = context.getPackageManager().getApplicationInfo(packageName, 0);
File wxDir = new File(info.dataDir);
File goDir = new File(outputDir, wxDir.getName());
copyDir(wxDir, goDir);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void copyDir(File srcDir, File dstDir) {
boolean success = dstDir.exists() || dstDir.mkdirs();
if (!success) return;
File[] files = srcDir.listFiles();
if (files == null) {
return;
}
for (File file : files) {
if (file.isDirectory()) {
copyDir(file, new File(dstDir, file.getName()));
} else {
copyFile(file, new File(dstDir, file.getName()));
}
}
}
private static boolean copyFile(File srcFile, File dstFile) {
if (srcFile == null || dstFile == null) return false;
FileInputStream fis = null;
FileOutputStream fos = null;
boolean isSuccess = false;
try {
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(dstFile);
int len;
byte[] buf = new byte[102400];
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
fos.flush();
}
isSuccess = true;
} catch (Exception e) {
//Log.e(TAG, e.toString());
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (fis != null) {
fis.close();
}
} catch (Exception e) {
e.printStackTrace();
}
if (!isSuccess) {
if (dstFile.exists()) dstFile.delete();
}
}
return isSuccess;
}
同様に、QR コード名刺を外部から呼び出せるように変更するなど、他の属性も変更できます。
ResXmlElement activityElement = manifestBlock.getActivity("com.tencent.mm.plugin.setting.ui.setting.ColorfulSelfQRCodeUI", false);
ResXmlAttribute exportedAttr = activityElement.getOrCreateAndroidAttribute("exported", 16842768);
exportedAttr.setValueAsBoolean(true); //导出改为true
上記のコードを実行すると、WeChat QR コード名刺インターフェイスがエクスポート可能になり、外部プログラムがこのページを自由に呼び出すことができます。この方法によれば、アプリケーション全体のすべてのアクティビティ コンポーネントをエクスポート可能に変更できますが、一部のコンポーネントはエクスポート可能であることに注意してください。署名権限が含まれており、他のアプリがアプリケーションのすべてのコンポーネントを呼び出せるようにするには、削除する必要があります。