前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android资源热修复之修改aapt源码

Android资源热修复之修改aapt源码

作者头像
MelonTeam
发布2018-01-04 11:58:43
1.8K0
发布2018-01-04 11:58:43
举报
文章被收录于专栏:MelonTeam专栏MelonTeam专栏

导语 : 在Windows下定制自己的aapt!

一、环境配置

1.1 软件和源码

Codeblocks下载地址:< mingw64下载地址:<https://jaist.dl.sourceforge.net/project/tdm-gcc/TDM- GCC%20Installer/> aapt源码地址(为了避免麻烦,特地弄好了aaptCodeblocks项目,直接从我的githubclone下来就能在Codeblocks中用):https://github.com/ClaymanTwinkle/aapt

1.2 软件配置

软件安装好了就要先配置下

1.2.1Codeblocks配置Compiler

步骤一: 选择进入工具栏 Settings » Compiler,如下图所示;

步骤二: (1)选择Global compiler settings; (2)在Selected compiler中选择GNU GCC Compiler,然后下方点击Copy按钮,就会出现Copy of GNU GCC Compiler; (3)在下方Toolchain executables配置mingw64,相关配置如下图所示; (4)最后选择OK即可;

配置好编译环境后,就可以打开项目了;进入aapt/aapt-v24中打开aapt-v24.workspace

工程目录结构如下图所示;

1.2.2 为每个工程配置Compiler

步骤一:右键一个工程,在右键菜单中选择Build Options

步骤二:第一次配置的时候,会出现一个弹窗,如下图;选择刚刚自己创建的Copy of GNU GCC Compiler,点击确定;

步骤三:注意,如果此时,出现以下对话框,请选择

对每个工程重复以上步骤;

二、改aapt源码

没错,如果上面的步骤都弄成功了,现在就可以改aapt源码了,是的,在Windows上改aapt源码,想想就激动! 普及一下一个小知识,在R.Java中可以看到系统资源的id都是以0x01开头的,而自己的资源id都是以0x7f开头的;这也就是说0x010x7f之间的的值我们都可以拿来用。 废话不多说,赶紧动手!

2.1 试改0x7f0x66

(1)在CodeBlocks中打开aapt-v24,找到我们要找的入口类main.cpp;同时也找到了入口方法main

(2)找到这个main.cpp有什么用,怎么修改0x7f呢?

我们可以这样,按快捷键Ctrl+F(真的很好用!),在aapt-v24中搜索0x7f,如下图所示;

搜索结果如下,这样我们就找到赋值0x7f的地方了;

ResourceTable.cpp这个类中;

(3)既然找到了位置,那赶紧改下这个值试试(直接改硬编码不太优雅,后面介绍一种优雅的方式),修改结果如下图所示;

接着,打包出自己的aapt吧!

(4)右键aapt-v24,在右键菜单中选择build或者rebuild,编译成功,打包出aapt.exe

aapt\aapt-v24\bin\Debug目录下可以看到打包好的aapt-24.exe

(5)打包好了,是骡子是马牵出来溜溜吧。

随便找个Android工程,然后在cmd中敲出类似这样一段命令行生成R.java

aapt-v24.exe p -f -m -I C:\Android\sdk\platforms\android-25\android.jar -J C:\Users\andyqtchen\Desktop\plurals -M C:\Android\workspace\AndroidQQ_Lite_proj/QQLite//AndroidManifest.xml -S C:\Android\workspace\AndroidQQ_Lite_proj/QQLite/res

结果……出乎意料啊,居然错了,是啊,哪有那么容易,想得美;但是,这些log好像是aapt自己内部打印出来吧?让我们看看这些log是从哪里打印出来的!

(6)神一样的快捷键Ctrl+F,搜~,结果如下图所示;

原来是在androidfw工程下的ResourceTypes.cpp搞的鬼! 先看看ResourceTypes.cpp耍的是什么把戏!

原来是这么回事,aapt除了会在aapt-v24中赋值,在androidfw中后面还会做一个判断拦截;

那么我在这里再加一个或者packageId==0x66就ok了(又一不文明操作,请勿模仿)! 改完重新rebuild androidfw,然后rebuild aapt-24打包出aapt.exe; 重新生成一次R.java,接下来就是见证奇迹的时刻!

2.2 定制化aapt

好了,上面的2.1只是小打小闹的一个实验而已,接下来要定制下随意修改资源ID前缀(packageId)的aapt

步骤一、定义一个单例

我在androidfw中定义一个单例,用来记录0x7f(默认值)或者其他自定义packageId的值;

代码语言:javascript
复制
// BlinkPackageId.h文件
#ifndef __BlinkPackageId_h
#define __BlinkPackageId_h

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

class BlinkPackageId
{
        ssize_t mPackageId;
public:
        static BlinkPackageId* getInstance()
        {
                static BlinkPackageId instance;
                return &instance;
        }
        ssize_t getPackageId();
        void setPackageId(ssize_t packageId);
        void setPackageId(const char* packageId);
protected:
        struct Object_Creator
        {
                Object_Creator()
                {
                        BlinkPackageId::getInstance();
                }
        };
        static Object_Creator _object_creator;
        BlinkPackageId() {
                mPackageId=0x7f;
        }
        ~BlinkPackageId() {
        }
};
#endif



// BlinkPackageId.cpp文件
#include 

#include 
#include 
#include 
using namespace std;

// char2int
static uint32_t apkgetHex(char c, bool* outError){
    if (c >= '0' && c <= '9') {
        return c - '0';
    } else if (c >= 'a' && c <= 'f') {
        return c - 'a' + 0xa;
    } else if (c >= 'A' && c <= 'F') {
        return c - 'A' + 0xa;
    }
    *outError = true;
    return 0;
}

// string2int
static ssize_t apkStringToInt(const android::String8& s){
    size_t i = 0;
    ssize_t val = 0;
    size_t len=s.length();
    if (s[i] < '0' || s[i] > '9') {
        return -1;
    }
    // Decimal or hex?
    if (s[i] == '0' && s[i+1] == 'x') {
        i += 2;
        bool error = false;
        while (i < len && !error) {
            val = (val*16) + apkgetHex(s[i], &error);
            i++;
        }
        if (error) {
            return -1;
        }
    } else {
        while (i < len) {
            if (s[i] < '0' || s[i] > '9') {
                return false;
            }
            val = (val*10) + s[i]-'0';
            i++;
        }
    }
    if (i == len) {
        return val;
    }
    return -1;
}

BlinkPackageId::Object_Creator BlinkPackageId::_object_creator;

ssize_t BlinkPackageId::getPackageId(){
        return mPackageId;
}
void BlinkPackageId::setPackageId(ssize_t  packageId){
        mPackageId=packageId;
}
void BlinkPackageId::setPackageId(const char* packageId){
        android::String8 str = android::String8(packageId);
        mPackageId=apkStringToInt(str);
}
步骤二、改造aapt命令行

定个需求,要加个--blink-package-id命令参数,后面带packageId;

锁定到aapt-v24工程下main.cpp源代码:

ResourceTable.cpp,将0x7f改成BlinkPackageId::getInstance()->getPackageId()

然后到androidfw工程下,把BlinkPackageId::getInstance()->getPackageId()放到if中:

ok!大功告成!

看看效果!!!

代码语言:javascript
复制
aapt-v24.exe p -f -m -I C:\Android\sdk\platforms\android-25\android.jar -J C:\Users\andyqtchen\Desktop\plurals -M C:\Android\workspace\AndroidQQ_Lite_proj/QQLite//AndroidManifest.xml -S C:\Android\workspace\AndroidQQ_Lite_proj/QQLite/res --blink-package-id 0x55

参考文章

如何实现携程动态加载插件中对aapt的改造 Android中如何修改编译的资源ID值(默认值是0x7F…可以随意改成0x02~0x7E)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-08-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、环境配置
    • 1.1 软件和源码
      • 1.2 软件配置
        • 1.2.1Codeblocks配置Compiler
        • 1.2.2 为每个工程配置Compiler
    • 二、改aapt源码
      • 2.1 试改0x7f为0x66
        • 2.2 定制化aapt
          • 步骤一、定义一个单例
          • 步骤二、改造aapt命令行
      • 参考文章
      相关产品与服务
      数据库
      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档