You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/mobile-pentesting/android-app-pentesting/reversing-native-libraries.md
+157-4Lines changed: 157 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -130,19 +130,172 @@ When you spot *third-party* `.so` files inside an APK, always cross-check their
130
130
131
131
---
132
132
133
-
### Resources
133
+
### Neutralizing early native initializers (.init_array) and JNI_OnLoad for early instrumentation (ARM64 ELF)
134
+
135
+
Highly protected apps often place root/emulator/debug checks in native constructors that run extremely early via `.init_array`, before `JNI_OnLoad` and long before any Java code executes. You can make those implicit initializers explicit and regain control by:
136
+
- Removing `INIT_ARRAY`/`INIT_ARRAYSZ` from the DYNAMIC table so the loader does not auto-execute `.init_array` entries.
137
+
- Resolving the constructor address from RELATIVE relocations and exporting it as a regular function symbol (e.g., `INIT0`).
138
+
- Renaming `JNI_OnLoad` to `JNI_OnLoad0` to prevent ART from calling it implicitly.
139
+
140
+
Why this works on Android/arm64
141
+
- On AArch64, `.init_array` entries are often populated at load time by `R_AARCH64_RELATIVE` relocations whose addend is the target function address inside `.text`.
142
+
- The bytes of `.init_array` may look empty statically; the dynamic linker writes the resolved address during relocation processing.
143
+
144
+
Identify the constructor target
145
+
- Use the Android NDK toolchain for accurate ELF parsing on AArch64:
146
+
```bash
147
+
# Adjust paths to your NDK; use the aarch64-linux-android-* variants
148
+
readelf -W -a ./libnativestaticinit.so | grep -n "INIT_ARRAY" -C 4
149
+
readelf -W --relocs ./libnativestaticinit.so
150
+
```
151
+
- Find the relocation that lands inside the `.init_array` virtual address range; the `addend` of that `R_AARCH64_RELATIVE` is the constructor (e.g., `0xA34`, `0x954`).
152
+
- Disassemble around that address to sanity check:
153
+
```bash
154
+
objdump -D ./libnativestaticinit.so --start-address=0xA34 | head -n 40
155
+
```
156
+
157
+
Patch plan
158
+
1) Remove `INIT_ARRAY` and `INIT_ARRAYSZ` DYNAMIC tags. Do not delete sections.
159
+
2) Add a GLOBAL DEFAULT FUNC symbol `INIT0` at the constructor address so it can be called manually.
160
+
3) Rename `JNI_OnLoad` → `JNI_OnLoad0` to stop ART from invoking it implicitly.
# Rename JNI_OnLoad -> JNI_OnLoad0 to block implicit ART init
216
+
j = b.get_symbol('JNI_OnLoad')
217
+
if j:
218
+
j.name ='JNI_OnLoad0'
219
+
220
+
b.write('libnativestaticinit.so.patched')
221
+
```
222
+
</details>
223
+
224
+
Notes and failed approaches (for portability)
225
+
- Zeroing `.init_array` bytes or setting the section length to 0 does not help: the dynamic linker repopulates it via relocations.
226
+
- Setting `INIT_ARRAY`/`INIT_ARRAYSZ` to 0 can break the loader due to inconsistent tags. Clean removal of those DYNAMIC entries is the reliable lever.
227
+
- Deleting the `.init_array` section entirely tends to crash the loader.
228
+
- After patching, function/layout addresses might shift; always recompute the constructor from `.rela.dyn` addends on the patched file if you need to re-run the patch.
229
+
230
+
Bootstrapping a minimal ART/JNI to invoke INIT0 and JNI_OnLoad0
231
+
- Use JNIInvocation to spin up a tiny ART VM context in a standalone binary. Then call `INIT0()` and `JNI_OnLoad0(vm)` manually before any Java code.
232
+
- Include the target APK/classes on the classpath so any `RegisterNatives` finds its Java classes.
233
+
234
+
<details>
235
+
<summary>Minimal harness (CMake and C) to call INIT0 → JNI_OnLoad0 → Java method</summary>
-**Debugging Native Libraries:**[Debug Android Native Libraries Using JEB Decompiler](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3)
138
285
139
286
### References
140
287
288
+
-**Learning ARM Assembly:**[Azeria Labs – ARM Assembly Basics](https://azeria-labs.com/writing-arm-assembly-part-1/)
-**Debugging Native Libraries:**[Debug Android Native Libraries Using JEB Decompiler](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3)
0 commit comments