Some time ago, I came up with a whole without Root can also use the Xposed Method, in simple terms, is through double open technology (VirtualApp) combined with the process of Java Method Hook (EPIC) to load the Xposed module, so as to modify the internal App Method. Project just open source soon, there are a large number of users accused VirtualXposed is malware, a virus! Such as:

  • VirusTotal says you have malware · Issue #10 · Android-hacker /VirtualXposed
  • McAfee Update · Issue #21 · Android – Hacker /VirtualXposed
  • Galaxy Note8 Device maintenance prompt harmful to device · Issue #8 · Android-hacker /VirtualXposed

And the detection results of VirusTotal:



(Address of test report: VirusTotal)

I didn’t think much of it, so I didn’t mind it; After all, what kind of virus would be so blatantly public as to release its own code for others to use?

Until later, in the face of some XDA users’ doubts and some foreign media reports, I realized that in the eyes of some users, the word “virus” is very sensitive to them. 16 anti-virus engines said that you have a virus, even if you think that you are clear, others will stay away from you. So I began my “clear my name” journey.

In the beginning I also do not know how to start, to search the virus’s name, what ` Android: Agent – QBQ PUP `, ` Tool. SilentInstaller. 6. Origin ` little meaningful results; How can I tell which part of the code is wrong? Where should I start?

Then I found a few engineers who had done virus analysis to chat, they told me that the current general static analysis method of Android APK is to use feature analysis, that is, to extract the features of your APK installation package, and then pick up and virus library to do comparison, if there is a match, so that you may be harmful programs.

So I thought, if I’m a virus analysis engineer, what characteristics should I extract? Load code dynamically, run executable, sensitive package name? Following this thought, I did a few things:

  1. VirtualApp contains a large number of ‘odex’, ‘dex’ and other strings. Replace these strings with hard-coded Base64 encryption strings, decrypt them at runtime and use them.
  2. All hard-coded class names, such as wechat, QQ classes (special processing for these apps) are also replaced with Base64 strings.
  3. Modify the component names registered in the manifest to avoid matching VirtualApp.

After doing so, 14 anti-virus engines still considered it a virus (two fewer); At that time I was a little confused, in the heart of ten thousand grass mud horse pentium…

Such a mere guess is not the way, there needs to be a scientific method to analyze and solve the problem. Now that we know that the antivirus engine matches features and doesn’t try to guess which features it extracts, we can work the other way around and see what “things” hit which of its features. Specifically, APK files are divided into several parts: Manifest, resource, dex file (Java code), SO file (native code) and other files; We can remove part of the APK file, and then take the missing part of the APK file to the anti-virus engine detection, if the detection results are different, then it means that the deleted part may match the characteristics of some viruses, so as to be misjudged. Of course, this approach may not be correct, depending on how the antivirus engine extracts the features; But you can try.

After trying it, only Java Code can cause the antivirus engine to be judged as a virus; Other previously assumed manifest components, so files are actually fine. So what part of Java code was judged to be problematic? At first I intend to rely on the library from the point of view to do the code removed, but was immediately denied – although I rely on more than a dozen tripartite libraries, but it is clear that it is likely to find the end of the VirtualXposed itself code was judged as the root of the virus. Finally, the method I used was like this:


  1. Take all the Java classes and sort them by fully qualified names.
  2. Delete half of the classes in sequence, and then package them as APK for anti-virus engine detection; If there is a change, there is a problem with the deleted class. Then use the deleted part of the class to do another half (delete half again) continue to detect, until it is locked to one or more specific classes. If there is no change, divide the remaining part of the class in the same way.
  3. Locking to specific classes is not enough; it is better to lock to specific rows. We can then continue binary testing at method granularity until all methods are located.

However, thinking is not enough. How to implement this plan? You want to delete half of your classes. How? Obviously, if you delete the Java source directly, you will not be able to compile successfully and get the final APK file. We should do something with the compiled product. Before the D8 compiler came out, the packaging process of APK looked like this:




Watching the Java source code and third-party libraries packaged as dex, we can see that deleting the compiled class files does the job; Gradle’s Transform API is a great choice if you want to control this process.

In addition, there is a way: The Android virtual machine has its own VIRTUAL machine instruction smali, we can also decompile APK to get smALI files, delete part of the SMALI files and repackage; The gradle Transform API makes deleting class files much easier and easier. Combined with bytecode manipulation tools, we can make various modifications to apK to test the anti-virus engine.

The final code used is here: fuck_anti_virus.gradle. Gradle plugin – This is a Gradle plugin that you can reference directly in your project.


After a few days of probing 16 antivirus engines, I resolved all the false positives; The final test result looks like this:




The code that was misidentified as a virus, however, was quite ironic. Take a look:


1. Sensitive API call, ‘openDexFileNative’, ‘openDexFile’, base64 encoding solution

2. Sensitive API calls, ‘system.setProperty’, are bypassed by reflection calls

3. Log printing and exception stack misjudged (I don’t know why, it’s a bit confusing)

4. Replace the Mainifest component name

5. Change the class name and the log input posture

If the first and second are anything to go by, those last ones and the rest of my modifications, I’d like to say, not personally, that these anti-virus engines are insane…


Then share a code I recently stumbled across:






This is some dual-open software, dynamically loaded after the plug-in reverse code. When I first saw it, I was shocked. This is a direct check by the double open wechat internal database ah! I remember before said, double open software is very unsafe, double open software itself to internal APP has full control, and the double open within the APP to other was double open APP has full access to the data (for example you installed inside a malicious software, this software can access WeChat, pay treasure to all of the data; Therefore, it is not appropriate to sandbox dual-open software, which is not safe. But I had no idea that someone actually did it, and it was done by themselves. But what if you throw it into an anti-virus program? Yes, it’s safe. The “Android:Agent-QBQ [PUP]” (Potentially Unwanted Program) doesn’t even have one.


Finally, I still want to say that the current anti-virus engine is really weak. Of course, also may be because VirusTotal is free, the major antivirus engine given API is relatively weak version of the rooster, very welcome all security engineers come to play face ^_^ and, the use of double open software and Xposed and other functions, must pay attention to safety oh ~