Skip to content

Commit

Permalink
Strong zip protector
Browse files Browse the repository at this point in the history
  • Loading branch information
REAndroid committed Nov 8, 2024
1 parent 4d3cfe3 commit 10749cd
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2022 github.com/REAndroid
*
* 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 com.reandroid.apkeditor.protect;

import com.reandroid.apk.ApkModule;
import com.reandroid.apk.DexFileInputSource;
import com.reandroid.app.AndroidManifest;
import com.reandroid.archive.block.CentralEntryHeader;
import com.reandroid.archive.block.DataDescriptor;
import com.reandroid.archive.block.LocalFileHeader;
import com.reandroid.archive.writer.ApkFileWriter;
import com.reandroid.archive.writer.HeaderInterceptor;
import com.reandroid.arsc.chunk.TableBlock;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

public class ProtectedFileWriter implements HeaderInterceptor {

private final ApkModule apkModule;
private final File file;
private final Set<String> mProtectedFiles;

public ProtectedFileWriter(ApkModule apkModule, File file) {
this.apkModule = apkModule;
this.file = file;
this.mProtectedFiles = new HashSet<>();
}

public void write() throws IOException {
ApkFileWriter writer = apkModule.createApkFileWriter(this.file);
writer.getInterceptorChain().setHeaderInterceptor(this);
writer.write();
writer.close();
}

@Override
public void onWriteLfh(LocalFileHeader lfh) {
String name = lfh.getFileName();
if (needsProtection(name)) {
mProtectedFiles.add(name);
lfh.getGeneralPurposeFlag().setEncryption(true);
}
}

@Override
public void onWriteDD(DataDescriptor dataDescriptor) {
}

@Override
public void onWriteCeh(CentralEntryHeader ceh) {
if (mProtectedFiles.contains(ceh.getFileName())) {
ceh.getGeneralPurposeFlag().setEncryption(true);
}
}

private boolean needsProtection(String name) {
if (AndroidManifest.FILE_NAME.equals(name)) {
return true;
}
if (TableBlock.FILE_NAME.equals(name)) {
return true;
}
if (name.startsWith("lib/") && name.endsWith(".so")) {
return true;
}
return DexFileInputSource.isDexName(name);
}
}
7 changes: 6 additions & 1 deletion src/main/java/com/reandroid/apkeditor/protect/Protector.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@ public void runCommand() throws IOException {
new TableConfuser(this).confuse();
module.getTableBlock().refresh();
logMessage("Writing apk ...");
module.writeApk(options.outputFile);
if (!options.skipZip) {
logMessage("Protecting zip structure");
new ProtectedFileWriter(module, options.outputFile).write();
} else {
module.writeApk(options.outputFile);
}
module.close();
logMessage("Saved to: " + options.outputFile);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public class ProtectorOptions extends Options {
@OptionArg(name = "-skip-manifest", flag = true, description = "protect_skip_manifest")
public boolean skipManifest;

@OptionArg(name = "-skip-zip", flag = true, description = "protect_skip_zip")
public boolean skipZip;

@OptionArg(name = "-keep-type", description = "protect_keep_type")
public final Set<String> keepTypes = new HashSet<>();

Expand Down
1 change: 1 addition & 0 deletions src/main/resources/strings/strings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ protect_description=Protects/Obfuscates apk resource files. Using unique obfusca
protect_example_1=[Basic]\n java -jar APKEditor.jar p -i path/input.apk -o path/output.apk
protect_keep_type=Keep specific resource type names (e.g drawable), By default keeps only <font> resource type.\n *Can be multiple
protect_skip_manifest=Do not protect manifest.
protect_skip_zip=Do not protect zip structure.
raw_dex=Copy raw dex files / skip smali.
res_dir_name=Sets resource files root dir name. e.g. for obfuscation to move files from 'res/*' to 'r/*' or vice versa.
refactor_description=Refactors obfuscated resource names
Expand Down

0 comments on commit 10749cd

Please sign in to comment.