3 ms·
> Library .so files are not harder to scan than jar files. Of course they are. You can trivially reverse engineer Java bytecode back to Java, with almost every
by junon 5y ago
> Library .so files are not harder to scan than jar files.
Of course they are. You can trivially reverse engineer Java bytecode back to Java, with almost everything except generic annotations due to erasure, and a few other small things. Tools have been around for ages that do this[0], and while they're not perfect, they can re-generate nearly perfectly compilable source code.
.so files are ELF files, which means while they have sections, those sections don't typically reveal much about the internals of the code. This means you need to convert machine code (assembly) back to a higher level language - which is not a trivial transformation. There are tools that do do this (e.g. hexrays[1]) but they are far from perfect, especially for optimized machine code.
Java systems are very, very easy to crack, RE and patch. There are virtually no protections. JAR injection is still a valid means of patching a Java application. No, manifest files and integrity checks are not a security measure but an error detection measure, and are trivially bypassed.
If you asked me to choose between patching this vulnerability in a .JAR vs a .SO, I would choose the .JAR any day of the week.
[0] http://java-decompiler.github.io/ http://java-decompiler.github.io/
[1] https://hex-rays.com/ https://hex-rays.com/
- ncmncm 5y agoYou do not need to decompile any code to scan a .so for symbols used. So, more advocacy BS.
- junon 5y agoPlease re-read my original comment. If the binary is stripped, no internal symbols would have been visible or even present in the file to be scanned. The jumps between subroutines happen directly, without a symbol jump table (because a jump table adds runtime overhead and is largely unnecessary, especially in statically linked executables).
- ncmncm 5y agoYou do not need internal symbols. All the public entry points are spelled out exactly by name, and all the external symbol dependencies.
- junon 5y agoI addressed the point about symbol tables, and that's assuming the vulnerable code was pulled in via an external dependency or exported directly (flat function/subroutine) from an .SO. That also assumes that the binary wasn't linked statically - in which case, there are no external symbols to even look for. Lastly, please stop calling someone educating you "BS".
- ncmncm 5y agoYou instead wholly failed to address the point about symbol tables.
- junon 5y agoSymbol table patching doesn't do anything if the functionality is internal... Do you know how programs are linked?
- nitrogen 5y agoWe're all on the same team here, there's no need for this hostility back and forth. Binary patching, JAR patching, disassembly, library interception, syscall interception, whatever, these are all tools that are on the table. You do what it takes to get the job done, knowing and weighing the pros and cons.
- ncmncm 5y agoDo you? Have you, e.g., written a linker? Educating is an entirely different process than you are engaged in.
- derefr 5y ago> This means you need to convert machine code (assembly) back to a higher level language ...why? You don't need code to be in an HLL representation in order to patch it. Where by "patching" I mean "automatic insertion of a JMP into the subroutine prologue, that branches to your replacement code." You don't even need to write any assembly in order to do that, either; you can write your replacement subroutine in C or whatever. The replacement subroutine just needs to codegen as a C-ABI subroutine with the same register preconditions/postconditions as the subroutine it's replacing.
- junon 5y agoYou don't need to, you're right. But people aren't going to be writing very complex mitigations by reverse engineering the bytecode generated by a compiler, especially for OSS. There are many compilers, many optimizations, and some of them can even produce non-deterministic outputs (not common but it can happen). The amount of patching for an internal subroutine, which is probably what would have resulted here, would have been completely practically infeasible.