Native / Intermediate / 20 min read
REA native analysis: what triggers “File too large”?
Use REA and Ghidra to trace an error string to a native function. Recover the file size check and design boundary tests for a replacement.
On this page
The guard condition, its input units and a test matrix for the exact limit.
You will needA local executable you can inspect and a configured native analysis provider such as Ghidra. The commands below explicitly select Ghidra.
01. Use the error as your entry point
An application refuses a file. Its interface says “File too large”, but does that mean bytes, decoded pixels, compressed size or a service limit? Recover the decision before changing your own implementation.
Choose one exact message from your target. Search the native engine’s analyzed strings. A missing result does not prove the message is absent: it may be localized, encoded, assembled at runtime or stored outside the executable.
npx -y [email protected] search "/absolute/path/program" --pattern="File too large" --kind strings --provider ghidra --format json02. Find the function that uses the string
Take the address from the search result and inspect its references. A reference may point to a general error-display helper rather than the actual guard. Follow the caller until you find the branch deciding whether to report the error.
The placeholders below must be replaced with addresses returned for your binary. Addresses from another build are not interchangeable.
npx -y [email protected] xrefs "/absolute/path/program" --address="RETURNED_STRING_ADDRESS" --provider ghidra --format json
npx -y [email protected] decompile "/absolute/path/program" --procedure="RETURNED_FUNCTION_ADDRESS" --provider ghidra --format json03. Recover the comparison, including its units
Identify both sides of the comparison. Follow where the size value comes from, whether arithmetic happens before the comparison, and whether the branch uses greater-than or greater-than-or-equal. Those details decide the edge case.
Treat decompiled names and types as working hypotheses. If the result is incomplete, inspect the selected function’s instructions and callees. Signedness, integer width and conversion order can change the result even when the pseudocode looks simple.
Use the returned function evidence to explain the branch that emits this error. Trace the compared value back to its input. Identify the threshold, units, signedness and exact comparison. If decompilation is incomplete, inspect instructions and the relevant helper. Cite addresses and mark unresolved types instead of guessing.04. Probe the boundary, not just a happy path
If the recovered rule uses a threshold L, test L−1, L and L+1 in the input’s actual units. Also test zero and malformed input where the application accepts it. Run these only in your controlled copy of the program.
For a file-size guard, record file bytes and the observed outcome. For a decoded-image guard, varying file bytes alone may not exercise the relevant condition. Compare the same input with your replacement and save mismatches.
- L−1: accepted or rejected?
- L: does equality pass?
- L+1: which error is returned?
- Does malformed input fail earlier in a different branch?
05. Keep the conclusion the size of the evidence
Your deliverable is one recovered rule and the tests run against it. This workflow has not been executed on a particular target for this article; the error text is a scenario to replace with your own.
For a real example of the same discipline, the REA project documents DX-Ball’s sound-pan function: its report distinguishes 3,205 differential input checks from a separate 63-byte compiler match. Neither claim means the whole game is reconstructed. See the linked official native guide and its case study for that investigation.
Commands checked against REA 6.4.0. Target-specific results depend on your artifact and provider. Read the upstream source and scope →
DX-Ball: original function checks and compiler-match report →
New to the tool? What is REA? · How we check our guides