Skip to content

Fix String.getBytes: honour the charset (was UTF-16LE unconditionally) - #1

Open
monperrus wants to merge 1 commit into
fatalSec:mainfrom
monperrus:fix/string-getbytes-charset
Open

monperrus wants to merge 1 commit into
fatalSec:mainfrom
monperrus:fix/string-getbytes-charset

Conversation

@monperrus

Copy link
Copy Markdown

String.getBytes() / getBytes(charset) in _builtin_virtual_hooks encoded UTF-16LE unconditionally, ignoring the requested charset.

Java's default charset on Android is UTF-8, and getBytes("UTF-8") is the common case in the obfuscated string/crypto code this VM is used to analyse. Encoding UTF-16LE returned twice as many bytes, so every downstream digest, cipher, or Base64 over the result was wrong — e.g. "hi".getBytes("UTF-8") returned [0x68,0x00,0x69,0x00] instead of [0x68,0x69].

Fix: honour the charset argument when present (normalising e.g. UTF_8utf-8), default to UTF-8, fall back to UTF-8 on an unknown charset, and keep the existing surrogatepass handling. One hook, no API change.

Found while using DaliVM to recover strings from a real APK; happy to adjust naming/comments.

String.getBytes() and getBytes(charset) both encoded UTF-16LE regardless
of the requested charset. Java's default on Android is UTF-8, and
getBytes("UTF-8") is the common case in the obfuscated string/crypto code
this VM is used to analyse. Encoding UTF-16LE returned twice as many
bytes, so every downstream digest, cipher, or Base64 over the result was
wrong.

Honour the charset argument when present and default to UTF-8; keep the
surrogatepass handling. Example: "hi".getBytes("UTF-8") now yields
[0x68,0x69] instead of [0x68,0x00,0x69,0x00].

Co-Authored-By: Martin Monperrus (AI-assisted) <martin.monperrus+ai@gnieh.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant