Summary of packaging process based on quickSDK, U8SDK

Table of contents

1: Decompilation of apktool

1. Use tools

2. Command line

3. Effect display

4. Questions to consider

2: SDK jar to dex

1. Use tools

2. Command line

3. Effect display

4. Questions to consider

3: The process of converting dex to smail

1. Use tools

2. Command line

3. Effect display

4. Questions to consider

4: Merge AndroidManifest, so library, assets, res directory

1. Merge the Android Manifest

2. so library

3. assets file

4. res directory

5: Add icon corner mark, start page, etc.

1. Add icon

2. Start page

3、versionCode和targetSdkVersion

6: Working with R resources

1. Use tools

2. Command line

3. Effect display

4. Questions to consider

7: Subcontracting

8: Compile back

1. Use tools

2. Command line

3. Effect display

4. Questions to consider

9: Signature

1. Use tools

2. Command line

3. Effect display

4. Questions to consider

10: Optimization

1. Use tools

2. Command line

11: Reinforcement and Shelling

12: Fanwai (multi-threaded attempt):

3-thread 3-channel package:

Main thread single channel:

Summarize


foreword

Decompilation and packaging: decompilation of the parent package, loading and merging of the channel SDK, recompilation of the channel package, signature...

First look at a flow chart to understand some phased issues of decompilation and packaging mode

1: Decompilation of apktool

1. Use tools

apktool.jar

Download link: iBotPeaches / Apktool / Downloads — Bitbucket

2. Command line

java -jar -Xms512m -Xmx512m apktool_2.6.0.jar -q d -b -f xxx.apk -o targetdir     

3. Effect display

Directory of simple packages (normal de-merge)

A directory containing koltin and multiple smali packages (the parent package contains multiple smails, which need to be copied to the first one, which is convenient for calculation and merging when subcontracting)

4. Questions to consider

1. It is necessary to consider the size of the mother package and the cost of decompilation. This stage consumes more CPU

2. It is necessary to consider the directory structure of the parent package to facilitate the calculation of subsequent subcontracts

3. If there are only changes to the AndroidManifest, such as the version number, permissions, package name, etc., you can manually change the file and then compile it back. It is recommended to process it with a script.

2: SDK jar to dex

1. Use tools

#--------dx tools --------- or

The directory where dx.bat is located: android-sdk\build-tools\28.0.2\dx.bat

The directory where dx.jar is located: android-sdk\build-tools\28.0.2\lib\dx.jar

#--------d8tools---------

The directory where d8.bat is located: android-sdk\build-tools\28.0.2\d8.bat

The directory where d8.jar is located: android-sdk\build-tools\28.0.2\lib\d8.jar

2. Command line

dx

dx.bat --dex --output=dstDir + "/classes.dex" sdk1.jar sdk2 ...

dx.bat --dex --min-sdk-version=26 --output=dstDir + "/classes.dex" sdk1.jar ...

d8

d8.bat --lib android.jar --output dstDir sdk1.jar ...

3. Effect display

4. Questions to consider

1. The dx tool does not support lambda, and desugaring requires --min-sdk-version=26 of d8 or dx

2. If you use d8, shield the warning log in d8.jar to reduce the output of the command line

3. If the channel provides the aar version, you need to decompose the aar, and then convert the dex file

3: The process of converting dex to smail

1. Use tools

baksmali.jar

Download address: JesusFreke / smali / Downloads — Bitbucket

2. Command line

java -jar baksmali.jar -o targetdir dexFile

3. Effect display

 In this way, the smali of the SDK can be merged into the parent package directory, and then the resource files are processed.

4. Questions to consider

1. It is necessary to consider the conflict problem of merging the SDK directory into the parent package ( the script will be overwritten directly, but there is no problem with packaging now, and I am not sure if there will be any in the future. It is a potential risk. The sdk version integrated by the game party is 1.0.0, the sdk used by the channel is 1.1.0, because the third-party sdk is different, it is best that the higher version is compatible with the lower version. At present, the script is the channel coverage master package. If the SDK in the channel is a higher version, it may be compatible , if the channel is low and the parent package is high, new features and functions will definitely be lost after overwriting. You can choose not to overwrite, or strip off the channel SDK conflicting SDK, you need to be familiar with the smail directory structure )

2. Understand smail syntax

3. For different games, if WeChat payment is integrated, but the callback cannot be received, you need to replace the package name in the WXPayEntryActivity.smail file, so that after compiling, the WeChat callback class will appear under the apk package name path.

4: Merge AndroidManifest, so library, assets, res directory

1. Merge the Android Manifest

This process is not difficult, after all, you can get the decompiled AndroidManifest. What needs to be considered is the modification of packagename, meta tags, launchMode , etc., and the existing tags during the merge process, and the xml.etree.cElementTree library needs to be used. You can refer to the blog of modifying AndroidManifest.xml_sunbofiy23 with python - CSDN blog

2. so library

Because the cpu architecture supported by each game is different, and most channels require mobile games to support 64-bit, so the merger of the so library needs to be adapted to armeabi-v7a|arm64-v8a

3. assets file

There is nothing to say about this, mainly the writing of some special parameters, such as the appid, appkey, etc. generated by the game in the channel

4. res directory

Directly copy the sdk res to the parent package res to prepare for the subsequent regeneration of R.java.

5: Add icon corner mark, start page, etc.

1. Add icon

The processing idea is: get the icon corner mark provided by the channel, use the image of the PIL library, paste the corner mark png and the game png, because the drawable and mipmap directories will be compiled with -v4, so the pasted png will be placed Go to the -v4 directory . As for whether to put it in mipmap-v4 or drawable-v4, it needs to be confirmed in combination with AndroidManifest. Different developers provide different parent packages and different usage specifications. In theory, mipmap

2. Start page

The idea of ​​​​this process is roughly: if it is necessary to add a channel for the startup page,

1. Prepare the xml layout and merge the xx.png to be loaded into the layout and drawable directories of the parent package

2、removeGameLaunchActivity

Start the activity of the parent package   

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

intent-filter remove

3. Write the SplashActivity prepared by yourself into the parent package AndroidManifest. The reference code is as follows:

def appendSplashActivity(decompileDir, splashType):
    manifestFile = decompileDir + "/AndroidManifest.xml"
    manifestFile = file_utils.getFullPath(manifestFile)
    ET.register_namespace('android', androidNS)
    key = '{' + androidNS + '}name'
    screenkey = '{' + androidNS + '}screenOrientation'
    theme = '{' + androidNS + '}theme'
    lanchLoad = '{' + androidNS + '}launchMode'
    configChanges = '{' + androidNS + '}configChanges'
    tree = ET.parse(manifestFile)
    root = tree.getroot()

    applicationNode = root.find('application')
    if applicationNode is None:
        return

    splashNode = SubElement(applicationNode, 'activity')
    splashNode.set(key, 'com.lhcit.game.api.activity.GameSplashActivity')
    splashNode.set(theme, '@android:style/Theme.Black.NoTitleBar.Fullscreen')

    if splashType[:1] == '1':
        splashNode.set(screenkey, 'landscape')
    else:
        splashNode.set(screenkey, 'portrait')
        
    splashNode.set(lanchLoad,"singleTop")
    splashNode.set(configChanges,"orientation|screenSize|keyboardHidden")

    intentNode = SubElement(splashNode, 'intent-filter')
    actionNode = SubElement(intentNode, 'action')
    actionNode.set(key, 'android.intent.action.MAIN')
    categoryNode = SubElement(intentNode, 'category')
    categoryNode.set(key, 'android.intent.category.LAUNCHER')
    tree.write(manifestFile, 'UTF-8')

4. Find the smail file and replace the internal jump action. Because when we prepare the Activity GameSplashActivity, in addition to loading xml, there is also a delay to jump to the main game Activity. The path of the intent jump is first declared with a placeholder. After all, each game is inconsistent, so when packaging, It is also necessary to replace the placeholder by the full path of the package name + the activity of the game.

3、versionCode和targetSdkVersion

In the process of channel package submission, some channels will have requirements for targetSdkVersion. For example, the UC requirement is lower than 26, the xx channel is lower than 28, and the parent package may be 30+. If we manually process it, we need to prepare multiple different versions of the parent package. Package, this way the efficiency will be very low. Therefore, the apktool.yml file can be obtained after decompilation , and we can modify and replace the text through the script. The scenarios and requirements of versionCode are similar. 

6: Working with R resources

The R resource processing logic here is: After merging the res of the Sdk into the res directory of the parent package, use the aapt tool to regenerate the R.java file. Then compile R.java into a class file through javac, convert the class file into dex, convert dex into smail, and merge it into the parent package .

1. Use tools

aapt.exe

The directory where aapt is located: android-sdk\build-tools\28.0.2\aapt.exe

javac

The directory where javac is located: jdk\bin\javac.exe

After getting the R.class, carry out the conversion process of dx and baksmail, and finally merge it into the parent package.

2. Command line

aapt p -f -m -J targetdir -S sourcedir -I android.jar -M AndroidManifest.xml

Need to rely on android.jar, and the merged AndroidManifest file, pay attention to capitalization. The generated R file is generated based on the application package name. If there is an R path in the SDK, you need to copy the application R. There is also an R file in the smali below to prevent the SDK resources from being found during runtime. The solution here is to adapt to multiple package names , refer to question 4-1

3. Effect display

4. Questions to consider

1. The third-party SDK directly references resources through R... This way, it cannot be found at runtime, and multiple package names need to be adapted

U8SDK——Generate R.java under the name of multiple packages (a common pitfall encountered in overseas SDK access)

2. aapt merges the package compiled by aapt2, the resource.arsc file cannot start with attr

Based on U8SDK Android packaging and decompilation, recompiling error records_u8sdk github_sunbofiy23's blog-CSDN Blog

3. After decompiling the global custom label of the parent package and turning it into a local label, the resource cannot be found. Need to deal with channel and parent package R$styleable.smali, please refer to blog

U8SDK——Merge of declare-styleable custom resources

7: Subcontracting

If the R resource is ok, the following is the Android 65536 problem limited by Google (the number of Java method references in the Android Dalvik executable file .dex exceeds 65536)

The processing idea is to calculate the number of smail methods first, so how to calculate more accurately? We first traverse the entire smail directory, and then read the text. Here we need to use the smail syntax. In the smail file, the method starts with .method and ends with invoke-, so we can count by this rule .

When it exceeds 65536, we divide a smail directory into multiple smail_classes, so that when recompiling, a single smail will not exceed 6553.

Question: When the parent package already contains multiple smail directories, how to calculate accurately and complete the subpackage? The processing idea here: After decompiling, you can merge more smails into the first one. As long as you don’t recompile, there is no 65536 problem. In this way, the first smail directory must be very large, and then go to the subpackage stage , using method counting, repackaging.

8: Compile back

1. Use tools

 apktool.jar

Download link: iBotPeaches / Apktool / Downloads — Bitbucket

2. Command line

java -jar -Xms512m -Xms512m apktool_2.6.0.jar -q b -f decompile -o output/r.apk

3. Effect display

 

4. Questions to consider

1. Comparing CPU performance

2.Could not smali file: There are some lamdba expressions, and the smail syntax cannot be recognized. During the process of converting dex to smail, avoid using the dx tool. Android already supports d8 syntax desugaring

3. Sometimes due to inaccurate subcontracting, the compilation will exceed 65536. The solution is to reduce the subcontracting threshold. Try not to get too close to 65536 for each smail directory

9: Signature

1. Use tools

jarsigner.exe

Directory: jdk\bin\jarsigner.exe

apksigner.jar

Directory: build-tools\27.0.3\lib\apksigner

2. Command line

1. View the signature information of the apk

jarsigner.exe -verify -verbose -certs xx.apk

2. View the signature information of the jsk or keystore file

keytool -v -list -keystore xx.keystore

3. Sign the apk with v1

jarsigner -keystore xx.keystore -storepass xx -keypass xaliaspwd xx.apk alias -sigalg SHA256withRSA -digestalg SHA-256

4. Sign the apk with v2

java -jar apksigner.jar sign -verbose --ks xx.keystore --ks-pass pass:xx --ks-key-alias xx.keystore --key-pass pass:xx --out output.apk source.apk

3. Effect display

1. View the signature information of the apk

 2. Sign the apk with v1

  2. Sign the apk with v2

It is obvious that the signing time has been shortened.

4. Questions to consider

1. jarsigner signature tool SHA1 algorithm warning

Using jarsigner tool apk signature algorithm problem_Using sha1withrsa algorithm risk_sunbofiy23's blog-CSDN blog

2. After jarsigner is replaced by apksigner, the signature efficiency is improved

Because jarsigner signs each java file, it takes a long time, and apksigner signs the entire file, which takes a short time

3. The apksigner.jar used in the Android7.0 tool supports v2 signatures. If you use 7.0 or above, the default includes v1, v2, and v3 signatures, and select the appropriate signature tool according to the channel requirements.

10: Optimization

When developers upload their apps to Google play, they will probably encounter the failure prompt "Has the APK you uploaded been processed by Zipalign?", which shows that Google attaches great importance to the Zipalign tool .

Zipalign is an optimization tool for archive alignment of all files in the Apk package. Its purpose is to ensure that the uncompressed data in all files is arranged in the specified alignment from the beginning of the file to which it belongs (such as writing data in the top grid) . In particular, the image resources and unprocessed related files in the .apk compressed package are aligned in 4 bytes.

The advantage is that it can reduce the RAM (Random Access Memory) memory resource consumption of the application program and improve the smoothness of the user's use. The special feature in Google's Adnroid development documentation is that you must use the Zipalign tool to optimize your .apk file before releasing the application to end customers.

1. Use tools

zipalign.exe

Directory: android-sdk\build-tools\27.0.3\zipalign.exe

2. Command line

4 means the specified corresponding number of bytes, if it is an integer, it must be specified as 4

zipalign -f 4 xx.apk target.apk

11: Reinforcement and Shelling

Hardening is essentially to pack the dex file, so that some decompilation tools decompile the dex shell instead of the dex file itself. The specific implementation method is to encrypt the original dex file and synthesize it into the dex shell, and when the system runs the application, it will load the dex shell file, and there is a custom ClassLoader class in the dex shell, which will convert the original dex file to decrypt before loading into the dex array. Because the current reinforcement of the project still uses 360's free reinforcement service. I also tried to read the official documents of 360, and also tried to use the command line to strengthen. The free version is not supported.

Here is a 360 command line reinforcement document:

360Tianyu - One-stop service platform for enterprise mobile application security

And fees and support services:

360Tianyu - One-stop service platform for enterprise mobile application security

Later, I also tried to download the 360 ​​reinforcement service. The effect is shown in the figure. The free version supports the client, but does not support the command line.

The essence of unpacking is to crack the reinforcement. The common method is memory dump, and some hook frameworks are used on the market, such as frida. For the introduction of frida, you can learn about python+camille+frida from another blog of mine  , and realize the stack analysis of apk privacy information_sunbofiy23's blog-CSDN blog

And use frida to unpack, you can refer to

https://github.com/GuoQiang1993/Frida-Apk-Unpack

12: Fanwai (multi-threaded attempt):

I also tried to enable multi-threaded packaging, but after experimenting, I found that the decompilation of a single-threaded channel package took 100s, and after multi-threading was enabled, such as 3 threads, it became 300s. Then analyze the reason, it may be the packaging tool, the packaging process has turned on multi-threading, because decompilation, recompilation, and subpackaging stages, a large number of copies and jres are designed, and there is only one native jdk, which doubles the time consumption. I also considered that because of the same parent package, it only needs to be decompiled once, but there is no way to solve the stages of recompiling and subpackaging at once. After all, it is the work of multi-channel packages, so cluster development can be solved, but cluster-related knowledge, I don't know much about it, or the cost of clustering is too high for small companies to afford. Therefore, multi-channel thread optimization has a long way to go.

3-thread 3-channel package:

Decompilation takes about 380s

It takes about 203s to compile back

 Subcontracting takes about 477s

Main thread single channel:

Decompilation takes 93s

Subcontracting takes 130s

It takes about 180s to compile back 

Summarize

Some channels or the Ministry of Industry and Information Technology will require the apk to be reinforced. Theoretically, after the signature is completed, there will be an apk reinforcement stage. At that time, we used 360, a third-party solution from Tencent Legu. In fact, there are some self-developed reinforcement methods

When I first came into contact with this packaging method, there were really too many pitfalls. I solved it a little bit later, and then summarized it, including tool upgrades, and gradually supported general configuration to multi-channel packaging, log management, and efficiency improvement at each stage. Improve and more. In short, with a little analysis and then trying, even the biggest problems will be solved.

Guess you like

Origin blog.csdn.net/qq_34123324/article/details/131328165