verify-16k-page-align 0.0.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) since 2021 @hebertcisco
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # verify-16k-page-align
2
+
3
+ [![npm version](https://img.shields.io/npm/v/verify-16k-page-align.svg)](https://www.npmjs.com/package/verify-16k-page-align)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE.md)
5
+ [![Linux Only](https://img.shields.io/badge/platform-linux-lightgrey)](#platform-support)
6
+
7
+ A shell script and npm package to verify if your Android APK/AAB native libraries are aligned to 16KB (0x4000) memory pages. This is required for compatibility with Android 15+ devices and Google Play submissions after **November 1, 2025** ([see official docs](https://developer.android.com/guide/practices/page-sizes?hl=pt-br)).
8
+
9
+ ---
10
+
11
+ ## Features
12
+
13
+ - Checks all native `.so` libraries in APK/AAB for 16KB page alignment
14
+ - Works with both APK and AAB files
15
+ - Uses `readelf` or `llvm-readelf` (auto-detects)
16
+ - Fast, zero dependencies (besides unzip/readelf)
17
+ - CLI and npm global install
18
+ - Clear pass/fail output for CI/CD
19
+
20
+ ---
21
+
22
+ ## Why 16KB Page Alignment?
23
+
24
+ Starting with Android 15, many devices will use 16KB memory pages for improved performance and reliability. All apps targeting Android 15+ and distributed via Google Play **must** ensure their native libraries (`.so` files) are 16KB aligned. See:
25
+ - [Android Developers: 16 KB Page Size](https://developer.android.com/guide/practices/page-sizes?hl=pt-br)
26
+ - [Google Play Blog: Prepare for 16 KB page size](https://android-developers.googleblog.com/2025/05/prepare-play-apps-for-devices-with-16kb-page-size.html)
27
+ - [Medium: Android 15 Mandatory 16KB Memory Page Size](https://devharshmittal.medium.com/android-15-is-raising-the-bar-mandatory-16kb-memory-page-size-what-developers-need-to-know-4dd81ec58f67)
28
+ - [Reddit discussion](https://www.reddit.com/r/brdev/comments/1nl3fx4/android_15_seus_apps_j%C3%A1_est%C3%A3o_prontos_para_16kb/)
29
+
30
+ **Benefits:**
31
+ - Faster app launches (3–30% improvement)
32
+ - Lower battery usage
33
+ - Reduced memory fragmentation
34
+ - Required for Play Store submission (from Nov 2025)
35
+
36
+ ---
37
+
38
+ ## Installation
39
+
40
+ ### Shell script (one-liner)
41
+ ```sh
42
+ sh -c "$(curl -fsSL https://raw.githubusercontent.com/hotbrainstech/verify-16k-page-align/main/src/verify-16k-page-align.sh)"
43
+ ```
44
+
45
+ ### NPM global install
46
+ ```sh
47
+ sudo npm i -g verify-16k-page-align
48
+ ```
49
+
50
+ ---
51
+
52
+ ## Usage
53
+
54
+
55
+ ### Check an APK or AAB file
56
+ By default, only `arm64-v8a` libraries are checked. To also check `x86_64` libraries, add `x86` as a second argument.
57
+
58
+ ```sh
59
+ # Default: check arm64-v8a only
60
+ verify-16k-page-align <path-to-apk-or-aab>
61
+
62
+ # Check arm64-v8a and x86_64
63
+ verify-16k-page-align <path-to-apk-or-aab> x86
64
+ ```
65
+
66
+ Or, if using the raw script:
67
+ ```sh
68
+ # Default: check arm64-v8a only
69
+ sh ./src/verify-16k-page-align.sh <path-to-apk-or-aab>
70
+
71
+ # Check arm64-v8a and x86_64
72
+ sh ./src/verify-16k-page-align.sh <path-to-apk-or-aab> x86
73
+ ```
74
+
75
+ Or, make the script executable and run directly:
76
+ ```sh
77
+ chmod +x ./src/verify-16k-page-align.sh
78
+ # Default: check arm64-v8a only
79
+ ./src/verify-16k-page-align.sh <path-to-apk-or-aab>
80
+ # Check arm64-v8a and x86_64
81
+ ./src/verify-16k-page-align.sh <path-to-apk-or-aab> x86
82
+ ```
83
+
84
+ #### Example output
85
+ ```
86
+ Using readelf: /usr/bin/readelf
87
+ Inspecting: app-release.apk
88
+ Found 3 native libraries
89
+ [OK] lib/arm64-v8a/libfoo.so aligned to 16KB (no 0x1000 LOAD segments detected).
90
+ [FAIL] lib/arm64-v8a/libbar.so has LOAD segment aligned to 0x1000 (4KB).
91
+
92
+ One or more native libraries are not 16KB aligned.
93
+ Ensure AGP >= 8.5.1, NDK r27+, and rebuild any third-party .so with 16KB page alignment.
94
+ ```
95
+
96
+ #### CI/CD Example
97
+ Add to your pipeline to fail builds if any library is not 16KB aligned.
98
+
99
+ ---
100
+
101
+ ## How It Works
102
+
103
+ 1. Extracts all `.so` files from your APK/AAB
104
+ 2. Uses `readelf` or `llvm-readelf` to inspect ELF program headers
105
+ 3. Flags any library with a LOAD segment aligned to 4KB (0x1000)
106
+ 4. Passes if all LOAD segments are aligned to 16KB (0x4000)
107
+
108
+ ---
109
+
110
+ ## Platform Support
111
+
112
+ - Linux only (uses bash, unzip, readelf)
113
+ - Not supported on Windows or macOS
114
+
115
+ ---
116
+
117
+ ## Requirements
118
+
119
+ - unzip
120
+ - readelf or llvm-readelf (from binutils or Android NDK)
121
+
122
+ ---
123
+
124
+ ## Migration Guide
125
+
126
+ If your app or any dependency uses native code:
127
+ - **Update your build tools:** Use Android Gradle Plugin (AGP) >= 8.5.1 and NDK r27+ (prefer r28+)
128
+ - **Recompile all native libraries** with 16KB alignment
129
+ - **Remove hardcoded page size assumptions** (replace `4096`/`0x1000`/`PAGE_SIZE` with `sysconf(_SC_PAGESIZE)`)
130
+ - **Check all third-party .so files** for compliance
131
+ - **Test on Android 15+ emulators or real devices**
132
+
133
+ See [official migration steps](https://developer.android.com/guide/practices/page-sizes?hl=pt-br#compile-16-kb-alignment) and [Medium migration guide](https://devharshmittal.medium.com/android-15-is-raising-the-bar-mandatory-16kb-memory-page-size-what-developers-need-to-know-4dd81ec58f67).
134
+
135
+ ---
136
+
137
+ ## Troubleshooting
138
+
139
+ - If you see `[FAIL] ... has LOAD segment aligned to 0x1000 (4KB)`, update and rebuild the affected library.
140
+ - For AGP < 8.5.1, use `packagingOptions.jniLibs.useLegacyPackaging true` in `build.gradle` (not recommended).
141
+ - For NDK < r27, set linker flags: `-Wl,-z,max-page-size=16384` and `-Wl,-z,common-page-size=16384`.
142
+
143
+ ---
144
+
145
+ ## FAQ
146
+
147
+ **Q: Does this work for Java/Kotlin-only apps?**
148
+ A: No need—Java/Kotlin-only apps do not use native libraries and are already compatible.
149
+
150
+ **Q: What if my library is not 16KB aligned?**
151
+ A: Update your build tools and recompile. Contact third-party vendors for updated .so files.
152
+
153
+ **Q: Can I use this on macOS or Windows?**
154
+ A: No, Linux only. Use a Linux VM or Docker if needed.
155
+
156
+ **Q: Is this required for Play Store submission?**
157
+ A: Yes, for Android 15+ apps after Nov 1, 2025.
158
+
159
+ ---
160
+
161
+ ## 🤝 Contributing
162
+
163
+ Pull requests and issues are welcome! See [GitHub Issues](https://github.com/hotbrainstech/verify-16k-page-align/issues).
164
+
165
+ ---
166
+
167
+ ## References & Further Reading
168
+ - [Android 16KB Page Size Docs](https://developer.android.com/guide/practices/page-sizes?hl=pt-br)
169
+ - [Google Play Blog](https://android-developers.googleblog.com/2025/05/prepare-play-apps-for-devices-with-16kb-page-size.html)
170
+ - [Medium: Migration Guide](https://devharshmittal.medium.com/android-15-is-raising-the-bar-mandatory-16kb-memory-page-size-what-developers-need-to-know-4dd81ec58f67)
171
+ - [Reddit: brdev discussion](https://www.reddit.com/r/brdev/comments/1nl3fx4/android_15_seus_apps_j%C3%A1_est%C3%A3o_prontos_para_16kb/)
172
+
173
+ ## Show your support
174
+
175
+ Give a ⭐️ if this project helps you!
176
+
177
+ Or buy me a coffee 🙌🏾
178
+
179
+ <a href="https://www.buymeacoffee.com/hebertcisco">
180
+ <img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=hebertcisco&button_colour=FFDD00&font_colour=000000&font_family=Inter&outline_colour=000000&coffee_colour=ffffff" />
181
+ </a>
182
+
183
+ ## 📝 License
184
+
185
+ Copyright © 2025 [@hotbrainstech](https://github.com/hotbrainstech).
186
+
187
+ This project is [MIT](LICENSE) licensed.
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "verify-16k-page-align",
3
+ "version": "0.0.1-alpha.1",
4
+ "description": "A simple shell script to verify if a android app is 16k page aligned",
5
+ "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
7
+ "private": false,
8
+ "author": "hotbrainstech",
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "license": "MIT",
13
+ "scripts": {
14
+ "lint": "shellcheck src/verify-16k-page-align.sh",
15
+ "lint:fix": "shellcheck -f gcc -o ./lib/verify-16k-page-align.sh",
16
+ "version": "git add -A src",
17
+ "postversion": "git push && git push --tags"
18
+ },
19
+ "bin": {
20
+ "verify-16k-page-align": "./src/verify-16k-page-align.sh"
21
+ },
22
+ "engines": {
23
+ "node": ">=20.0.0"
24
+ },
25
+ "files": [
26
+ "bin/**/*"
27
+ ],
28
+ "os": [
29
+ "linux",
30
+ "!darwin",
31
+ "!win32"
32
+ ],
33
+ "bundleDependencies": [
34
+ "@types/node"
35
+ ],
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/hotbrainstech/verify-16k-page-align.git"
39
+ },
40
+ "keywords": [
41
+ "android",
42
+ "react-native",
43
+ "npm",
44
+ "module"
45
+ ],
46
+ "bugs": {
47
+ "url": "https://github.com/hotbrainstech/verify-16k-page-align/issues"
48
+ },
49
+ "homepage": "https://github.com/hotbrainstech/verify-16k-page-align#readme",
50
+ "devDependencies": {
51
+ "@types/node": "^24.5.2",
52
+ "concurrently": "^9.2.1"
53
+ }
54
+ }
@@ -0,0 +1,121 @@
1
+ #!/bin/bash
2
+ progname="${0##*/}"
3
+ progname="${progname%.sh}"
4
+
5
+ # usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
6
+
7
+ cleanup_trap() {
8
+ if [ -n "${tmp}" -a -d "${tmp}" ]; then
9
+ rm -rf ${tmp}
10
+ fi
11
+ exit $1
12
+ }
13
+
14
+ usage() {
15
+ echo "Host side script to check the ELF alignment of shared libraries."
16
+ echo "Shared libraries are reported ALIGNED when their ELF regions are"
17
+ echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
18
+ echo
19
+ echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
20
+ }
21
+
22
+
23
+ # Parse arguments
24
+ if [ ${#} -lt 1 ] || [ ${#} -gt 2 ]; then
25
+ usage
26
+ exit
27
+ fi
28
+
29
+ case "${1}" in
30
+ --help|-h|'-?')
31
+ usage
32
+ exit
33
+ ;;
34
+ *)
35
+ dir="${1}"
36
+ ;;
37
+ esac
38
+
39
+ if ! [ -f "${dir}" -o -d "${dir}" ]; then
40
+ echo "Invalid file: ${dir}" >&2
41
+ exit 1
42
+ fi
43
+
44
+ # Set architecture filter
45
+ arch_filter="arm64-v8a"
46
+ if [ ${#} -eq 2 ] && [ "${2}" = "x86" ]; then
47
+ arch_filter="arm64-v8a|x86_64"
48
+ fi
49
+
50
+ if [[ "${dir}" == *.apk ]]; then
51
+ trap 'cleanup_trap' EXIT
52
+
53
+ echo
54
+ echo "Recursively analyzing $dir"
55
+ echo
56
+
57
+ if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
58
+ echo "=== APK zip-alignment ==="
59
+ zipalign -v -c -P 16 4 "${dir}" | egrep "lib/(${arch_filter})|Verification"
60
+ echo "========================="
61
+ else
62
+ echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
63
+ echo " You can install the latest build-tools by running the below command"
64
+ echo " and updating your \$PATH:"
65
+ echo
66
+ echo " sdkmanager \"build-tools;35.0.0-rc3\""
67
+ fi
68
+
69
+ dir_filename=$(basename "${dir}")
70
+ tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
71
+ unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
72
+ dir="${tmp}"
73
+ fi
74
+
75
+ if [[ "${dir}" == *.apex ]]; then
76
+ trap 'cleanup_trap' EXIT
77
+
78
+ echo
79
+ echo "Recursively analyzing $dir"
80
+ echo
81
+
82
+ dir_filename=$(basename "${dir}")
83
+ tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
84
+ deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
85
+ dir="${tmp}"
86
+ fi
87
+
88
+ RED="\e[31m"
89
+ GREEN="\e[32m"
90
+ ENDCOLOR="\e[0m"
91
+
92
+ unaligned_libs=()
93
+
94
+ echo
95
+ echo "=== ELF alignment ==="
96
+
97
+
98
+ matches="$(find "${dir}" -type f | egrep "lib/(${arch_filter})/.*\.so$")"
99
+ IFS=$'\n'
100
+ for match in $matches; do
101
+ # We could recursively call this script or rewrite it to though.
102
+ [[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
103
+ [[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
104
+
105
+ [[ $(file "${match}") == *"ELF"* ]] || continue
106
+
107
+ res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
108
+ if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
109
+ echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
110
+ else
111
+ echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
112
+ unaligned_libs+=("${match}")
113
+ fi
114
+ done
115
+
116
+ if [ ${#unaligned_libs[@]} -gt 0 ]; then
117
+ echo -e "${RED}Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
118
+ elif [ -n "${dir_filename}" ]; then
119
+ echo -e "ELF Verification Successful"
120
+ fi
121
+ echo "====================="