diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..bcb6d7b --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/.idea/markdown.xml b/.idea/markdown.xml new file mode 100644 index 0000000..c61ea33 --- /dev/null +++ b/.idea/markdown.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bad55e3 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/antik/build/classes/java/main/com/antik/AntikUtils.class b/antik/build/classes/java/main/com/antik/AntikUtils.class new file mode 100644 index 0000000..09e5a30 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/AntikUtils.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/DexPatcher.class b/antik/build/classes/java/main/com/antik/DexPatcher/DexPatcher.class new file mode 100644 index 0000000..d39efd2 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/DexPatcher.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/MethodT/patchLaunchMethod.class b/antik/build/classes/java/main/com/antik/DexPatcher/MethodT/patchLaunchMethod.class new file mode 100644 index 0000000..4841932 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/MethodT/patchLaunchMethod.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/MethodT/patchLauncher.class b/antik/build/classes/java/main/com/antik/DexPatcher/MethodT/patchLauncher.class new file mode 100644 index 0000000..ba7c763 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/MethodT/patchLauncher.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/MethodT/patchM.class b/antik/build/classes/java/main/com/antik/DexPatcher/MethodT/patchM.class new file mode 100644 index 0000000..16e83bd Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/MethodT/patchM.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/PairipMethodMake/CMethod.class b/antik/build/classes/java/main/com/antik/DexPatcher/PairipMethodMake/CMethod.class new file mode 100644 index 0000000..a257f10 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/PairipMethodMake/CMethod.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/Translation/MethodT/MethodMaker.class b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/MethodT/MethodMaker.class new file mode 100644 index 0000000..3c6f972 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/MethodT/MethodMaker.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/Translation/MethodT/RestoreMethodMaker.class b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/MethodT/RestoreMethodMaker.class new file mode 100644 index 0000000..fa1b83f Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/MethodT/RestoreMethodMaker.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationData$Entry.class b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationData$Entry.class new file mode 100644 index 0000000..09b3444 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationData$Entry.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationData.class b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationData.class new file mode 100644 index 0000000..1fa4571 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationData.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationPatcher$PendingDex.class b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationPatcher$PendingDex.class new file mode 100644 index 0000000..c9905f3 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationPatcher$PendingDex.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationPatcher.class b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationPatcher.class new file mode 100644 index 0000000..b84828b Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationPatcher.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationRewriter.class b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationRewriter.class new file mode 100644 index 0000000..4d63dde Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/TranslationRewriter.class differ diff --git a/antik/build/classes/java/main/com/antik/DexPatcher/Translation/antik/PairipClass.class b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/antik/PairipClass.class new file mode 100644 index 0000000..9510517 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/DexPatcher/Translation/antik/PairipClass.class differ diff --git a/antik/build/classes/java/main/com/antik/Main.class b/antik/build/classes/java/main/com/antik/Main.class new file mode 100644 index 0000000..d44fa4f Binary files /dev/null and b/antik/build/classes/java/main/com/antik/Main.class differ diff --git a/antik/build/classes/java/main/com/antik/Opcode.class b/antik/build/classes/java/main/com/antik/Opcode.class new file mode 100644 index 0000000..bcadbd5 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/Opcode.class differ diff --git a/antik/build/classes/java/main/com/antik/crc32/Casting.class b/antik/build/classes/java/main/com/antik/crc32/Casting.class new file mode 100644 index 0000000..caeda42 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/crc32/Casting.class differ diff --git a/antik/build/classes/java/main/com/antik/crc32/JVMCasting.class b/antik/build/classes/java/main/com/antik/crc32/JVMCasting.class new file mode 100644 index 0000000..f106e84 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/crc32/JVMCasting.class differ diff --git a/antik/build/classes/java/main/com/antik/crc32/crc32.class b/antik/build/classes/java/main/com/antik/crc32/crc32.class new file mode 100644 index 0000000..1cdc624 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/crc32/crc32.class differ diff --git a/antik/build/classes/java/main/com/antik/crc32/hyper/DHeader.class b/antik/build/classes/java/main/com/antik/crc32/hyper/DHeader.class new file mode 100644 index 0000000..d5d060b Binary files /dev/null and b/antik/build/classes/java/main/com/antik/crc32/hyper/DHeader.class differ diff --git a/antik/build/classes/java/main/com/antik/crc32/hyper/Directory.class b/antik/build/classes/java/main/com/antik/crc32/hyper/Directory.class new file mode 100644 index 0000000..ed6aa5c Binary files /dev/null and b/antik/build/classes/java/main/com/antik/crc32/hyper/Directory.class differ diff --git a/antik/build/classes/java/main/com/antik/crc32/hyper/TFileHeader.class b/antik/build/classes/java/main/com/antik/crc32/hyper/TFileHeader.class new file mode 100644 index 0000000..c08f578 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/crc32/hyper/TFileHeader.class differ diff --git a/antik/build/classes/java/main/com/antik/crc32/hyper/ZipSignature.class b/antik/build/classes/java/main/com/antik/crc32/hyper/ZipSignature.class new file mode 100644 index 0000000..2ccc0c8 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/crc32/hyper/ZipSignature.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/FileUtils.class b/antik/build/classes/java/main/com/antik/librarySurgery/FileUtils.class new file mode 100644 index 0000000..26ceca0 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/FileUtils.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/LibSurgery.class b/antik/build/classes/java/main/com/antik/librarySurgery/LibSurgery.class new file mode 100644 index 0000000..a026f26 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/LibSurgery.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/LibraryExtractor.class b/antik/build/classes/java/main/com/antik/librarySurgery/LibraryExtractor.class new file mode 100644 index 0000000..0e090c7 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/LibraryExtractor.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/LibraryPatcher.class b/antik/build/classes/java/main/com/antik/librarySurgery/LibraryPatcher.class new file mode 100644 index 0000000..3b11d43 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/LibraryPatcher.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/PatchResult.class b/antik/build/classes/java/main/com/antik/librarySurgery/PatchResult.class new file mode 100644 index 0000000..cc84abf Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/PatchResult.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/elf/DynamicEntry.class b/antik/build/classes/java/main/com/antik/librarySurgery/elf/DynamicEntry.class new file mode 100644 index 0000000..fe15f10 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/elf/DynamicEntry.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/elf/Elf.class b/antik/build/classes/java/main/com/antik/librarySurgery/elf/Elf.class new file mode 100644 index 0000000..a820fd3 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/elf/Elf.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/elf/ElfConstants.class b/antik/build/classes/java/main/com/antik/librarySurgery/elf/ElfConstants.class new file mode 100644 index 0000000..e0b3562 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/elf/ElfConstants.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/elf/ElfHeader.class b/antik/build/classes/java/main/com/antik/librarySurgery/elf/ElfHeader.class new file mode 100644 index 0000000..9ff9d8c Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/elf/ElfHeader.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/elf/ProgramHeader.class b/antik/build/classes/java/main/com/antik/librarySurgery/elf/ProgramHeader.class new file mode 100644 index 0000000..a0ba367 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/elf/ProgramHeader.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/io/ByteReader.class b/antik/build/classes/java/main/com/antik/librarySurgery/io/ByteReader.class new file mode 100644 index 0000000..842dcce Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/io/ByteReader.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/io/ByteWriter.class b/antik/build/classes/java/main/com/antik/librarySurgery/io/ByteWriter.class new file mode 100644 index 0000000..1a6a11b Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/io/ByteWriter.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/memory/Memory.class b/antik/build/classes/java/main/com/antik/librarySurgery/memory/Memory.class new file mode 100644 index 0000000..e1170a8 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/memory/Memory.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/memory/MemoryMap.class b/antik/build/classes/java/main/com/antik/librarySurgery/memory/MemoryMap.class new file mode 100644 index 0000000..1dbfbe0 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/memory/MemoryMap.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/memory/MemoryRegion.class b/antik/build/classes/java/main/com/antik/librarySurgery/memory/MemoryRegion.class new file mode 100644 index 0000000..708c54c Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/memory/MemoryRegion.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/process/ProcessFinder.class b/antik/build/classes/java/main/com/antik/librarySurgery/process/ProcessFinder.class new file mode 100644 index 0000000..c6305cc Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/process/ProcessFinder.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/shell/Shell.class b/antik/build/classes/java/main/com/antik/librarySurgery/shell/Shell.class new file mode 100644 index 0000000..d51c762 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/shell/Shell.class differ diff --git a/antik/build/classes/java/main/com/antik/librarySurgery/shell/ShellResult.class b/antik/build/classes/java/main/com/antik/librarySurgery/shell/ShellResult.class new file mode 100644 index 0000000..e47fcc9 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/librarySurgery/shell/ShellResult.class differ diff --git a/antik/build/classes/java/main/com/antik/logCat.class b/antik/build/classes/java/main/com/antik/logCat.class new file mode 100644 index 0000000..c86c32c Binary files /dev/null and b/antik/build/classes/java/main/com/antik/logCat.class differ diff --git a/antik/build/classes/java/main/com/antik/manifest/manifestP.class b/antik/build/classes/java/main/com/antik/manifest/manifestP.class new file mode 100644 index 0000000..1de29ad Binary files /dev/null and b/antik/build/classes/java/main/com/antik/manifest/manifestP.class differ diff --git a/antik/build/classes/java/main/com/antik/root/Base.class b/antik/build/classes/java/main/com/antik/root/Base.class new file mode 100644 index 0000000..6f4f89e Binary files /dev/null and b/antik/build/classes/java/main/com/antik/root/Base.class differ diff --git a/antik/build/classes/java/main/com/antik/root/PackageM/Installer.class b/antik/build/classes/java/main/com/antik/root/PackageM/Installer.class new file mode 100644 index 0000000..082faa7 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/root/PackageM/Installer.class differ diff --git a/antik/build/classes/java/main/com/antik/root/PackageM/uninstaller.class b/antik/build/classes/java/main/com/antik/root/PackageM/uninstaller.class new file mode 100644 index 0000000..f0c54e6 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/root/PackageM/uninstaller.class differ diff --git a/antik/build/classes/java/main/com/antik/root/Pull.class b/antik/build/classes/java/main/com/antik/root/Pull.class new file mode 100644 index 0000000..b7f583e Binary files /dev/null and b/antik/build/classes/java/main/com/antik/root/Pull.class differ diff --git a/antik/build/classes/java/main/com/antik/root/launchApp.class b/antik/build/classes/java/main/com/antik/root/launchApp.class new file mode 100644 index 0000000..f542979 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/root/launchApp.class differ diff --git a/antik/build/classes/java/main/com/antik/ui/banner.class b/antik/build/classes/java/main/com/antik/ui/banner.class new file mode 100644 index 0000000..3287184 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/ui/banner.class differ diff --git a/antik/build/classes/java/main/com/antik/ui/help.class b/antik/build/classes/java/main/com/antik/ui/help.class new file mode 100644 index 0000000..1c7531f Binary files /dev/null and b/antik/build/classes/java/main/com/antik/ui/help.class differ diff --git a/antik/build/classes/java/main/com/antik/utils/deleteDir.class b/antik/build/classes/java/main/com/antik/utils/deleteDir.class new file mode 100644 index 0000000..26b8807 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/utils/deleteDir.class differ diff --git a/antik/build/classes/java/main/com/antik/utils/loading$1$1.class b/antik/build/classes/java/main/com/antik/utils/loading$1$1.class new file mode 100644 index 0000000..0c8383a Binary files /dev/null and b/antik/build/classes/java/main/com/antik/utils/loading$1$1.class differ diff --git a/antik/build/classes/java/main/com/antik/utils/loading$1.class b/antik/build/classes/java/main/com/antik/utils/loading$1.class new file mode 100644 index 0000000..edcba9d Binary files /dev/null and b/antik/build/classes/java/main/com/antik/utils/loading$1.class differ diff --git a/antik/build/classes/java/main/com/antik/utils/loading.class b/antik/build/classes/java/main/com/antik/utils/loading.class new file mode 100644 index 0000000..a1a3d3d Binary files /dev/null and b/antik/build/classes/java/main/com/antik/utils/loading.class differ diff --git a/antik/build/classes/java/main/com/antik/utils/output$1.class b/antik/build/classes/java/main/com/antik/utils/output$1.class new file mode 100644 index 0000000..ea9433c Binary files /dev/null and b/antik/build/classes/java/main/com/antik/utils/output$1.class differ diff --git a/antik/build/classes/java/main/com/antik/utils/output.class b/antik/build/classes/java/main/com/antik/utils/output.class new file mode 100644 index 0000000..d249a66 Binary files /dev/null and b/antik/build/classes/java/main/com/antik/utils/output.class differ diff --git a/antik/build/libs/RePairip.jar b/antik/build/libs/RePairip.jar new file mode 100644 index 0000000..8f4eda3 Binary files /dev/null and b/antik/build/libs/RePairip.jar differ diff --git a/antik/build/resources/main/info.txt b/antik/build/resources/main/info.txt new file mode 100644 index 0000000..bfdfbad --- /dev/null +++ b/antik/build/resources/main/info.txt @@ -0,0 +1,3 @@ +This is a resource file for the antik project. +Project: RePairip +Subproject: antik diff --git a/antik/build/resources/main/log.dex b/antik/build/resources/main/log.dex new file mode 100644 index 0000000..38a44dc Binary files /dev/null and b/antik/build/resources/main/log.dex differ diff --git a/antik/build/resources/main/restoreMethod.dex b/antik/build/resources/main/restoreMethod.dex new file mode 100644 index 0000000..8187362 Binary files /dev/null and b/antik/build/resources/main/restoreMethod.dex differ diff --git a/antik/build/tmp/compileJava/compileTransaction/stash-dir/MethodMaker.class.uniqueId1 b/antik/build/tmp/compileJava/compileTransaction/stash-dir/MethodMaker.class.uniqueId1 new file mode 100644 index 0000000..fb70399 Binary files /dev/null and b/antik/build/tmp/compileJava/compileTransaction/stash-dir/MethodMaker.class.uniqueId1 differ diff --git a/antik/build/tmp/compileJava/compileTransaction/stash-dir/TranslationRewriter.class.uniqueId0 b/antik/build/tmp/compileJava/compileTransaction/stash-dir/TranslationRewriter.class.uniqueId0 new file mode 100644 index 0000000..4d63dde Binary files /dev/null and b/antik/build/tmp/compileJava/compileTransaction/stash-dir/TranslationRewriter.class.uniqueId0 differ diff --git a/antik/build/tmp/compileJava/previous-compilation-data.bin b/antik/build/tmp/compileJava/previous-compilation-data.bin new file mode 100644 index 0000000..6e6a03d Binary files /dev/null and b/antik/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/antik/build/tmp/shadowJar/MANIFEST.MF b/antik/build/tmp/shadowJar/MANIFEST.MF new file mode 100644 index 0000000..5a9240c --- /dev/null +++ b/antik/build/tmp/shadowJar/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: com.antik.Main + diff --git a/antik/src/main/java/com/antik/DexPatcher/Translation/MethodT/MethodMaker.java b/antik/src/main/java/com/antik/DexPatcher/Translation/MethodT/MethodMaker.java index 180609e..1407617 100644 --- a/antik/src/main/java/com/antik/DexPatcher/Translation/MethodT/MethodMaker.java +++ b/antik/src/main/java/com/antik/DexPatcher/Translation/MethodT/MethodMaker.java @@ -129,7 +129,7 @@ public class MethodMaker { public static ImmutableMethod createClinit() { MethodImplementationBuilder builder = new MethodImplementationBuilder(1); - builder.addInstruction(new BuilderInstruction21c(Opcode.CONST_STRING, 0, new ImmutableStringReference("RePatcher v1.5.20"))); + builder.addInstruction(new BuilderInstruction21c(Opcode.CONST_STRING, 0, new ImmutableStringReference("RePatcher v1.6.30"))); builder.addInstruction(new BuilderInstruction35c(Opcode.INVOKE_STATIC, 0, 0, 0, 0, 0, 0, new ImmutableMethodReference(PairipClass.STARTUP_LAUNCHER.type, "launch", null, "V"))); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); return new ImmutableMethod(PairipClass.APPLICATION.type, "", null, "V", AccessFlags.STATIC.getValue() | AccessFlags.CONSTRUCTOR.getValue(), null, null, builder.getMethodImplementation()); diff --git a/antik/src/main/java/com/antik/librarySurgery/FileUtils.java b/antik/src/main/java/com/antik/librarySurgery/FileUtils.java new file mode 100644 index 0000000..c71e5d7 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/FileUtils.java @@ -0,0 +1,26 @@ +package com.antik.librarySurgery; + +import java.io.File; + +public class FileUtils { + + public static void deleteDirectory(File dir) { + if (dir == null || !dir.exists()) return; + File[] files = dir.listFiles(); + if (files != null) { + for (File f : files) { + if (f.isDirectory()) { + deleteDirectory(f); + } else { + if (!f.delete()) { + f.deleteOnExit(); + } + } + } + } + boolean deleted = dir.delete(); + if (!deleted) { + dir.deleteOnExit(); + } + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/LibSurgery.java b/antik/src/main/java/com/antik/librarySurgery/LibSurgery.java index 8cdc0ff..c116b5e 100644 --- a/antik/src/main/java/com/antik/librarySurgery/LibSurgery.java +++ b/antik/src/main/java/com/antik/librarySurgery/LibSurgery.java @@ -1,245 +1,17 @@ package com.antik.librarySurgery; +import com.antik.librarySurgery.memory.Memory; +import com.antik.librarySurgery.memory.MemoryRegion; +import com.antik.librarySurgery.process.ProcessFinder; import com.antik.ui.banner; -import java.io.*; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.charset.StandardCharsets; +import java.io.File; import java.nio.file.Files; -import java.util.*; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; +import java.util.List; +import java.util.Map; public class LibSurgery { - public record PatchResult(boolean success, String message) {} - - public static List getInstalledApks(String packageName) { - String out = Memory.runRootCmd("pm path " + packageName); - List apks = new ArrayList<>(); - for (String l : out.split("\r?\n")) { - String trimmed = l.trim(); - if (trimmed.startsWith("package:")) { - String apkPath = trimmed.replace("package:", "").trim(); - File f = new File(apkPath); - if (f.exists()) { - apks.add(f); - } else { - File tmpCopy = new File("/data/local/tmp/temp_base.apk"); - Memory.runRootCmd("cp " + apkPath + " " + tmpCopy.getAbsolutePath() + " && chmod 666 " + tmpCopy.getAbsolutePath()); - if (tmpCopy.exists()) { - apks.add(tmpCopy); - } - } - } - } - if (apks.isEmpty()) { - System.err.println("[ERROR] Package not installed or APK paths unavailable : " + packageName); - System.exit(1); - } - System.out.println("[INFO] Found " + apks.size() + " APK path(s) for package : " + packageName); - return apks; - } - - public static Map extractArm64Libs(List apks, File tmpDir) { - Map extractedLibs = new HashMap<>(); - for (File apkFile : apks) { - try (ZipFile zip = new ZipFile(apkFile)) { - Enumeration entries = zip.entries(); - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - String fname = entry.getName(); - if (fname.endsWith(".so") && fname.contains("arm64")) { - String libName = new File(fname).getName(); - if (!extractedLibs.containsKey(libName)) { - File extPath = new File(tmpDir, libName); - try (InputStream is = zip.getInputStream(entry); - OutputStream os = new FileOutputStream(extPath)) { - is.transferTo(os); - } - extractedLibs.put(libName, extPath); - } - } - } - } catch (Exception e) { - System.err.println("[ERROR] Extracting native libs failed : " + e.getMessage()); - } - } - System.out.println("[INFO] Extracted " + extractedLibs.size() + " ARM64 native library/libraries"); - return extractedLibs; - } - - public static PatchResult patchSingleLib(byte[] data, byte[] memDump) { - if (data.length < 0x40 || data[0] != 0x7f || data[1] != 'E' || data[2] != 'L' || data[3] != 'F') { - return new PatchResult(false, "Invalid ELF header"); - } - - ByteBuffer buf = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN); - - long ePhOff = buf.getLong(0x20); - int ePhNum = buf.getShort(0x38) & 0xFFFF; - - Long dynOff = null; - Long dynSz = null; - - for (int i = 0; i < ePhNum; i++) { - int o = (int) (ePhOff + i * 56L); - if (o + 56 > data.length) break; - int pType = buf.getInt(o); - if (pType == 2) { // PT_DYNAMIC - dynOff = buf.getLong(o + 8); - dynSz = buf.getLong(o + 32); - break; - } - } - - if (dynOff == null) { - return new PatchResult(false, "No PT_DYNAMIC header found"); - } - - Long strtabVa = null; - int dynOffInt = dynOff.intValue(); - int dynSzInt = dynSz.intValue(); - - for (int j = 0; j < dynSzInt; j += 16) { - int entryPos = dynOffInt + j; - if (entryPos + 16 > data.length) break; - long t = buf.getLong(entryPos); - long v = buf.getLong(entryPos + 8); - if (t == 5) { // DT_STRTAB - strtabVa = v; - break; - } - } - - Long strtabOff = null; - if (strtabVa != null) { - for (int i = 0; i < ePhNum; i++) { - int o = (int) (ePhOff + i * 56L); - if (o + 56 > data.length) break; - int pt = buf.getInt(o); - long pVa = buf.getLong(o + 16); - long pFsz = buf.getLong(o + 32); - if (pt == 1 && pVa <= strtabVa && strtabVa < pVa + pFsz) { // PT_LOAD - long pOff = buf.getLong(o + 8); - strtabOff = pOff + (strtabVa - pVa); - break; - } - } - } - - Long initVa = null; - List newEntries = new ArrayList<>(); - boolean hasPairip = false; - - for (int j = 0; j < dynSzInt; j += 16) { - int entryPos = dynOffInt + j; - if (entryPos + 16 > data.length) break; - long t = buf.getLong(entryPos); - long v = buf.getLong(entryPos + 8); - - if (t == 0) { // DT_NULL - break; - } - if (t == 12) { // DT_INIT - initVa = v; - continue; - } - if (t == 1 && strtabOff != null) { // DT_NEEDED - int strPos = (int) (strtabOff + v); - String name = readNullTerminatedString(data, strPos); - if (name.toLowerCase().contains("pairip")) { - hasPairip = true; - continue; - } - } - newEntries.add(new long[]{t, v}); - } - - if (!hasPairip && initVa == null) { - return new PatchResult(false, "Not protected by PairIP"); - } - - newEntries.add(new long[]{0, 0}); - - for (int k = 0; k < newEntries.size(); k++) { - int pos = dynOffInt + k * 16; - if (pos + 16 <= data.length) { - buf.putLong(pos, newEntries.get(k)[0]); - buf.putLong(pos + 8, newEntries.get(k)[1]); - } - } - - for (int k = newEntries.size() * 16; k < dynSzInt; k += 16) { - int pos = dynOffInt + k; - if (pos + 16 <= data.length) { - buf.putLong(pos, 0L); - buf.putLong(pos + 8, 0L); - } - } - - if (initVa != null) { - for (int i = 0; i < ePhNum; i++) { - int o = (int) (ePhOff + i * 56L); - if (o + 56 > data.length) break; - int pt = buf.getInt(o); - long pVa = buf.getLong(o + 16); - long pMsz = buf.getLong(o + 40); - if (pt == 1 && pVa <= initVa && initVa < pVa + pMsz) { - buf.putInt(o, 0); // PT_NULL - } - } - } - - byte[] oldStr = "ExecuteProgram\0".getBytes(StandardCharsets.US_ASCII); - byte[] newStr = "memset\0\0\0\0\0\0\0\0\0".getBytes(StandardCharsets.US_ASCII); - int posStr = indexOf(data, oldStr); - if (posStr != -1 && posStr + newStr.length <= data.length) { - System.arraycopy(newStr, 0, data, posStr, newStr.length); - } - - int pos4af0 = 0x4af0; - byte[] arm64Stub = new byte[] { - (byte) 0xc0, 0x00, (byte) 0x80, 0x52, - 0x20, 0x00, (byte) 0xa0, 0x72, - (byte) 0xc0, 0x03, 0x5f, (byte) 0xd6 - }; - if (data.length > pos4af0 + arm64Stub.length) { - System.arraycopy(arm64Stub, 0, data, pos4af0, arm64Stub.length); - } - - if (memDump != null && memDump.length > 0) { - int copyLen = Math.min(data.length, memDump.length); - System.arraycopy(memDump, 0, data, 0, copyLen); - } - - return new PatchResult(true, "Successfully patched"); - } - - private static String readNullTerminatedString(byte[] data, int offset) { - if (offset < 0 || offset >= data.length) return ""; - int end = offset; - while (end < data.length && data[end] != 0) { - end++; - } - return new String(data, offset, end - offset, StandardCharsets.US_ASCII); - } - - private static int indexOf(byte[] array, byte[] target) { - if (target.length == 0) return 0; - outer: - for (int i = 0; i <= array.length - target.length; i++) { - for (int j = 0; j < target.length; j++) { - if (array[i + j] != target[j]) { - continue outer; - } - } - return i; - } - return -1; - } - public static void process(String packageName, String outDirStr) { banner.banner(); @@ -255,12 +27,16 @@ public class LibSurgery { try { tmpDir = Files.createTempDirectory("pairip_surgery_").toFile(); - List apks = getInstalledApks(packageName); - Map extractedLibs = extractArm64Libs(apks, tmpDir); + List apks = LibraryExtractor.getInstalledApks(packageName); + Map extractedLibs = LibraryExtractor.extractArm64Libs(apks, tmpDir); - String pid = Memory.waitForProcess(packageName); + String pid = ProcessFinder.waitForProcess(packageName); + + MemoryRegion rxRegion = Memory.findRxRegion(pid); + String rxAddr = rxRegion != null ? Long.toHexString(rxRegion.getStartAddress()) : null; + String dumpedPath = rxRegion != null ? rxRegion.getPathname() : ""; + String dumpedLibName = !dumpedPath.isEmpty() ? new File(dumpedPath).getName() : ""; - String rxAddr = Memory.findRxAddress(pid); byte[] memDumpData = Memory.dumpMemory(pid, rxAddr); int patchedCount = 0; @@ -273,10 +49,10 @@ public class LibSurgery { } byte[] data = Files.readAllBytes(libPath.toPath()); - byte[] dumpToUse = (libName.contains("mjpg") || libName.contains("unity") || libName.contains("il2cpp")) + byte[] dumpToUse = (dumpedLibName.isEmpty() || libName.equalsIgnoreCase(dumpedLibName) || dumpedLibName.contains(libName)) ? memDumpData : null; - PatchResult res = patchSingleLib(data, dumpToUse); + PatchResult res = LibraryPatcher.patchSingleLib(data, dumpToUse); if (res.success()) { String outName = libName.replace(".so", "") + "_patched.so"; File outPath = new File(outDir, outName); @@ -294,30 +70,11 @@ public class LibSurgery { System.err.println("[ERROR] Process failed : " + e.getMessage()); } finally { if (tmpDir != null) { - deleteDirectory(tmpDir); + FileUtils.deleteDirectory(tmpDir); } } } - private static void deleteDirectory(File dir) { - File[] files = dir.listFiles(); - if (files != null) { - for (File f : files) { - if (f.isDirectory()) { - deleteDirectory(f); - } else { - if (!f.delete()) { - f.deleteOnExit(); - } - } - } - } - boolean deleted = dir.delete(); - if (!deleted) { - dir.deleteOnExit(); - } - } - public static void main(String[] args) { String packageName = null; String outDir = null; diff --git a/antik/src/main/java/com/antik/librarySurgery/LibraryExtractor.java b/antik/src/main/java/com/antik/librarySurgery/LibraryExtractor.java new file mode 100644 index 0000000..5f06f09 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/LibraryExtractor.java @@ -0,0 +1,76 @@ +package com.antik.librarySurgery; + +import com.antik.librarySurgery.shell.Shell; +import com.antik.librarySurgery.shell.ShellResult; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class LibraryExtractor { + + public static List getInstalledApks(String packageName) { + ShellResult result = Shell.runRootCmd("pm path " + packageName); + List apks = new ArrayList<>(); + if (result.isSuccess() && !result.getStdout().isEmpty()) { + for (String line : result.getStdout().split("\r?\n")) { + String trimmed = line.trim(); + if (trimmed.startsWith("package:")) { + String apkPath = trimmed.replace("package:", "").trim(); + File f = new File(apkPath); + if (f.exists()) { + apks.add(f); + } else { + File tmpCopy = new File("/data/local/tmp/temp_base.apk"); + Shell.runRootCmd("cp " + apkPath + " " + tmpCopy.getAbsolutePath() + " && chmod 666 " + tmpCopy.getAbsolutePath()); + if (tmpCopy.exists()) { + apks.add(tmpCopy); + } + } + } + } + } + if (apks.isEmpty()) { + System.err.println("[ERROR] Package not installed or APK paths unavailable : " + packageName); + System.exit(1); + } + System.out.println("[INFO] Found " + apks.size() + " APK path(s) for package : " + packageName); + return apks; + } + + public static Map extractArm64Libs(List apks, File tmpDir) { + Map extractedLibs = new HashMap<>(); + for (File apkFile : apks) { + try (ZipFile zip = new ZipFile(apkFile)) { + Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + String fname = entry.getName(); + if (fname.endsWith(".so") && fname.contains("arm64")) { + String libName = new File(fname).getName(); + if (!extractedLibs.containsKey(libName)) { + File extPath = new File(tmpDir, libName); + try (InputStream is = zip.getInputStream(entry); + OutputStream os = new FileOutputStream(extPath)) { + is.transferTo(os); + } + extractedLibs.put(libName, extPath); + } + } + } + } catch (Exception e) { + System.err.println("[ERROR] Extracting native libs failed : " + e.getMessage()); + } + } + System.out.println("[INFO] Extracted " + extractedLibs.size() + " ARM64 native library/libraries"); + return extractedLibs; + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/LibraryPatcher.java b/antik/src/main/java/com/antik/librarySurgery/LibraryPatcher.java new file mode 100644 index 0000000..8efd723 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/LibraryPatcher.java @@ -0,0 +1,129 @@ +package com.antik.librarySurgery; + +import com.antik.librarySurgery.elf.DynamicEntry; +import com.antik.librarySurgery.elf.Elf; +import com.antik.librarySurgery.elf.ElfConstants; +import com.antik.librarySurgery.elf.ProgramHeader; +import com.antik.librarySurgery.io.ByteReader; +import com.antik.librarySurgery.io.ByteWriter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class LibraryPatcher { + + public static PatchResult patchSingleLib(byte[] data, byte[] memDump) { + Elf elf = new Elf(data); + if (!elf.getHeader().isValid()) { + return new PatchResult(false, "Invalid ELF header"); + } + + ProgramHeader dynamicHeader = elf.getDynamicHeader(); + if (dynamicHeader == null) { + return new PatchResult(false, "No PT_DYNAMIC header found"); + } + + ByteReader reader = elf.getReader(); + ByteWriter writer = new ByteWriter(data); + + int dynOff = (int) dynamicHeader.getPOffset(); + int dynSz = (int) dynamicHeader.getPFileSz(); + + Long initVa = null; + Long initArrayVa = null; + Long initArraySz = null; + List newEntries = new ArrayList<>(); + boolean hasPairip = false; + + for (int j = 0; j < dynSz; j += 16) { + int entryPos = dynOff + j; + if (entryPos + 16 > reader.length()) break; + long tag = reader.readUInt64(entryPos); + long val = reader.readUInt64(entryPos + 8); + + if (tag == ElfConstants.DT_NULL) { + break; + } + if (tag == ElfConstants.DT_INIT) { + initVa = val; + continue; + } + if (tag == ElfConstants.DT_INIT_ARRAY) { + initArrayVa = val; + continue; + } + if (tag == ElfConstants.DT_INIT_ARRAYSZ) { + initArraySz = val; + continue; + } + if (tag == ElfConstants.DT_NEEDED) { + String name = elf.readStringFromStrtab(val); + if (name.toLowerCase().contains("pairip")) { + hasPairip = true; + continue; + } + } + newEntries.add(new DynamicEntry(tag, val)); + } + + int posStr = reader.indexOf(ElfConstants.OLD_EXECUTE_PROGRAM); + boolean isPairipProtected = hasPairip || posStr != -1; + + if (!isPairipProtected) { + return new PatchResult(false, "Not protected by PairIP"); + } + + newEntries.add(new DynamicEntry(ElfConstants.DT_NULL, 0L)); + + for (int k = 0; k < newEntries.size(); k++) { + int pos = dynOff + k * 16; + if (pos + 16 <= reader.length()) { + writer.writeUInt64(pos, newEntries.get(k).getTag()); + writer.writeUInt64(pos + 8, newEntries.get(k).getVal()); + } + } + + writer.zeroRange(dynOff + newEntries.size() * 16, dynOff + dynSz); + + if (initVa != null) { + for (ProgramHeader ph : elf.getProgramHeaders()) { + if (ph.getPType() == ElfConstants.PT_LOAD && ph.getPVaddr() <= initVa && initVa < ph.getPVaddr() + ph.getPMemSz()) { + writer.writeUInt32(ph.getHeaderOffset(), ElfConstants.PT_NULL); + } + } + } + + if (initArrayVa != null && initArraySz != null) { + Long initArrayOff = elf.vaddrToOffset(initArrayVa); + if (initArrayOff != null) { + int arrayPos = initArrayOff.intValue(); + int arraySize = initArraySz.intValue(); + if (arrayPos >= 0 && arrayPos + arraySize <= reader.length()) { + writer.zeroRange(arrayPos, arrayPos + arraySize); + } + } + } + + if (posStr != -1) { + writer.writeBytes(posStr, ElfConstants.NEW_MEMSET); + } + + Long jniOnLoadOffset = elf.findSymbolAddress("JNI_OnLoad"); + if (jniOnLoadOffset != null) { + int stubPos = jniOnLoadOffset.intValue(); + if (stubPos >= 0 && stubPos + ElfConstants.ARM64_STUB_BYTES.length <= reader.length()) { + writer.writeBytes(stubPos, ElfConstants.ARM64_STUB_BYTES); + } + } else { + System.out.println("[INFO] JNI_OnLoad symbol not found in ELF, skipping stub patch safely."); + } + + if (memDump != null && memDump.length > 0) { + int copyLen = Math.min(reader.length(), memDump.length); + writer.writeBytes(0, Arrays.copyOf(memDump, copyLen)); + } + + return new PatchResult(true, "Successfully patched"); + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/Memory.java b/antik/src/main/java/com/antik/librarySurgery/Memory.java deleted file mode 100644 index e45fb65..0000000 --- a/antik/src/main/java/com/antik/librarySurgery/Memory.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.antik.librarySurgery; - -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStreamReader; -import java.nio.file.Files; - -public class Memory { - - public static String runRootCmd(String cmd) { - try { - Process process = Runtime.getRuntime().exec(new String[]{"su", "-c", cmd}); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - StringBuilder sb = new StringBuilder(); - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - sb.append(line).append("\n"); - } - process.waitFor(); - return sb.toString().trim(); - } catch (Exception e) { - return ""; - } - } - - public static String getPidForPackage(String packageName) { - String pidOut = runRootCmd("ps -A | grep " + packageName); - if (pidOut.isEmpty()) { - pidOut = runRootCmd("pidof " + packageName); - if (!pidOut.isEmpty()) { - String[] pids = pidOut.trim().split("\\s+"); - return pids[0]; - } - return null; - } - - for (String line : pidOut.split("\r?\n")) { - String trimmed = line.trim(); - if (trimmed.contains(packageName)) { - String[] parts = trimmed.split("\\s+"); - if (parts.length >= 2) { - return parts[1]; - } - } - } - return null; - } - - public static String waitForProcess(String packageName) { - System.out.println("[INFO] Waiting for package : " + packageName); - System.out.println("[INFO] Please launch the app on your device "); - - while (true) { - String pid = getPidForPackage(packageName); - if (pid != null && !pid.isEmpty()) { - System.out.println("[ROOT] App process detected with PID : " + pid); - return pid; - } - try { - Thread.sleep(1500); - } catch (InterruptedException ignored) {} - } - } - - public static String findRxAddress(String pid) { - String mapsOut = runRootCmd("grep 'r-xp' /proc/" + pid + "/maps"); - for (String line : mapsOut.split("\r?\n")) { - if (line.contains("apk") || line.contains("lib")) { - String[] parts = line.trim().split("\\s+"); - if (parts.length > 0) { - return parts[0].split("-")[0]; - } - } - } - return null; - } - - public static byte[] dumpMemory(String pid, String rxAddr) { - if (rxAddr == null || rxAddr.isEmpty()) { - return null; - } - String dumpPath = "/data/local/tmp/pairip_dump.bin"; - System.out.println("[ROOT] Dumping decrypted .text memory from RAM (Address 0x" + rxAddr + ")"); - runRootCmd("dd if=/proc/" + pid + "/mem of=" + dumpPath + " bs=1024 count=576 skip=$((0x" + rxAddr + "/1024))"); - - File dumpFile = new File(dumpPath); - byte[] data = null; - if (dumpFile.exists() && dumpFile.length() > 0) { - try { - data = Files.readAllBytes(dumpFile.toPath()); - System.out.println("[ROOT] Captured " + data.length + " bytes decrypted memory dump"); - } catch (Exception e) { - System.err.println("[ERROR] Reading memory dump failed : " + e.getMessage()); - } - } - runRootCmd("rm -f " + dumpPath); - return data; - } -} diff --git a/antik/src/main/java/com/antik/librarySurgery/PatchResult.java b/antik/src/main/java/com/antik/librarySurgery/PatchResult.java new file mode 100644 index 0000000..9102c7f --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/PatchResult.java @@ -0,0 +1,3 @@ +package com.antik.librarySurgery; + +public record PatchResult(boolean success, String message) {} diff --git a/antik/src/main/java/com/antik/librarySurgery/elf/DynamicEntry.java b/antik/src/main/java/com/antik/librarySurgery/elf/DynamicEntry.java new file mode 100644 index 0000000..c6594f3 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/elf/DynamicEntry.java @@ -0,0 +1,20 @@ +package com.antik.librarySurgery.elf; + +public class DynamicEntry { + + private final long tag; + private final long val; + + public DynamicEntry(long tag, long val) { + this.tag = tag; + this.val = val; + } + + public long getTag() { + return tag; + } + + public long getVal() { + return val; + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/elf/Elf.java b/antik/src/main/java/com/antik/librarySurgery/elf/Elf.java new file mode 100644 index 0000000..8819df0 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/elf/Elf.java @@ -0,0 +1,120 @@ +package com.antik.librarySurgery.elf; + +import com.antik.librarySurgery.io.ByteReader; + +import java.util.ArrayList; +import java.util.List; + +public class Elf { + + private final ByteReader reader; + private final ElfHeader header; + private final List programHeaders = new ArrayList<>(); + private ProgramHeader dynamicHeader = null; + private Long strtabVa = null; + private Long strtabOff = null; + private Long symtabVa = null; + private Long symtabOff = null; + + public Elf(byte[] data) { + this.reader = new ByteReader(data); + this.header = new ElfHeader(reader); + + if (header.isValid()) { + parseProgramHeaders(); + parseDynamicSection(); + } + } + + private void parseProgramHeaders() { + long phOff = header.getPhOff(); + int phNum = header.getPhNum(); + for (int i = 0; i < phNum; i++) { + int offset = (int) (phOff + i * 56L); + if (offset + 56 > reader.length()) break; + ProgramHeader ph = new ProgramHeader(reader, offset); + programHeaders.add(ph); + if (ph.getPType() == ElfConstants.PT_DYNAMIC) { + this.dynamicHeader = ph; + } + } + } + + private void parseDynamicSection() { + if (dynamicHeader == null) return; + int dynOff = (int) dynamicHeader.getPOffset(); + int dynSz = (int) dynamicHeader.getPFileSz(); + + for (int j = 0; j < dynSz; j += 16) { + int pos = dynOff + j; + if (pos + 16 > reader.length()) break; + long tag = reader.readUInt64(pos); + long val = reader.readUInt64(pos + 8); + if (tag == ElfConstants.DT_STRTAB) { + this.strtabVa = val; + } else if (tag == ElfConstants.DT_SYMTAB) { + this.symtabVa = val; + } + } + + if (strtabVa != null) { + this.strtabOff = vaddrToOffset(strtabVa); + } + if (symtabVa != null) { + this.symtabOff = vaddrToOffset(symtabVa); + } + } + + public Long vaddrToOffset(long vaddr) { + for (ProgramHeader ph : programHeaders) { + if (ph.getPType() == ElfConstants.PT_LOAD && ph.getPVaddr() <= vaddr && vaddr < ph.getPVaddr() + ph.getPMemSz()) { + return ph.getPOffset() + (vaddr - ph.getPVaddr()); + } + } + return null; + } + + public Long findSymbolAddress(String symbolName) { + if (symtabOff == null || strtabOff == null) return null; + int symOff = symtabOff.intValue(); + int maxSyms = 3000; + for (int i = 0; i < maxSyms; i++) { + int entryPos = symOff + i * 24; + if (entryPos + 24 > reader.length()) break; + long nameIdx = reader.readUInt32(entryPos); + long value = reader.readUInt64(entryPos + 8); + if (nameIdx > 0) { + String name = reader.readNullTerminatedString((int) (strtabOff + nameIdx)); + if (symbolName.equals(name)) { + return vaddrToOffset(value); + } + } + } + return null; + } + + public ByteReader getReader() { + return reader; + } + + public ElfHeader getHeader() { + return header; + } + + public List getProgramHeaders() { + return programHeaders; + } + + public ProgramHeader getDynamicHeader() { + return dynamicHeader; + } + + public Long getStrtabOff() { + return strtabOff; + } + + public String readStringFromStrtab(long offsetVal) { + if (strtabOff == null) return ""; + return reader.readNullTerminatedString((int) (strtabOff + offsetVal)); + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/elf/ElfConstants.java b/antik/src/main/java/com/antik/librarySurgery/elf/ElfConstants.java new file mode 100644 index 0000000..035cabd --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/elf/ElfConstants.java @@ -0,0 +1,27 @@ +package com.antik.librarySurgery.elf; + +public class ElfConstants { + + public static final byte[] ELF_MAGIC = new byte[]{(byte) 0x7f, 'E', 'L', 'F'}; + + public static final int PT_NULL = 0; + public static final int PT_LOAD = 1; + public static final int PT_DYNAMIC = 2; + + public static final long DT_NULL = 0L; + public static final long DT_NEEDED = 1L; + public static final long DT_STRTAB = 5L; + public static final long DT_SYMTAB = 6L; + public static final long DT_INIT = 12L; + public static final long DT_INIT_ARRAY = 25L; + public static final long DT_INIT_ARRAYSZ = 27L; + + public static final byte[] OLD_EXECUTE_PROGRAM = "ExecuteProgram\0".getBytes(java.nio.charset.StandardCharsets.US_ASCII); + public static final byte[] NEW_MEMSET = "memset\0\0\0\0\0\0\0\0\0".getBytes(java.nio.charset.StandardCharsets.US_ASCII); + + public static final byte[] ARM64_STUB_BYTES = new byte[]{ + (byte) 0xc0, 0x00, (byte) 0x80, 0x52, // mov w0, #0 + 0x20, 0x00, (byte) 0xa0, 0x72, // movk w0, #0x10, lsl #16 (JNI_VERSION_1_6 = 0x00010000) + (byte) 0xc0, 0x03, 0x5f, (byte) 0xd6 // ret + }; +} diff --git a/antik/src/main/java/com/antik/librarySurgery/elf/ElfHeader.java b/antik/src/main/java/com/antik/librarySurgery/elf/ElfHeader.java new file mode 100644 index 0000000..5e263b8 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/elf/ElfHeader.java @@ -0,0 +1,34 @@ +package com.antik.librarySurgery.elf; + +import com.antik.librarySurgery.io.ByteReader; + +public class ElfHeader { + + private final long phOff; + private final int phNum; + private final boolean valid; + + public ElfHeader(ByteReader reader) { + if (!reader.checkMagic(ElfConstants.ELF_MAGIC)) { + this.valid = false; + this.phOff = 0L; + this.phNum = 0; + return; + } + this.phOff = reader.readUInt64(0x20); + this.phNum = reader.readUInt16(0x38); + this.valid = true; + } + + public boolean isValid() { + return valid; + } + + public long getPhOff() { + return phOff; + } + + public int getPhNum() { + return phNum; + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/elf/ProgramHeader.java b/antik/src/main/java/com/antik/librarySurgery/elf/ProgramHeader.java new file mode 100644 index 0000000..392bddb --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/elf/ProgramHeader.java @@ -0,0 +1,46 @@ +package com.antik.librarySurgery.elf; + +import com.antik.librarySurgery.io.ByteReader; + +public class ProgramHeader { + + private final int headerOffset; + private final int pType; + private final long pOffset; + private final long pVaddr; + private final long pFileSz; + private final long pMemSz; + + public ProgramHeader(ByteReader reader, int headerOffset) { + this.headerOffset = headerOffset; + this.pType = (int) reader.readUInt32(headerOffset); + this.pOffset = reader.readUInt64(headerOffset + 8); + this.pVaddr = reader.readUInt64(headerOffset + 16); + this.pFileSz = reader.readUInt64(headerOffset + 32); + this.pMemSz = reader.readUInt64(headerOffset + 40); + } + + public int getHeaderOffset() { + return headerOffset; + } + + public int getPType() { + return pType; + } + + public long getPOffset() { + return pOffset; + } + + public long getPVaddr() { + return pVaddr; + } + + public long getPFileSz() { + return pFileSz; + } + + public long getPMemSz() { + return pMemSz; + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/io/ByteReader.java b/antik/src/main/java/com/antik/librarySurgery/io/ByteReader.java new file mode 100644 index 0000000..32f1842 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/io/ByteReader.java @@ -0,0 +1,70 @@ +package com.antik.librarySurgery.io; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; + +public class ByteReader { + + private final byte[] buffer; + private final ByteBuffer byteBuffer; + + public ByteReader(byte[] buffer) { + this.buffer = buffer; + this.byteBuffer = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN); + } + + public byte[] getBuffer() { + return buffer; + } + + public int length() { + return buffer.length; + } + + public int readUInt16(int offset) { + if (offset < 0 || offset + 2 > buffer.length) return 0; + return byteBuffer.getShort(offset) & 0xFFFF; + } + + public long readUInt32(int offset) { + if (offset < 0 || offset + 4 > buffer.length) return 0L; + return byteBuffer.getInt(offset) & 0xFFFFFFFFL; + } + + public long readUInt64(int offset) { + if (offset < 0 || offset + 8 > buffer.length) return 0L; + return byteBuffer.getLong(offset); + } + + public String readNullTerminatedString(int offset) { + if (offset < 0 || offset >= buffer.length) return ""; + int end = offset; + while (end < buffer.length && buffer[end] != 0) { + end++; + } + return new String(buffer, offset, end - offset, StandardCharsets.US_ASCII); + } + + public int indexOf(byte[] target) { + if (target == null || target.length == 0) return -1; + outer: + for (int i = 0; i <= buffer.length - target.length; i++) { + for (int j = 0; j < target.length; j++) { + if (buffer[i + j] != target[j]) { + continue outer; + } + } + return i; + } + return -1; + } + + public boolean checkMagic(byte[] magic) { + if (magic == null || buffer.length < magic.length) return false; + for (int i = 0; i < magic.length; i++) { + if (buffer[i] != magic[i]) return false; + } + return true; + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/io/ByteWriter.java b/antik/src/main/java/com/antik/librarySurgery/io/ByteWriter.java new file mode 100644 index 0000000..1af857d --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/io/ByteWriter.java @@ -0,0 +1,51 @@ +package com.antik.librarySurgery.io; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +public class ByteWriter { + + private final byte[] buffer; + private final ByteBuffer byteBuffer; + + public ByteWriter(byte[] buffer) { + this.buffer = buffer; + this.byteBuffer = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN); + } + + public byte[] getBuffer() { + return buffer; + } + + public void writeUInt16(int offset, int value) { + if (offset >= 0 && offset + 2 <= buffer.length) { + byteBuffer.putShort(offset, (short) value); + } + } + + public void writeUInt32(int offset, long value) { + if (offset >= 0 && offset + 4 <= buffer.length) { + byteBuffer.putInt(offset, (int) value); + } + } + + public void writeUInt64(int offset, long value) { + if (offset >= 0 && offset + 8 <= buffer.length) { + byteBuffer.putLong(offset, value); + } + } + + public void writeBytes(int offset, byte[] data) { + if (data != null && offset >= 0 && offset + data.length <= buffer.length) { + System.arraycopy(data, 0, buffer, offset, data.length); + } + } + + public void zeroRange(int startOffset, int endOffset) { + if (startOffset >= 0 && endOffset <= buffer.length && startOffset < endOffset) { + for (int i = startOffset; i < endOffset; i++) { + buffer[i] = 0; + } + } + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/memory/Memory.java b/antik/src/main/java/com/antik/librarySurgery/memory/Memory.java new file mode 100644 index 0000000..1001954 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/memory/Memory.java @@ -0,0 +1,36 @@ +package com.antik.librarySurgery.memory; + +import com.antik.librarySurgery.shell.Shell; + +import java.io.File; +import java.nio.file.Files; + +public class Memory { + + public static MemoryRegion findRxRegion(String pid) { + MemoryMap map = MemoryMap.parseFromProcess(pid); + return map.findRxRegion(); + } + + public static byte[] dumpMemory(String pid, String rxAddr) { + if (rxAddr == null || rxAddr.isEmpty()) { + return null; + } + String dumpPath = "/data/local/tmp/pairip_dump.bin"; + System.out.println("[ROOT] Dumping decrypted .text memory from RAM (Address 0x" + rxAddr + ")"); + Shell.runRootCmd("dd if=/proc/" + pid + "/mem of=" + dumpPath + " bs=1024 count=576 skip=$((0x" + rxAddr + "/1024))"); + + File dumpFile = new File(dumpPath); + byte[] data = null; + if (dumpFile.exists() && dumpFile.length() > 0) { + try { + data = Files.readAllBytes(dumpFile.toPath()); + System.out.println("[ROOT] Captured " + data.length + " bytes decrypted memory dump"); + } catch (Exception e) { + System.err.println("[ERROR] Reading memory dump failed : " + e.getMessage()); + } + } + Shell.runRootCmd("rm -f " + dumpPath); + return data; + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/memory/MemoryMap.java b/antik/src/main/java/com/antik/librarySurgery/memory/MemoryMap.java new file mode 100644 index 0000000..416aae9 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/memory/MemoryMap.java @@ -0,0 +1,58 @@ +package com.antik.librarySurgery.memory; + +import com.antik.librarySurgery.shell.Shell; +import com.antik.librarySurgery.shell.ShellResult; + +import java.util.ArrayList; +import java.util.List; + +public class MemoryMap { + + private final List> regions = new ArrayList<>(); + + public static MemoryMap parseFromProcess(String pid) { + MemoryMap map = new MemoryMap(); + ShellResult result = Shell.runRootCmd("grep 'r-xp' /proc/" + pid + "/maps"); + if (!result.getStdout().isEmpty()) { + for (String line : result.getStdout().split("\r?\n")) { + String trimmed = line.trim(); + String[] parts = trimmed.split("\\s+"); + if (parts.length >= 1) { + String[] addrs = parts[0].split("-"); + if (addrs.length == 2) { + try { + long start = Long.parseUnsignedLong(addrs[0], 16); + long end = Long.parseUnsignedLong(addrs[1], 16); + String perms = parts.length > 1 ? parts[1] : ""; + String path = parts.length > 5 ? parts[5] : ""; + map.regions.add(new MemoryRegion<>(start, end, perms, path)); + } catch (NumberFormatException ignored) {} + } + } + } + } + return map; + } + + public List> getRegions() { + return regions; + } + + public MemoryRegion findRxRegion() { + for (MemoryRegion region : regions) { + String path = region.getPathname(); + if (region.isExecutable() && (path.contains("apk") || path.contains("lib"))) { + return region; + } + } + return null; + } + + public String findRxAddressString() { + MemoryRegion region = findRxRegion(); + if (region != null) { + return Long.toHexString(region.getStartAddress()); + } + return null; + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/memory/MemoryRegion.java b/antik/src/main/java/com/antik/librarySurgery/memory/MemoryRegion.java new file mode 100644 index 0000000..26bf042 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/memory/MemoryRegion.java @@ -0,0 +1,40 @@ +package com.antik.librarySurgery.memory; + +public class MemoryRegion { + + private final T startAddress; + private final T endAddress; + private final String permissions; + private final String pathname; + + public MemoryRegion(T startAddress, T endAddress, String permissions, String pathname) { + this.startAddress = startAddress; + this.endAddress = endAddress; + this.permissions = permissions; + this.pathname = pathname; + } + + public T getStartAddress() { + return startAddress; + } + + public T getEndAddress() { + return endAddress; + } + + public String getPermissions() { + return permissions; + } + + public String getPathname() { + return pathname; + } + + public boolean isExecutable() { + return permissions != null && permissions.contains("x"); + } + + public boolean isReadable() { + return permissions != null && permissions.contains("r"); + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/process/ProcessFinder.java b/antik/src/main/java/com/antik/librarySurgery/process/ProcessFinder.java new file mode 100644 index 0000000..065d069 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/process/ProcessFinder.java @@ -0,0 +1,46 @@ +package com.antik.librarySurgery.process; + +import com.antik.librarySurgery.shell.Shell; +import com.antik.librarySurgery.shell.ShellResult; + +public class ProcessFinder { + + public static String getPidForPackage(String packageName) { + ShellResult result = Shell.runRootCmd("ps -A | grep " + packageName); + if (!result.isSuccess() || result.getStdout().isEmpty()) { + result = Shell.runRootCmd("pidof " + packageName); + if (result.isSuccess() && !result.getStdout().isEmpty()) { + String[] pids = result.getStdout().trim().split("\\s+"); + return pids[0]; + } + return null; + } + + for (String line : result.getStdout().split("\r?\n")) { + String trimmed = line.trim(); + if (trimmed.contains(packageName)) { + String[] parts = trimmed.split("\\s+"); + if (parts.length >= 2) { + return parts[1]; + } + } + } + return null; + } + + public static String waitForProcess(String packageName) { + System.out.println("[INFO] Waiting for package : " + packageName); + System.out.println("[INFO] Please launch the app on your device "); + + while (true) { + String pid = getPidForPackage(packageName); + if (pid != null && !pid.isEmpty()) { + System.out.println("[ROOT] App process detected with PID : " + pid); + return pid; + } + try { + Thread.sleep(1500); + } catch (InterruptedException ignored) {} + } + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/shell/Shell.java b/antik/src/main/java/com/antik/librarySurgery/shell/Shell.java new file mode 100644 index 0000000..c2718ed --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/shell/Shell.java @@ -0,0 +1,45 @@ +package com.antik.librarySurgery.shell; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class Shell { + + public static ShellResult runRootCmd(String command) { + try { + Process process = Runtime.getRuntime().exec(new String[]{"su", "-c", command}); + BufferedReader outReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + + StringBuilder outSb = new StringBuilder(); + for (String line = outReader.readLine(); line != null; line = outReader.readLine()) { + outSb.append(line).append("\n"); + } + + StringBuilder errSb = new StringBuilder(); + for (String line = errReader.readLine(); line != null; line = errReader.readLine()) { + errSb.append(line).append("\n"); + } + + int exitCode = process.waitFor(); + return new ShellResult(exitCode, outSb.toString(), errSb.toString()); + } catch (Exception e) { + return new ShellResult(-1, "", e.getMessage()); + } + } + + public static ShellResult runCmd(String command) { + try { + Process process = Runtime.getRuntime().exec(new String[]{"sh", "-c", command}); + BufferedReader outReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + StringBuilder outSb = new StringBuilder(); + for (String line = outReader.readLine(); line != null; line = outReader.readLine()) { + outSb.append(line).append("\n"); + } + int exitCode = process.waitFor(); + return new ShellResult(exitCode, outSb.toString(), ""); + } catch (Exception e) { + return runRootCmd(command); + } + } +} diff --git a/antik/src/main/java/com/antik/librarySurgery/shell/ShellResult.java b/antik/src/main/java/com/antik/librarySurgery/shell/ShellResult.java new file mode 100644 index 0000000..6849625 --- /dev/null +++ b/antik/src/main/java/com/antik/librarySurgery/shell/ShellResult.java @@ -0,0 +1,30 @@ +package com.antik.librarySurgery.shell; + +public class ShellResult { + + private final int exitCode; + private final String stdout; + private final String stderr; + + public ShellResult(int exitCode, String stdout, String stderr) { + this.exitCode = exitCode; + this.stdout = stdout != null ? stdout.trim() : ""; + this.stderr = stderr != null ? stderr.trim() : ""; + } + + public int getExitCode() { + return exitCode; + } + + public String getStdout() { + return stdout; + } + + public String getStderr() { + return stderr; + } + + public boolean isSuccess() { + return exitCode == 0; + } +} diff --git a/antik/src/main/java/com/antik/ui/banner.java b/antik/src/main/java/com/antik/ui/banner.java index 702d65b..739ce78 100644 --- a/antik/src/main/java/com/antik/ui/banner.java +++ b/antik/src/main/java/com/antik/ui/banner.java @@ -8,7 +8,7 @@ public class banner { System.out.println("░█▀▄░█▀▀░█▀█░█▀█░▀█▀░█▀▄░▀█▀░█▀█░"); System.out.println("░█▀▄░█▀▀░█▀▀░█▀█░░█░░█▀▄░░█░░█▀▀░"); System.out.println("░▀░▀░▀▀▀░▀░░░▀░▀░▀▀▀░▀░▀░▀▀▀░▀░░░"); - System.out.println("Version : 1.5.20"); + System.out.println("Version : 1.6.30"); System.out.println("--------------------------------------"); System.out.println("Dev : Antik"); System.out.println("Channel : https://t.me/RevDex"); diff --git a/antik/src/main/java/com/antik/ui/help.java b/antik/src/main/java/com/antik/ui/help.java index 4547006..b8cfcf1 100644 --- a/antik/src/main/java/com/antik/ui/help.java +++ b/antik/src/main/java/com/antik/ui/help.java @@ -6,6 +6,6 @@ public class help { System.out.println("java -jar RePairip.jar -i "); System.out.println("java -jar RePairip.jar -i -r "); System.out.println("java -jar RePairip.jar -i -t "); - System.out.println("java -jar RePairip.jar -p -o [-s ]"); + System.out.println("java -jar RePairip.jar -p -o "); } }