精华内容
下载资源
问答
  • Android编译流程

    2021-02-09 11:00:00
    众所周知,Android系统其实就是一个运行在Linux系统上面的应用桌面程序,当然这样概括可能不是很准确,但是他们的编译确实异曲同工之妙。 在Linux系统中,我们可以通过make命令来编译代码。执行Make命令默认会在...

    目录

    一、编译流程

    1、初始化编译环境

    2、选择编译平台

    3、开始编译

    二、Soong工具

    1、Soong工作原理

    2、转换关系

    三、make流程

    1、编译开端main.mk

    2、编译配置config.mk

    3、配置产品product.mk

    4、加载产品product_config.mk


    众所周知,Android系统其实就是一个运行在Linux系统上面的应用桌面程序,当然这样概括可能不是很准确,但是他们的编译确实异曲同工之妙。

    在Linux系统中,我们可以通过make命令来编译代码。执行Make命令默认会在当前目录找到一个Makefile文件,然后根据Makefile文件中的指令来对代码进行编译(makefile语法课参考《GNU make中文手册》)。也就是说make命令执行的是Makefile文件中的指令,Makefile文件中的指令可以是编译命令(例如gcc,也可以是其它命令)。

    在Android系统中,随着源代码越来越复杂,光一个makefile在性能上已经满足不了,因此在该机制之上新增了自己的android.mk和android.bp方式,为了优雅的与makefile兼容,soong就此诞生了。

    想看Android源码,可以到阅读网站,请点击我

    一、编译流程

    google已经给出了android的原生编译流程:source build/envsetup.sh加载命令初始化环境、lunch选择平台、make执行编译命令。

    1、初始化编译环境

    进入android源代码根目录执行命令source build/envsetup.sh即可初始化编译环境。如下日志:

    其实该过程从source命令就可以看出主要是执行了envsetup.sh脚本且加载环境变量到当前终端。脚本envsetup.sh中其实定义了很多函数,如下:

    //android/build/envsetup.sh
    function hmm() {
    cat <<EOF
    Run "m help" for help with the build system itself.
    Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
    - lunch:      lunch <product_name>-<build_variant>
                  Selects <product_name> as the product to build, and <build_variant> as the variant to
                  build, and stores those selections in the environment to be read by subsequent
                  invocations of 'm' etc.
    - tapas:      tapas [<App1> <App2> ...] [arm|x86|mips|arm64|x86_64|mips64] [eng|userdebug|user]
    - croot:      Changes directory to the top of the tree, or a subdirectory thereof.
    - m:          Makes from the top of the tree.
    - mm:         Builds and installs all of the modules in the current directory, and their
                  dependencies.
    - mmm:        Builds and installs all of the modules in the supplied directories, and their
                  dependencies.
                  To limit the modules being built use the syntax: mmm dir/:target1,target2.
    - mma:        Same as 'mm'
    - mmma:       Same as 'mmm'
    - provision:  Flash device with all required partitions. Options will be passed on to fastboot.
    - cgrep:      Greps on all local C/C++ files.
    - ggrep:      Greps on all local Gradle files.
    - gogrep:     Greps on all local Go files.
    - jgrep:      Greps on all local Java files.
    - resgrep:    Greps on all local res/*.xml files.
    - mangrep:    Greps on all local AndroidManifest.xml files.
    - mgrep:      Greps on all local Makefiles and *.bp files.
    - owngrep:    Greps on all local OWNERS files.
    - sepgrep:    Greps on all local sepolicy files.
    - sgrep:      Greps on all local source files.
    - godir:      Go to the directory containing a file.
    - allmod:     List all modules.
    - gomod:      Go to the directory containing a module.
    - pathmod:    Get the directory containing a module.
    - refreshmod: Refresh list of modules for allmod/gomod.
    Environment options:
    - SANITIZE_HOST: Set to 'address' to use ASAN for all host modules.
    - ANDROID_QUIET_BUILD: set to 'true' to display only the essential messages.
    Look at the source to view more functions. The complete list is:
    EOF
        local T=$(gettop)
        local A=""
        local i
        for i in `cat $T/build/envsetup.sh | sed -n "/^[[:blank:]]*function /s/function \([a-z_]*\).*/\1/p" | sort | uniq`; do
          A="$A $i"
        done
        echo $A
    }
    # Get the exact value of a build variable.
    function get_build_var() { }
    # check to see if the supplied product is one we can build
    function check_product() { }
    # 设置环境变量
    function setpaths() { }
    function chooseproduct() { }
    function add_lunch_combo() { }
    function print_lunch_menu() { }
    function lunch() { }
    function croot() { }
    function m() { }
    function mm() { }
    function make() { }
    # 加载执行产商定义vendorsetup.sh
    function source_vendorsetup() {
        unset VENDOR_PYTHONPATH
        allowed=
        for f in $(find -L device vendor product -maxdepth 4 -name 'allowed-vendorsetup_sh-files' 2>/dev/null | sort); do
            if [ -n "$allowed" ]; then
                echo "More than one 'allowed_vendorsetup_sh-files' file found, not including any vendorsetup.sh files:"
                echo "  $allowed"
                echo "  $f"
                return
            fi
            allowed="$f"
        done
    
        allowed_files=
        [ -n "$allowed" ] && allowed_files=$(cat "$allowed")
        for dir in device vendor product; do
            for f in $(test -d $dir && \
                find -L $dir -maxdepth 4 -name 'vendorsetup.sh' 2>/dev/null | sort); do
    
                if [[ -z "$allowed" || "$allowed_files" =~ $f ]]; then
                    echo "including $f"; . "$f"
                else
                    echo "ignoring $f, not in $allowed"
                fi
            done
        done
    }
    validate_current_shell
    source_vendorsetup  # 加载执行vendor分区的vendorsetup.sh  芯片产商通常会将自己的一些配置加载改文件
    addcompletions

    source build/envsetup.sh执行之后,为当前终端加载了上面的这些函数,之后可以在该终端执行这些命令(函数名)来执行这些函数的内容,最后调用函数source_vendorsetup加载其他目录(device vendor product)下的vendorsetup.sh脚本。注意,该命令只在当前终端生效,如果未生效那么lunch和mm等命令是无法使用的

    2、选择编译平台

    在Android根目录下执行lunch命令来选择当前编译平台,该命令可以直接跟上参数,也可以让其显示菜单让我们选择,如下:

    lunch函数代码如下:

    //android/build/envsetup.sh
    function lunch()
    {
        local answer
        #步骤1:判断是否带有参数$1表示第一个参数
        if [ "$1" ] ; then
            answer=$1
        else
            #打印当前所有product
            print_lunch_menu
            echo -n "Which would you like? [aosp_arm-eng] "
            #阻塞读取用户输入的编号
            read answer
        fi
        #步骤2:校验用户输入的编号或者product
        if [ -z "$answer" ]
        then
            #answer为空默认aosp_arm-eng平台
            selection=aosp_arm-eng
        elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
        then
            #answer是数字编号,通过get_build_var获取所有的product到choices并根据编号找到对应的product字符串
            local choices=($(TARGET_BUILD_APPS= get_build_var COMMON_LUNCH_CHOICES))
            if [ $answer -le ${#choices[@]} ]
            then
                # array in zsh starts from 1 instead of 0.
                if [ -n "$ZSH_VERSION" ]
                then
                    selection=${choices[$(($answer))]}
                else
                    selection=${choices[$(($answer-1))]}
                fi
            fi
        else
            #answer是字符串,即直接跟参数的情况 例如lunch full_v755-user
            selection=$answer
        fi
        #步骤3:切割selection,得到产品名称等这些信息保存在product version等变量中
        local product variant_and_version variant version
        product=${selection%%-*} # Trim everything after first dash
        variant_and_version=${selection#*-} # Trim everything up to first dash
        if [ "$variant_and_version" != "$selection" ]; then
            variant=${variant_and_version%%-*}
            if [ "$variant" != "$variant_and_version" ]; then
                version=${variant_and_version#*-}
            fi
        fi
        #步骤4:将上面得到的product variant version 等信息赋值到全局变量中
        TARGET_PRODUCT=$product \
        TARGET_BUILD_VARIANT=$variant \
        TARGET_PLATFORM_VERSION=$version \
        build_build_var_cache
        export TARGET_PRODUCT=$(get_build_var TARGET_PRODUCT)
        export TARGET_BUILD_VARIANT=$(get_build_var TARGET_BUILD_VARIANT)
        if [ -n "$version" ]; then
          export TARGET_PLATFORM_VERSION=$(get_build_var TARGET_PLATFORM_VERSION)
        else
          unset TARGET_PLATFORM_VERSION
        fi
        export TARGET_BUILD_TYPE=release
        #步骤5:将上面的全局变量TARGET_PRODUCT TARGET_BUILD_VARIANT等设置到环境变量中
        set_stuff_for_environment
        #步骤6:打印最新的配置
        printconfig
        #步骤7:销毁编译相关的局部变量
        destroy_build_var_cache
    }

    这里有个很有意思的问题,就是当前平台定义的product是怎么获取出来的呢?我们可以详细看看函数print_lunch_menu代码是怎么实现的,如下代码,该函数调用get_build_var,并传递参数COMMON_LUNCH_CHOICES来获取当前所有平台,COMMON_LUNCH_CHOICES被定义在AndroidProducts.mk中,后文继续介绍。

    3、开始编译

    最后就可以执行make或者mm等命令进行编译了,但他们的流程可能有些不一样。因为按照linux的makefile机制,make命令其实直接执行了当前目录下的makefile脚本,但是linux并没有mm或者mma等这些命令,根据下面的代码可以知道android 7.0之后采用了独有的soong编译系统直接执行了当前目录下的android.mk或者android.bp脚本。(注意android.mk一直存在,android编译系统对makefile做的一层封装,详情参考请点击我

    • mm命令
    //android/build/envsetup.sh
    function _trigger_build()
    (
        local -r bc="$1"; shift
        #通过soong_ui.bash进行编译
        if T="$(gettop)"; then
          _wrap_build "$T/build/soong/soong_ui.bash" --build-mode --${bc} --dir="$(pwd)" "$@"
        else
          echo "Couldn't locate the top of the tree. Try setting TOP."
        fi
    )
    function m()
    (
        _trigger_build "all-modules" "$@"
    )
    function mm()
    (
        _trigger_build "modules-in-a-dir-no-deps" "$@"
    )
    function mmm()
    (
        _trigger_build "modules-in-dirs-no-deps" "$@"
    )
    function mma()
    (
        _trigger_build "modules-in-a-dir" "$@"
    )
    function mmma()
    (
        _trigger_build "modules-in-dirs" "$@"
    )
    
    • make命令
    function make()
    {
        #调用了get_make_command,参数透传过去
        _wrap_build $(get_make_command "$@") "$@"
    }
    function get_make_command()
    {
        # If we're in the top of an Android tree, use soong_ui.bash instead of make
        #如果有soong_ui.bash就使用soong进行编译(android 7之后基本上采用该方式)
        if [ -f build/soong/soong_ui.bash ]; then
            # Always use the real make if -C is passed in
            for arg in "$@"; do
                if [[ $arg == -C* ]]; then
                    echo command make
                    return
                fi
            done
            echo build/soong/soong_ui.bash --make-mode
        else
            #如果没有soong_ui.bash就使用makefile方式进行编译(android 7之前采用该方式)
            echo command make
        fi
    }

    二、Soong工具

     随着android工程越来越大,包含的module越来越多,以makefile(包括android.mk)组织的项目编译花费的时间越来越多。谷歌在7.0开始引入了ninja进行编译系统的组织,相对于make来说ninja在大的项目管理中速度和并行方面有突出的优势,因此谷歌采用了ninja来取代之前使用的make。但是现有的android项目还是由makefile组织,因此谷歌引入了kati(后来被称为soong)将makefile(包括android.mk)翻译成ninja文件。

    Android 7.0开始逐步引入kati soong(未正式使用默认关闭,需要USE_SOONG=true手动开启),将makefile文件和Android.mk文件转化成ninja文件,使用ninja文件对编译系统进行管理。

    Android 8.0开始引入了Android.bp文件来替代之前的Android.mk文件。Android.bp只是纯粹的配置文件(类似json),不包括分支、循环等流程控制(如果想要进行分支循环控制可自己写go来完成),因此Android.bp文件被转化成ninja文件的效率远远高于Android.mk文件。

    Android 9.0开始强制使用Android.bp来代替Android.mk。

    参考:Android中的Android.bp、Blueprint 和Soong简介

    参考:Android.bp语法

    1、Soong工作原理

    Soong源代码路径位于/android/build/soong/,从第一章的内容了解到目前的Android代码编译命令make(包括mm等命令)都基本上使用的该目录下的soong_ui.bash来进行代码编译。主要涉及到如下流程:

    • Android.mk转换成ninja文件:soong_ui.bash将指定目录下的所有Android.mk(包括makefile)文件转换成out/build-<product_name>.ninja文件
    • Android.bp转换成ninja文件:soong_ui.bash将指定目录下所有的Android.bp文件也转换成out/soong/build.ninja文件
    • 组合nijia文件:soong_ui.bash还会生成一个较小的out/combined-<product_name>.ninja文件,负责把二者组合起来作为执行入口
    • Soong根据nijia来控制源码编译

    2、转换关系

    通过Kati工具将Android.mk和makefile文件转换成ninja格式的文件

    通过Buleprint工具解析Android.bp文件,在通过Soong将被解析后的Android.bp转换成ninja格式的文件

    通过androidmk工具可以直接将没有分支和循环流程控制的Android.mk文件转换成Android.bp文件(一般开发者可能会用到该工具)

    相关术语:

    • Ninja:ninja是一个编译框架,会根据相应的ninja格式的配置文件进行编译,但是ninja文件一般不会手动修改,而是通过将Android.bp文件转换成ninja格文件来编译
    • Android.mk:Android.mk其本质是执行envsetup.sh之后,编译系统对makefile进行了一层封装,让开发者更加简单的使用makefile。因此可直接把他当成makefile看待
    • Kati:kati是专为Android开发的一个基于Golang和C++的工具,主要功能是把Android中的Android.mk文件转换成Ninja文件
    • Android.bp:Android.bp的出现就是为了替换Android.mk文件。bp跟mk文件不同,它是纯粹的配置,没有分支、循环等流程控制,不能做算数逻辑运算。如果需要控制逻辑,那么只能通过Go语言编写
    • Soong:Soong类似于之前的Makefile编译系统的核心,负责提供Android.bp语义解析,并将之转换成Ninja文件。Soong还会编译生成一个androidmk命令,用于将Android.mk文件转换为Android.bp文件,不过这个转换功能仅限于没有分支、循环等流程控制的Android.mk才有效
    • Blueprint:Blueprint是生成、解析Android.bp的工具,是Soong的一部分。Soong负责Android编译而设计的工具,而Blueprint只是解析文件格式,Soong解析内容的具体含义。Blueprint和Soong都是由Golang写的项目,从Android 7.0,prebuilts/go/目录下新增Golang所需的运行环境,在编译时使用
    • androidmk:androidmk是Soong提供的一套可直接通过命令的方式将一个android.mk生成一个对应的android.bp。通常开发者需要手动替换Android.mk的时候用到

    三、make流程

    在android源码根目录输入make命令之后,将以树结构的方式编译整个工程所有子目录,这里只介绍一下从make是如何走到我们lunch选择的平台mk。

    1、编译开端main.mk

    根据前面两章的内容我们应该很容易知道,在进行模块编译的时候执行mm其实就是执行了当前目录下的android.mk或者android.bp文件里面的指定的内容。那么在根目录下执行make其本质还是执行的根目录下面的makefile文件(跟linux一模一样)。根目录下的Android.bp内容是空,makefile直接指向了build/make/core/main.mk文件,如下图:

    main.mk根据名称也知道是我们编译执行的主函数,当然其比较复杂,我们比较感兴趣大概流程如下三步:

    • 导入build/make/core/config.mk进行环境变量或重要参数的配置(比如常用的CLEAR_VARS、BUILD_PACKAGE)

    • 导入build/make/core/definitions.mk也定义了一些其他变量(比如常用的my-dir、all-subdir-makefiles、all-subdir-java-files)
    • 定义了一系列规则,规则的目标就是编译要生成的目标文件(比如单独编译某个分区可以直接使用make vendorimage、make xxximage)

    2、编译配置config.mk

    config.mk定义了很多变量,这些变量对应某个mk文件并有对应的逻辑功能,例如CLEAR_VARS其实就是对应执行clear_vars.mk脚本,如下代码:

     

    config.mk除了定义一些可以使用的变量之外,还导入了其他mk文件来帮他完成一些类似任务,例如配置全局变量的时候就导入了当前目录下的envsetup.mk,如下代码:

    envsetup.mk主要给一些变量设置却省值(详情请点击我),但最关心的还是加载了产品配置相关的product_config.mk,如下:

    3、配置产品product.mk

    关于product的相关设定,则是由build/core/product_config.mk所处理,使用 build/core/product.mk提供宏载入。根据AndroidProducts.mk的內容,product_config.mk确定product目标。

    由上节我们已经知道主控main.mk最终引入到了product_config.mk来进行product相关的配置,在第107行导入了product.mk来读取当前所选择的product(即lunch的时候选择的产品),如下代码:

    #http://172.16.20.244:8081/MT6762_R/xref/android/build/make/core/product.mk
    #android/build/make/core/product.mk
    
    #定义函数:_find-android-products-files 
    #函数功能:返回所有android产品的列表
    #         其中android/build/make/core/config.mk为SRC_TARGET_DIR := $(TOPDIR)build/make/target
    #         因此返回的是$(TOPDIR)build/make/target/product/AndroidProducts.mk文件里面定义的所有产品
    define _find-android-products-files
    $(file <$(OUT_DIR)/.module_paths/AndroidProducts.mk.list) \
      $(SRC_TARGET_DIR)/product/AndroidProducts.mk
    endef
    
    #定义函数:get-product-makefiles
    #函数功能:返回所有自定义产品的列表
    #         根据注释其中联合变量PRODUCT_MAKEFILES和COMMON_LUNCH_CHOICES被定义在AndroidProducts.mk
    #         下面代码主要逻辑根据PRODUCT_MAKEFILES和COMMON_LUNCH_CHOICES遍历所有自定义的product及对应的mk文件
    define get-product-makefiles
    $(sort \
      $(eval _COMMON_LUNCH_CHOICES :=) \
      $(foreach f,$(1), \
        $(eval PRODUCT_MAKEFILES :=) \
        $(eval COMMON_LUNCH_CHOICES :=) \
        $(eval LOCAL_DIR := $(patsubst %/,%,$(dir $(f)))) \
        $(eval include $(f)) \
        $(call _validate-common-lunch-choices,$(COMMON_LUNCH_CHOICES),$(PRODUCT_MAKEFILES)) \
        $(eval _COMMON_LUNCH_CHOICES += $(COMMON_LUNCH_CHOICES)) \
        $(PRODUCT_MAKEFILES) \
       ) \
      $(eval PRODUCT_MAKEFILES :=) \
      $(eval LOCAL_DIR :=) \
      $(eval COMMON_LUNCH_CHOICES := $(sort $(_COMMON_LUNCH_CHOICES))) \
      $(eval _COMMON_LUNCH_CHOICES :=) \
     )
    endef
    
    #定义函数:get-all-product-makefiles
    #函数功能:获取所有product,包括自定义的和android原生的
    define get-all-product-makefiles
    $(call get-product-makefiles,$(_find-android-products-files))
    endef
    
    

    这里我们再来看看AndroidProducts.mk中是如何配置PRODUCT_MAKEFILES和COMMON_LUNCH_CHOICES,当然AndroidProducts.mk并不止一个,一般被定义在device目录下,如果多个项目工基线的话就可以在该目录下配置多个项目。如下代码:

    #android/device/厂商名/项目名/AndroidProducts.mk
    
    #指定对应的makefile文件
    PRODUCT_MAKEFILES := $(LOCAL_DIR)/full_vshen.mk \
                         $(LOCAL_DIR)/vnd_vshen.mk
    
    #包含可以选择的lunch
    COMMON_LUNCH_CHOICES:=\
        full_vshen-eng \
        full_vshen-userdebug \
        full_vshen-user \
        vnd_vshen-eng \
        vnd_vshen-userdebug \
        vnd_vshen-user
    

    4、加载产品product_config.mk

    上节只介绍了lunch弹出的产品菜单是被定义在哪里的呢,现在我们再来看看已经选择了某个product,编译的是如何加载我们指定product相关的makefile文件的。继续回到product_config.mk文件中,如下代码:

    根据上面代码,可以得出如下逻辑,在android目录下执行make的时候,最终会根据lunch选择的product在COMMON_LUNCH_CHOICES中去寻找对应的product,然后再加载该AndroidProducts.mk文件中PRODUCT_MAKEFILES指定的.mk文件

     

    展开全文
  • Android APK反编译教程

    2021-11-02 14:39:55
    目录一、反编译工具二、注意事项三、apktool1.1 官方链接1.2 下载安装1.3 使用四、dex2jar1.1 官方链接1.2 下载安装1.3 使用五、jd-gui1.1 官方链接1.2 下载安装1.3 使用 一、反编译工具 1、apktool:获取资源文件,...

    一、反编译工具

    1、apktool:获取资源文件,提取图片文件,布局文件,还有一些XML的资源文件。

    2、dex2jar:将APK反编译成Java源码(将classes.dex转化为jar文件)。

    3、jd-gui:查看dex2jar中转换后的jar文件。

    二、注意事项

    1、在反编译的代码看到a、b、c等等,这些是apk发布时进行混淆了,然后进行一些加密,或者使用第三方的加密平台,用的比较多的“爱加密”,有兴趣的也自行百度查看更加详细的介绍!apk进行混淆后里面的代码就没有必要再看了!

    2、切勿拿反编译来做违法的事,比如把人家的APK重新打包后使用自己的签名然后发布到相关市场。

    3、我们是参考别人的代码,而不是完全拷贝!!!切记!!

    三、apktool

    1.1 官方链接

    链接:https://bitbucket.org/iBotPeaches/apktool/downloads/

    1.2 下载安装

    三种不同系统的安装教程:https://ibotpeaches.github.io/Apktool/install/
    请添加图片描述

    我使用的是Windows系统,这里我以Windows为例子来进行讲解如何安装。

    1、先创建一个名为apktool的文件夹,用来存放apktool的文件,再根据官方链接下载最新的jar(apktool_2.6.0.jar),再将jar 重命名为 apktool.jar
    请添加图片描述
    2、在apktool的文件夹里创建apktool.txt文件,再点击wrapper script链接,进入脚本复制内容到apktool.txt文件里,完成后将apktool.txt更改为apktool.bat即可。请添加图片描述
    请添加图片描述
    3、将两个文件 apktool.jarapktool.bat 移动到你的 Windows 目录(通常是C://Windows)。如果你无权访问C://Windows,你可以将这两个文件放在apktool.txt文件,然后将该目录添加到你的环境变量系统 PATH 变量中。

    4、win + r 再输入cmd 打开命令提示符,直接输入apktool 回车即可。

    1.3 使用

    在命令提示符里找到apk存放的目录,然后输入apktool.bat d Wi-Fi.apk(Wi-Fi指的是apk名) ,Enter回车即可。然后目录下就会出现同apk名的文件夹,里面就是我们所需的资源文件。
    请添加图片描述

    四、dex2jar

    1.1 官方链接

    链接:https://sourceforge.net/projects/dex2jar/files/

    1.2 下载安装

    1、下载最新dex2jar(dex2jar-2.0.zip)保存到文件夹里,并解压即可。
    请添加图片描述

    1.3 使用

    1、将Wi-Fi.apk的后缀名改为Wi-Fi.zip并解压得到Wi-Fi文件夹。
    请添加图片描述
    2、在Wi-Fi文件夹里有一个classes.dex文件,将classes.dex文件复制到dex2jar-2.0文件夹里。
    请添加图片描述
    请添加图片描述
    3、打开命令提示符,找到dex2jar-2.0目录,输入d2j-dex2jar.bat classes.dex 回车,这样我们就会得到一个classes-dex2jar.jar包,里面就是我们所需的java代码,但需要 jd-gui 打开来看。
    请添加图片描述
    请添加图片描述

    五、jd-gui

    1.1 官方链接

    链接:http://java-decompiler.github.io/

    1.2 下载安装

    1、打开官方链接,找到 JD-GUI —> 点击Download —> 点击jd-gui-1.6.6.jar下载,保存到文件夹里,并解压即可。
    请添加图片描述

    1.3 使用

    1、在jd-gui-windows-1.6.6文件夹里打开 jd-gui.exe ,再找到 classes-dex2jar.jar 打开就可以看到代码了。
    请添加图片描述
    请添加图片描述

    展开全文
  • 有两个途径可以达到这个目的:一个是使用安卓 NDK 提供的工具链直接编译 C 代码(其中又有两种方式,使用 android 的 mk 文件,使用自己编写的 Makefile );一个是使用 Qt 5.2 for Android ,Qt Creator ...

    作为 C/C++ 程序员,有时候我们希望在安卓上运行从 C/C++ 生成的可执行程序,而不是在 Java 中通过 jni 的方式来调用 C 动态库。有两个途径可以达到这个目的:一个是使用安卓 NDK 提供的工具链直接编译 C 代码(其中又有两种方式,使用 android 的 mk 文件,使用自己编写的 Makefile );一个是使用 Qt 5.2 for Android ,Qt Creator 可以生成安卓版本。这里我们说 Qt for Android,不说 NDK 方式。

    Qt for Android 的环境搭建,可以参考我之前的博文《Windows下Qt 5.2 for Android开发入门》。

    一旦你生成了一个项目,配置好了工具链,就可以在 Qt Creator 的项目标签中选择安卓版本进行编译。不过默认编译出来的是动态库, so 文件。而我们想要可执行程序。这个可以通过修改 Makefile 来完成,纯手动的方式有以下几个步骤:

    修改 Makefile ,找到 LFLAGS 开始的那一行,去掉 -shared 和 -Wl,-soname,xxx.so 这两个链接选项,这杨链接器就会生成可执行程序修改 Makefile ,找到 QMAKE_TARGET 和 TARGET 开始的两行,把 " = " 后面的目标修改为你想要的那个名字,假定为 xxx 打开 Qt 5.2.0 for Desktop (MinGW 4.8 32 bit) ,进入你的安卓编译目录,执行 mingw32-make ,可以看见, xxx 生成了

    使用原生程序比使用 APK + JNI 方式会有一个好处: Java 虚拟机无法控制原生程序占用的内存,而 APK + JNI 的方式, C 代码和 Java 代码共享整个 Java 虚拟机的内存, C 代码会受到虚拟机内存大小的限制。

    如果嫌上面的步骤麻烦(每次 Qt 工程变化都要手动修改 Makefile ,比如往添加了文件等),可以在 Qt Creator 中给工程添加一个构建步骤(自动修改 Makefile ),顺序放在 qmake 之后,这样每次 qmake 生成了 Makefile ,自定义的构建步骤就会自动执行来修改 Makefile ,在 make 时应用修改,最终生成可执行文件。下图是我的一个工程的配置:

    122512_0.jpg

    至于怎么自动修改 Makefile ,可以使用一些开源的文本工具(如 sed for windows 等),这里就展开了。我是自己写了个小程序,专用的,不通用,也不提了。

    展开全文
  • 一键反编译Android教程

    千次阅读 2021-10-29 16:39:52
    某些时候我们想修改apk包内容,比如汉化某个游戏,这时候就需要修改游戏apk的包内容,并重新签名成安卓手机识别的apk文件,下面详细介绍,文章末尾有一键修改工具。 确保java环境

    功能介绍

    某些时候我们想修改apk包内容,比如汉化某个游戏,这时候就需要修改游戏apk的包内容,并重新签名成安卓手机识别的apk文件,下面详细介绍,文章末尾有一键修改工具。(注意:此工具尚未整合修改代码,纯粹修改Android资源,修改代码可以结合dex2jar等工具自行处理)

    先看看工具的截图

     前提

    1、Windows系统,确保java环境安装完成并且配置好相关环境变量。

    java官方下载地址:http://www.java.com/

    2、下载博主写的工具包:https://download.csdn.net/download/egostudio/35518697

    没有积分的同学可以加群免费下载:Q群:904994482

    ps:因为安卓系统会更新,所以对应的apktool工具也会更新,当前工具集成的是2.6.0版本,有更新可以自己去官网下载最新版,改为apktool.jar放在工具目录下即可。apktool是安全的,360会误报病毒请无视。

    apktool官方地址:Apktool - A tool for reverse engineering 3rd party, closed, binary Android apps.

    使用步骤

    第一步 反编译apk

    1、将apk复制到当前目录下,改名为file.apk


    2、双击执行 “1反编译.bat”,等待结束(apk包过大等待需要久点)


    3、执行完毕后打开输出目录为dis/output,看到目录结构大概是这样

     

    4、根据需求对包进行修改即可

    ps:如果需要修改代码,可以结合dex2jar工具进行修改,百度教程一大堆,这里就不细说

    第二步 重新打包

    apk包内容修改完毕,需要对包内容重新打包成apk,注意,这个步骤打出来的apk是不能直接安装的,因为还没有签名。

    1、修改内容后,双击执行“2重新打包.bat”


    2、等待执行完毕,输出目录dis/files/output.apk,打包结束


    ps:当前apk是未签名版本,无法直接使用,请看签名部分

     第三步 签名apk

    1、双击“3签名.bat”


    2、执行完毕后,打开目录dis/files/output-signed.apk,即可看到最终文件,该文件即可安装到手机上

     

    ps:当前签名为默认签名,该签名是SignApk工具下载自带的签名,如果要自定义签名,可以搜索相关教程,关键字“安卓证书转pem和pk8”,替换下面目录的文件即可自定义签名

     

    ---------------------------

    20211230更新

    签名方法2

    直接使用keystore文件签名

    ps:工具已更新,支持自定义keystore文件,直接签名

    Unity不指定签名时会使用默认的keystore文件,文件路径在C:\Users\用户名\.android\debug.keysotre

    签名信息如下:

    Keystore名字:“debug.keysotre”
    Keystore密码:“android”
    Key别名:“androiddebugkey”
    Key密码:“android”
    eg:jarsigner -verbose -keystore debug.keystore -signedjar test_singed.apk test_unsigned.apk androiddebugkey
    1、双击3签名.bat
    2、输入密码:android
    2、执行完毕后,打开目录dis/files/output-signed.apk,即可看到最终文件

    展开全文
  • android studio反编译教程[2021-02-13 15:05:33]简介:php去除nbsp的方法:首先创建一个PHP代码示例文件;然后通过“preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/", " ", strip_tags($val));”方法去除所有nbsp...
  • Android Studio 如何编译运行应用?前面的小节我们介绍了运行配置相关的知识,从本小结我们学习如何构建和运行我们的应用。1. 构建和运行我们只需点击几下,即可让 Android Studio 设置好要部署至 Android 模拟器或...
  • 修改编译线程,因为使用的虚拟机,所以需要把编译线程数改小;这次是修改为使用8个线程;去掉make clean; diff --git a/build.sh b/build.sh index 6f54eb476b..92c8db8b70 100755 --- a/build.sh +++ b/build.sh ...
  • Unity Android编译与打包环境配置教程 UNITY ANDROID环境的配置有时会成为新人进行移动设备开发的第一个道关卡。 尽管在UNITY HUB中可以一次性配好ANDROID及JDK环境,但是手动设定环境仍是有很大的益处。 一来我们...
  • 配置环境,这个可以参考这个登录后免费查看当前隐藏内容需登录后查看免费已有1.07K人阅读登录后查看编译内核我们用不到那么多…我这里直接这么干了.最好还是配置临时环境变量登录后免费查看当前隐藏内容...
  • 01.反编译apk,得到dex文件,两种方法: 01.01.在线反编译:http://www.javadecompilers.com/apk 01.02.使用apktool反编译:https://ibotpeaches.github.io/Apktool/install/ 反编译后,可能会得到多个dex文件,...
  • 目前反编译安卓apk的软件非常多,但其中有个比较有特色的编译软件IDA,全名AndroidKiller IDA Jeb jadx,想知道这款安卓apk反编译神器怎么使用吗?请看下文。安卓apk反编译软件介绍:作为一个安卓开发人员,反编译...
  • 详解Android源码的编译

    2021-05-26 13:50:27
    在这里我们将介绍的是Android源码的编译,主要基于Android 1.0环境下。希望对大家有所帮助。本文将为大家介绍的是如何设置Android源码的编译环境,包括Linux下的配置。主要基于Android 1.0环境,希望对大家了解...
  • 教程仅针对Android 7.1系统,为便于虚拟机备份和出现问题时的还原,本教程分为3步:初始化编译环境、源码同步、编译源码导入Android Studio。编译源码:Android7.1.2_r1源码。编译环境:VMWare虚拟机、Ubuntu ...
  • Linux系统的安装和Android编译环境的配置亲测Android8.1-Android10.0可用安装Linux系统功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表...
  • WebRTC之Android编译

    2021-04-29 09:03:54
    前言 在前面关于WebRTC的相关学习笔记中,笔者记录的多是一些理论...本文的内容主要来源于官网WebRTC Android Native编译教程 https://webrtc.github.io/webrtc-org/native-code/android/ 编译环境 为了一次性编译成
  • 【萝卜前端打包教程v4.18版】Android Studio安卓前端编译视频教程/AS4.2.3版/最全的原生java打包app教程-紫咖啡小站紫咖啡小站-【萝卜前端打包教程v4.18版】Android Studio安卓前端编译视频教程/AS4.2.3版/最全的...
  • 编译教程

    2021-05-27 09:44:07
    该楼层疑似违规已被系统折叠隐藏此楼查看此楼如何修改信息,联系人,通话记录的2级字体颜色教程(4.1.1和4.1.2)第一个修改信息的字体颜色2级1.反编辑SecMms.apk2.打开res\layout-sw359dp的conversation_list_item.xml3....
  • 在网上搜索Android编译教程,搜出来的文章要么是抄袭的,要么是太过与简单,经过自己的实践和摸索,我在这里记录下如下反编译一个Apk并修改一些资源文件,比如App名字、启动界面等,然后重新打包成apk,你可以参照...
  • Android源码编译

    2021-06-02 19:43:18
    在out/target/product/generic下生成的三个镜像文件:...ramdisk.img是根文件系统,system.img包括了主要的包、库等文件,userdata.img包括了一些用户数据,android加载这3个映像文件后,会把 system和 userdata...
  • 适合人群:Android开发人员、逆向反编译开发人员、以及对Android逆向安全感兴趣的朋友。学习计划:1、建议大家循序渐进学习,课程安排内容由简到难;2、每章都有示例,大家先按照课程完成示例后再学习下一章;3、...
  • #从0开始编译android类原生系统写在文章开头的废话:为什么我要写这篇文章给自己留下笔记,给大家一起进步。为什么原生安卓?原生,即是AOSP,是不包括厂商或运营商定制程序以及任何第三方修改的Android系统...
  • 前言:去广告之前请保证APK包能完美反编译教程开始1、开启神秘功能全局搜索“const-string v1,“KEY_SECRET_UNLOCKED””把const/4 v2, 0x0 改成 const/4 v2,0x12、去除发现页面中的漫画中心、游戏中心搜索...
  • Android.mk编译的写法

    2021-05-28 08:55:07
    一.Android 的简介:1.Android.mk文件首先需要指定LOCAL_PATH变量,用于查找源文件。由于一般情况下Android.mk和需要编译的源文件在同一目录下,...2. Android.mk中可以定义多个编译模块,每个编译模块都是以include...
  • apk反编译教程

    2020-12-29 11:32:01
    apk反编译教程 工具介绍 apktool 最新版 jar 包 作用:资源文件获取,可以提取出图片文件和布局文件进行使用查看 dex2 jar 的zip包 作用:将apk反编译成java源码(classes.dex转化成jar文件) jd-gui 工具 作用:...
  • 总结 到此这篇关于android studio编译jar包或者aar包的方法教程详解的文章就介绍到这了,更多相关android studio编译jar包 aar包内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家...
  • android.mk文件的编译

    2021-06-02 16:31:02
    android编译系统的makefile文件Android.mk写法如下(1)Android.mk文件首先需要指定LOCAL_PATH变量,用于查找源文件。由于一般情况下Android.mk和需要编译的源文件在同一目录下,宏函数“my-dir”右编译系统提供的,...
  • 上一篇我们讲了Ogre3d 在 Window平台的编译流程方法这一篇我们介绍 Ogre3d 编译Android 平台的方法。可以和官方英文教程对照学习。转载自博客 http://blog.csdn.net/huutu QQ:790621656首先下载Ogre3d 依赖库源...
  • 一、Ubuntu的安装(网上很多教程)二、Ubuntu下安装ndk环境(网上很多教程)三、mupdf的源码获取方式:1.MuPdf官网下载,地址: https://mupdf.com/downloads/archive/,选择一个你需要的地址下载,我这里下载的是:mupdf...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 43,825
精华内容 17,530
关键字:

安卓编译教程