Android逆向小工具开发:快速查找应用XML数据第一步:获取应用的XML数据文件

小伙伴们大家好,又是一段时间过去了,在上面几篇的博客中我们主要学习了关于Xposed的进阶操作,还不知道大家学习的怎么样,那么在接下来的学习中,Xposed学习将会告一段落,接下来的学习正如标题所示:我将会带领大家来学习制作一款自己的逆向小工具,帮助大家在逆向分析中更好的掌握主动权,快速地进行逆向开发~

对于一个逆向工程师而言,什么才是最重要的东西?大家心里很快就会出现答案,没错!那就是逆向工具!一款好的逆向工具对逆向工程师而言那就犹如神兵利器,在逆向世界中叱咤风云的存在!要说鼎鼎大名的逆向工具,比如IDA,比如Apktool,还有Jadx,正是有了这些功能强大的逆向工具,逆向工程师才能在逆向分析中得心应手,如履平地。世界级的逆向工具博主自认是开发不出来,但是一些小儿灵巧的方便小工具,对于我们大家来说可为一试,通过一些小工具的开发,一方面能巩固加强我们代码的编写能力,另一方面开发完成后的小工具可以帮助辅助我们的逆向工作,可谓是一举两得!

那么相信你看到博文的题目就已经明白到我们要开发的小工具的功能,没错,那就是快速检索应用的XML数据,找出我们指定搜索内容的XML标签或者字段!关于XML数据,相比大家都很明白,在data/data/com.xxxx.xxxx/目录下的/shared_prefs文件夹中包含了这个应用所进行持久化处理的xml文件,这些xml文件正常情况下会使用SharedPreferences进行存取值操作,我们在应用层使用SharedPreferences进行数据的持久化处理,这些数据就是被放入了/shared_prefs文件夹下的xml文件内,在读取这些数值的时候说白了也是xml文件的解析操作,读取指定的字段值。

一般应用在XML文件中持久化处理的都会是一些比较重要的数据,比如说手机的一些基本参数数据,或者应用的一些配置数据等等。这些数据在我们逆向工作的时候也会是重要关注的对象之一,毕竟能够放进XML中持久化保存下来的数据都不是什么“泛泛之辈”!当需要我们去查看XML中保存下来的数据的时候,我们通过RE文件管理器进入data/data目录下进行查看,我相信那么多的XML文件,文件中那么多的字段值绝对会让你头大,想找到自己想要的东西无异于大海捞针。。。博主在翻看应用宝的XML数据简直生不如死,想想自己身为一名Android开发和逆向工程师,怎么能这么痛苦的折磨自己?!既然机器最擅长的事情就是查找的匹配,这个痛苦的工作还是交给机器好了!

于是博主立即着手进行相关的开发,具体开发的项目已经发布到博主个人的GitHub主页上,地址为:快速查找应用XML数据的小工具。大家可以去Github上下载项目源代码的压缩包,解压在Android Studio上运行即可,同时也可以配合本博客进行开发学习~好了,前言就到此为止,下面就让我们赶快进入今天的学习把!

首先开发的第一步还是进行需求分析。我们通过分析需求得到下面几条具体需求:

1:能够获取到某个应用的XML数据文件,即目录/data/data/com.xxx.xxx/shared_prefs

2:输入某一字符串,能够在获取的应用XML数据中查找出带有该字符串的标签或者文本

3:展示查询结果包含XML文件名,以及该XML文件内包含查询字段的标签文本

4:获取的应用XML数据文件可以重复利用,可以选择重新获取或者使用之前已经获取的XML文件

具体的需求分析就大致分为以上四条,我们大致分析一下开发流程就是:第一步获取应用的XML数据文件,第二步遍历XML数据文件进行查找,第三步展示查询之后的结果。一个查找的小工具,流程非常的清晰简单,那么我们就先来进行第一步:如何获取应用的XML数据文件?

我们这里已经知道的是应用的XML数据文件保存路径位于/data/data/...路径下,这个路径只允许本身的应用访问,其他的应用是无权访问的,那么这里我们如果想拿到别的应用的XML数据文件该怎么办?其实这里也很好解决,看过博主之前的博文的小伙伴大概就已经猜到了方法,没错,那就是利用adb命令啦!哎,不对,准确的来说,是利用adb命令和Liunx命令!

这里估计就蒙圈了,怎么还会有Liunx命令?!咱们这里又不是Linux虚拟机环境!这里可以提一下Liunx和Android的关系,简单的一句话:Android是基于Linux内核的操作系统,所以在安卓内你可以使用Liunx命令来操作~对这段历史感兴趣的小伙伴可以自行搜索相关资料,这不再做过多的叙述。首先先说一下具体的分工,adb命令负责进行权限的分配,Liunx命令负责进行操作文件。你可能会说,adb命令中也有很多文件的操作命令,为什么不使用adb命令来操作文件呢?这里就来解释一下,adb确实有相关的文件操作命令,但是在这里它并不能胜任我们的文件操作需求,因为这里我们需要操作的是整个文件夹内的所有XML文件,而不是单一的某一个文件!adb其实更多的被用于和电脑设备连接起来后的操作,进行设备之间文件的复制和删除都是非常的方便,这里从它的中文名字就可以看出来。但是在这里我们并不是进行两个设备之间的文件处理,而是手机内部中的文件操作!显然,Linux更能胜任这份工作!

下面我们就开始编写代码,开始尝试获取某一应用的XML数据文件:首先还是adb命令和Liunx命令的翻译者和执行者:

public class RootCmd {

    public static AppModel modelChange;
    private List<AppModel> appModels=new ArrayList<>();
    Context context;

    public RootCmd(Context mContext){
        context=mContext;
    }

    //翻译并执行相应的adb命令
    public static boolean exusecmd(String command) {
        Process process = null;
        DataOutputStream os = null;
        try {
            process = Runtime.getRuntime().exec("su");
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes(command + "\n");
            os.writeBytes("exit\n");
            os.flush();
            Log.e("updateFile", "======000==writeSuccess======");
            process.waitFor();
        } catch (Exception e) {
            Log.e("updateFile", "======111=writeError======" + e.toString());
            return false;
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (process != null) {
                    process.destroy();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return true;
    }

}

 写一个方法moveFileToSD(String,String):

    //移动文件
    public void moveFileToSD(String filePath, String cpFilePath) {
        exusecmd("mount -o rw,remount "+cpFilePath);
        exusecmd("chmod 777 "+cpFilePath);
        exusecmd("cp -r "+filePath+" "+cpFilePath);
    }

我们通过moveFileToSD()方法来把某一应用的XML数据文件给复制到手机的SD卡内。上面两句adb命令想必大家很熟悉了,修改目的路径的权限为可读写,给目的路径777权限,然后执行Liunx的文件夹复制命令:cp -r xxxx xxxx;表示遍历该文件夹内所有的文件,并把它们全部复制到目的路径下。

命令方法已经写好,那么下面就要开始进行相关选择App操作然后进行路径组装,因为每一个应用的XML数据文件存放路径都不同,/data/data/com.xxx.xxx/shared_prefs路径中/data/data/后面需要填写该应用的包名,我们需要获取他们的包名才能组装读取路径!

写一个App信息Model:AppModel

package com.example.xmlfileparsing;

import android.graphics.drawable.Drawable;

/**
 * Created by 王将 on 2018/10/29.
 */

public class AppModel {
    private int id;
    private Drawable icon;
    private String appName;
    private String packageName;

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setIcon(Drawable icon) {
        this.icon = icon;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    public Drawable getIcon() {
        return icon;
    }

    public String getPackageName() {
        return packageName;
    }

    public String getAppName() {
        return appName;
    }
}

 在RootCmd类中写一个方法用来获取手机内所有App的相关信息:getAppInfo()

public List<AppModel> getAppInfo(){
        if (appModels.size()==0){
            PackageManager pm = context.getPackageManager();
            List<PackageInfo> list = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);

            int i=0;
            for (PackageInfo packageInfo:list) {
                AppModel appModel = new AppModel();
                appModel.setId(i);
                appModel.setAppName(packageInfo.applicationInfo.loadLabel(context.getPackageManager()).toString());
                appModel.setPackageName(packageInfo.packageName);
                appModel.setIcon(packageInfo.applicationInfo.loadIcon(context.getPackageManager()));
                appModels.add(appModel);
                i++;
            }
        }

        return appModels;
    }

下面我们需要弹出一个Dialog用来展示所获取的所有App信息,然后让用户选择需要获取哪一个App的XML数据文件:

public void appShowDialog(final boolean isNew, final ImageView imageView, final TextView textView, final List<AppModel> appModels){
        final Dialog dialog=new Dialog(context, R.style.app_style_dialog);

        View view= LayoutInflater.from(context).inflate(R.layout.show_package,null,false);
        dialog.setContentView(view);

        LinearLayout linearLayout=(LinearLayout) view.findViewById(R.id.scroll_appInfo);
        TextView title=(TextView) view.findViewById(R.id.title_show);

        title.setText("请选择你需要解析的应用:");
        for (final AppModel appModel:appModels){
            final View app= LayoutInflater.from(context).inflate(R.layout.appinfo_layout,linearLayout,false);

            ImageView icon=(ImageView) app.findViewById(R.id.icon_app);
            TextView name=(TextView) app.findViewById(R.id.name_app);
            TextView packageName=(TextView) app.findViewById(R.id.package_app);

            icon.setImageDrawable(appModel.getIcon());
            name.setText(appModel.getAppName());
            packageName.setText(appModel.getPackageName());

            app.setTag(appModel);
            app.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        AppModel model=(AppModel) v.getTag();
                        if (isNew){
                            String dataFilePath="/data/data/"+model.getPackageName()+"/shared_prefs";
                            moveFileToSD(dataFilePath,getSDPath()+"/xmlTransit",model.getAppName()+"ID"+model.getId());
                        }

                        imageView.setVisibility(View.VISIBLE);
                        imageView.setImageDrawable(model.getIcon());
                        textView.setText(model.getAppName());
                        dialog.dismiss();
                    }
            });
            linearLayout.addView(app);
        }


        Window window = dialog.getWindow();
        window.setGravity(Gravity.BOTTOM);
        window.getDecorView().setPadding(0, 0, 0, 0);

        WindowManager.LayoutParams lp = window.getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.MATCH_PARENT;
        window.setAttributes(lp);

        dialog.show();
    }

在点击的监听事件中,我们会拿到用户选择的App信息Model,组装它的XML数据文件路径和目的路径,调用命令执行方法moveFileToSD()开始进行XML文件的复制。这样我们基本下来就完成了第一步,XML数据文件的获取!

这里还需要特别的分析一下:细心分析过项目代码的小伙伴就会发现不明白的地方了,代码中具体获取XML数据文件的方法并没有上面说的那么简单!当然了,这里博主是挑主要代码进行大致的讲解,其实在代码的开发中,博主选择了两步走的获取战略!

什么是两步走战略?准确的来说就是,第一步使用命令复制XML文件到一个取名为“中转站”的文件夹内,这里中转站的路径为:/storage/emulated/0/xmlTransit/,第二步从中转站内使用代码复制中转站内所有的XML文件到最终的目的路径为:/storage/emulated/0/xmlTarget/xxxx/,xxx为具体的应用名称加上它在getInstalledPackages()方法获取到的List的下标值!复制成功后执行文件夹删除命令,删除中转站/storage/emulated/0/xmlTransit/。

为什么要这么处理?一步到位不好么?一步到位当然很好,简单方便快捷,但是没有办法通过命令去实现!博主起初目标是直接复制到目的路径/storage/emulated/0/xmlTarget/xxxx/下,注意,其中/xmlTarget/xxxx/是不存在的路径。博主在尝试了好多文件复制命令后,始终没有办法将XML文件直接复制到目的路径下,只能是复制到SD卡的一级目录内。所以博主想了一个办法,进行了两步走战略,先把文件复制到SD内的中转站路径下,然后执行文件操作代码,进行文件的读写操作,把中转站内的文件复制到最终的目的路径下,之后删除文件中转站即可!

两步走战略的第二步:方法writeTarget()

private void writeTarget(String path,String name){
        File file = new File(path);
        File[] subFile = file.listFiles();
        if (subFile!=null&&subFile.length>0){
            for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) {
                if (!subFile[iFileLength].isDirectory()) {
                    String filePath = subFile[iFileLength].getAbsolutePath();

                    List<String> strList=readText(filePath);
                    writeTxtToFile(strList,getSDPath()+"/xmlTarget/"+name+"/"+subFile[iFileLength].getName());
                }
            }
            deleFile();

            showToast("XML文件获取成功!");
        }else {
            showToast("没有找到该应用的XML文件!");
        }

    }

 遍历中转站内所有的文件,读取文件的内容存放进一个List内,然后把文件内容写入最终目的路径。具体的文件读写代码不再贴出分析。后面执行deleFile()方法,把中转站文件夹删除。这里你可能会问,为什么不使用代码删除文件?那是因为此时执行代码删除是删除不掉的,博主猜测原因可能是此时文件夹所处的状态还是输入输出流状态,想关闭又找不到地方,于是万能的命令又来了,直接赋予管理员权限,执行文件夹强制删除命令,至此风平浪静~

好啦,第一部分的获取应用XML数据到此讲解完毕,我们主要学习到的是Liunx命令的相关处理和操作,以及针对顽固问题的解决思路!死磕命令不是最终之道,配合代码实现具体功能才是王道!

下面的博客中我们接着进行小工具的开发之旅第二部分:处理XML数据文件以及展示~大家要跟上脚步抓紧时间学习呀!

本篇博文到此结束,如有引用请标明出处,谢谢合作!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Android应用安全实战:Frida协议分析》是一本介绍Frida工具的使用和Android应用安全分析的书籍。Frida是一个强大的动态分析工具,可以帮助开发人员和安全研究人员对应用进行动态分析。本书以Frida为基础,介绍了如何对一些常见的安全问题进行定位和修复。 本书主要分为三部分,第一部分介绍了Frida工具的安装和使用方法,包括如何在Windows、Mac和Ubuntu三个系统上安装Frida,以及如何使用Frida对应用进行动态分析和漏洞挖掘。第二部分介绍了一些常见的安全问题,如反调试、class tampering、hook、rpc等问题,并详细介绍了如何通过Frida对这些问题进行分析和修复。第三部分介绍了一些应用案例分析,以及如何通过Frida对应用中的加密算法、网络协议、第三方代码等进行分析。 本书的特点在于实战性强,作者通过大量的实例和案例,让读者能够更加深入地理解Frida工具的使用方法,并能够将所学知识应用到实际的项目中。同时,本书还提供了一些工具和脚本,方便读者能够更加快速地进行分析和修复工作。 总的来说,本书是一本对于安卓开发人员、移动安全研究人员和安全工程师来说非常有价值的工具书,无论是对于入门和提高都有很大的帮助。Frida工具的特点在于动态分析,能够帮助开发人员和安全工程师快速定位和修复常见的安全问题。而本书则是一个详细的实例教程,通过这份教程的学习,读者将能够掌握Frida工具的使用方法,并能够熟练地应用到实际的项目中。 ### 回答2: 《Android应用安全实战:Frida协议分析PDF》是一本针对移动应用安全的实战指南。这本书主要讲述了如何借助Frida这个强大的工具来进行移动应用的安全分析和漏洞挖掘。 Frida是一款可用于对移动应用进行实时动态分析的工具,它的优点在于可以轻松地hook任意函数和类,还可以在不用重新编译应用程序的情况下动态修改应用程序的行为。Frida的这些特性使得它成为了许多黑客和渗透测试人员使用的首选工具之一。 在《Android应用安全实战:Frida协议分析PDF》中,作者首先介绍了Frida工具的基本原理和使用方法,包括安装和配置Frida、使用Frida脚本、使用Frida进行hook等。接着,作者详细介绍了Android应用程序的各个组成部分和重要的安全机制,并给出了许多实例来演示如何通过Frida来绕过这些安全机制。 最后,作者还介绍了一些常用的Frida脚本和工具,比如Hooking SSLPinning脚本、Frida-Extract工具、在Android 8.0上使用Frida等。这些工具和脚本可以帮助读者更快更高效地进行移动应用的安全分析和漏洞挖掘。 总的来说,《Android应用安全实战:Frida协议分析PDF》是一本非常实用的书籍,对于渗透测试人员、黑客和移动应用开发人员来说都具有一定的参考价值。通过学习和掌握Frida这个工具,可以让我们更好地发现和修复移动应用程序中的安全问题,从而提升我们的移动应用程序的安全性和可靠性。 ### 回答3: 《Android应用安全实战:Frida协议分析》是一本关于安卓应用安全的实战教程。该书的重点在于介绍如何使用Frida协议进行应用程序的逆向分析,得出应用程序的安全漏洞,并给出相应的解决方案。 Frida是一个能够在运行时动态注入JavaScript并调试代码的工具。这也意味着Frida能够直接访问运行在内存中的应用程序。这个优势使Frida成为了一个强大的安卓应用程序分析和调试工具。通过使用Frida,用户可以对应用程序进行监视、修改、甚至是攻击。 《Android应用安全实战:Frida协议分析》详细介绍了Frida的使用方法,包括Frida的架构、基本操作、配置和调试应用程序等。此外,该书还介绍了有关安卓应用程序逆向工程和安全审计的实操技能。通过本书的学习,在安卓应用程序的开发过程中,读者可以掌握一定的安全知识和技能,从而提高应用程序的安全性,避免攻击和漏洞的发生。 总之,《Android应用安全实战:Frida协议分析》是一本非常实用、易懂的安卓应用程序安全入门教材。在阅读该书并掌握其中的技能后,用户可以应用这些技能进行应用程序的逆向分析和安全审计,从而达到提高安卓应用程序安全性的目的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值