From 51a84f2f41f8265a2992979b0e99aa7e074f401c Mon Sep 17 00:00:00 2001
From: Renji Yuusei <166010224+RenjiYuusei@users.noreply.github.com>
Date: Wed, 29 Oct 2025 23:25:01 +0700
Subject: [PATCH 01/16] Create main.yml
---
.github/workflows/main.yml | 1 +
1 file changed, 1 insertion(+)
create mode 100644 .github/workflows/main.yml
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..7898192
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1 @@
+a
From ecd333400ce4b47721112bcd65c3c041925913b0 Mon Sep 17 00:00:00 2001
From: Renji Yuusei <166010224+RenjiYuusei@users.noreply.github.com>
Date: Wed, 29 Oct 2025 23:31:40 +0700
Subject: [PATCH 02/16] Delete .github/workflows/main.yml
---
.github/workflows/main.yml | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 .github/workflows/main.yml
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
deleted file mode 100644
index 7898192..0000000
--- a/.github/workflows/main.yml
+++ /dev/null
@@ -1 +0,0 @@
-a
From 438cb8ac49ac46761e2283ed54f8f7ae45367b9c Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Wed, 29 Oct 2025 16:33:00 +0000
Subject: [PATCH 03/16] feat: Add icon extraction, auto-language, and build
workflow
- Adds a feature to extract the APK icon by clicking on it.
- Implements automatic language selection based on the system's language, defaulting to English.
- Adds a GitHub Actions workflow to build the application and upload it as a downloadable artifact.
---
.github/workflows/build.yml | 37 +++++++++++++++++++++++++++
APKToolGUI/Forms/FormMain.Designer.cs | 1 +
APKToolGUI/Forms/FormMain.cs | 16 ++++++++++++
APKToolGUI/Program.cs | 19 +++++++++++---
4 files changed, 70 insertions(+), 3 deletions(-)
create mode 100644 .github/workflows/build.yml
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..4ff2bd3
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,37 @@
+name: Build
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+ build:
+
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ name: Checkout Code
+
+ - name: Setup MSBuild Path
+ uses: microsoft/setup-msbuild@v1.3.1
+
+ - name: Setup NuGet
+ uses: NuGet/setup-nuget@v2
+
+ - name: Restore NuGet Packages
+ run: nuget restore APKToolGUI.sln
+
+ - name: Build Application
+ run: msbuild APKToolGUI.sln /p:Configuration=Release
+
+ - name: Package application
+ run: powershell Compress-Archive -Path APKToolGUI/bin/Release/* -DestinationPath APKToolGUI.zip
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: APKToolGUI
+ path: APKToolGUI.zip
diff --git a/APKToolGUI/Forms/FormMain.Designer.cs b/APKToolGUI/Forms/FormMain.Designer.cs
index d48bef4..e983b9b 100644
--- a/APKToolGUI/Forms/FormMain.Designer.cs
+++ b/APKToolGUI/Forms/FormMain.Designer.cs
@@ -827,6 +827,7 @@ private void InitializeComponent()
resources.ApplyResources(this.apkIconPicBox, "apkIconPicBox");
this.apkIconPicBox.Name = "apkIconPicBox";
this.apkIconPicBox.TabStop = false;
+ this.apkIconPicBox.Click += new System.EventHandler(this.apkIconPicBox_Click);
//
// label11
//
diff --git a/APKToolGUI/Forms/FormMain.cs b/APKToolGUI/Forms/FormMain.cs
index b711434..b4752fb 100644
--- a/APKToolGUI/Forms/FormMain.cs
+++ b/APKToolGUI/Forms/FormMain.cs
@@ -1627,5 +1627,21 @@ private void CancelProcess()
}
}
#endregion
+
+ private void apkIconPicBox_Click(object sender, EventArgs e)
+ {
+ if (apkIconPicBox.Image != null)
+ {
+ SaveFileDialog saveFile = new SaveFileDialog();
+ saveFile.Filter = "PNG Image|*.png";
+ saveFile.Title = "Save an Image File";
+ saveFile.ShowDialog();
+
+ if (saveFile.FileName != "")
+ {
+ apkIconPicBox.Image.Save(saveFile.FileName, System.Drawing.Imaging.ImageFormat.Png);
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/APKToolGUI/Program.cs b/APKToolGUI/Program.cs
index eaf6520..1a8ccdf 100644
--- a/APKToolGUI/Program.cs
+++ b/APKToolGUI/Program.cs
@@ -145,8 +145,19 @@ public static void SetLanguage()
{
if (settingsCulture.Equals("Auto"))
{
- System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InstalledUICulture;
- System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InstalledUICulture;
+ System.Globalization.CultureInfo systemCulture = System.Globalization.CultureInfo.InstalledUICulture;
+ try
+ {
+ System.Globalization.CultureInfo.GetCultureInfo(systemCulture.Name);
+ System.Threading.Thread.CurrentThread.CurrentUICulture = systemCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = systemCulture;
+ }
+ catch (System.Globalization.CultureNotFoundException)
+ {
+ System.Globalization.CultureInfo defaultCulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
+ System.Threading.Thread.CurrentThread.CurrentUICulture = defaultCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = defaultCulture;
+ }
}
else
{
@@ -157,7 +168,9 @@ public static void SetLanguage()
}
catch
{
-
+ System.Globalization.CultureInfo defaultCulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
+ System.Threading.Thread.CurrentThread.CurrentUICulture = defaultCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = defaultCulture;
}
}
From 7bc15f5503090409bdd255afb30d2af99ee5f9b0 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Wed, 29 Oct 2025 16:44:19 +0000
Subject: [PATCH 04/16] feat: Implement icon extraction, auto-language, and
build workflow
- Adds a feature to extract the APK icon by clicking on it in the APK Info tab.
- Implements automatic language selection based on the system's culture, letting the .NET resource manager handle fallbacks.
- Adds a GitHub Actions workflow to build the application.
- The workflow packages the application executable, resources, and dependencies into a clean directory.
- This package is uploaded as a downloadable ZIP artifact, avoiding nested ZIP files.
---
.github/workflows/build.yml | 13 ++++++++++---
APKToolGUI/Program.cs | 39 +++++++++++++------------------------
2 files changed, 23 insertions(+), 29 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 4ff2bd3..111b42d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -27,11 +27,18 @@ jobs:
- name: Build Application
run: msbuild APKToolGUI.sln /p:Configuration=Release
- - name: Package application
- run: powershell Compress-Archive -Path APKToolGUI/bin/Release/* -DestinationPath APKToolGUI.zip
+ - name: Create package directory
+ run: mkdir package
+
+ - name: Copy essential files to package
+ run: |
+ cp APKToolGUI/bin/Release/APKToolGUI.exe package/
+ cp APKToolGUI/bin/Release/config.xml package/
+ cp -r APKToolGUI/bin/Release/Resources package/
+ cp APKToolGUI/bin/Release/*.dll package/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: APKToolGUI
- path: APKToolGUI.zip
+ path: package/
diff --git a/APKToolGUI/Program.cs b/APKToolGUI/Program.cs
index 1a8ccdf..435a051 100644
--- a/APKToolGUI/Program.cs
+++ b/APKToolGUI/Program.cs
@@ -141,36 +141,23 @@ public static bool IsDarkTheme()
public static void SetLanguage()
{
String settingsCulture = Settings.Default.Culture;
+ if (settingsCulture.Equals("Auto"))
+ {
+ // Let .NET handle the resource fallback process.
+ // It will automatically use the system's language if a satellite assembly is available,
+ // otherwise it will fall back to the neutral language defined in the main assembly (English).
+ return;
+ }
+
try
{
- if (settingsCulture.Equals("Auto"))
- {
- System.Globalization.CultureInfo systemCulture = System.Globalization.CultureInfo.InstalledUICulture;
- try
- {
- System.Globalization.CultureInfo.GetCultureInfo(systemCulture.Name);
- System.Threading.Thread.CurrentThread.CurrentUICulture = systemCulture;
- System.Threading.Thread.CurrentThread.CurrentCulture = systemCulture;
- }
- catch (System.Globalization.CultureNotFoundException)
- {
- System.Globalization.CultureInfo defaultCulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
- System.Threading.Thread.CurrentThread.CurrentUICulture = defaultCulture;
- System.Threading.Thread.CurrentThread.CurrentCulture = defaultCulture;
- }
- }
- else
- {
- System.Globalization.CultureInfo _settingsCulture = System.Globalization.CultureInfo.GetCultureInfo(settingsCulture);
- System.Threading.Thread.CurrentThread.CurrentUICulture = _settingsCulture;
- System.Threading.Thread.CurrentThread.CurrentCulture = _settingsCulture;
- }
+ System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.GetCultureInfo(settingsCulture);
+ System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = culture;
}
- catch
+ catch (System.Globalization.CultureNotFoundException)
{
- System.Globalization.CultureInfo defaultCulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
- System.Threading.Thread.CurrentThread.CurrentUICulture = defaultCulture;
- System.Threading.Thread.CurrentThread.CurrentCulture = defaultCulture;
+ // If the culture in settings is invalid, do nothing and let it use the default.
}
}
From bc741ab2e49d8b5657c8b1c0b95a58e22fb3471d Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Wed, 29 Oct 2025 16:51:30 +0000
Subject: [PATCH 05/16] feat: Add icon extraction, auto-language, and build
workflow
- Adds a feature to extract the APK icon by clicking on it.
- Implements automatic language selection based on the system's language, defaulting to English.
- Adds a GitHub Actions workflow to build the application and upload it as a downloadable artifact.
- Fixes the build process by creating a placeholder config.xml to prevent errors.
---
.github/workflows/build.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 111b42d..3f2aedd 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -33,10 +33,12 @@ jobs:
- name: Copy essential files to package
run: |
cp APKToolGUI/bin/Release/APKToolGUI.exe package/
- cp APKToolGUI/bin/Release/config.xml package/
cp -r APKToolGUI/bin/Release/Resources package/
cp APKToolGUI/bin/Release/*.dll package/
+ - name: Create placeholder config.xml
+ run: New-Item -Path package/ -Name "config.xml" -ItemType "file"
+
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
From 09d9b4803c65e2184a2d586800bf96976010f9c5 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Thu, 30 Oct 2025 00:58:20 +0000
Subject: [PATCH 06/16] feat: Add icon extraction, auto-language, and build
workflow
- Adds a feature to extract the APK icon by clicking on it.
- Automatically suggests the app name as the default filename when saving the icon.
- Implements automatic language selection based on the system's language, defaulting to English.
- Adds a GitHub Actions workflow to build the application and upload it as a downloadable artifact.
- Fixes the build process by creating a placeholder config.xml to prevent errors.
---
.github/workflows/build.yml | 46 +++++++++++++++++++++++++++
APKToolGUI/Forms/FormMain.Designer.cs | 1 +
APKToolGUI/Forms/FormMain.cs | 19 +++++++++++
APKToolGUI/Program.cs | 26 +++++++--------
4 files changed, 79 insertions(+), 13 deletions(-)
create mode 100644 .github/workflows/build.yml
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..3f2aedd
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,46 @@
+name: Build
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+ build:
+
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ name: Checkout Code
+
+ - name: Setup MSBuild Path
+ uses: microsoft/setup-msbuild@v1.3.1
+
+ - name: Setup NuGet
+ uses: NuGet/setup-nuget@v2
+
+ - name: Restore NuGet Packages
+ run: nuget restore APKToolGUI.sln
+
+ - name: Build Application
+ run: msbuild APKToolGUI.sln /p:Configuration=Release
+
+ - name: Create package directory
+ run: mkdir package
+
+ - name: Copy essential files to package
+ run: |
+ cp APKToolGUI/bin/Release/APKToolGUI.exe package/
+ cp -r APKToolGUI/bin/Release/Resources package/
+ cp APKToolGUI/bin/Release/*.dll package/
+
+ - name: Create placeholder config.xml
+ run: New-Item -Path package/ -Name "config.xml" -ItemType "file"
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: APKToolGUI
+ path: package/
diff --git a/APKToolGUI/Forms/FormMain.Designer.cs b/APKToolGUI/Forms/FormMain.Designer.cs
index d48bef4..e983b9b 100644
--- a/APKToolGUI/Forms/FormMain.Designer.cs
+++ b/APKToolGUI/Forms/FormMain.Designer.cs
@@ -827,6 +827,7 @@ private void InitializeComponent()
resources.ApplyResources(this.apkIconPicBox, "apkIconPicBox");
this.apkIconPicBox.Name = "apkIconPicBox";
this.apkIconPicBox.TabStop = false;
+ this.apkIconPicBox.Click += new System.EventHandler(this.apkIconPicBox_Click);
//
// label11
//
diff --git a/APKToolGUI/Forms/FormMain.cs b/APKToolGUI/Forms/FormMain.cs
index b711434..d1ba027 100644
--- a/APKToolGUI/Forms/FormMain.cs
+++ b/APKToolGUI/Forms/FormMain.cs
@@ -1627,5 +1627,24 @@ private void CancelProcess()
}
}
#endregion
+
+ private void apkIconPicBox_Click(object sender, EventArgs e)
+ {
+ if (apkIconPicBox.Image != null)
+ {
+ SaveFileDialog saveFile = new SaveFileDialog();
+ saveFile.Filter = "PNG Image|*.png";
+ saveFile.Title = "Save an Image File";
+ saveFile.FileName = appTxtBox.Text; // Set default filename to app name
+
+ if (saveFile.ShowDialog() == DialogResult.OK)
+ {
+ if (saveFile.FileName != "")
+ {
+ apkIconPicBox.Image.Save(saveFile.FileName, System.Drawing.Imaging.ImageFormat.Png);
+ }
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/APKToolGUI/Program.cs b/APKToolGUI/Program.cs
index eaf6520..435a051 100644
--- a/APKToolGUI/Program.cs
+++ b/APKToolGUI/Program.cs
@@ -141,23 +141,23 @@ public static bool IsDarkTheme()
public static void SetLanguage()
{
String settingsCulture = Settings.Default.Culture;
+ if (settingsCulture.Equals("Auto"))
+ {
+ // Let .NET handle the resource fallback process.
+ // It will automatically use the system's language if a satellite assembly is available,
+ // otherwise it will fall back to the neutral language defined in the main assembly (English).
+ return;
+ }
+
try
{
- if (settingsCulture.Equals("Auto"))
- {
- System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InstalledUICulture;
- System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InstalledUICulture;
- }
- else
- {
- System.Globalization.CultureInfo _settingsCulture = System.Globalization.CultureInfo.GetCultureInfo(settingsCulture);
- System.Threading.Thread.CurrentThread.CurrentUICulture = _settingsCulture;
- System.Threading.Thread.CurrentThread.CurrentCulture = _settingsCulture;
- }
+ System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.GetCultureInfo(settingsCulture);
+ System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = culture;
}
- catch
+ catch (System.Globalization.CultureNotFoundException)
{
-
+ // If the culture in settings is invalid, do nothing and let it use the default.
}
}
From 2d2574f8411a61922dc89c9be1eb5535baddf36e Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Thu, 30 Oct 2025 01:43:47 +0000
Subject: [PATCH 07/16] fix: Correct syntax error in icon extraction logic
This commit fixes a C# syntax error in the `apkIconPicBox_Click` event handler that was causing the build to fail. The logic is now corrected to properly handle the SaveFileDialog and save the icon image.
This also includes the previous features and fixes:
- Adds a feature to extract the APK icon by clicking on it.
- Automatically suggests the app name as the default filename.
- Implements correct automatic language selection.
- Adds a robust GitHub Actions workflow to build and package the application.
---
APKToolGUI/Forms/FormMain.cs | 20 ++++++--------------
1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/APKToolGUI/Forms/FormMain.cs b/APKToolGUI/Forms/FormMain.cs
index 0c4a2ec..5c95f60 100644
--- a/APKToolGUI/Forms/FormMain.cs
+++ b/APKToolGUI/Forms/FormMain.cs
@@ -1632,24 +1632,16 @@ private void apkIconPicBox_Click(object sender, EventArgs e)
{
if (apkIconPicBox.Image != null)
{
- SaveFileDialog saveFile = new SaveFileDialog();
- saveFile.Filter = "PNG Image|*.png";
- saveFile.Title = "Save an Image File";
- feat-apk-tool-gui-updates
- saveFile.FileName = appTxtBox.Text; // Set default filename to app name
-
- if (saveFile.ShowDialog() == DialogResult.OK)
+ using (SaveFileDialog saveFile = new SaveFileDialog())
{
- if (saveFile.FileName != "")
+ saveFile.Filter = "PNG Image|*.png";
+ saveFile.Title = "Save an Image File";
+ saveFile.FileName = appTxtBox.Text; // Set default filename to app name
+
+ if (saveFile.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty(saveFile.FileName))
{
apkIconPicBox.Image.Save(saveFile.FileName, System.Drawing.Imaging.ImageFormat.Png);
}
- saveFile.ShowDialog();
-
- if (saveFile.FileName != "")
- {
- apkIconPicBox.Image.Save(saveFile.FileName, System.Drawing.Imaging.ImageFormat.Png);
- master
}
}
}
From d00601c7a153c0f424b3d7e4a859305afc24de19 Mon Sep 17 00:00:00 2001
From: Renji Yuusei <166010224+RenjiYuusei@users.noreply.github.com>
Date: Thu, 30 Oct 2025 23:16:14 +0700
Subject: [PATCH 08/16] Remove bundled dpt.jar
---
APKToolGUI/APKToolGUI.csproj | 2 +
APKToolGUI/ApkTool/DptShell.cs | 112 ++
APKToolGUI/Forms/FormMain.cs | 401 ++++++
APKToolGUI/Handlers/DragDropHandlers.cs | 20 +
.../Handlers/ObfuscateControlEventHandlers.cs | 86 ++
APKToolGUI/Languages/Language.Designer.cs | 218 +++-
APKToolGUI/Languages/Language.de.resx | 72 ++
APKToolGUI/Languages/Language.hu.resx | 1102 +++++++++--------
APKToolGUI/Languages/Language.ja.resx | 72 ++
APKToolGUI/Languages/Language.pt-BR.resx | 72 ++
APKToolGUI/Languages/Language.resx | 72 ++
APKToolGUI/Languages/Language.ru.resx | 72 ++
APKToolGUI/Languages/Language.tr.resx | 72 ++
APKToolGUI/Languages/Language.vi-VN.resx | 72 ++
APKToolGUI/Languages/Language.zh-CN.resx | 72 ++
APKToolGUI/Program.cs | 2 +
APKToolGUI/Properties/Settings.Designer.cs | 166 ++-
APKToolGUI/Properties/Settings.settings | 36 +
APKToolGUI/app.config | 36 +
19 files changed, 2240 insertions(+), 517 deletions(-)
create mode 100644 APKToolGUI/ApkTool/DptShell.cs
create mode 100644 APKToolGUI/Handlers/ObfuscateControlEventHandlers.cs
diff --git a/APKToolGUI/APKToolGUI.csproj b/APKToolGUI/APKToolGUI.csproj
index 22a63b3..9c5ff06 100644
--- a/APKToolGUI/APKToolGUI.csproj
+++ b/APKToolGUI/APKToolGUI.csproj
@@ -312,6 +312,7 @@
Component
+
@@ -323,6 +324,7 @@
+
diff --git a/APKToolGUI/ApkTool/DptShell.cs b/APKToolGUI/ApkTool/DptShell.cs
new file mode 100644
index 0000000..3b52b28
--- /dev/null
+++ b/APKToolGUI/ApkTool/DptShell.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using APKToolGUI.Utils;
+using Java;
+
+namespace APKToolGUI
+{
+ public class DptShell : JarProcess
+ {
+ public event DptShellDataReceivedEventHandler DptShellOutputDataReceived;
+ public event DptShellDataReceivedEventHandler DptShellErrorDataReceived;
+
+ public DptShell(string javaPath, string jarPath)
+ : base(javaPath, jarPath)
+ {
+ OutputDataReceived += OnOutputDataReceived;
+ ErrorDataReceived += OnErrorDataReceived;
+ }
+
+ void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
+ {
+ if (e.Data != null)
+ DptShellErrorDataReceived?.Invoke(this, new DptShellDataReceivedEventArgs(e.Data));
+ }
+
+ void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
+ {
+ if (e.Data != null)
+ DptShellOutputDataReceived?.Invoke(this, new DptShellDataReceivedEventArgs(e.Data));
+ }
+
+ public int Obfuscate(string packageFile, string outputDirectory, DptShellOptions options)
+ {
+ List args = new List();
+
+ if (options.Debug)
+ args.Add("--debug");
+ if (options.DisableAcf)
+ args.Add("--disable-acf");
+ if (options.DumpCode)
+ args.Add("--dump-code");
+ if (options.NoisyLog)
+ args.Add("--noisy-log");
+ if (options.Smaller)
+ args.Add("--smaller");
+ if (options.NoSign)
+ args.Add("--no-sign");
+ if (options.KeepClasses)
+ args.Add("--keep-classes");
+
+ if (!String.IsNullOrWhiteSpace(options.ExcludeAbi))
+ args.Add($"--exclude-abi \"{options.ExcludeAbi}\"");
+ if (!String.IsNullOrWhiteSpace(options.RulesFile))
+ args.Add($"--rules-file \"{options.RulesFile}\"");
+ if (!String.IsNullOrWhiteSpace(outputDirectory))
+ args.Add($"--output \"{outputDirectory}\"");
+
+ args.Add($"--package-file \"{packageFile}\"");
+
+ Start(String.Join(" ", args));
+ BeginOutputReadLine();
+ BeginErrorReadLine();
+ WaitForExit();
+ CancelOutputRead();
+ CancelErrorRead();
+
+ return ExitCode;
+ }
+
+ public void Cancel()
+ {
+ try
+ {
+ foreach (var process in Process.GetProcessesByName("java"))
+ {
+ if (process.Id == Id)
+ {
+ ProcessUtils.KillAllProcessesSpawnedBy((uint)Id);
+ process.Kill();
+ }
+ }
+ }
+ catch { }
+ }
+ }
+
+ public class DptShellOptions
+ {
+ public bool Debug { get; set; }
+ public bool DisableAcf { get; set; }
+ public bool DumpCode { get; set; }
+ public bool NoisyLog { get; set; }
+ public bool Smaller { get; set; }
+ public bool NoSign { get; set; }
+ public bool KeepClasses { get; set; }
+ public string ExcludeAbi { get; set; }
+ public string RulesFile { get; set; }
+ }
+
+ public delegate void DptShellDataReceivedEventHandler(object sender, DptShellDataReceivedEventArgs e);
+
+ public class DptShellDataReceivedEventArgs : EventArgs
+ {
+ public string Message { get; private set; }
+
+ public DptShellDataReceivedEventArgs(string message)
+ {
+ Message = message;
+ }
+ }
+}
diff --git a/APKToolGUI/Forms/FormMain.cs b/APKToolGUI/Forms/FormMain.cs
index 5c95f60..5cd5682 100644
--- a/APKToolGUI/Forms/FormMain.cs
+++ b/APKToolGUI/Forms/FormMain.cs
@@ -31,6 +31,32 @@ public partial class FormMain : Form
internal Zipalign zipalign;
internal UpdateChecker updateCheker;
internal AaptParser aapt;
+ internal DptShell dptShell;
+
+ internal TabPage tabPageObfuscate;
+ internal GroupBox groupBox_OBF_Input;
+ internal Label label_OBF_InputFile;
+ internal TextBox textBox_OBF_InputFile;
+ internal Button button_OBF_BrowseInputFile;
+ internal GroupBox groupBox_OBF_Output;
+ internal CheckBox checkBox_OBF_UseOutputDir;
+ internal Label label_OBF_OutputDir;
+ internal TextBox textBox_OBF_OutputDir;
+ internal Button button_OBF_BrowseOutputDir;
+ internal GroupBox groupBox_OBF_Options;
+ internal CheckBox checkBox_OBF_Debug;
+ internal CheckBox checkBox_OBF_DisableAcf;
+ internal CheckBox checkBox_OBF_DumpCode;
+ internal CheckBox checkBox_OBF_NoisyLog;
+ internal CheckBox checkBox_OBF_Smaller;
+ internal CheckBox checkBox_OBF_NoSign;
+ internal CheckBox checkBox_OBF_KeepClasses;
+ internal Label label_OBF_ExcludeAbi;
+ internal TextBox textBox_OBF_ExcludeAbi;
+ internal Label label_OBF_RulesFile;
+ internal TextBox textBox_OBF_RulesFile;
+ internal Button button_OBF_BrowseRulesFile;
+ internal Button button_OBF_Obfuscate;
private bool IgnoreOutputDirContextMenu;
private bool isRunning;
@@ -49,6 +75,7 @@ public FormMain()
Program.SetLanguage();
InitializeComponent();
+ InitializeObfuscateTab();
if (Program.IsDarkTheme())
DarkTheme.SetTheme(Controls, this);
@@ -102,6 +129,7 @@ public FormMain()
new AdbControlEventHandlers(this);
new DragDropHandlers(this);
new ApkinfoControlEventHandlers(this);
+ new ObfuscateControlEventHandlers(this);
new MainWindowEventHandlers(this);
new MenuItemHandlers(this);
new TaskBarJumpList(Handle);
@@ -413,6 +441,281 @@ internal void Running(string msg)
ToStatus(msg, Resources.waiting);
}
+ private void InitializeObfuscateTab()
+ {
+ int groupWidth = Math.Max(tabControlMain.DisplayRectangle.Width - 12, 560);
+ int buttonWidth = 100;
+ int rightButtonX = groupWidth - buttonWidth - 10;
+ int textStartX = 150;
+ int textWidth = Math.Max(rightButtonX - textStartX - 6, 220);
+
+ tabPageObfuscate = new TabPage
+ {
+ Name = "tabPageObfuscate",
+ Padding = new Padding(3),
+ AutoScroll = true,
+ BackColor = Color.White,
+ UseVisualStyleBackColor = true,
+ Text = Language.ObfuscateTabTitle
+ };
+ tabPageObfuscate.AllowDrop = true;
+
+ groupBox_OBF_Input = new GroupBox
+ {
+ Name = "groupBox_OBF_Input",
+ Text = Language.ObfuscateInputGroup,
+ Location = new Point(6, 6),
+ Size = new Size(groupWidth, 72),
+ Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
+ };
+
+ label_OBF_InputFile = new Label
+ {
+ Name = "label_OBF_InputFile",
+ AutoSize = true,
+ Location = new Point(9, 30),
+ Text = Language.ObfuscateInputFileLabel
+ };
+
+ textBox_OBF_InputFile = new TextBox
+ {
+ Name = "textBox_OBF_InputFile",
+ Location = new Point(textStartX, 27),
+ Size = new Size(textWidth, 23),
+ Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right,
+ AllowDrop = true
+ };
+ textBox_OBF_InputFile.DataBindings.Add(new Binding("Text", Settings.Default, nameof(Settings.Default.Obfuscate_InputFile), true, DataSourceUpdateMode.OnPropertyChanged));
+ textBox_OBF_InputFile.Text = Settings.Default.Obfuscate_InputFile;
+
+ button_OBF_BrowseInputFile = new Button
+ {
+ Name = "button_OBF_BrowseInputFile",
+ Location = new Point(rightButtonX, 25),
+ Size = new Size(buttonWidth, 27),
+ Anchor = AnchorStyles.Top | AnchorStyles.Right,
+ Text = Language.ObfuscateBrowse,
+ UseVisualStyleBackColor = true
+ };
+
+ groupBox_OBF_Input.Controls.Add(label_OBF_InputFile);
+ groupBox_OBF_Input.Controls.Add(textBox_OBF_InputFile);
+ groupBox_OBF_Input.Controls.Add(button_OBF_BrowseInputFile);
+
+ groupBox_OBF_Output = new GroupBox
+ {
+ Name = "groupBox_OBF_Output",
+ Text = Language.ObfuscateOutputGroup,
+ Location = new Point(6, groupBox_OBF_Input.Bottom + 10),
+ Size = new Size(groupWidth, 96),
+ Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
+ };
+
+ checkBox_OBF_UseOutputDir = new CheckBox
+ {
+ Name = "checkBox_OBF_UseOutputDir",
+ AutoSize = true,
+ Location = new Point(9, 25),
+ Text = Language.ObfuscateUseOutputDir
+ };
+ checkBox_OBF_UseOutputDir.DataBindings.Add(new Binding("Checked", Settings.Default, nameof(Settings.Default.Obfuscate_UseOutputDir), true, DataSourceUpdateMode.OnPropertyChanged));
+ checkBox_OBF_UseOutputDir.Checked = Settings.Default.Obfuscate_UseOutputDir;
+
+ label_OBF_OutputDir = new Label
+ {
+ Name = "label_OBF_OutputDir",
+ AutoSize = true,
+ Location = new Point(9, 58),
+ Text = Language.ObfuscateOutputDirectoryLabel
+ };
+
+ textBox_OBF_OutputDir = new TextBox
+ {
+ Name = "textBox_OBF_OutputDir",
+ Location = new Point(textStartX, 55),
+ Size = new Size(textWidth, 23),
+ Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
+ };
+ textBox_OBF_OutputDir.DataBindings.Add(new Binding("Text", Settings.Default, nameof(Settings.Default.Obfuscate_OutputDir), true, DataSourceUpdateMode.OnPropertyChanged));
+ textBox_OBF_OutputDir.Text = Settings.Default.Obfuscate_OutputDir;
+
+ button_OBF_BrowseOutputDir = new Button
+ {
+ Name = "button_OBF_BrowseOutputDir",
+ Location = new Point(rightButtonX, 53),
+ Size = new Size(buttonWidth, 27),
+ Anchor = AnchorStyles.Top | AnchorStyles.Right,
+ Text = Language.ObfuscateBrowse,
+ UseVisualStyleBackColor = true
+ };
+
+ groupBox_OBF_Output.Controls.Add(checkBox_OBF_UseOutputDir);
+ groupBox_OBF_Output.Controls.Add(label_OBF_OutputDir);
+ groupBox_OBF_Output.Controls.Add(textBox_OBF_OutputDir);
+ groupBox_OBF_Output.Controls.Add(button_OBF_BrowseOutputDir);
+
+ groupBox_OBF_Options = new GroupBox
+ {
+ Name = "groupBox_OBF_Options",
+ Text = Language.ObfuscateOptionsGroup,
+ Location = new Point(6, groupBox_OBF_Output.Bottom + 10),
+ Size = new Size(groupWidth, 230),
+ Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
+ };
+
+ int secondColumnX = Math.Max(groupWidth / 2, 280);
+
+ checkBox_OBF_Debug = new CheckBox
+ {
+ Name = "checkBox_OBF_Debug",
+ AutoSize = true,
+ Location = new Point(9, 25),
+ Text = Language.ObfuscateDebug
+ };
+ checkBox_OBF_Debug.DataBindings.Add(new Binding("Checked", Settings.Default, nameof(Settings.Default.Obfuscate_Debug), true, DataSourceUpdateMode.OnPropertyChanged));
+ checkBox_OBF_Debug.Checked = Settings.Default.Obfuscate_Debug;
+
+ checkBox_OBF_DisableAcf = new CheckBox
+ {
+ Name = "checkBox_OBF_DisableAcf",
+ AutoSize = true,
+ Location = new Point(9, 50),
+ Text = Language.ObfuscateDisableAcf
+ };
+ checkBox_OBF_DisableAcf.DataBindings.Add(new Binding("Checked", Settings.Default, nameof(Settings.Default.Obfuscate_DisableAcf), true, DataSourceUpdateMode.OnPropertyChanged));
+ checkBox_OBF_DisableAcf.Checked = Settings.Default.Obfuscate_DisableAcf;
+
+ checkBox_OBF_DumpCode = new CheckBox
+ {
+ Name = "checkBox_OBF_DumpCode",
+ AutoSize = true,
+ Location = new Point(9, 75),
+ Text = Language.ObfuscateDumpCode
+ };
+ checkBox_OBF_DumpCode.DataBindings.Add(new Binding("Checked", Settings.Default, nameof(Settings.Default.Obfuscate_DumpCode), true, DataSourceUpdateMode.OnPropertyChanged));
+ checkBox_OBF_DumpCode.Checked = Settings.Default.Obfuscate_DumpCode;
+
+ checkBox_OBF_NoisyLog = new CheckBox
+ {
+ Name = "checkBox_OBF_NoisyLog",
+ AutoSize = true,
+ Location = new Point(9, 100),
+ Text = Language.ObfuscateNoisyLog
+ };
+ checkBox_OBF_NoisyLog.DataBindings.Add(new Binding("Checked", Settings.Default, nameof(Settings.Default.Obfuscate_NoisyLog), true, DataSourceUpdateMode.OnPropertyChanged));
+ checkBox_OBF_NoisyLog.Checked = Settings.Default.Obfuscate_NoisyLog;
+
+ checkBox_OBF_Smaller = new CheckBox
+ {
+ Name = "checkBox_OBF_Smaller",
+ AutoSize = true,
+ Location = new Point(9, 125),
+ Text = Language.ObfuscateSmaller
+ };
+ checkBox_OBF_Smaller.DataBindings.Add(new Binding("Checked", Settings.Default, nameof(Settings.Default.Obfuscate_Smaller), true, DataSourceUpdateMode.OnPropertyChanged));
+ checkBox_OBF_Smaller.Checked = Settings.Default.Obfuscate_Smaller;
+
+ checkBox_OBF_NoSign = new CheckBox
+ {
+ Name = "checkBox_OBF_NoSign",
+ AutoSize = true,
+ Location = new Point(secondColumnX, 25),
+ Text = Language.ObfuscateNoSign
+ };
+ checkBox_OBF_NoSign.DataBindings.Add(new Binding("Checked", Settings.Default, nameof(Settings.Default.Obfuscate_NoSign), true, DataSourceUpdateMode.OnPropertyChanged));
+ checkBox_OBF_NoSign.Checked = Settings.Default.Obfuscate_NoSign;
+
+ checkBox_OBF_KeepClasses = new CheckBox
+ {
+ Name = "checkBox_OBF_KeepClasses",
+ AutoSize = true,
+ Location = new Point(secondColumnX, 50),
+ Text = Language.ObfuscateKeepClasses
+ };
+ checkBox_OBF_KeepClasses.DataBindings.Add(new Binding("Checked", Settings.Default, nameof(Settings.Default.Obfuscate_KeepClasses), true, DataSourceUpdateMode.OnPropertyChanged));
+ checkBox_OBF_KeepClasses.Checked = Settings.Default.Obfuscate_KeepClasses;
+
+ label_OBF_ExcludeAbi = new Label
+ {
+ Name = "label_OBF_ExcludeAbi",
+ AutoSize = true,
+ Location = new Point(9, 155),
+ Text = Language.ObfuscateExcludeAbiLabel
+ };
+
+ textBox_OBF_ExcludeAbi = new TextBox
+ {
+ Name = "textBox_OBF_ExcludeAbi",
+ Location = new Point(textStartX, 152),
+ Size = new Size(textWidth, 23),
+ Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
+ };
+ textBox_OBF_ExcludeAbi.DataBindings.Add(new Binding("Text", Settings.Default, nameof(Settings.Default.Obfuscate_ExcludeAbi), true, DataSourceUpdateMode.OnPropertyChanged));
+ textBox_OBF_ExcludeAbi.Text = Settings.Default.Obfuscate_ExcludeAbi;
+
+ label_OBF_RulesFile = new Label
+ {
+ Name = "label_OBF_RulesFile",
+ AutoSize = true,
+ Location = new Point(9, 185),
+ Text = Language.ObfuscateRulesFileLabel
+ };
+
+ textBox_OBF_RulesFile = new TextBox
+ {
+ Name = "textBox_OBF_RulesFile",
+ Location = new Point(textStartX, 182),
+ Size = new Size(textWidth, 23),
+ Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
+ };
+ textBox_OBF_RulesFile.DataBindings.Add(new Binding("Text", Settings.Default, nameof(Settings.Default.Obfuscate_RulesFile), true, DataSourceUpdateMode.OnPropertyChanged));
+ textBox_OBF_RulesFile.Text = Settings.Default.Obfuscate_RulesFile;
+
+ button_OBF_BrowseRulesFile = new Button
+ {
+ Name = "button_OBF_BrowseRulesFile",
+ Location = new Point(rightButtonX, 180),
+ Size = new Size(buttonWidth, 27),
+ Anchor = AnchorStyles.Top | AnchorStyles.Right,
+ Text = Language.ObfuscateBrowse,
+ UseVisualStyleBackColor = true
+ };
+
+ groupBox_OBF_Options.Controls.Add(checkBox_OBF_Debug);
+ groupBox_OBF_Options.Controls.Add(checkBox_OBF_DisableAcf);
+ groupBox_OBF_Options.Controls.Add(checkBox_OBF_DumpCode);
+ groupBox_OBF_Options.Controls.Add(checkBox_OBF_NoisyLog);
+ groupBox_OBF_Options.Controls.Add(checkBox_OBF_Smaller);
+ groupBox_OBF_Options.Controls.Add(checkBox_OBF_NoSign);
+ groupBox_OBF_Options.Controls.Add(checkBox_OBF_KeepClasses);
+ groupBox_OBF_Options.Controls.Add(label_OBF_ExcludeAbi);
+ groupBox_OBF_Options.Controls.Add(textBox_OBF_ExcludeAbi);
+ groupBox_OBF_Options.Controls.Add(label_OBF_RulesFile);
+ groupBox_OBF_Options.Controls.Add(textBox_OBF_RulesFile);
+ groupBox_OBF_Options.Controls.Add(button_OBF_BrowseRulesFile);
+
+ button_OBF_Obfuscate = new Button
+ {
+ Name = "button_OBF_Obfuscate",
+ Location = new Point(rightButtonX, groupBox_OBF_Options.Bottom + 12),
+ Size = new Size(buttonWidth, 32),
+ Anchor = AnchorStyles.Top | AnchorStyles.Right,
+ Text = Language.ObfuscateButton,
+ UseVisualStyleBackColor = true
+ };
+ button_OBF_Obfuscate.AllowDrop = true;
+
+ tabPageObfuscate.Controls.Add(groupBox_OBF_Input);
+ tabPageObfuscate.Controls.Add(groupBox_OBF_Output);
+ tabPageObfuscate.Controls.Add(groupBox_OBF_Options);
+ tabPageObfuscate.Controls.Add(button_OBF_Obfuscate);
+
+ int insertIndex = tabControlMain.TabPages.IndexOf(tabPageSign);
+ if (insertIndex < 0)
+ insertIndex = tabControlMain.TabPages.Count;
+ tabControlMain.TabPages.Insert(insertIndex, tabPageObfuscate);
+ }
+
internal void Done(string msg = null)
{
isRunning = false;
@@ -1171,6 +1474,90 @@ await Task.Factory.StartNew(() =>
}
#endregion
+ #region DPT Shell
+ private void InitializeDptShell()
+ {
+ dptShell = new DptShell(javaPath, Program.DPT_PATH);
+ dptShell.DptShellOutputDataReceived += DptShell_OutputDataReceived;
+ dptShell.DptShellErrorDataReceived += DptShell_ErrorDataReceived;
+ }
+
+ private void DptShell_ErrorDataReceived(object sender, DptShellDataReceivedEventArgs e)
+ {
+ ToLog(ApktoolEventType.Error, e.Message);
+ }
+
+ private void DptShell_OutputDataReceived(object sender, DptShellDataReceivedEventArgs e)
+ {
+ ToLog(ApktoolEventType.None, e.Message);
+ }
+
+ internal async Task Obfuscate(string inputFile)
+ {
+ int code = 0;
+
+ if (dptShell == null)
+ {
+ ShowMessage(Language.ErrorJavaDetect, MessageBoxIcon.Error);
+ return 1;
+ }
+
+ Running(Language.Obfuscating);
+ ToLog(ApktoolEventType.None, string.Format(Language.InputFile, inputFile));
+
+ string outputDirectory = null;
+ if (Settings.Default.Obfuscate_UseOutputDir && !IgnoreOutputDirContextMenu)
+ {
+ if (!string.IsNullOrWhiteSpace(Settings.Default.Obfuscate_OutputDir))
+ {
+ outputDirectory = Settings.Default.Obfuscate_OutputDir;
+ Directory.CreateDirectory(outputDirectory);
+ }
+ }
+
+ DptShellOptions options = new DptShellOptions
+ {
+ Debug = Settings.Default.Obfuscate_Debug,
+ DisableAcf = Settings.Default.Obfuscate_DisableAcf,
+ DumpCode = Settings.Default.Obfuscate_DumpCode,
+ NoisyLog = Settings.Default.Obfuscate_NoisyLog,
+ Smaller = Settings.Default.Obfuscate_Smaller,
+ NoSign = Settings.Default.Obfuscate_NoSign,
+ KeepClasses = Settings.Default.Obfuscate_KeepClasses,
+ ExcludeAbi = Settings.Default.Obfuscate_ExcludeAbi,
+ RulesFile = Settings.Default.Obfuscate_RulesFile
+ };
+
+ try
+ {
+ await Task.Factory.StartNew(() =>
+ {
+ code = dptShell.Obfuscate(inputFile, outputDirectory, options);
+
+ if (code == 0)
+ {
+ if (!string.IsNullOrWhiteSpace(outputDirectory))
+ ToLog(ApktoolEventType.None, string.Format(Language.ObfuscateOutputSavedTo, outputDirectory));
+
+ ToLog(ApktoolEventType.None, Language.ObfuscateSuccessfullyCompleted);
+ Done();
+ }
+ else
+ {
+ Error(Language.ErrorObfuscating);
+ }
+ });
+ }
+ catch (Exception ex)
+ {
+ Error(ex);
+ code = 1;
+ }
+
+ return code;
+ }
+ #endregion
+
#region Signapk
private void InitializeSignapk()
{
@@ -1391,6 +1778,7 @@ await Task.Factory.StartNew(() =>
InitializeAPKTool();
InitializeSignapk();
InitializeApkEditor();
+ InitializeDptShell();
string javaVersion = apktool.GetJavaVersion();
if (javaVersion != null)
@@ -1423,6 +1811,7 @@ await Task.Factory.StartNew(() =>
tabPageMain.Enabled = false;
tabPageBaksmali.Enabled = false;
tabPageInstallFramework.Enabled = false;
+ tabPageObfuscate.Enabled = false;
}));
}
@@ -1549,6 +1938,17 @@ private bool ActionButtonsEnabled
else
comSmaliBtn.Enabled = value;
+ if (button_OBF_Obfuscate != null)
+ {
+ if (button_OBF_Obfuscate.InvokeRequired)
+ button_OBF_Obfuscate.BeginInvoke(new Action(delegate
+ {
+ button_OBF_Obfuscate.Enabled = value;
+ }));
+ else
+ button_OBF_Obfuscate.Enabled = value;
+ }
+
if (mergeApkBtn.InvokeRequired)
mergeApkBtn.BeginInvoke(new Action(delegate
{
@@ -1619,6 +2019,7 @@ private void CancelProcess()
smali.Cancel();
zipalign.Cancel();
signapk.Cancel();
+ dptShell?.Cancel();
}
catch (Exception ex)
{
diff --git a/APKToolGUI/Handlers/DragDropHandlers.cs b/APKToolGUI/Handlers/DragDropHandlers.cs
index 93b1757..30fdce5 100644
--- a/APKToolGUI/Handlers/DragDropHandlers.cs
+++ b/APKToolGUI/Handlers/DragDropHandlers.cs
@@ -47,6 +47,11 @@ public DragDropHandlers(FormMain Main)
Register(main.textBox_SIGN_InputFile, main.signPanel, signEventHandler, apk);
Register(main.button_SIGN_Sign, main.signPanel, signEventHandler, apk);
+ DragEventHandler obfuscateEventHandler = new DragEventHandler((sender, e) => { DropApkToObfuscate(e); });
+ Register(main.tabPageObfuscate, null, obfuscateEventHandler, apks);
+ Register(main.textBox_OBF_InputFile, main.tabPageObfuscate, obfuscateEventHandler, apks);
+ Register(main.button_OBF_Obfuscate, main.tabPageObfuscate, obfuscateEventHandler, apks);
+
DragEventHandler mergeEventHandler = new DragEventHandler((sender, e) => { DropApkToMerge(e); });
Register(main.mergePanel, null, mergeEventHandler, apks);
Register(main.splitApkPathTxtBox, main.mergePanel, mergeEventHandler, apks);
@@ -154,6 +159,21 @@ private async void DropApkToSign(DragEventArgs e)
}
}
+ private async void DropApkToObfuscate(DragEventArgs e)
+ {
+ string[] apkFiles = null;
+ if (e.DropManyByEnd(file => apkFiles = file, apks))
+ {
+ main.tabPageObfuscate.BackColor = PanelBackColor();
+
+ foreach (var apkFile in apkFiles)
+ {
+ main.textBox_OBF_InputFile.Text = apkFile;
+ await main.Obfuscate(apkFile);
+ }
+ }
+ }
+
private async void DropApkToMerge(DragEventArgs e)
{
string[] apkFiles = null;
diff --git a/APKToolGUI/Handlers/ObfuscateControlEventHandlers.cs b/APKToolGUI/Handlers/ObfuscateControlEventHandlers.cs
new file mode 100644
index 0000000..b55c0be
--- /dev/null
+++ b/APKToolGUI/Handlers/ObfuscateControlEventHandlers.cs
@@ -0,0 +1,86 @@
+using APKToolGUI.Languages;
+using APKToolGUI.Properties;
+using Ookii.Dialogs.WinForms;
+using System;
+using System.IO;
+using System.Windows.Forms;
+
+namespace APKToolGUI.Handlers
+{
+ class ObfuscateControlEventHandlers
+ {
+ private static FormMain main;
+
+ public ObfuscateControlEventHandlers(FormMain Main)
+ {
+ main = Main;
+
+ main.button_OBF_BrowseInputFile.Click += button_OBF_BrowseInputFile_Click;
+ main.button_OBF_BrowseOutputDir.Click += button_OBF_BrowseOutputDir_Click;
+ main.button_OBF_BrowseRulesFile.Click += button_OBF_BrowseRulesFile_Click;
+ main.button_OBF_Obfuscate.Click += button_OBF_Obfuscate_Click;
+ }
+
+ internal void button_OBF_BrowseInputFile_Click(object sender, EventArgs e)
+ {
+ using (OpenFileDialog ofd = new OpenFileDialog())
+ {
+ ofd.Filter = "Android packages|*.apk;*.aab;*.apks;*.apkm;*.zip";
+
+ if (ofd.ShowDialog() == DialogResult.OK)
+ {
+ main.textBox_OBF_InputFile.Text = ofd.FileName;
+
+ if (String.IsNullOrEmpty(main.textBox_OBF_OutputDir.Text))
+ main.textBox_OBF_OutputDir.Text = Path.GetDirectoryName(ofd.FileName);
+ }
+ }
+ }
+
+ internal void button_OBF_BrowseOutputDir_Click(object sender, EventArgs e)
+ {
+ VistaFolderBrowserDialog dlg = new VistaFolderBrowserDialog();
+ dlg.ShowNewFolderButton = true;
+
+ if (dlg.ShowDialog() == DialogResult.OK)
+ main.textBox_OBF_OutputDir.Text = dlg.SelectedPath;
+ }
+
+ internal void button_OBF_BrowseRulesFile_Click(object sender, EventArgs e)
+ {
+ using (OpenFileDialog ofd = new OpenFileDialog())
+ {
+ ofd.Filter = "Rules file|*.rules;*.txt|All files|*.*";
+
+ if (ofd.ShowDialog() == DialogResult.OK)
+ main.textBox_OBF_RulesFile.Text = ofd.FileName;
+ }
+ }
+
+ internal async void button_OBF_Obfuscate_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ main.Save();
+
+ if (!File.Exists(Settings.Default.Obfuscate_InputFile))
+ {
+ main.ShowMessage(Language.ObfuscateInputFileNotFound, MessageBoxIcon.Warning);
+ return;
+ }
+
+ if (!String.IsNullOrEmpty(Settings.Default.Obfuscate_RulesFile) && !File.Exists(Settings.Default.Obfuscate_RulesFile))
+ {
+ main.ShowMessage(Language.ObfuscateRulesFileNotFound, MessageBoxIcon.Warning);
+ return;
+ }
+
+ await main.Obfuscate(Settings.Default.Obfuscate_InputFile);
+ }
+ catch (Exception ex)
+ {
+ main.ToLog(ApktoolEventType.Error, ex.Message);
+ }
+ }
+ }
+}
diff --git a/APKToolGUI/Languages/Language.Designer.cs b/APKToolGUI/Languages/Language.Designer.cs
index eeac4b0..f9d7474 100644
--- a/APKToolGUI/Languages/Language.Designer.cs
+++ b/APKToolGUI/Languages/Language.Designer.cs
@@ -869,7 +869,223 @@ internal static string InputFile {
return ResourceManager.GetString("InputFile", resourceCulture);
}
}
-
+
+ ///
+ /// Looks up a localized string similar to Obfuscate.
+ ///
+ internal static string ObfuscateTabTitle {
+ get {
+ return ResourceManager.GetString("ObfuscateTabTitle", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Input.
+ ///
+ internal static string ObfuscateInputGroup {
+ get {
+ return ResourceManager.GetString("ObfuscateInputGroup", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Output.
+ ///
+ internal static string ObfuscateOutputGroup {
+ get {
+ return ResourceManager.GetString("ObfuscateOutputGroup", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Options.
+ ///
+ internal static string ObfuscateOptionsGroup {
+ get {
+ return ResourceManager.GetString("ObfuscateOptionsGroup", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Package file:.
+ ///
+ internal static string ObfuscateInputFileLabel {
+ get {
+ return ResourceManager.GetString("ObfuscateInputFileLabel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Browse....
+ ///
+ internal static string ObfuscateBrowse {
+ get {
+ return ResourceManager.GetString("ObfuscateBrowse", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Use output directory.
+ ///
+ internal static string ObfuscateUseOutputDir {
+ get {
+ return ResourceManager.GetString("ObfuscateUseOutputDir", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Output directory:.
+ ///
+ internal static string ObfuscateOutputDirectoryLabel {
+ get {
+ return ResourceManager.GetString("ObfuscateOutputDirectoryLabel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Make package debuggable (--debug).
+ ///
+ internal static string ObfuscateDebug {
+ get {
+ return ResourceManager.GetString("ObfuscateDebug", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Disable app component factory (--disable-acf).
+ ///
+ internal static string ObfuscateDisableAcf {
+ get {
+ return ResourceManager.GetString("ObfuscateDisableAcf", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Dump code (--dump-code).
+ ///
+ internal static string ObfuscateDumpCode {
+ get {
+ return ResourceManager.GetString("ObfuscateDumpCode", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Enable noisy log (--noisy-log).
+ ///
+ internal static string ObfuscateNoisyLog {
+ get {
+ return ResourceManager.GetString("ObfuscateNoisyLog", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Optimize for smaller size (--smaller).
+ ///
+ internal static string ObfuscateSmaller {
+ get {
+ return ResourceManager.GetString("ObfuscateSmaller", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Do not sign package (--no-sign).
+ ///
+ internal static string ObfuscateNoSign {
+ get {
+ return ResourceManager.GetString("ObfuscateNoSign", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Keep classes (--keep-classes).
+ ///
+ internal static string ObfuscateKeepClasses {
+ get {
+ return ResourceManager.GetString("ObfuscateKeepClasses", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Exclude ABI list (comma separated):.
+ ///
+ internal static string ObfuscateExcludeAbiLabel {
+ get {
+ return ResourceManager.GetString("ObfuscateExcludeAbiLabel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Rules file:.
+ ///
+ internal static string ObfuscateRulesFileLabel {
+ get {
+ return ResourceManager.GetString("ObfuscateRulesFileLabel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Obfuscate.
+ ///
+ internal static string ObfuscateButton {
+ get {
+ return ResourceManager.GetString("ObfuscateButton", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Obfuscating.
+ ///
+ internal static string Obfuscating {
+ get {
+ return ResourceManager.GetString("Obfuscating", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Obfuscation completed successfully..
+ ///
+ internal static string ObfuscateSuccessfullyCompleted {
+ get {
+ return ResourceManager.GetString("ObfuscateSuccessfullyCompleted", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Obfuscated package saved to "{0}"..
+ ///
+ internal static string ObfuscateOutputSavedTo {
+ get {
+ return ResourceManager.GetString("ObfuscateOutputSavedTo", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Input file not found. Please select a valid Android package..
+ ///
+ internal static string ObfuscateInputFileNotFound {
+ get {
+ return ResourceManager.GetString("ObfuscateInputFileNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Rules file not found. Please select a valid file..
+ ///
+ internal static string ObfuscateRulesFileNotFound {
+ get {
+ return ResourceManager.GetString("ObfuscateRulesFileNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Error obfuscating package..
+ ///
+ internal static string ErrorObfuscating {
+ get {
+ return ResourceManager.GetString("ErrorObfuscating", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to APK Installation failed.
///
diff --git a/APKToolGUI/Languages/Language.de.resx b/APKToolGUI/Languages/Language.de.resx
index 346a7b1..89995eb 100644
--- a/APKToolGUI/Languages/Language.de.resx
+++ b/APKToolGUI/Languages/Language.de.resx
@@ -489,6 +489,78 @@
{0} Gerät gefunden
+
+ Verschleiern
+
+
+ Eingabe
+
+
+ Ausgabe
+
+
+ Optionen
+
+
+ Paketdatei:
+
+
+ Durchsuchen...
+
+
+ Ausgabeverzeichnis verwenden
+
+
+ Ausgabeverzeichnis:
+
+
+ Paket debuggbar machen (--debug)
+
+
+ App-Komponentenfabrik deaktivieren (--disable-acf)
+
+
+ Code ausgeben (--dump-code)
+
+
+ Ausführliches Protokoll aktivieren (--noisy-log)
+
+
+ Für kleinere Größe optimieren (--smaller)
+
+
+ Paket nicht signieren (--no-sign)
+
+
+ Klassen beibehalten (--keep-classes)
+
+
+ Auszuschließende ABI-Liste (durch Kommas getrennt):
+
+
+ Regeldatei:
+
+
+ Verschleiern
+
+
+ Verschleierung läuft
+
+
+ Verschleierung erfolgreich abgeschlossen.
+
+
+ Verschleiertes Paket gespeichert unter "{0}".
+
+
+ Eingabedatei nicht gefunden. Bitte wählen Sie ein gültiges Android-Paket aus.
+
+
+ Regeldatei nicht gefunden. Bitte wählen Sie eine gültige Datei aus.
+
+
+ Fehler beim Verschleiern des Pakets.
+
APK Installation fehlgeschlagen
diff --git a/APKToolGUI/Languages/Language.hu.resx b/APKToolGUI/Languages/Language.hu.resx
index 614566e..7f93e9f 100644
--- a/APKToolGUI/Languages/Language.hu.resx
+++ b/APKToolGUI/Languages/Language.hu.resx
@@ -1,516 +1,588 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Rólunk
-
-
- Apktool verzió
-
-
- Frissítés keresése
-
-
- Hibakereső mód
-
-
- Kilépés
-
-
- Fájl
-
-
- Súgó
-
-
- Beállítások
-
-
- Java nincs vagy rosszul van telepítve. Telepítse a Javát vagy adja meg az egyéni helyét a Beállításokban
-
-
- Hiba a beállítások olvasásakor!
-
-
- Új verzió érhető el. Szeretne frissíteni?
-
-
- Nincs frissítés.
-
-
- Dekódolási mappa nincs kiválasztva!
-
-
- A dekódolandó fájl nincs kiválasztva!
-
-
- Az aláírni szánt fájl nincs kiválasztva!
-
-
- A framework nincs kiválasztva!
-
-
- Hiba a beállítások mentése során!
-
-
- A módosítások érvényesítéséhez újra kell indítania a programot. Most akarja megtenni?
-
-
- A fájl nem található
-
-
- A mappa nem létezik
-
-
- Hiba
-
-
- Build
-
-
- Dekódolás
-
-
- A keretrendszer telepítése
-
-
- Aláírás
-
-
- Rendszer nyelve
-
-
- Tényleg telepíteni szeretné a kontextus menüt?
-
-
- Tényleg el akarja távolítani a kontextus menüt?
-
-
- Kész
-
-
- Nem érzékeli az apktool verzióját.
-
-
- A dekompilálás sikeresen befejeződött. Kimeneti könyvtár "{0}".
-
-
- Frissítés ell. hiba:
-
-
- Az aláírás sikeresen befejeződött. Fájl mentve: "{0}".
-
-
- Igazítás
-
-
- A kódolás sikertelen
-
-
- Hiba a framework címke bevitelében.
-
-
- A kiválasztott fájl nem létezik.
-
-
- Hiba a keretrendszer könyvtár kiválasztásában.
-
-
- Hiba a keretrendszer fájl kiválasztásában. A fájl nem létezik.
-
-
- Az aláírás sikertelen.
-
-
- Hiba. A keretrendszer telepítése nem indult el.
-
-
- A keretrendszer telepítése
-
-
- Aláírás
-
-
- A bemeneti fájl nem található.
-
-
- Privát kulcs nem található.
-
-
- Nyilvános kulcs nem található.
-
-
- ZIP archívumok
-
-
- A kiválasztott dekompilációs könyvtárat nem lehetett létrehozni, mert érvénytelen karaktereket tartalmaz.
-
-
- A dekompilációs könyvtár nincs kiválasztva.
-
-
- A kiválasztott keretkönyvtár nem létezik.
-
-
- Dekódolás
-
-
- A dekompilálás sikertelen
-
-
- Végrehajtható fájl
-
-
- A cél SDK 29-re változott
-
-
- Nem sikerült elemezni a verziót
-
-
- Javított AndroidManifest.xml
-
-
- Eltávolítottuk az összes ApkTool dummie-t
-
-
- APK kiválasztva:
-
-
- A kiválasztott mappa nem létezik.
-
-
- Az AndroidManifest.xml nem létezik
-
-
- A dekompilált APK könyvtár nem létezik
-
-
- A MainActivity itt, "{0}" található
-
-
- Nem találta a MainActivity-t. Kérjük keresse meg manuálisan
-
-
- Keretrendszer tisztítás
-
-
- Az összeállítás sikeresen befejeződött. Kimeneti könyvtár "{0}"
-
-
- A Zipalign nem sikerült
-
-
- A Zipalign sikeresen befejeződött. Fájl ide mentve "{0}"
-
-
- Keretrendszer törlési hiba
-
-
- A keretrendszer gyorsítótára törölve
-
-
- Minden kész!
-
-
- A keretrendszer sikeresen települt
-
-
- A keretrendszer könyvtár nem létezik
-
-
- Dex dekódolása
-
-
- A kiválasztott kimeneti mappa nem létezik.
-
-
- Dex összeállítása
-
-
- Rendszergazdaként fut. A Húzd & Dobd nem támogatott
-
-
- A Húzd & Dobd támogatott
-
-
- Ez a könyvtár nem egy Android csomag
-
-
- Baksmali
-
-
- Smali
-
-
- Zipalign
-
-
- APK összeállítása
-
-
- DEX összeszerelése
-
-
- APK dekompilálása
-
-
- DEX szétszerelése
-
-
- APK infó beszerzése
-
-
- Ez a mappa nem egy dekompilált APK
-
-
- Ez a mappa nem dekompilált DEX
-
-
- Szükséges fájlok hiányoznak
-
-
- APK aláírása
-
-
- Szöveg fájl
-
-
- APK Zipalign
-
-
- Aláírás nélküli APK létrehozása
-
-
- A META-INF mappa nem létezik. Kihagyva
-
-
- Hiba történt az APK-infó megszerzésében
-
-
- Bemeneti könyvtár: {0}
-
-
- Bemeneti fájl: {0}
-
-
- "{0}" fájl törlése
-
-
- "{0}" fájl másolása "{1}" ideiglenes könyvtárba.
-
-
- Dekompilált apk mappa "{0}" másolása "{1}" ideiglenes könyvtárba.
-
-
- A "{0}" célkönyvtár már létezik. Ha felül szeretné írni, engedélyezze a "Célkönyvtár kényszerített törlésének" beállítását.
-
-
- A "{0}" ideiglenes mappa áthelyezése a "{1}" kimeneti könyvtárba
-
-
- A(z) "{0}" ideiglenes apk áthelyezése a "{1}" kimeneti könyvtárba
-
-
- APK információk elemzése...
-
-
- Az összes APK fájl visszafejtése
-
-
- {0} bázisként észlelve
-
-
- {0} részeként észlelve
-
-
- Az összes APK fájl kicsomagolása
-
-
- Egyesítés kész. Könyvtár áthelyezése ide: "{0}"
-
-
- APK egyesítése
-
-
- Bázis könyvtár áthelyezése ide: "{0}"
-
-
- A(z) "{0}" könyvtár nem létezik
-
-
- Temp könyvtár: "{0}"
-
-
- Az ˘egyesítés nem sikerült
-
-
- APK egyesítése az APKEditor.jar használatával
-
-
- Megszakítva
-
-
- Biztosan megszakítja a folyamatot?
-
-
- Eszközök keresése...
-
-
- Kis türelmet...
-
-
- Biztosan leállítja az ADB szervert? Lehet, hogy újra kell csatlakoztatnia az eszközt, vagy újra kell indítania az emulátort
-
-
- Az eszköz nincs kiválasztva
-
-
- Kiválasztott eszköz: "{0}"
-
-
- {0} eszköz található
-
-
- Az APK telepítése nem sikerült
-
-
- Az APK telepítése sikeres volt
-
-
- APK telepítése
-
-
- "{0}" APK telepítése
-
-
- Nem találhatók eszközök. Győződjön meg róla, hogy eszközén be van kapcsolva az adb hibakeresés. Ha emulátort használ, indítsa újra és várja meg amíg elindul
-
-
- Befejezve: {0}
-
-
- Elkezdve: {0}
-
-
- A váratlan hibák elkerülése érdekében az Apktool verziójának módosítása után törölni kell a framework gyorsítótárát. Szeretné most törölni?
-
-
- A nyelv be van állítva. Újra akarja indítani az alkalmazást?
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Rólunk
+
+
+ Apktool verzió
+
+
+ Frissítés keresése
+
+
+ Hibakereső mód
+
+
+ Kilépés
+
+
+ Fájl
+
+
+ Súgó
+
+
+ Beállítások
+
+
+ Java nincs vagy rosszul van telepítve. Telepítse a Javát vagy adja meg az egyéni helyét a Beállításokban
+
+
+ Hiba a beállítások olvasásakor!
+
+
+ Új verzió érhető el. Szeretne frissíteni?
+
+
+ Nincs frissítés.
+
+
+ Dekódolási mappa nincs kiválasztva!
+
+
+ A dekódolandó fájl nincs kiválasztva!
+
+
+ Az aláírni szánt fájl nincs kiválasztva!
+
+
+ A framework nincs kiválasztva!
+
+
+ Hiba a beállítások mentése során!
+
+
+ A módosítások érvényesítéséhez újra kell indítania a programot. Most akarja megtenni?
+
+
+ A fájl nem található
+
+
+ A mappa nem létezik
+
+
+ Hiba
+
+
+ Build
+
+
+ Dekódolás
+
+
+ A keretrendszer telepítése
+
+
+ Aláírás
+
+
+ Rendszer nyelve
+
+
+ Tényleg telepíteni szeretné a kontextus menüt?
+
+
+ Tényleg el akarja távolítani a kontextus menüt?
+
+
+ Kész
+
+
+ Nem érzékeli az apktool verzióját.
+
+
+ A dekompilálás sikeresen befejeződött. Kimeneti könyvtár "{0}".
+
+
+ Frissítés ell. hiba:
+
+
+ Az aláírás sikeresen befejeződött. Fájl mentve: "{0}".
+
+
+ Igazítás
+
+
+ A kódolás sikertelen
+
+
+ Hiba a framework címke bevitelében.
+
+
+ A kiválasztott fájl nem létezik.
+
+
+ Hiba a keretrendszer könyvtár kiválasztásában.
+
+
+ Hiba a keretrendszer fájl kiválasztásában. A fájl nem létezik.
+
+
+ Az aláírás sikertelen.
+
+
+ Hiba. A keretrendszer telepítése nem indult el.
+
+
+ A keretrendszer telepítése
+
+
+ Aláírás
+
+
+ A bemeneti fájl nem található.
+
+
+ Privát kulcs nem található.
+
+
+ Nyilvános kulcs nem található.
+
+
+ ZIP archívumok
+
+
+ A kiválasztott dekompilációs könyvtárat nem lehetett létrehozni, mert érvénytelen karaktereket tartalmaz.
+
+
+ A dekompilációs könyvtár nincs kiválasztva.
+
+
+ A kiválasztott keretkönyvtár nem létezik.
+
+
+ Dekódolás
+
+
+ A dekompilálás sikertelen
+
+
+ Végrehajtható fájl
+
+
+ A cél SDK 29-re változott
+
+
+ Nem sikerült elemezni a verziót
+
+
+ Javított AndroidManifest.xml
+
+
+ Eltávolítottuk az összes ApkTool dummie-t
+
+
+ APK kiválasztva:
+
+
+ A kiválasztott mappa nem létezik.
+
+
+ Az AndroidManifest.xml nem létezik
+
+
+ A dekompilált APK könyvtár nem létezik
+
+
+ A MainActivity itt, "{0}" található
+
+
+ Nem találta a MainActivity-t. Kérjük keresse meg manuálisan
+
+
+ Keretrendszer tisztítás
+
+
+ Az összeállítás sikeresen befejeződött. Kimeneti könyvtár "{0}"
+
+
+ A Zipalign nem sikerült
+
+
+ A Zipalign sikeresen befejeződött. Fájl ide mentve "{0}"
+
+
+ Keretrendszer törlési hiba
+
+
+ A keretrendszer gyorsítótára törölve
+
+
+ Minden kész!
+
+
+ A keretrendszer sikeresen települt
+
+
+ A keretrendszer könyvtár nem létezik
+
+
+ Dex dekódolása
+
+
+ A kiválasztott kimeneti mappa nem létezik.
+
+
+ Dex összeállítása
+
+
+ Rendszergazdaként fut. A Húzd & Dobd nem támogatott
+
+
+ A Húzd & Dobd támogatott
+
+
+ Ez a könyvtár nem egy Android csomag
+
+
+ Baksmali
+
+
+ Smali
+
+
+ Zipalign
+
+
+ APK összeállítása
+
+
+ DEX összeszerelése
+
+
+ APK dekompilálása
+
+
+ DEX szétszerelése
+
+
+ APK infó beszerzése
+
+
+ Ez a mappa nem egy dekompilált APK
+
+
+ Ez a mappa nem dekompilált DEX
+
+
+ Szükséges fájlok hiányoznak
+
+
+ APK aláírása
+
+
+ Szöveg fájl
+
+
+ APK Zipalign
+
+
+ Aláírás nélküli APK létrehozása
+
+
+ A META-INF mappa nem létezik. Kihagyva
+
+
+ Hiba történt az APK-infó megszerzésében
+
+
+ Bemeneti könyvtár: {0}
+
+
+ Bemeneti fájl: {0}
+
+
+ "{0}" fájl törlése
+
+
+ "{0}" fájl másolása "{1}" ideiglenes könyvtárba.
+
+
+ Dekompilált apk mappa "{0}" másolása "{1}" ideiglenes könyvtárba.
+
+
+ A "{0}" célkönyvtár már létezik. Ha felül szeretné írni, engedélyezze a "Célkönyvtár kényszerített törlésének" beállítását.
+
+
+ A "{0}" ideiglenes mappa áthelyezése a "{1}" kimeneti könyvtárba
+
+
+ A(z) "{0}" ideiglenes apk áthelyezése a "{1}" kimeneti könyvtárba
+
+
+ APK információk elemzése...
+
+
+ Az összes APK fájl visszafejtése
+
+
+ {0} bázisként észlelve
+
+
+ {0} részeként észlelve
+
+
+ Az összes APK fájl kicsomagolása
+
+
+ Egyesítés kész. Könyvtár áthelyezése ide: "{0}"
+
+
+ APK egyesítése
+
+
+ Bázis könyvtár áthelyezése ide: "{0}"
+
+
+ A(z) "{0}" könyvtár nem létezik
+
+
+ Temp könyvtár: "{0}"
+
+
+ Az ˘egyesítés nem sikerült
+
+
+ APK egyesítése az APKEditor.jar használatával
+
+
+ Megszakítva
+
+
+ Biztosan megszakítja a folyamatot?
+
+
+ Eszközök keresése...
+
+
+ Kis türelmet...
+
+
+ Biztosan leállítja az ADB szervert? Lehet, hogy újra kell csatlakoztatnia az eszközt, vagy újra kell indítania az emulátort
+
+
+ Az eszköz nincs kiválasztva
+
+
+ Kiválasztott eszköz: "{0}"
+
+
+ {0} eszköz található
+
+
+ Obfuszkálás
+
+
+ Bemenet
+
+
+ Kimenet
+
+
+ Beállítások
+
+
+ Csomagfájl:
+
+
+ Tallózás...
+
+
+ Kimeneti könyvtár használata
+
+
+ Kimeneti könyvtár:
+
+
+ Csomag debuggálhatóvá tétele (--debug)
+
+
+ Alkalmazáskomponens-gyár letiltása (--disable-acf)
+
+
+ Kód kiírása (--dump-code)
+
+
+ Részletes napló engedélyezése (--noisy-log)
+
+
+ Kisebb méretre optimalizálás (--smaller)
+
+
+ Csomag aláírásának kihagyása (--no-sign)
+
+
+ Osztályok megtartása (--keep-classes)
+
+
+ Kizárt ABI-k listája (vesszővel elválasztva):
+
+
+ Szabályfájl:
+
+
+ Obfuszkálás
+
+
+ Obfuszkálás folyamatban
+
+
+ Az obfuszkálás sikeresen befejeződött.
+
+
+ Az obfuszkált csomag ide lett mentve: "{0}".
+
+
+ A bemeneti fájl nem található. Válasszon érvényes Android csomagot.
+
+
+ A szabályfájl nem található. Válasszon érvényes fájlt.
+
+
+ Hiba történt a csomag obfuszkálása közben.
+
+
+ Az APK telepítése nem sikerült
+
+
+ Az APK telepítése sikeres volt
+
+
+ APK telepítése
+
+
+ "{0}" APK telepítése
+
+
+ Nem találhatók eszközök. Győződjön meg róla, hogy eszközén be van kapcsolva az adb hibakeresés. Ha emulátort használ, indítsa újra és várja meg amíg elindul
+
+
+ Befejezve: {0}
+
+
+ Elkezdve: {0}
+
+
+ A váratlan hibák elkerülése érdekében az Apktool verziójának módosítása után törölni kell a framework gyorsítótárát. Szeretné most törölni?
+
+
+ A nyelv be van állítva. Újra akarja indítani az alkalmazást?
+
\ No newline at end of file
diff --git a/APKToolGUI/Languages/Language.ja.resx b/APKToolGUI/Languages/Language.ja.resx
index b84679d..e7167bf 100644
--- a/APKToolGUI/Languages/Language.ja.resx
+++ b/APKToolGUI/Languages/Language.ja.resx
@@ -489,6 +489,78 @@
{0} 件のデバイスを検出
+
+ 難読化
+
+
+ 入力
+
+
+ 出力
+
+
+ オプション
+
+
+ パッケージファイル:
+
+
+ 参照...
+
+
+ 出力フォルダーを使用
+
+
+ 出力フォルダー:
+
+
+ パッケージをデバッグ可能にする (--debug)
+
+
+ アプリコンポーネントファクトリを無効化 (--disable-acf)
+
+
+ コードをダンプ (--dump-code)
+
+
+ 詳細ログを有効化 (--noisy-log)
+
+
+ サイズ最適化 (--smaller)
+
+
+ パッケージに署名しない (--no-sign)
+
+
+ クラスを保持 (--keep-classes)
+
+
+ 除外する ABI の一覧 (カンマ区切り):
+
+
+ ルールファイル:
+
+
+ 難読化
+
+
+ 難読化中
+
+
+ 難読化が正常に完了しました。
+
+
+ 難読化済みパッケージを "{0}" に保存しました。
+
+
+ 入力ファイルが見つかりません。正しい Android パッケージを選択してください。
+
+
+ ルールファイルが見つかりません。正しいファイルを選択してください。
+
+
+ パッケージの難読化中にエラーが発生しました。
+
APK のインストールに失敗しました
diff --git a/APKToolGUI/Languages/Language.pt-BR.resx b/APKToolGUI/Languages/Language.pt-BR.resx
index 7906006..e31ff79 100644
--- a/APKToolGUI/Languages/Language.pt-BR.resx
+++ b/APKToolGUI/Languages/Language.pt-BR.resx
@@ -426,4 +426,76 @@
Arquivos ZIP
+
+ Ofuscar
+
+
+ Entrada
+
+
+ Saída
+
+
+ Opções
+
+
+ Arquivo do pacote:
+
+
+ Procurar...
+
+
+ Usar diretório de saída
+
+
+ Diretório de saída:
+
+
+ Tornar pacote depurável (--debug)
+
+
+ Desativar fábrica de componentes do app (--disable-acf)
+
+
+ Gerar dump do código (--dump-code)
+
+
+ Ativar log detalhado (--noisy-log)
+
+
+ Otimizar para tamanho menor (--smaller)
+
+
+ Não assinar o pacote (--no-sign)
+
+
+ Manter classes (--keep-classes)
+
+
+ Lista de ABIs a excluir (separada por vírgulas):
+
+
+ Arquivo de regras:
+
+
+ Ofuscar
+
+
+ Ofuscando
+
+
+ Ofuscação concluída com sucesso.
+
+
+ Pacote ofuscado salvo em "{0}".
+
+
+ Arquivo de entrada não encontrado. Selecione um pacote Android válido.
+
+
+ Arquivo de regras não encontrado. Selecione um arquivo válido.
+
+
+ Erro ao ofuscar o pacote.
+
diff --git a/APKToolGUI/Languages/Language.resx b/APKToolGUI/Languages/Language.resx
index 97f7be4..bdd5d5c 100644
--- a/APKToolGUI/Languages/Language.resx
+++ b/APKToolGUI/Languages/Language.resx
@@ -489,6 +489,78 @@
{0} devices found
+
+ Obfuscate
+
+
+ Input
+
+
+ Output
+
+
+ Options
+
+
+ Package file:
+
+
+ Browse...
+
+
+ Use output directory
+
+
+ Output directory:
+
+
+ Make package debuggable (--debug)
+
+
+ Disable app component factory (--disable-acf)
+
+
+ Dump code (--dump-code)
+
+
+ Enable noisy log (--noisy-log)
+
+
+ Optimize for smaller size (--smaller)
+
+
+ Do not sign package (--no-sign)
+
+
+ Keep classes (--keep-classes)
+
+
+ Exclude ABI list (comma separated):
+
+
+ Rules file:
+
+
+ Obfuscate
+
+
+ Obfuscating
+
+
+ Obfuscation completed successfully.
+
+
+ Obfuscated package saved to "{0}".
+
+
+ Input file not found. Please select a valid Android package.
+
+
+ Rules file not found. Please select a valid file.
+
+
+ Error obfuscating package.
+
APK Installation failed
diff --git a/APKToolGUI/Languages/Language.ru.resx b/APKToolGUI/Languages/Language.ru.resx
index dcc47b3..718266a 100644
--- a/APKToolGUI/Languages/Language.ru.resx
+++ b/APKToolGUI/Languages/Language.ru.resx
@@ -486,6 +486,78 @@
Найдено {0} устройств
+
+ Обфускация
+
+
+ Входные данные
+
+
+ Выходные данные
+
+
+ Параметры
+
+
+ Файл пакета:
+
+
+ Обзор...
+
+
+ Использовать выходной каталог
+
+
+ Выходной каталог:
+
+
+ Сделать пакет отлаживаемым (--debug)
+
+
+ Отключить фабрику компонентов приложения (--disable-acf)
+
+
+ Создать дамп кода (--dump-code)
+
+
+ Включить подробный журнал (--noisy-log)
+
+
+ Оптимизировать для меньшего размера (--smaller)
+
+
+ Не подписывать пакет (--no-sign)
+
+
+ Сохранить классы (--keep-classes)
+
+
+ Список исключаемых ABI (через запятую):
+
+
+ Файл правил:
+
+
+ Обфусцировать
+
+
+ Обфускация...
+
+
+ Обфускация успешно завершена.
+
+
+ Обфусцированный пакет сохранён по пути "{0}".
+
+
+ Входной файл не найден. Выберите корректный пакет Android.
+
+
+ Файл правил не найден. Выберите корректный файл.
+
+
+ Ошибка при обфускации пакета.
+
Ошибка при установке АРК
diff --git a/APKToolGUI/Languages/Language.tr.resx b/APKToolGUI/Languages/Language.tr.resx
index 081ee83..f31a992 100644
--- a/APKToolGUI/Languages/Language.tr.resx
+++ b/APKToolGUI/Languages/Language.tr.resx
@@ -489,6 +489,78 @@
{0} cihaz bulundu
+
+ Karmaşıklaştır
+
+
+ Girdi
+
+
+ Çıktı
+
+
+ Seçenekler
+
+
+ Paket dosyası:
+
+
+ Gözat...
+
+
+ Çıktı klasörünü kullan
+
+
+ Çıktı klasörü:
+
+
+ Paketi hata ayıklanabilir yap (--debug)
+
+
+ Uygulama bileşen fabrikasını devre dışı bırak (--disable-acf)
+
+
+ Kodu dök (--dump-code)
+
+
+ Ayrıntılı günlüğü etkinleştir (--noisy-log)
+
+
+ Daha küçük boyut için optimize et (--smaller)
+
+
+ Paketi imzalama (--no-sign)
+
+
+ Sınıfları koru (--keep-classes)
+
+
+ Hariç tutulacak ABI listesi (virgülle ayrılmış):
+
+
+ Kural dosyası:
+
+
+ Karmaşıklaştır
+
+
+ Karmaşıklaştırılıyor
+
+
+ Karmaşıklaştırma başarıyla tamamlandı.
+
+
+ Karmaşıklaştırılmış paket "{0}" konumuna kaydedildi.
+
+
+ Girdi dosyası bulunamadı. Lütfen geçerli bir Android paketi seçin.
+
+
+ Kural dosyası bulunamadı. Lütfen geçerli bir dosya seçin.
+
+
+ Paket karmaşıklaştırılırken hata oluştu.
+
APK Kurulumu başarısız
diff --git a/APKToolGUI/Languages/Language.vi-VN.resx b/APKToolGUI/Languages/Language.vi-VN.resx
index f68034c..79bdebb 100644
--- a/APKToolGUI/Languages/Language.vi-VN.resx
+++ b/APKToolGUI/Languages/Language.vi-VN.resx
@@ -489,6 +489,78 @@
Đã tìm thấy {0} thiết bị
+
+ Làm rối mã
+
+
+ Đầu vào
+
+
+ Đầu ra
+
+
+ Tùy chọn
+
+
+ Tệp gói:
+
+
+ Duyệt...
+
+
+ Sử dụng thư mục đầu ra
+
+
+ Thư mục đầu ra:
+
+
+ Cho phép gói gỡ lỗi (--debug)
+
+
+ Tắt bộ tạo thành phần ứng dụng (--disable-acf)
+
+
+ Xuất mã (--dump-code)
+
+
+ Bật nhật ký chi tiết (--noisy-log)
+
+
+ Tối ưu kích thước nhỏ hơn (--smaller)
+
+
+ Không ký gói (--no-sign)
+
+
+ Giữ lại lớp (--keep-classes)
+
+
+ Danh sách ABI loại trừ (phân tách bằng dấu phẩy):
+
+
+ Tệp luật:
+
+
+ Làm rối mã
+
+
+ Đang làm rối mã
+
+
+ Làm rối mã thành công.
+
+
+ Gói đã làm rối mã được lưu tại "{0}".
+
+
+ Không tìm thấy tệp đầu vào. Vui lòng chọn gói Android hợp lệ.
+
+
+ Không tìm thấy tệp luật. Vui lòng chọn tệp hợp lệ.
+
+
+ Xảy ra lỗi khi làm rối gói.
+
Cài đặt APK thất bại
diff --git a/APKToolGUI/Languages/Language.zh-CN.resx b/APKToolGUI/Languages/Language.zh-CN.resx
index 888098e..f121147 100644
--- a/APKToolGUI/Languages/Language.zh-CN.resx
+++ b/APKToolGUI/Languages/Language.zh-CN.resx
@@ -489,6 +489,78 @@
发现 {0} 设备
+
+ 混淆
+
+
+ 输入
+
+
+ 输出
+
+
+ 选项
+
+
+ 包文件:
+
+
+ 浏览...
+
+
+ 使用输出目录
+
+
+ 输出目录:
+
+
+ 使包可调试 (--debug)
+
+
+ 禁用应用组件工厂 (--disable-acf)
+
+
+ 导出代码 (--dump-code)
+
+
+ 启用详细日志 (--noisy-log)
+
+
+ 优化为更小体积 (--smaller)
+
+
+ 不签名包 (--no-sign)
+
+
+ 保留类 (--keep-classes)
+
+
+ 排除的 ABI 列表(用逗号分隔):
+
+
+ 规则文件:
+
+
+ 混淆
+
+
+ 正在混淆
+
+
+ 混淆已成功完成。
+
+
+ 已将混淆后的包保存到“{0}”。
+
+
+ 未找到输入文件。请选择有效的 Android 包。
+
+
+ 未找到规则文件。请选择有效的文件。
+
+
+ 混淆包时出错。
+
APK 安装失败
diff --git a/APKToolGUI/Program.cs b/APKToolGUI/Program.cs
index 435a051..92445d5 100644
--- a/APKToolGUI/Program.cs
+++ b/APKToolGUI/Program.cs
@@ -198,6 +198,7 @@ private static List MissingFilesCheck()
ADBWINAPI_PATH,
ADBWINUSBAPI_PATH,
LIBWINP_PATH,
+ DPT_PATH,
};
for (int i = 0; i < fileList.Length; i++)
if (!File.Exists(fileList[i]))
@@ -268,6 +269,7 @@ public static string RandTempDirectory()
public static string AAPT_PATH { get { return Path.Combine(RES_PATH, "aapt.exe"); } }
public static string AAPT2_PATH { get { return Path.Combine(RES_PATH, "aapt2.exe"); } }
public static string APKEDITOR_PATH { get { return Path.Combine(RES_PATH, "apkeditor.jar"); } }
+ public static string DPT_PATH { get { return Path.Combine(RES_PATH, "dpt.jar"); } }
public static string ADB_PATH { get { return Path.Combine(RES_PATH, "adb.exe"); } }
public static string ADBWINAPI_PATH { get { return Path.Combine(RES_PATH, "AdbWinApi.dll"); } }
public static string ADBWINUSBAPI_PATH { get { return Path.Combine(RES_PATH, "AdbWinUsbApi.dll"); } }
diff --git a/APKToolGUI/Properties/Settings.Designer.cs b/APKToolGUI/Properties/Settings.Designer.cs
index 043d673..a104380 100644
--- a/APKToolGUI/Properties/Settings.Designer.cs
+++ b/APKToolGUI/Properties/Settings.Designer.cs
@@ -157,7 +157,171 @@ public string Sign_OutputDir {
this["Sign_OutputDir"] = value;
}
}
-
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public string Obfuscate_InputFile {
+ get {
+ return ((string)(this["Obfuscate_InputFile"]));
+ }
+ set {
+ this["Obfuscate_InputFile"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public bool Obfuscate_UseOutputDir {
+ get {
+ return ((bool)(this["Obfuscate_UseOutputDir"]));
+ }
+ set {
+ this["Obfuscate_UseOutputDir"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public string Obfuscate_OutputDir {
+ get {
+ return ((string)(this["Obfuscate_OutputDir"]));
+ }
+ set {
+ this["Obfuscate_OutputDir"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public bool Obfuscate_Debug {
+ get {
+ return ((bool)(this["Obfuscate_Debug"]));
+ }
+ set {
+ this["Obfuscate_Debug"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public bool Obfuscate_DisableAcf {
+ get {
+ return ((bool)(this["Obfuscate_DisableAcf"]));
+ }
+ set {
+ this["Obfuscate_DisableAcf"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public bool Obfuscate_DumpCode {
+ get {
+ return ((bool)(this["Obfuscate_DumpCode"]));
+ }
+ set {
+ this["Obfuscate_DumpCode"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public bool Obfuscate_NoisyLog {
+ get {
+ return ((bool)(this["Obfuscate_NoisyLog"]));
+ }
+ set {
+ this["Obfuscate_NoisyLog"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public bool Obfuscate_Smaller {
+ get {
+ return ((bool)(this["Obfuscate_Smaller"]));
+ }
+ set {
+ this["Obfuscate_Smaller"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public bool Obfuscate_NoSign {
+ get {
+ return ((bool)(this["Obfuscate_NoSign"]));
+ }
+ set {
+ this["Obfuscate_NoSign"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public bool Obfuscate_KeepClasses {
+ get {
+ return ((bool)(this["Obfuscate_KeepClasses"]));
+ }
+ set {
+ this["Obfuscate_KeepClasses"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public string Obfuscate_ExcludeAbi {
+ get {
+ return ((string)(this["Obfuscate_ExcludeAbi"]));
+ }
+ set {
+ this["Obfuscate_ExcludeAbi"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
+ public string Obfuscate_RulesFile {
+ get {
+ return ((string)(this["Obfuscate_RulesFile"]));
+ }
+ set {
+ this["Obfuscate_RulesFile"] = value;
+ }
+ }
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
diff --git a/APKToolGUI/Properties/Settings.settings b/APKToolGUI/Properties/Settings.settings
index 17fc993..456743e 100644
--- a/APKToolGUI/Properties/Settings.settings
+++ b/APKToolGUI/Properties/Settings.settings
@@ -32,6 +32,42 @@
+
+
+
+
+ False
+
+
+
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+
False
diff --git a/APKToolGUI/app.config b/APKToolGUI/app.config
index d5b2269..b5cdc53 100644
--- a/APKToolGUI/app.config
+++ b/APKToolGUI/app.config
@@ -37,6 +37,42 @@
+
+
+
+
+ False
+
+
+
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+
False
From eefaa0752edbdd38cde57d0d26443e13b250b878 Mon Sep 17 00:00:00 2001
From: Renji Yuusei <166010224+RenjiYuusei@users.noreply.github.com>
Date: Thu, 30 Oct 2025 23:31:48 +0700
Subject: [PATCH 09/16] Relocate obfuscate action button
---
APKToolGUI/Forms/FormMain.cs | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/APKToolGUI/Forms/FormMain.cs b/APKToolGUI/Forms/FormMain.cs
index 5cd5682..eda5be7 100644
--- a/APKToolGUI/Forms/FormMain.cs
+++ b/APKToolGUI/Forms/FormMain.cs
@@ -554,11 +554,22 @@ private void InitializeObfuscateTab()
groupBox_OBF_Output.Controls.Add(textBox_OBF_OutputDir);
groupBox_OBF_Output.Controls.Add(button_OBF_BrowseOutputDir);
+ button_OBF_Obfuscate = new Button
+ {
+ Name = "button_OBF_Obfuscate",
+ Location = new Point(6, groupBox_OBF_Output.Bottom + 12),
+ Size = new Size(groupWidth, 32),
+ Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right,
+ Text = Language.ObfuscateButton,
+ UseVisualStyleBackColor = true
+ };
+ button_OBF_Obfuscate.AllowDrop = true;
+
groupBox_OBF_Options = new GroupBox
{
Name = "groupBox_OBF_Options",
Text = Language.ObfuscateOptionsGroup,
- Location = new Point(6, groupBox_OBF_Output.Bottom + 10),
+ Location = new Point(6, button_OBF_Obfuscate.Bottom + 12),
Size = new Size(groupWidth, 230),
Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
};
@@ -694,21 +705,10 @@ private void InitializeObfuscateTab()
groupBox_OBF_Options.Controls.Add(textBox_OBF_RulesFile);
groupBox_OBF_Options.Controls.Add(button_OBF_BrowseRulesFile);
- button_OBF_Obfuscate = new Button
- {
- Name = "button_OBF_Obfuscate",
- Location = new Point(rightButtonX, groupBox_OBF_Options.Bottom + 12),
- Size = new Size(buttonWidth, 32),
- Anchor = AnchorStyles.Top | AnchorStyles.Right,
- Text = Language.ObfuscateButton,
- UseVisualStyleBackColor = true
- };
- button_OBF_Obfuscate.AllowDrop = true;
-
tabPageObfuscate.Controls.Add(groupBox_OBF_Input);
tabPageObfuscate.Controls.Add(groupBox_OBF_Output);
- tabPageObfuscate.Controls.Add(groupBox_OBF_Options);
tabPageObfuscate.Controls.Add(button_OBF_Obfuscate);
+ tabPageObfuscate.Controls.Add(groupBox_OBF_Options);
int insertIndex = tabControlMain.TabPages.IndexOf(tabPageSign);
if (insertIndex < 0)
From ecef0f22de403dcd9c7429b7b64f1785ff6fdbd6 Mon Sep 17 00:00:00 2001
From: Renji Yuusei <166010224+RenjiYuusei@users.noreply.github.com>
Date: Fri, 31 Oct 2025 00:17:58 +0700
Subject: [PATCH 10/16] Improve obfuscate workflow and fetch dpt shell
---
APKToolGUI/APKToolGUI.csproj | 1 +
APKToolGUI/Forms/FormMain.cs | 62 +++++++++-
.../Handlers/DecodeControlEventHandlers.cs | 1 +
APKToolGUI/Handlers/DragDropHandlers.cs | 2 +
APKToolGUI/Program.cs | 3 +
APKToolGUI/Utils/DptShellResourceManager.cs | 106 ++++++++++++++++++
6 files changed, 172 insertions(+), 3 deletions(-)
create mode 100644 APKToolGUI/Utils/DptShellResourceManager.cs
diff --git a/APKToolGUI/APKToolGUI.csproj b/APKToolGUI/APKToolGUI.csproj
index 9c5ff06..c1ce19d 100644
--- a/APKToolGUI/APKToolGUI.csproj
+++ b/APKToolGUI/APKToolGUI.csproj
@@ -334,6 +334,7 @@
+
diff --git a/APKToolGUI/Forms/FormMain.cs b/APKToolGUI/Forms/FormMain.cs
index eda5be7..c45ad01 100644
--- a/APKToolGUI/Forms/FormMain.cs
+++ b/APKToolGUI/Forms/FormMain.cs
@@ -202,6 +202,8 @@ internal async Task GetApkInfo(string file)
{
if (File.Exists(file))
{
+ SetObfuscateInputFromSelection(file);
+
ToLog(ApktoolEventType.None, Language.ParsingApkInfo);
ToStatus(Language.ParsingApkInfo, Resources.waiting);
@@ -446,6 +448,8 @@ private void InitializeObfuscateTab()
int groupWidth = Math.Max(tabControlMain.DisplayRectangle.Width - 12, 560);
int buttonWidth = 100;
int rightButtonX = groupWidth - buttonWidth - 10;
+ int obfuscateButtonWidth = Math.Min(Math.Max(buttonWidth, 160), groupWidth);
+ int obfuscateButtonX = Math.Max(6, 6 + groupWidth - obfuscateButtonWidth);
int textStartX = 150;
int textWidth = Math.Max(rightButtonX - textStartX - 6, 220);
@@ -557,9 +561,9 @@ private void InitializeObfuscateTab()
button_OBF_Obfuscate = new Button
{
Name = "button_OBF_Obfuscate",
- Location = new Point(6, groupBox_OBF_Output.Bottom + 12),
- Size = new Size(groupWidth, 32),
- Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right,
+ Location = new Point(obfuscateButtonX, groupBox_OBF_Output.Bottom + 12),
+ Size = new Size(obfuscateButtonWidth, 32),
+ Anchor = AnchorStyles.Top | AnchorStyles.Right,
Text = Language.ObfuscateButton,
UseVisualStyleBackColor = true
};
@@ -716,6 +720,37 @@ private void InitializeObfuscateTab()
tabControlMain.TabPages.Insert(insertIndex, tabPageObfuscate);
}
+ internal void SetObfuscateInputFromSelection(string packagePath, bool updateOutputDirectory = true)
+ {
+ if (String.IsNullOrWhiteSpace(packagePath))
+ return;
+
+ if (!packagePath.EndsWith(".apk", StringComparison.OrdinalIgnoreCase))
+ return;
+
+ if (InvokeRequired)
+ {
+ BeginInvoke(new Action(() => SetObfuscateInputFromSelection(packagePath, updateOutputDirectory)));
+ return;
+ }
+
+ if (!String.Equals(textBox_OBF_InputFile.Text, packagePath, StringComparison.OrdinalIgnoreCase))
+ textBox_OBF_InputFile.Text = packagePath;
+
+ if (updateOutputDirectory)
+ {
+ string selectedDirectory = Path.GetDirectoryName(packagePath);
+ if (!String.IsNullOrWhiteSpace(selectedDirectory))
+ {
+ bool outputMissing = String.IsNullOrWhiteSpace(textBox_OBF_OutputDir.Text) ||
+ !Directory.Exists(textBox_OBF_OutputDir.Text);
+
+ if (outputMissing)
+ textBox_OBF_OutputDir.Text = selectedDirectory;
+ }
+ }
+ }
+
internal void Done(string msg = null)
{
isRunning = false;
@@ -1477,9 +1512,30 @@ await Task.Factory.StartNew(() =>
#region DPT Shell
private void InitializeDptShell()
{
+ bool resourcesReady = DptShellResourceManager.EnsureResources(
+ message => ToLog(ApktoolEventType.Infomation, message),
+ message => ToLog(ApktoolEventType.Error, message));
+
+ if (!resourcesReady)
+ {
+ ToLog(ApktoolEventType.Error, "Unable to prepare dpt-shell resources. Please download the latest release and place it inside the Resources folder.");
+ BeginInvoke(new Action(() =>
+ {
+ tabPageObfuscate.Enabled = false;
+ ShowMessage("Unable to prepare dpt-shell resources. Please ensure you have an internet connection or place the dpt-shell release into the Resources folder.", MessageBoxIcon.Error);
+ }));
+ return;
+ }
+
dptShell = new DptShell(javaPath, Program.DPT_PATH);
dptShell.DptShellOutputDataReceived += DptShell_OutputDataReceived;
dptShell.DptShellErrorDataReceived += DptShell_ErrorDataReceived;
+
+ BeginInvoke(new Action(() =>
+ {
+ if (!tabPageObfuscate.Enabled)
+ tabPageObfuscate.Enabled = true;
+ }));
}
private void DptShell_ErrorDataReceived(object sender, DptShellDataReceivedEventArgs e)
diff --git a/APKToolGUI/Handlers/DecodeControlEventHandlers.cs b/APKToolGUI/Handlers/DecodeControlEventHandlers.cs
index 7476c6d..552de1a 100644
--- a/APKToolGUI/Handlers/DecodeControlEventHandlers.cs
+++ b/APKToolGUI/Handlers/DecodeControlEventHandlers.cs
@@ -59,6 +59,7 @@ internal void button_DECODE_BrowseInputAppPath_Click(object sender, EventArgs e)
if (ofd.ShowDialog() == DialogResult.OK)
{
main.textBox_DECODE_InputAppPath.Text = ofd.FileName;
+ main.SetObfuscateInputFromSelection(ofd.FileName);
if (!Settings.Default.Decode_DontParseApkInfo)
main.GetApkInfo(ofd.FileName);
diff --git a/APKToolGUI/Handlers/DragDropHandlers.cs b/APKToolGUI/Handlers/DragDropHandlers.cs
index 30fdce5..ae59ce4 100644
--- a/APKToolGUI/Handlers/DragDropHandlers.cs
+++ b/APKToolGUI/Handlers/DragDropHandlers.cs
@@ -94,6 +94,7 @@ private async void DropApkToDec(DragEventArgs e)
foreach (var apkFile in apkFiles)
{
main.textBox_DECODE_InputAppPath.Text = apkFile;
+ main.SetObfuscateInputFromSelection(apkFile);
if (!Settings.Default.Decode_DontParseApkInfo)
await main.GetApkInfo(apkFile);
@@ -231,6 +232,7 @@ private void DropApkToGetInfo(DragEventArgs e)
main.smaliBrowseInputDirTxtBox.Text = apkFile;
main.basicInfoTabPage.BackColor = PanelBackColor();
main.GetApkInfo(apkFile);
+ main.SetObfuscateInputFromSelection(apkFile);
}
}
diff --git a/APKToolGUI/Program.cs b/APKToolGUI/Program.cs
index 92445d5..c96a2db 100644
--- a/APKToolGUI/Program.cs
+++ b/APKToolGUI/Program.cs
@@ -76,6 +76,8 @@ static void Main(String[] arg)
}
else
{
+ DptShellResourceManager.EnsureResources();
+
if (arg.Length == 2)
{
switch (arg[0])
@@ -270,6 +272,7 @@ public static string RandTempDirectory()
public static string AAPT2_PATH { get { return Path.Combine(RES_PATH, "aapt2.exe"); } }
public static string APKEDITOR_PATH { get { return Path.Combine(RES_PATH, "apkeditor.jar"); } }
public static string DPT_PATH { get { return Path.Combine(RES_PATH, "dpt.jar"); } }
+ public static string DptShellFilesPath { get { return Path.Combine(RES_PATH, "shell-files"); } }
public static string ADB_PATH { get { return Path.Combine(RES_PATH, "adb.exe"); } }
public static string ADBWINAPI_PATH { get { return Path.Combine(RES_PATH, "AdbWinApi.dll"); } }
public static string ADBWINUSBAPI_PATH { get { return Path.Combine(RES_PATH, "AdbWinUsbApi.dll"); } }
diff --git a/APKToolGUI/Utils/DptShellResourceManager.cs b/APKToolGUI/Utils/DptShellResourceManager.cs
new file mode 100644
index 0000000..23f96be
--- /dev/null
+++ b/APKToolGUI/Utils/DptShellResourceManager.cs
@@ -0,0 +1,106 @@
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using System.Net;
+
+namespace APKToolGUI.Utils
+{
+ internal static class DptShellResourceManager
+ {
+ private const string DownloadUrl = "https://github.com/luoyesiqiu/dpt-shell/releases/download/v2.5.0/dpt-shell-v2.5.0.zip";
+ private const string ZipFileName = "dpt-shell-v2.5.0.zip";
+ private const string ZipRootPrefix = "executable/";
+ private static readonly object SyncLock = new object();
+
+ internal static bool EnsureResources(Action statusLog = null, Action errorLog = null)
+ {
+ lock (SyncLock)
+ {
+ try
+ {
+ if (ResourcesAvailable())
+ return true;
+
+ statusLog?.Invoke("Downloading dpt-shell components...");
+
+ string resourcesDirectory = Path.GetDirectoryName(Program.DPT_PATH);
+ if (String.IsNullOrEmpty(resourcesDirectory))
+ return false;
+
+ Directory.CreateDirectory(resourcesDirectory);
+
+ string tempRoot = Path.Combine(Path.GetTempPath(), "APKToolGUI", "dpt-shell");
+ Directory.CreateDirectory(tempRoot);
+ string zipPath = Path.Combine(tempRoot, ZipFileName);
+
+ try
+ {
+ using (var client = new WebClient())
+ {
+ client.DownloadFile(DownloadUrl, zipPath);
+ }
+
+ ExtractResources(zipPath, resourcesDirectory);
+ }
+ finally
+ {
+ if (File.Exists(zipPath))
+ File.Delete(zipPath);
+ }
+
+ statusLog?.Invoke("dpt-shell components are ready.");
+ return ResourcesAvailable();
+ }
+ catch (Exception ex)
+ {
+ errorLog?.Invoke($"Failed to prepare dpt-shell: {ex.Message}");
+ return false;
+ }
+ }
+ }
+
+ private static bool ResourcesAvailable()
+ {
+ if (!File.Exists(Program.DPT_PATH))
+ return false;
+
+ string shellFilesPath = Program.DptShellFilesPath;
+ if (!Directory.Exists(shellFilesPath))
+ return false;
+
+ return Directory.EnumerateFileSystemEntries(shellFilesPath).Any();
+ }
+
+ private static void ExtractResources(string zipPath, string destinationRoot)
+ {
+ string shellFilesPath = Program.DptShellFilesPath;
+ if (Directory.Exists(shellFilesPath))
+ Directory.Delete(shellFilesPath, true);
+
+ using (ZipArchive archive = ZipFile.OpenRead(zipPath))
+ {
+ foreach (ZipArchiveEntry entry in archive.Entries)
+ {
+ if (!entry.FullName.StartsWith(ZipRootPrefix, StringComparison.OrdinalIgnoreCase))
+ continue;
+
+ string relativePath = entry.FullName.Substring(ZipRootPrefix.Length);
+ string destinationPath = Path.Combine(destinationRoot, relativePath.Replace('/', Path.DirectorySeparatorChar));
+
+ if (entry.FullName.EndsWith("/"))
+ {
+ Directory.CreateDirectory(destinationPath);
+ continue;
+ }
+
+ string directoryName = Path.GetDirectoryName(destinationPath);
+ if (!String.IsNullOrEmpty(directoryName))
+ Directory.CreateDirectory(directoryName);
+
+ entry.ExtractToFile(destinationPath, true);
+ }
+ }
+ }
+ }
+}
From e916c53bb3cb5474558b640d0d3eb0e8cd2bb918 Mon Sep 17 00:00:00 2001
From: Renji Yuusei <166010224+RenjiYuusei@users.noreply.github.com>
Date: Fri, 31 Oct 2025 00:18:15 +0700
Subject: [PATCH 11/16] Remove automatic dpt-shell resource download
---
APKToolGUI/APKToolGUI.csproj | 1 -
APKToolGUI/Forms/FormMain.cs | 16 +--
APKToolGUI/Program.cs | 3 -
APKToolGUI/Utils/DptShellResourceManager.cs | 106 --------------------
4 files changed, 9 insertions(+), 117 deletions(-)
delete mode 100644 APKToolGUI/Utils/DptShellResourceManager.cs
diff --git a/APKToolGUI/APKToolGUI.csproj b/APKToolGUI/APKToolGUI.csproj
index c1ce19d..9c5ff06 100644
--- a/APKToolGUI/APKToolGUI.csproj
+++ b/APKToolGUI/APKToolGUI.csproj
@@ -334,7 +334,6 @@
-
diff --git a/APKToolGUI/Forms/FormMain.cs b/APKToolGUI/Forms/FormMain.cs
index c45ad01..d036638 100644
--- a/APKToolGUI/Forms/FormMain.cs
+++ b/APKToolGUI/Forms/FormMain.cs
@@ -1512,22 +1512,24 @@ await Task.Factory.StartNew(() =>
#region DPT Shell
private void InitializeDptShell()
{
- bool resourcesReady = DptShellResourceManager.EnsureResources(
- message => ToLog(ApktoolEventType.Infomation, message),
- message => ToLog(ApktoolEventType.Error, message));
+ string jarPath = Program.DPT_PATH;
+ string shellFilesPath = Program.DptShellFilesPath;
+ bool hasShellFiles = Directory.Exists(shellFilesPath) && Directory.EnumerateFileSystemEntries(shellFilesPath).Any();
- if (!resourcesReady)
+ if (!File.Exists(jarPath) || !hasShellFiles)
{
- ToLog(ApktoolEventType.Error, "Unable to prepare dpt-shell resources. Please download the latest release and place it inside the Resources folder.");
+ const string message = "dpt-shell resources not found. Please place dpt.jar and the shell-files directory into the Resources folder.";
+
+ ToLog(ApktoolEventType.Error, message);
BeginInvoke(new Action(() =>
{
tabPageObfuscate.Enabled = false;
- ShowMessage("Unable to prepare dpt-shell resources. Please ensure you have an internet connection or place the dpt-shell release into the Resources folder.", MessageBoxIcon.Error);
+ ShowMessage(message, MessageBoxIcon.Error);
}));
return;
}
- dptShell = new DptShell(javaPath, Program.DPT_PATH);
+ dptShell = new DptShell(javaPath, jarPath);
dptShell.DptShellOutputDataReceived += DptShell_OutputDataReceived;
dptShell.DptShellErrorDataReceived += DptShell_ErrorDataReceived;
diff --git a/APKToolGUI/Program.cs b/APKToolGUI/Program.cs
index c96a2db..45e8980 100644
--- a/APKToolGUI/Program.cs
+++ b/APKToolGUI/Program.cs
@@ -1,6 +1,5 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
-using APKToolGUI.Utils;
using Bluegrams.Application;
using Dark.Net;
using OSVersionExtension;
@@ -76,8 +75,6 @@ static void Main(String[] arg)
}
else
{
- DptShellResourceManager.EnsureResources();
-
if (arg.Length == 2)
{
switch (arg[0])
diff --git a/APKToolGUI/Utils/DptShellResourceManager.cs b/APKToolGUI/Utils/DptShellResourceManager.cs
deleted file mode 100644
index 23f96be..0000000
--- a/APKToolGUI/Utils/DptShellResourceManager.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using System;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Net;
-
-namespace APKToolGUI.Utils
-{
- internal static class DptShellResourceManager
- {
- private const string DownloadUrl = "https://github.com/luoyesiqiu/dpt-shell/releases/download/v2.5.0/dpt-shell-v2.5.0.zip";
- private const string ZipFileName = "dpt-shell-v2.5.0.zip";
- private const string ZipRootPrefix = "executable/";
- private static readonly object SyncLock = new object();
-
- internal static bool EnsureResources(Action statusLog = null, Action errorLog = null)
- {
- lock (SyncLock)
- {
- try
- {
- if (ResourcesAvailable())
- return true;
-
- statusLog?.Invoke("Downloading dpt-shell components...");
-
- string resourcesDirectory = Path.GetDirectoryName(Program.DPT_PATH);
- if (String.IsNullOrEmpty(resourcesDirectory))
- return false;
-
- Directory.CreateDirectory(resourcesDirectory);
-
- string tempRoot = Path.Combine(Path.GetTempPath(), "APKToolGUI", "dpt-shell");
- Directory.CreateDirectory(tempRoot);
- string zipPath = Path.Combine(tempRoot, ZipFileName);
-
- try
- {
- using (var client = new WebClient())
- {
- client.DownloadFile(DownloadUrl, zipPath);
- }
-
- ExtractResources(zipPath, resourcesDirectory);
- }
- finally
- {
- if (File.Exists(zipPath))
- File.Delete(zipPath);
- }
-
- statusLog?.Invoke("dpt-shell components are ready.");
- return ResourcesAvailable();
- }
- catch (Exception ex)
- {
- errorLog?.Invoke($"Failed to prepare dpt-shell: {ex.Message}");
- return false;
- }
- }
- }
-
- private static bool ResourcesAvailable()
- {
- if (!File.Exists(Program.DPT_PATH))
- return false;
-
- string shellFilesPath = Program.DptShellFilesPath;
- if (!Directory.Exists(shellFilesPath))
- return false;
-
- return Directory.EnumerateFileSystemEntries(shellFilesPath).Any();
- }
-
- private static void ExtractResources(string zipPath, string destinationRoot)
- {
- string shellFilesPath = Program.DptShellFilesPath;
- if (Directory.Exists(shellFilesPath))
- Directory.Delete(shellFilesPath, true);
-
- using (ZipArchive archive = ZipFile.OpenRead(zipPath))
- {
- foreach (ZipArchiveEntry entry in archive.Entries)
- {
- if (!entry.FullName.StartsWith(ZipRootPrefix, StringComparison.OrdinalIgnoreCase))
- continue;
-
- string relativePath = entry.FullName.Substring(ZipRootPrefix.Length);
- string destinationPath = Path.Combine(destinationRoot, relativePath.Replace('/', Path.DirectorySeparatorChar));
-
- if (entry.FullName.EndsWith("/"))
- {
- Directory.CreateDirectory(destinationPath);
- continue;
- }
-
- string directoryName = Path.GetDirectoryName(destinationPath);
- if (!String.IsNullOrEmpty(directoryName))
- Directory.CreateDirectory(directoryName);
-
- entry.ExtractToFile(destinationPath, true);
- }
- }
- }
- }
-}
From 7822f2fb6b9d03ab2e7b2c2f7ae8299afea40bcf Mon Sep 17 00:00:00 2001
From: Renji Yuusei <166010224+RenjiYuusei@users.noreply.github.com>
Date: Fri, 31 Oct 2025 00:24:09 +0700
Subject: [PATCH 12/16] Fix missing StringExt import in Program
---
APKToolGUI/Program.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/APKToolGUI/Program.cs b/APKToolGUI/Program.cs
index 45e8980..602d04e 100644
--- a/APKToolGUI/Program.cs
+++ b/APKToolGUI/Program.cs
@@ -1,5 +1,6 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
+using APKToolGUI.Utils;
using Bluegrams.Application;
using Dark.Net;
using OSVersionExtension;
From cd03181bcf1ad6870a1bcbdac8203c60e7419920 Mon Sep 17 00:00:00 2001
From: RenjiYuusei
Date: Fri, 31 Oct 2025 00:30:12 +0700
Subject: [PATCH 13/16] dpt shell library
---
Tools/dpt.jar | Bin 0 -> 10123284 bytes
Tools/shell-files/dex/classes.dex | Bin 0 -> 9460 bytes
.../libs/arm/libd1b98aadffdc1f09.so | Bin 0 -> 234916 bytes
.../libs/arm64/libd1b98aadffdc1f09.so | Bin 0 -> 378112 bytes
.../libs/x86_64/libd1b98aadffdc1f09.so | Bin 0 -> 400176 bytes
Tools/shell-files/readonly-config.json | 4 ++++
6 files changed, 4 insertions(+)
create mode 100644 Tools/dpt.jar
create mode 100644 Tools/shell-files/dex/classes.dex
create mode 100644 Tools/shell-files/libs/arm/libd1b98aadffdc1f09.so
create mode 100644 Tools/shell-files/libs/arm64/libd1b98aadffdc1f09.so
create mode 100644 Tools/shell-files/libs/x86_64/libd1b98aadffdc1f09.so
create mode 100644 Tools/shell-files/readonly-config.json
diff --git a/Tools/dpt.jar b/Tools/dpt.jar
new file mode 100644
index 0000000000000000000000000000000000000000..97c8b2967b120a623081d533908cfbd9df345568
GIT binary patch
literal 10123284
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