Head First Java Reverse

Say (shui) good (shui) weekly update is coming!


By chance, I got a piece of news that a supposedly famous mind-mapping software that I have never used before is currently on sale. The original price of the software is 39 or 49 dollars, and now it only costs one dollar! I took a look at it based on the principle that I can’t buy it at a loss and I can’t be fooled.链接在这儿 (The event is still available until the 12th) Although it feels good, I still don’t want to pay without strong demand. Go to a cracked version of the website to search, it is like this…

Note: According to feedback from netizens, there are still problems with this crack. It can be activated but the function cannot be used. Please use the old version first and wait for the new version. 1.Copy net.xmind.verify_3.6.50.201606270419.jar to the /Applications/ directory 2. Open the Serial.rtfd file and add the serial number to the software activation page (any mailbox ). 3. If it has been installed before, be sure to uninstall the old version with AppDelete first

Uh… I can’t use you as an egg. But notice two things.

  • crack filename suffix .jar
  • Only one file needs to be replaced

In other words,

  • The source program is written in Java and may be decompiled into high-level language code
  • Only need to crack a file

Of course you have to do such a simple thing by yourself~ You must not miss the good learning opportunity. The following briefly summarizes the steps and ideas needed to crack a Java application that is (again) unencrypted and unobfuscated.


  • Java Decompiler Decompiler tool with interface
    • if you like在线版
    • There are also plugins for Eclipse and Intelij
  • Java Bytecode Editor Also with interface, disassembler/assembler tool
  • KrakatauThe name looks like it was made by the Japanese, another Java assembler, disassembler, decompiler tool
  • your favorite editor


First, observe the directory structure (Mac version)


If jre has seen it, it must be java. Look at the Plugins directory, which is very suspicious. There are a lot of jar files in it. After searching, sure enough, verify is in it.

Load it into JD. The interface is as shown in the figure.


Open one of the classes. Well,


Java has a good conscience. Even the enumerated types must be listed for you. Tsk, after all, many people use it. The most impressive feature of the JD GUI is the function defined by the click jump function. When the brain is turned, the operation can also keep up with the train of thought. The feeling of jumping in the middle of the code is simply poison for me to wait for programmers!

The variable names and method names in the code are clearly written. The idea here is to follow the call down. During this period, I even found the encryption and decryption part of the key, but unfortunately, it cannot be automatically generated, so the cracked version on the Internet must replace the file. Later, I will talk about why.

After compiling Java, like C#, it generates an intermediate code, Bytecode, which is close to assembly in form. You need to care about stacking and popping, and whether the bytecode length will exceed the limit after patching, but some advanced data types can also be used And function calls, and the executable file contains the line number comparison table, constant table, etc., which is equivalent to giving you the debug symbol. Thinking about them, coders think they are stupid—otherwise, where do spigot and forge still use? So what about older developers?

Walking out of the verification function, I found that I can only save the country with a curve, because the content of the registration code is encrypted by the private key and cannot be generated by itself. Change your mind. All registration codes will always have a blacklist. I found a registration code on the Internet, it must be blacklisted, but the signature verification can pass, and then change the code, so that it neither reads nor saves the list when the server obtains it, nor does it save it after saving. read. When requesting and saving the blacklist from the Internet, there should be a space between the name and the serial number |, when reading and identifying the black key, let it be randomly separated from each other, and it will never find that the blacklist is wrong… Reversing is always more wretched than writing programs, well~

// 保存的黑名单|XAka34A2rVRYJ4XBI...
// 读取名单时对比所用的字串*XAka34A2rVRYJ4XBI...
// 永远不会相等

After a while, I found out that he would keep writing the key blacklist in the blacklist file, because the program found that MD said why it was not blacklisted in the blacklist, and kept adding it. Online verification is at VerificationJob In such a separate thread, when the program is running, even if Pro has been certified, it will spin and jump without stopping. So, I can only find a way to get the saved file, nop it.

private static File getBlacklistFile()
  return null;

Σ( ̄. ̄ノ)ノ

cracking method

As for how to perform Patch, there are mainly two methods. One is to edit the disassembly directly with JBE or Krakatau, and then compile it back and save it. The other is to use JD or Krakatau to decompile, edit the source code and then compile it back. Although there is no JDK, it is also possible to compile it. Moreover, if another class is embedded in a Java class, it will be saved in other files during compilation, and it will also be decompiled. This creates two problems.

The first question is that there will be problems when compiling the scattered source code together. In what order? Which ones to put together? How to combine with classes that have not been patched? What should I do if there are bytecodes in the class that fail to be decompiled due to over-optimization? Therefore, decompilation is impossible for large projects, and we can only change the bytecode in a small way.

After deciding to disassemble, it is necessary to decide which codes are useful and which codes are not. As mentioned above, the code generated by a class will be distributed to several files, and some classes have names and some do not 1.

Named subclasses are stored in a file of the form LicenseVerifier$VerificationJob.class in the file. Anonymous subclasses are LicenseVerifier$1.class, which is mostly used for calling back functions or specifying the program to be executed when creating a thread. Like this.

public void notifyValidityListener(final IValidity validity)
  if (this.display != null)
    if (!this.display.isDisposed()) {
      this.display.syncExec(new Runnable()
      {  // LicenseVerifier$ValidityNotifier$1.class
        public void run()
          { // LicenseVerifier$ValidityNotifier$1$1.class
            public void run()
            throws Exception
  else { SafeRunnable()
    { // LicenseVerifier$ValidityNotifier$2.class
      public void run()
      throws Exception

Generally speaking, anonymous subclasses are useless for reverse engineering (spread hands), and named subclasses are generally the objects we focus on. But the simpler way is to look at the size, especially the obfuscated code, some of the perverts may even write the name of the anonymous class as if nothing happened. In short, a class with more code is definitely a useful class~

The rest of the process is the ones mentioned above casually, locate the function, delete it, and it’s done.

a few pits


Start to treat java bytecode as ordinary x86 assembly, and fill it with nop after changing the method until the size is the same. Later, I found out that it is not necessary. In the disassembly, numbers are used instead of constants and names. After compilation, it is automatically squeezed into a file, and the free and redundant places are taken care of. This is very convenient, and you can add a little malicious code yourself (yeah)


At the beginning, I was not familiar with this kind of bytecode~~ (I am not familiar with it now)~~ After modifying the assembly with JBE, I always couldn’t open the modified disassembly, and I thought it was software garbage at first. Later, I discovered Krakatau, which has its own grammar checker, and only after using it did I know that it was my own problem, such as a ldc_w written as ldc (This is also Krakatau’s modification suggestion super smart), the software with interface threw an exception and ignored me. Or the command line tool is better, um.



guard against

asymmetric encryption

Tell me how to write a qualified verification code. This program is a good example. Let me draw a flow chart with the program I just cracked [Squint Eye]


The most important of these is to use_ asymmetric way _ encryption. Keeping the key locally in any form will not only be cracked by others, but will also be made into a registration machine. The evil effect of being a registration machine is that even if it is updated later, ordinary people other than hackers can easily crack your latest version software, the fruits of labor are easily stolen, which is very sad.

Code obfuscation

For things like Java, after decompilation, there is not much difference from binary. After all, it is a conversion from a high-level language to a low-level language instead of a machine language, and the amount of information is not lost, not to mention that pig teammates leave debugging information in it. I have never learned Java, but looking at the contents of the disassembled file, the default compiled jar or class has local variable table, stackmap table and line number table (???). . This is, even the correspondence between source code and byte code is given to you, and I can see that this is the debug version that should be used by myself!

Java is not a bad language. It is not much worse than node and python. The bad thing is that it is too easy to learn. There are all kinds of birds in the forest, and there are people doing all kinds of weird things. Same for all studious languages, C#, VB, python. Tut tut. It’s never the programming language that’s rubbish, it’s the…

  1. For anonymous subclasses, see这里 ↩︎