[GH-ISSUE #3489] [Feature] inspect_android_class: report method access flags (native, abstract, static, synthetic, bridge) #1301

Open
opened 2026-10-16 21:03:56 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @Rinkia on GitHub (Oct 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/3489

Before submitting

  • I searched the open and closed issues and pull requests for a related proposal.
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This request does not include credentials, private samples, or sensitive target data.

Area

Native analysis or decompilation

Current limitation

inspect_android_class method entries carry name, reported_signature, overload_index, is_constructor and dex_descriptor (the descriptor was added on main by #2439). They carry no access flags, so a caller can't tell which methods are native (the JNI entry points into bundled .so libraries), abstract, static, synthetic or bridge without decompiling each one.

Decompiling each method isn't a reliable substitute:

  • A native method can return another member's code as its "complete" body (#3488).
  • An inlined ordinary method is reported as "native/abstract" (#3443).
  • The placeholder text itself can't tell native from abstract.

Example: in F-Droid de.markusfisch.android.binaryeye vc 180, class de.markusfisch.android.zxingcpp.ZxingCpp has 33 listed methods. Seven are native and match Java_* exports in libzxingcpp_android.so. I could only find them by decompiling methods one by one and reading the first line.

Use cases

  • Find every JNI entry point in an APK before opening native libraries in Ghidra.
  • Interpret inspect_android_method results correctly: a native or abstract flag explains an empty body, while a concrete method with an empty body points to inlining (#3443) or a decompile failure.
  • Spot compiler-generated synthetic and bridge methods (lambdas, Kotlin $default helpers) quickly.

Desired outcome and success criteria

  • Each method entry includes its DEX access flags, either as a raw access_flags integer plus decoded booleans, or as a list of decoded flag names.
  • inspect_android_method uses the same flags to set a specific unavailable reason (native, abstract) in place of the combined placeholder.
  • Success: for the class above, the seven native methods are identifiable from inspect_android_class alone.

Expected interaction with targets

Read existing files or captured data.

Verification available so far

I can suggest a sample or manual check.

Verification details

  • rea-agents@6.4.0: inspect-android-class /targets/binaryeye.apk de.markusfisch.android.zxingcpp.ZxingCpp returns 33 methods with no flag fields.
  • Source check on main: src/android/JadxProtocol.ts and src/android/JadxAnalysis.ts map is_constructor and descriptor fields but no access flags.
  • Manual check: compare the reported flags with ACC_NATIVE (0x100) in the DEX for readYBuffer(Ljava/nio/ByteBuffer;IIIIIILde/markusfisch/android/zxingcpp/ZxingCpp$ReaderOptions;)Ljava/util/List;.

Alternatives considered

  • Decompiling every method and parsing modifiers from the first line: slow, and unreliable as shown above.
  • Searching the .so for Java_* exports: this finds the native side only, and misses RegisterNatives-bound methods.

Possible direction

JADX's MethodNode/AccessInfo already exposes these flags. The REA bridge could add them to the class summary it returns.

References

  • #3443, #2439, #1846
  • src/android/JadxProtocol.ts, src/android/JadxAnalysis.ts, bridge/android/ReaJadxBridge.java
Originally created by @Rinkia on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3489 ### Before submitting - [x] I searched the open and closed issues and pull requests for a related proposal. - [x] I understand the contribution scope must be reviewed before integration; open questions are welcome here. - [x] This request does not include credentials, private samples, or sensitive target data. ### Area Native analysis or decompilation ### Current limitation `inspect_android_class` method entries carry `name`, `reported_signature`, `overload_index`, `is_constructor` and `dex_descriptor` (the descriptor was added on `main` by #2439). They carry no access flags, so a caller can't tell which methods are `native` (the JNI entry points into bundled `.so` libraries), `abstract`, `static`, `synthetic` or `bridge` without decompiling each one. Decompiling each method isn't a reliable substitute: - A native method can return another member's code as its "complete" body (#3488). - An inlined ordinary method is reported as "native/abstract" (#3443). - The placeholder text itself can't tell native from abstract. Example: in F-Droid `de.markusfisch.android.binaryeye` vc 180, class `de.markusfisch.android.zxingcpp.ZxingCpp` has 33 listed methods. Seven are native and match `Java_*` exports in `libzxingcpp_android.so`. I could only find them by decompiling methods one by one and reading the first line. ### Use cases - Find every JNI entry point in an APK before opening native libraries in Ghidra. - Interpret `inspect_android_method` results correctly: a `native` or `abstract` flag explains an empty body, while a concrete method with an empty body points to inlining (#3443) or a decompile failure. - Spot compiler-generated `synthetic` and `bridge` methods (lambdas, Kotlin `$default` helpers) quickly. ### Desired outcome and success criteria - Each method entry includes its DEX access flags, either as a raw `access_flags` integer plus decoded booleans, or as a list of decoded flag names. - `inspect_android_method` uses the same flags to set a specific unavailable reason (`native`, `abstract`) in place of the combined placeholder. - Success: for the class above, the seven native methods are identifiable from `inspect_android_class` alone. ### Expected interaction with targets Read existing files or captured data. ### Verification available so far I can suggest a sample or manual check. ### Verification details - `rea-agents@6.4.0`: `inspect-android-class /targets/binaryeye.apk de.markusfisch.android.zxingcpp.ZxingCpp` returns 33 methods with no flag fields. - Source check on `main`: `src/android/JadxProtocol.ts` and `src/android/JadxAnalysis.ts` map `is_constructor` and descriptor fields but no access flags. - Manual check: compare the reported flags with `ACC_NATIVE` (0x100) in the DEX for `readYBuffer(Ljava/nio/ByteBuffer;IIIIIILde/markusfisch/android/zxingcpp/ZxingCpp$ReaderOptions;)Ljava/util/List;`. ### Alternatives considered - Decompiling every method and parsing modifiers from the first line: slow, and unreliable as shown above. - Searching the `.so` for `Java_*` exports: this finds the native side only, and misses `RegisterNatives`-bound methods. ### Possible direction JADX's `MethodNode`/`AccessInfo` already exposes these flags. The REA bridge could add them to the class summary it returns. ### References - #3443, #2439, #1846 - `src/android/JadxProtocol.ts`, `src/android/JadxAnalysis.ts`, `bridge/android/ReaJadxBridge.java`
Author
Owner

@daniyyell-dev commented on GitHub (Oct 14, 2026):

I would like to work on this one, I plan to preserve raw method access flags from the JADX snapshot, expose them with decoded flags through the existing class-summary contract, and use the same observations to distinguish native and abstract method-body unavailability. I will add boundary tests and real-JADX fixture coverage. I checked PR #3527; its no-body fix is related, so I will keep that overlap explicit and avoid duplicating its implementation. Please let me know if someone is already working on this or if you prefer a narrower contract.

<!-- gh-comment-id:6173850451 --> @daniyyell-dev commented on GitHub (Oct 14, 2026): I would like to work on this one, I plan to preserve raw method access flags from the JADX snapshot, expose them with decoded flags through the existing class-summary contract, and use the same observations to distinguish native and abstract method-body unavailability. I will add boundary tests and real-JADX fixture coverage. I checked PR #3527; its no-body fix is related, so I will keep that overlap explicit and avoid duplicating its implementation. Please let me know if someone is already working on this or if you prefer a narrower contract.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1301
No description provided.