As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I have been working on some Android apps recently and am slightly frustrated that my apps can be reverse engineered. I do obsfucate my code but that can only go so far, a talented developer can easily get around the obsfucation.
Anyway, my question is this, why can Java app's be decompiled ? What part of Java's design allows its app's to be decompiled?
My understanding is that Java apps deploy JIT compilation, so they are only compiled before they are used for efficiency purposes, is this correct ? I would love to know the reason,
thanks!
Anyway, my question is this, why can Java app's be decompiled ?
Any app, in any language, can be decompiled. That should be obvious to anyone with a smattering of programming experience in a compiled programming language.
A compiler takes bytes and creates a different set of bytes that represents the same set of instructions. A decompiler takes bytes and creates a different set of bytes that represents the same set of instructions. The difference is merely in what those bytes are. A compiler takes bytes that are (relatively) human readable and creates bytes that are (relatively) machine readable. A decompiler does the reverse.
How well a given decompiler can do its job, though, depends on the programming language and the implementation of the decompiler itself.
In the case of a language like C, the compiler generates machine instructions for a CPU. Those can be readily decompiled into assembly language, as assembler instructions map fairly closely 1:1 to machine instructions. A sufficiently sophisticated decompiler can emit C as output, though probably not C that would be natural to write. More importantly, the decompiled output will largely use decompiler-generated names for functions and variables, unless the compiled C code has debug symbols, in which case the decompiler might be able to use those.
A language like Java is not significantly different in concept. While Java or Dalvik bytecode is for a VM rather than a CPU, the basic approach is the same. Obfuscation helps to ensure that the minimum number of human-readable symbols exist in the resulting bytecode, to reduce the legibility of any decompiled results. Also, the mapping of VM bytecode to language statements tends to be far closer than the mapping of machine code to C statements, which makes it easier to write a decompiler that gives you closer to Java syntax back (e.g., smali/baksmali).
It is the degree of difficulty in interpreting decompiled machine code that results in recommendations to move license management logic into native code via the NDK, for example. However, that is not to say that the results of a C compiler cannot be decompiled at all.
Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
As I know a java developer, need to let their .java file to become .class, and the .class requires the JVM to convert to native code to execute. Why the Java design in this way? Why don't just as a scripting language, using a interpreter, to interpreter .java file? or why don't just convert it to executable like C? Why need to convert to bytecode? What is the design philosophy behind the java language?
It is for sake of speed and portability at the same time.
All of what I am going to say is to be adapted and moderated depending on the case, but roughly:
If you merely interpret the java file with an interpreter you
would have portability but not speed.
If you have to compile the code for a given processor
architecture you would have speed but not portability.
With the bytecode, you compile the code (into bytecode) for a common
machine that will execute it (the JVM) it is a compromise between
speed and portability.
Why the Java design in this way?
Write once, run everywhere - portability.
Why don't just as a scripting language, using a interpreter, to interpreter .java file?
Performance. Bytecode can be compiled to native code with some aggressive optimizations, not available for normal compilers.
or why don't just convert it to executable like C?
Because different platforms require different executable binaries. Java bytecode is (again) portable.
Why don't just as a scripting language, using a interpreter, to
interpreter .java file? or why don't just convert it to executable
like C? Why need to convert to bytecode?
I think the intention was to have
1) Compile time safety
2) Write once, run anywhere.
If you converted to an executable like C, you would lose #2. In a sense, the JVM is an interpreter, so Java bytecode in interpreted, while Java code code is compiled.
Why don't just as a scripting language, using a interpreter, to interpreter .java file?
Suit yourself.
or why don't just convert it to executable like C?
Because that won't work cross-platform. A Portable Executable (used on Windows) won't run on, say, Linux or iOS, at least not without tricks.
A simple comparison can be made by thinking of sockets and file access. How would you do that on different platforms, with one executable, without the JVM?
Interpreting (and compiling) byte code is faster than interpreting raw java.
Byte code is portable. You can compile on Windows, and run the byte code on Mac or Unix.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
After reading the Java White Paper, I have a question on my mind and it might not be a very smart question but here it is anyway:
From what I gathered, Java attempted to improve an a number of fallacies associated with C++ such as redundancy, confusion with pointers, full-object orientation etc.,
If Java managed to overcome these issues, why would it be incorret to say that Java can replace C++.
There are many situations where C++ is a better option than Java. Comparison here.
Specifically:
In addition to running a compiled Java program, computers running Java
applications generally must also run the Java Virtual Machine JVM,
while compiled C++ programs can be run without external applications.
Early versions of Java were significantly outperformed by statically
compiled languages such as C++. This is because the program statements
of these two closely related languages may compile to a few machine
instructions with C++, while compiling into several byte codes
involving several machine instructions each when interpreted by a JVM.
Certain inefficiencies are inherent to the Java language itself,
primarily:
All objects are allocated on the heap. For functions using small objects this can result in performance degradation as stack
allocation, in contrast, costs essentially zero. However, this
advantage is obsoleted by modern JIT compilers utilising escape
analysis or escape detection to allocate objects on the stack. Escape
analysis was introduced in Oracle JDK 6.
Methods are by-default virtual. This slightly increases memory usage by adding a single pointer to a virtual table per each object.
Also, it induces a startup performance penalty, because a JIT compiler
has to do additional optimization passes even for de-virtualization of
small functions.
A lot of casting required even using standard containers induces a performance penalty. However, most of these casts are statically
eliminated by the JIT compiler, and the casts that remain in the code
usually do not cost more than a single CPU cycle on modern processors,
thanks to branch prediction.
Array access must be safe. The compiler is required to put appropriate range checks in the code. Naive approach of guarding each
array access with a range check is not efficient, so most JIT
compilers generate range check instructions only if they cannot
statically prove the array access is safe. Even if all runtime range
checks cannot be statically elided, JIT compilers try to move them out
of inner loops to make the performance degradation as low as possible.
Lack of access to low level details does not allow the developer to better optimize the program where the compiler is unable to do
so.[10]. Programmers can interface with the OS directly by providing
code in C or C++ and calling that code from Java by means of JNI.
Also as an iOS/Mac dev, and strong background in DSP, and lover of many open source C++ and Objective C libraries, I could go on and on as to why Java is not better...
Java didn't have the same goals and so doesn't serve the same function as C++. In other words, Java may have made some improvements, but also some regressions in things that are important for C++ applications.
Therefore Java cannot simply replace C++.
Your question is kind of off-topic for this forum (it's not about a programming problem). Nevertheless, here's my two cents.
Java and C++ serve different needs. For instance, while pointers in C++ (as in C) are certainly complicated, it is precisely because of pointers that one can manipulate specific addresses in memory. This is quite valuable for certain applications and impossible to do in Java (without resorting to native methods—often implemented in (ahem) C++).
C++ is compiled into machine code native to the machine. Java is compiled into machine-independent byte code. Thus C++ tends to have a speed advantage. This is offset somewhat, but not entirely, by just-in-time compilers for Java.
I'm sure others here will post additional differences between the two.
Java is a reasonably good application development platform.
It is not a systems development platform. It can't provide direct access to hardware. It can't be used to implement a Java Virtual Machine (chicken and egg problem).
So you will always need a language that compiles to native code in order to bootstrap your high-level runtime.
Because C++ is often still a factor faster in applications and the JRE hasn't been ported to all platforms/OS's.
Other than that, not everyone agrees that, just from a design perspective, Java is an improvement on C++.
The main answer is probably that the language syntax is not what matters the most. C++ is designed to be compiled as native applications, while Java is designed to be compiled as Java bytecode applications, which run on a Java Virtual Machine.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
To my experience, most of java applications on desktop platforms are less responsive than a similar application written in c++ or some other natively compiled language. Which is understandable considering that java only compiles to intermediate language.
And by responsiveness here I mean the general feel of how the application responds to mouse clicks and keyboard events, the little lags between the user clicking somewhere and the program actually redrawing all the needed things to represent the response to that click. Most often these lags are so small that you don't see them as lag, but you get a feeling that the whole aplication gets a little slow.
Examples of such java applications that I would see as less responsive are Azureus, java-based versions of Zend studio, Eclipse, and a couple of my own swing-based java projects.
Is this really the case? Can a java application ever be as responsive as a native application? Should it perhaps be compiled in some different way? (although you would think that if that was possible, big products such as Zend studio would do that already)
Application responsiveness in Java is frequently down to bad/inefficient programming. While a Java UI is heavier than one written in C/C++, on a recent computer (last few years or so) shouldn't struggle with a well coded application.
Most recent benchmarks show Java 1.6 to be of comparative speed to C/C++ (infact in the last cross language benchmarks I saw it sat snugly between the two in terms of performance).
I think a symptom of Java and the IDEs people use to write it is that it is a forgiving language that lets you do things the wrong way (read, less good way), without complaining too much while C++ would just fall over, forcing you to write better software.
As a personal note, I've seen Java applications where the devs attached a single listener to every element in the UI, then that listener had an enormous if...elseif...elseif... to check the tooltip string that was passed back from the event object.
javac compiles to an intermediate byte code. However the JVM compiles to native code based on how the code is used dynamically (something static compilers cannot do) For GUIs most of the real work is done in native code components so you shouldn't see a real difference.
Many real time trading systems are developed using Java and respond in less than 100 micro-seconds. i.e. 0.0001 seconds. If you have a responsiveness issue, its not the language at fault.
BTW: Eclipse uses SWT which is a native library.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
The JIT compiler has been around for some time. Occasionally it comes to my mind that, "hey, why not just compile Java source file directly to machine code?"
Along with compiled library, we can get rid of the cumbersome JVM.
The only barrier I can think of is the garbage collector. How's your thoughts?
PS: Oh, you say portability? WTH is that? Plus, I'm forced to install a JVM in the first place.
Well, my friend uses Ubuntu, and I use Windows XP, and my other friend uses OSX.
When I send them a jar that I compiled they can both run the file without any changes.
That is why you should not get rid of the JVM.
vm can do complex optimizations based on information only available at runtime. Static compile time optimization simply can't compete. Java is fast because it is running on the vm.
watch this
http://www.infoq.com/presentations/Towards-a-Universal-VM
On some platforms (mostly embedded ones), it's just as you say (or else the machines speak java natively). You can also download compilers that do what you are suggesting, but I imagine you lose a lot of the Java API in the process.
Back to your question, the main reason why is that the people who design the languge and specification want to have it. Plain and simple. It offers portability in the consideration that the "hard" part of making portable code supposedly only has to be done once per environment (another poster spoke of 3 different OS's running the JVM) rather than once per each environment per project. Have you ever tried to make even mostly-portable C++ code without the aid of frameworks like Qt or packages like Boost? It gets VERY difficult, and even then you must still re-compile for each architecture.
Beside portability another issue that comes to mind is dynamic classloading which is difficult to handle via machine code. How would servlet containers work in such a scenario? Maybe it works well for embedded Java, but I don't think for J2EE.
Would the .class form just be an intermediate binary that is converted to machine code before execution? Or would you directly compile from Java source to machine code?
Bytecode generation is necessary for platform independence of code.
JVM (JVM is different for all platforms) reads these bytecode and converts these into machine code depending upon which platform its running. This makes Java compiled code platform independent. JVM also does optimizations which makes Java fast.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 13 years ago.
Question about Cassandra
Why the hell on earth would anybody write a database ENGINE in Java ?
I can understand why you would want to have a Java interface, but the engine...
I was under the impression that there's nothing faster than C/C++, and that a database engine shouldn't be any slower than max speed, and certainly not use garbage collection...
Can anybody explain me what possible sense that makes / why Cassandra can be faster than ordinary SQL that runs on C/C++ code ?
Edit:
Sorry for the "Why the hell on earth" part, but it really didn't make any sense to me.
I neglected to consider that a database, unlike the average garden-varitety user programs, needs to be started only once and then runs for a very long time, and probably also as the only program on the server, which self-evidently makes for an important performance difference.
I was more comparing/referencing to a 'disfunctional' (to put it mildly) Java tax program I was using at the time of writing (or rather would have liked to use).
In fact, unlike using Java for tax programs, using Java for writing a dedicated server program makes perfect sense.
What do you mean, C++? Hand coded assembly would be faster if you have a few decades to spare.
I can see a few reasons:
Security: it's easier to write secure software in Java than in C++ (remember the buffer overflows?)
Performance: it's not THAT worse. It's definitely worse at startup, but once the code is up and running, it's not a big thing. Actually, you have to remember an important point here: Java code is continually optimized by the VM, so in some circumstances, it gets faster than C++
Why the hell on earth would anybody write a database ENGINE in JAVA ?
Platform independance is a pretty big factor for servers, because you have a lot more hardware and OS heterogenity than with desktop PCs. Another is security. Not having to worry about buffer overflows means most of the worst kind of security holes are simply impossible.
I was under the impression that
there's nothing faster than C/C++, and
that a database engine shouldn't be
any slower than max speed, and
certainly not use garbage
collection...
Your impression is incorrect. C/C++ is not necessarily faster than Java, and modern garbage collectors have a big part in that because they enable object creation to be incredibly fast.
Don't forget that Java VMs make use of a just-in-time (JIT) engine that perform on-the-fly optimisations to make Java comparable to C++ in terms of speed. Bearing in mind that Java is quite a productive language (despite its naysayers) and portable, together with the JIT optimisation capability, means that Java isn't an unreasonable choice for something like this.
The performance penalty for modern Java runtimes is not that big and programming in Java is less error-prone than in c.