APK反编译工具(APKINFO)及制作详解(附图)

介绍了一款名为APKINFO的工具,用于查看、反编译、重签名APK文件,以及将Jar包代码打入Apk。该工具封装了aapt、jarsigner、zipalign等命令行工具,提供了查看APK信息、源代码、签名信息,反编译、重签名APK,以及将Jar包代码打入Apk等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处:https://blog.csdn.net/xiangxinzijiwonen/article/details/83547250(来自ZhongGuanYao的csdn博客)

目录

前言

一、查看APK信息

二、查看APK源代码

三、查看签名信息

四、反编译APK

五、重签名

六、打入Jar包代码


 

前言

从事游戏SDK接入和打包相关工作时,经常对要APK文件进行信息检查、打包测试、问题排查等等,难免要敲一些反编译、重签名等繁琐的命令行,为方便和提高工作效率,制作一款适合自己工作需要的APKINFO小工具是有必要的。

APKINFO工具下载:https://download.csdn.net/download/xiangxinzijiwonen/10766262

github源码:https://github.com/zhongguanyao/APKINFO

注意:无法在CSDN资源下载时,可到github下载源码工程,直接使用bin/Debug目录即可

先展示张图片看下效果:

使用语言:C#

涉及到的工具:aapt.exe、jarsigner.exe、zipalign.exe、apktool、java.exe、keytool.exe,第三方jadx等

APKINFO的功能是通过C#语言对这些工具的命令行进一步封装来实现的,你会发现APKINFO工具为什么有一百多M那么大,是因为它引用了JDK和ADT的部分工具。

项目结构如下:

 

一、查看APK信息

工具:aapt.exe

命令行:aapt dump badging apkFilePath

示例截图:

编程思路:C#调用命令行后获得APK信息,然后将应用名、包名、版本号、图标、权限等信息整理出来,最后展示到窗体的控件上。

注意点:

  • C#在调用命令行时,需要设置使用Shell执行,输出重定向,可以屏蔽Shell窗体的显示。
  • 截图上的中文应用名出现乱码,是因为Shell输出编码默认使用了gb2312,将标准输出编码设置为UTF-8即可。
  • 不同版本的aapt.exe,查看APK信息的速度不一样,输出来的信息结构也稍有不同,一般低版本的aapt执行速度比较快。
  • 图标读取是先在APK信息中找到图标路径,然后根据路径解压图标文件的,项目中是引入Ionic.Zip.dll解压文件。
  • 另外,增加了查看APK的assets目录下的配置,至于查看哪些个配置文件里的参数,由用户设置决定,这里只能读取内容格式为key=value的配置文件。

C#关键代码如下:

BrowseApkInfoBLL类:
 
       /// <summary>
        /// 读取APK信息
        /// </summary>
        /// <param name="apkFilePath"></param>
        /// <returns></returns>
        public static ApkInfo ReadApkInfo(string apkFilePath)
        {
            if (String.IsNullOrEmpty(apkFilePath))
                return null;

            string aaptPath = PathUtils.GetPath(Constants.PATH_AAPT);
            var startInfo = new ProcessStartInfo(aaptPath);
            string args = string.Format("dump badging \"{0}\"", apkFilePath);
            startInfo.Arguments = args;
            startInfo.UseShellExecute = false;
            startInfo.RedirectStandardOutput = true;
            startInfo.CreateNoWindow = true;
            startInfo.StandardOutputEncoding = Encoding.UTF8;
            
            // 读取命令行返回的所有txt文本和字符编码
            List<string> lineLst = new List<string>();
            using (var process = Process.Start(startInfo))
            {
                var sr = process.StandardOutput;
                while (!sr.EndOfStream)
                {
                    lineLst.Add(sr.ReadLine());
                }
                process.WaitForExit();
            }


            ApkInfo apkInfo = new ApkInfo();
            apkInfo.ApkFilePath = apkFilePath;
            apkInfo.CurrentFileName = Path.GetFileName(apkFilePath);
            apkInfo.AllInfoList = lineLst;

            // 解析相关的配置参数
            ParseTxtFile(ref apkInfo);
            ParseIcon(ref apkInfo);
            ParseAssetsConfig(ref apkInfo);

            return apkInfo;
        }


        /// <summary>
        /// 解压并读取icon图片
        /// </summary>
        /// <param name="apkInfo"></param>
        private static void ParseIcon(ref ApkInfo apkInfo)
        {
            if (apkInfo == null 
                || string.IsNullOrEmpty(apkInfo.ApkFilePath)
                || apkInfo.IconDic == null 
                || apkInfo.IconDic.Count <= 0) return;

            string icon = null;
            int i = 0;
            // 在多张尺寸的ICON里选择尺寸为240
            foreach (KeyValuePair<string, string> kv in apkInfo.IconDic)
            {
                if (kv.Key.Contains("240"))
                {
                    icon = kv.Value;
                    apkInfo.IconName = Path.GetFileName(icon);
                    break;
                }
                if (i == apkInfo.IconDic.Count - 1)
                {
                    icon = kv.Value;
                    apkInfo.IconName = Path.GetFileName(icon);
                    break;
                }
                i++;
            }

            // 指定解压目录
            string unZipPath = PathUtils.GetPath(Constants.DIR_TEMP_ICON);
            // 清空解压目录
            FileUtils.ClearDir(unZipPath);

            // 解压指定的icon图片文件
            ZipUtils.UnZip(apkInfo.ApkFilePath, unZipPath, icon);

            // 读取解压出来的图片文件
            string iconPath = PathUtils.JoinPath(unZipPath, icon);

            apkInfo.Icon = new Bitmap(iconPath);
        }

 

二、查看APK源代码

工具:jadx-0.7.1

命令行:jadx-gui.bat  apkFilePath 或jarFilePath 或dexFilePath

之前使用过jd-gui.exe查看源码,但它只能打开jar文件,dex和apk文件需要转换成jar文件才能打开,并不好用;这里推荐使用jadx工具,jar、dex和apk文件它都能直接打开。

编程思路:程序判断用户传递的文件类型,如果为jar或dex文件,则直接通过命令行调用jadx-0.7.1打开,如果为apk文件,则展示APK信息,让用户通过点击《查看源码》按钮打开,当jadx-0.7.1打开后,关闭程序。

C#关键代码如下:

BrowseSourceBLL类:

        /// <summary>
        /// 用jadx-gui.bat打开文件
        /// </summary>
        /// <param name="filePath">以.jar/.dex/.apk为后缀的文件路径</param>
        public static void OpenJadxGUI(string filePath) {

            if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) return;

            string jadxPath = PathUtils.GetPath(Constants.PATH_JADXGUI);
            if (!File.Exists(jadxPath))
            {
                LogUtils.WriteLine(jadxPath + "不存在!");
                return;
            }

            string cmdArgs = jadxPath + " " + filePath;
            CmdUtils.ExecCmd(cmdArgs);
        }    


CmdUtils类:

        /// <summary>
        /// 执行CMD命令,但不等待执行结果
        /// </summary>
        /// <param name="args"></param>
        public static void ExecCmd(string args)
        {
            try
            {
                Process proc = new Process();
                proc.StartInfo.WorkingDirectory = System.Windows.Forms.Application.StartupPath;
                proc.StartInfo.FileName = "cmd.exe";
                proc.StartInfo.Arguments = "/C " + args;
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.RedirectStandardError = true;
                proc.StartInfo.CreateNoWindow = true;//不创建窗口  
                proc.Start();
               
            }
          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值