├── .gitignore ├── README.md ├── pom.xml └── src ├── main └── java │ └── com │ └── javadeobfuscator │ └── javavm │ ├── Cause.java │ ├── ConstantPool.java │ ├── Effect.java │ ├── ExecutionOptions.java │ ├── HookInfo.java │ ├── InstructionSnapshot.java │ ├── Locals.java │ ├── MethodExecution.java │ ├── Stack.java │ ├── StackTraceHolder.java │ ├── VirtualMachine.java │ ├── exceptions │ ├── AbortException.java │ ├── ConvertedException.java │ ├── ExecutionException.java │ ├── FallingOffCodeException.java │ ├── NoSuchHandlerException.java │ ├── NoSuchMethodHandlerException.java │ └── VMException.java │ ├── ext │ ├── Filesystem.java │ ├── Memory.java │ └── net │ │ ├── DNSResolver.java │ │ ├── InterfaceAddress.java │ │ ├── JSocket.java │ │ ├── Network.java │ │ ├── NetworkInterface.java │ │ ├── SocketConnectionEstablisher.java │ │ └── SystemDNSResolver.java │ ├── hooks │ ├── HookGenerator.java │ ├── HookedFieldGetter.java │ ├── HookedFieldSetter.java │ └── HookedMethod.java │ ├── instructions │ ├── AconstNullInstruction.java │ ├── ArrayLoadInstruction.java │ ├── ArrayStoreInstruction.java │ ├── BipushInstruction.java │ ├── CheckcastInstruction.java │ ├── DoubleMathInstruction.java │ ├── DoublePredicateInstruction.java │ ├── FloatMathInstruction.java │ ├── Instruction.java │ ├── IntegerMathInstruction.java │ ├── InvocationInstruction.java │ ├── InvokeDynamicInstruction.java │ ├── InvokeSpecialInstruction.java │ ├── LdcInstruction.java │ ├── LoadOneWordInstruction.java │ ├── LoadTwoWordInstruction.java │ ├── LocalLoadInstruction.java │ ├── LocalStoreInstruction.java │ ├── LongIntegerMathInstruction.java │ ├── LongMathInstruction.java │ ├── NewArrayInstruction.java │ ├── NewInstruction.java │ ├── NopInstruction.java │ ├── SinglePredicateInstruction.java │ └── SipushInstruction.java │ ├── internals │ ├── CallInfo.java │ ├── ClassLoaderData.java │ ├── FieldDescriptor.java │ ├── FieldType.java │ ├── Handle.java │ ├── KlassHandle.java │ ├── LinkResolver.java │ ├── MethodHandle.java │ ├── SystemDictionary.java │ └── VMSymbols.java │ ├── mirrors │ ├── JavaClass.java │ ├── JavaExecutable.java │ ├── JavaField.java │ ├── JavaMethod.java │ ├── JavaMethodHandle.java │ └── JavaThread.java │ ├── nativeimpls │ ├── java_awt_Font.java │ ├── java_io_FileDescriptor.java │ ├── java_io_FileInputStream.java │ ├── java_io_FileOutputStream.java │ ├── java_io_UnixFileSystem.java │ ├── java_io_WinNTFileSystem.java │ ├── java_lang_Class.java │ ├── java_lang_ClassLoader.java │ ├── java_lang_Double.java │ ├── java_lang_Float.java │ ├── java_lang_Object.java │ ├── java_lang_Runtime.java │ ├── java_lang_SecurityManager.java │ ├── java_lang_StrictMath.java │ ├── java_lang_String.java │ ├── java_lang_System.java │ ├── java_lang_Thread.java │ ├── java_lang_Throwable.java │ ├── java_lang_invoke_MemberName.java │ ├── java_lang_invoke_MethodHandle.java │ ├── java_lang_invoke_MethodHandleNatives.java │ ├── java_lang_invoke_MethodType.java │ ├── java_lang_reflect_Array.java │ ├── java_lang_reflect_Constructor.java │ ├── java_lang_reflect_Field.java │ ├── java_lang_reflect_Method.java │ ├── java_net_DualStackPlainSocketImpl.java │ ├── java_net_Inet4Address.java │ ├── java_net_Inet4AddressImpl.java │ ├── java_net_Inet6Address.java │ ├── java_net_InetAddress.java │ ├── java_net_InetAddressImplFactory.java │ ├── java_net_NetworkInterface.java │ ├── java_net_SocketInputStream.java │ ├── java_net_SocketOutputStream.java │ ├── java_security_AccessController.java │ ├── java_util_jar_JarFile.java │ ├── java_util_zip_CRC32.java │ ├── java_util_zip_Inflater.java │ ├── java_util_zip_ZipFile.java │ ├── sun_awt_windows_WToolkit.java │ ├── sun_java2d_Disposer.java │ ├── sun_misc_Perf.java │ ├── sun_misc_URLClassPath.java │ ├── sun_misc_Unsafe.java │ ├── sun_nio_fs_WindowsNativeDispatcher.java │ ├── sun_reflect_ConstantPool.java │ ├── sun_reflect_NativeConstructorAccessorImpl.java │ ├── sun_reflect_NativeMethodAccessorImpl.java │ ├── sun_reflect_Reflection.java │ └── sun_security_provider_NativeSeedGenerator.java │ ├── oops │ ├── Oop.java │ └── ThreadOop.java │ ├── utils │ ├── ASMHelper.java │ ├── ArrayConversionHelper.java │ ├── ArrayHelper.java │ ├── BiDoubleFunction.java │ ├── BiFloatInstruction.java │ ├── BiIntegerFunction.java │ ├── BiLongFunction.java │ ├── BiLongIntegerFunction.java │ ├── ExecutionUtils.java │ ├── MaybeBoolean.java │ ├── NameHelper.java │ ├── PrimitiveUtils.java │ ├── TypeHelper.java │ └── Utils.java │ └── values │ ├── JavaAddress.java │ ├── JavaArray.java │ ├── JavaNull.java │ ├── JavaObject.java │ ├── JavaTop.java │ ├── JavaUninitialized.java │ ├── JavaUnknown.java │ ├── JavaValue.java │ ├── JavaValueType.java │ ├── JavaWrapper.java │ └── prim │ ├── JDouble.java │ ├── JFloat.java │ ├── JInteger.java │ ├── JLong.java │ └── JPrimitive.java └── test └── java └── com └── javadeobfuscator └── javavm ├── CompilationTest.java └── TestHelper.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | # Compiled class file 4 | *.class 5 | 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | 15 | # Package Files # 16 | *.jar 17 | *.war 18 | *.ear 19 | *.zip 20 | *.tar.gz 21 | *.rar 22 | 23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 24 | hs_err_pid* 25 | ### JetBrains template 26 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 27 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 28 | 29 | # User-specific stuff: 30 | .idea/**/workspace.xml 31 | .idea/**/tasks.xml 32 | .idea/dictionaries 33 | 34 | # Sensitive or high-churn files: 35 | .idea/**/dataSources/ 36 | .idea/**/dataSources.ids 37 | .idea/**/dataSources.xml 38 | .idea/**/dataSources.local.xml 39 | .idea/**/sqlDataSources.xml 40 | .idea/**/dynamic.xml 41 | .idea/**/uiDesigner.xml 42 | 43 | # Gradle: 44 | .idea/**/gradle.xml 45 | .idea/**/libraries 46 | 47 | # Mongo Explorer plugin: 48 | .idea/**/mongoSettings.xml 49 | 50 | ## File-based project format: 51 | *.iws 52 | 53 | ## Plugin-specific files: 54 | 55 | # IntelliJ 56 | /out/ 57 | 58 | # mpeltonen/sbt-idea plugin 59 | .idea_modules/ 60 | 61 | # JIRA plugin 62 | atlassian-ide-plugin.xml 63 | 64 | # Crashlytics plugin (for Android Studio and IntelliJ) 65 | com_crashlytics_export_strings.xml 66 | crashlytics.properties 67 | crashlytics-build.properties 68 | fabric.properties 69 | ### Maven template 70 | target/ 71 | pom.xml.tag 72 | pom.xml.releaseBackup 73 | pom.xml.versionsBackup 74 | pom.xml.next 75 | release.properties 76 | dependency-reduced-pom.xml 77 | buildNumber.properties 78 | .mvn/timing.properties 79 | 80 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) 81 | !/.mvn/wrapper/maven-wrapper.jar 82 | 83 | *.iml 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JavaVM 2 | 3 | Yeah so this is nowhere near finished but hey let's put it on the internet for people to look at. 4 | Be careful though. It's pretty bad in there and I don't want to be responsible for anyone going crazy. 5 | 6 | Supported things include: 7 | * Threading 8 | * Filesystem (some of it) 9 | * Networking (some of it) 10 | * No SSL though 11 | * invokedynamic (kind of) 12 | * Defining new classes 13 | * It's been like a year since I worked on this so probably other stuff 14 | 15 | ## For Zelix People 16 | 17 | If you work at Zelix and you're reading this, just pretend like this doesn't even exist. Definitely don't design new features intended to circumvent this! 18 | 19 | I'm super busy these days so I don't have much time to play with you guys, but at least give me some time to catch up ok? Also feel free to hmu if you ever wanna chat :) -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/Cause.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm; 2 | 3 | /** 4 | * How dependent this method call will be on the outside context 5 | *

6 | * i.e. System.currentTimeMillis() is ALL because it depends on the current time 7 | * String.valueOf() is NONE because it depends only on the local context 8 | */ 9 | public enum Cause { 10 | NONE, 11 | UNKNOWN, 12 | ALL 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/ConstantPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm; 18 | 19 | import com.google.common.io.ByteArrayDataInput; 20 | import com.google.common.io.ByteStreams; 21 | import com.javadeobfuscator.javavm.internals.VMSymbols; 22 | import org.objectweb.asm.ClassReader; 23 | 24 | public class ConstantPool { 25 | private final VirtualMachine _vm; 26 | private final ClassReader classReader; 27 | 28 | // todo load constants lazily (to prevent abuse with large constant pools) 29 | public ConstantPool(VirtualMachine virtualMachine, ClassReader classReader) { 30 | _vm = virtualMachine; 31 | this.classReader = classReader; 32 | } 33 | 34 | public int getSize() { 35 | return this.classReader.getItemCount(); 36 | } 37 | 38 | public String getUTF8At(int i) { 39 | if (i < 0 || i > this.classReader.getItemCount()) { 40 | throw _vm.newThrowable(VMSymbols.java_lang_IllegalArgumentException, "Constant pool index out of bounds"); 41 | } 42 | if (i == 0) { 43 | throw _vm.newThrowable(VMSymbols.java_lang_IllegalArgumentException, "Wrong type at constant pool index"); 44 | } 45 | int index = classReader.getItem(i); 46 | if (index == 0) { 47 | throw _vm.newThrowable(VMSymbols.java_lang_IllegalArgumentException, "Wrong type at constant pool index"); // long/double take 2 slots, this item might not exist 48 | } 49 | if (classReader.readByte(index - 1) != 1) { 50 | throw _vm.newThrowable(VMSymbols.java_lang_IllegalArgumentException, "Wrong type at constant pool index"); 51 | } 52 | 53 | ByteArrayDataInput din = ByteStreams.newDataInput(classReader.b); 54 | din.skipBytes(index); 55 | String result = din.readUTF(); 56 | return result; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/Effect.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm; 2 | 3 | /** 4 | * The effect that the particular method call will have on the rest of the program. 5 | *

6 | * For example, nearly any method call (such as System.setProperty) will be ALL, because it will affect the outside program 7 | * However, a call like Integer.intValue() will be NONE 8 | */ 9 | public enum Effect { 10 | /** 11 | * 12 | */ 13 | NONE, 14 | UNKNOWN, 15 | ALL; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/ExecutionOptions.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm; 2 | 3 | import com.javadeobfuscator.javavm.values.JavaWrapper; 4 | import org.objectweb.asm.tree.AbstractInsnNode; 5 | import org.objectweb.asm.tree.ClassNode; 6 | import org.objectweb.asm.tree.MethodNode; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.function.Consumer; 13 | 14 | public class ExecutionOptions { 15 | 16 | private Map> _watchlist = new HashMap<>(); 17 | private List _stacktrace = new ArrayList<>(); 18 | 19 | public ExecutionOptions watch(AbstractInsnNode insn, Consumer consumer) { 20 | _watchlist.put(insn, consumer); 21 | return this; 22 | } 23 | 24 | public boolean shouldRecord(AbstractInsnNode target) { 25 | return !_watchlist.isEmpty() && _watchlist.containsKey(target); 26 | } 27 | 28 | public void notify(AbstractInsnNode node, BreakpointInfo info) { 29 | _watchlist.get(node).accept(info); 30 | } 31 | 32 | public static class BreakpointInfo { 33 | private AbstractInsnNode now; 34 | private Stack stack; 35 | private Locals locals; 36 | 37 | public BreakpointInfo(AbstractInsnNode now, Stack stack, Locals locals) { 38 | this.now = now; 39 | this.stack = stack; 40 | this.locals = locals; 41 | } 42 | 43 | public Stack getStack() { 44 | return stack; 45 | } 46 | 47 | public Locals getLocals() { 48 | return locals; 49 | } 50 | 51 | public AbstractInsnNode getNow() { 52 | return now; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/HookInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm; 18 | 19 | import com.javadeobfuscator.javavm.values.JavaWrapper; 20 | import org.objectweb.asm.tree.ClassNode; 21 | import org.objectweb.asm.tree.MethodNode; 22 | 23 | import java.util.List; 24 | 25 | public class HookInfo { 26 | private ClassNode classNode; 27 | private MethodNode methodNode; 28 | private List params; 29 | private JavaWrapper instance; 30 | private JavaWrapper returnValue; 31 | 32 | public HookInfo(ClassNode classNode, MethodNode methodNode) { 33 | this.classNode = classNode; 34 | this.methodNode = methodNode; 35 | } 36 | 37 | public HookInfo(ClassNode classNode, MethodNode methodNode, JavaWrapper instance, List params) { 38 | this.classNode = classNode; 39 | this.methodNode = methodNode; 40 | this.instance = instance; 41 | this.params = params; 42 | } 43 | 44 | public ClassNode getClassNode() { 45 | return classNode; 46 | } 47 | 48 | public MethodNode getMethodNode() { 49 | return methodNode; 50 | } 51 | 52 | public void setClassNode(ClassNode classNode) { 53 | this.classNode = classNode; 54 | } 55 | 56 | public void setMethodNode(MethodNode methodNode) { 57 | this.methodNode = methodNode; 58 | } 59 | 60 | public JavaWrapper getReturnValue() { 61 | return returnValue; 62 | } 63 | 64 | public void setReturnValue(JavaWrapper returnValue) { 65 | this.returnValue = returnValue; 66 | } 67 | 68 | public boolean is(String owner, String name, String desc) { 69 | return classNode.name.equals(owner) && (methodNode != null) && methodNode.name.equals(name) && methodNode.desc.equals(desc); 70 | } 71 | 72 | public List getParams() { 73 | return params; 74 | } 75 | 76 | public JavaWrapper getInstance() { 77 | return instance; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/InstructionSnapshot.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm; 2 | 3 | import org.apache.commons.lang3.tuple.Pair; 4 | 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | public class InstructionSnapshot { 9 | public Set> _pairs = new HashSet<>(); 10 | 11 | public void merge(Stack stack, Locals locals) { 12 | _pairs.add(Pair.of(stack, locals)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/Locals.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm; 2 | 3 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 4 | import com.javadeobfuscator.javavm.values.JavaWrapper; 5 | 6 | public class Locals { 7 | public JavaWrapper[] _values = new JavaWrapper[16]; 8 | 9 | public JavaWrapper get(int index) { 10 | if (index >= _values.length) { 11 | throw new ExecutionException("Illegal local variable number"); 12 | } 13 | JavaWrapper value = _values[index]; 14 | if (value == null) { 15 | throw new ExecutionException("Accessing value from uninitialized register " + index); 16 | } 17 | return value; 18 | } 19 | 20 | public JavaWrapper remove(int index) { 21 | if (index >= _values.length) { 22 | throw new ExecutionException("Illegal local variable number"); 23 | } 24 | JavaWrapper value = _values[index]; 25 | if (value == null) { 26 | throw new ExecutionException("Accessing value from uninitialized register " + index); 27 | } 28 | _values[index] = null; 29 | return value; 30 | } 31 | 32 | public void set(int index, JavaWrapper value) { 33 | if (index >= _values.length) { 34 | int newSize = (1 << (Integer.highestOneBit(_values.length) + 1)); 35 | JavaWrapper[] copy = new JavaWrapper[newSize]; 36 | System.arraycopy(_values, 0, copy, 0, _values.length); 37 | _values = copy; 38 | } 39 | 40 | _values[index] = value; 41 | } 42 | 43 | public int size() { 44 | return _values.length; 45 | } 46 | 47 | JavaWrapper[] internalArray() { 48 | JavaWrapper[] copy = new JavaWrapper[_values.length]; 49 | System.arraycopy(_values, 0, copy, 0, _values.length); 50 | return copy; 51 | } 52 | 53 | public Locals copy() { 54 | Locals newLocals = new Locals(); 55 | newLocals._values = new JavaWrapper[_values.length]; 56 | for (int i = 0; i < _values.length; i++) { 57 | newLocals._values[i] = _values[i]; 58 | } 59 | return newLocals; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | StringBuilder builder = new StringBuilder(); 65 | for (int i = 0; i < _values.length; i++) { 66 | if (_values[i] != null) { 67 | builder.append(i).append(": ").append(_values[i].get()).append(" "); 68 | } 69 | } 70 | return builder.toString(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/MethodExecution.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm; 2 | 3 | import com.javadeobfuscator.javavm.values.JavaWrapper; 4 | import org.objectweb.asm.tree.AbstractInsnNode; 5 | import org.objectweb.asm.tree.ClassNode; 6 | import org.objectweb.asm.tree.MethodNode; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | public class MethodExecution { 12 | private final VirtualMachine _virtualMachine; 13 | private final ClassNode _classNode; 14 | private final MethodNode _methodNode; 15 | private final ExecutionOptions _options; 16 | 17 | private final InstructionSnapshot[] _instructions; 18 | public Map Visited = new HashMap<>(); 19 | private JavaWrapper _returnValue; 20 | 21 | public MethodExecution(VirtualMachine vm, ClassNode classNode, MethodNode methodNode, ExecutionOptions options) { 22 | this._virtualMachine = vm; 23 | this._classNode = classNode; 24 | this._methodNode = methodNode; 25 | this._instructions = new InstructionSnapshot[methodNode.instructions.size()]; 26 | this._options = options; 27 | } 28 | 29 | public InstructionSnapshot[] getInstructions() { 30 | return this._instructions; 31 | } 32 | 33 | public ClassNode getClassNode() { 34 | return this._classNode; 35 | } 36 | 37 | public MethodNode getMethodNode() { 38 | return this._methodNode; 39 | } 40 | 41 | public ExecutionOptions getOptions() { 42 | return this._options; 43 | } 44 | 45 | public JavaWrapper getReturnValue() { 46 | return this._returnValue; 47 | } 48 | 49 | void setReturnValue(JavaWrapper value) { 50 | this._returnValue = value; 51 | } 52 | 53 | public VirtualMachine getVM() { 54 | return _virtualMachine; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/Stack.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm; 2 | 3 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 4 | import com.javadeobfuscator.javavm.values.JavaTop; 5 | import com.javadeobfuscator.javavm.values.JavaValueType; 6 | import com.javadeobfuscator.javavm.values.JavaWrapper; 7 | 8 | public class Stack { 9 | private int _index = 0; 10 | private JavaWrapper[] _values = new JavaWrapper[16]; 11 | 12 | public void push(JavaWrapper next) { 13 | if (next.is(JavaValueType.DOUBLE) || next.is(JavaValueType.LONG)) { 14 | push(JavaWrapper.createTop()); 15 | } 16 | if (_index >= _values.length) { 17 | int newSize = (1 << (Integer.highestOneBit(_values.length) + 1)); 18 | JavaWrapper[] copy = new JavaWrapper[newSize]; 19 | System.arraycopy(_values, 0, copy, 0, _values.length); 20 | _values = copy; 21 | } 22 | _values[_index++] = next; 23 | } 24 | 25 | public void pushAll(JavaWrapper... next) { 26 | for (JavaWrapper w : next) { 27 | push(w); 28 | } 29 | } 30 | 31 | public JavaWrapper pop() { 32 | if (--_index < 0) { 33 | throw new ExecutionException("Unable to pop operand off empty stack"); 34 | } 35 | JavaWrapper result = _values[_index]; 36 | _values[_index] = null; 37 | if (result.is(JavaValueType.DOUBLE) || result.is(JavaValueType.LONG)) { 38 | JavaWrapper shouldBeTop = pop(); 39 | if (!(shouldBeTop.get() instanceof JavaTop)) { 40 | throw new RuntimeException("Unexpected " + shouldBeTop); 41 | } 42 | } 43 | return result; 44 | } 45 | 46 | public JavaWrapper peek() { 47 | return _values[_index - 1]; 48 | } 49 | 50 | public int size() { 51 | return _index; 52 | } 53 | 54 | JavaWrapper[] internalArray() { 55 | JavaWrapper[] copy = new JavaWrapper[_values.length]; 56 | System.arraycopy(_values, 0, copy, 0, _values.length); 57 | return copy; 58 | } 59 | 60 | public Stack copy() { 61 | Stack newStack = new Stack(); 62 | newStack._values = new JavaWrapper[_values.length]; 63 | newStack._index = _index; 64 | for (int i = 0; i < _values.length; i++) { 65 | newStack._values[i] = _values[i]; 66 | } 67 | return newStack; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | StringBuilder builder = new StringBuilder(); 73 | for (int i = _values.length - 1; i >= 0; i--) { 74 | if (_values[i] != null) { 75 | builder.append(i).append(": ").append(_values[i].get()).append(" "); 76 | } 77 | } 78 | return builder.toString(); 79 | } 80 | 81 | public void clear() { 82 | _values = new JavaWrapper[16]; 83 | _index = 0; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/StackTraceHolder.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm; 2 | 3 | import org.objectweb.asm.tree.AbstractInsnNode; 4 | import org.objectweb.asm.tree.ClassNode; 5 | import org.objectweb.asm.tree.MethodNode; 6 | 7 | public class StackTraceHolder { 8 | private ClassNode _class; 9 | private MethodNode _method; 10 | private AbstractInsnNode _instruction; 11 | 12 | public StackTraceHolder(ClassNode clazz, MethodNode method, AbstractInsnNode instruction) { 13 | this._class = clazz; 14 | this._method = method; 15 | this._instruction = instruction; 16 | } 17 | 18 | public ClassNode getClassNode() { 19 | return _class; 20 | } 21 | 22 | public MethodNode getMethod() { 23 | return _method; 24 | } 25 | 26 | public AbstractInsnNode getInstruction() { 27 | return _instruction; 28 | } 29 | 30 | public void setInstruction(AbstractInsnNode instruction) { 31 | this._instruction = instruction; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "at " + _class.name + "." + _method.name + _method.desc; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/exceptions/AbortException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.exceptions; 18 | 19 | public class AbortException extends RuntimeException { 20 | public static final AbortException INSTANCE = new AbortException(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/exceptions/ConvertedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.exceptions; 18 | 19 | public class ConvertedException extends Exception { 20 | public ConvertedException() { 21 | } 22 | 23 | public ConvertedException(String message) { 24 | super(message); 25 | } 26 | 27 | public ConvertedException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public ConvertedException(Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | public ConvertedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 36 | super(message, cause, enableSuppression, writableStackTrace); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/exceptions/ExecutionException.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.exceptions; 2 | 3 | public class ExecutionException extends RuntimeException { 4 | public ExecutionException() { 5 | } 6 | 7 | public ExecutionException(String message) { 8 | super(message); 9 | } 10 | 11 | public ExecutionException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public ExecutionException(Throwable cause) { 16 | super(cause); 17 | } 18 | 19 | public ExecutionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 20 | super(message, cause, enableSuppression, writableStackTrace); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/exceptions/FallingOffCodeException.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.exceptions; 2 | 3 | public class FallingOffCodeException extends ExecutionException { 4 | public FallingOffCodeException() { 5 | super(""); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/exceptions/NoSuchHandlerException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.exceptions; 18 | 19 | public abstract class NoSuchHandlerException extends ExecutionException { 20 | public NoSuchHandlerException(String msg) { 21 | super(msg); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/exceptions/NoSuchMethodHandlerException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.exceptions; 18 | 19 | public class NoSuchMethodHandlerException extends NoSuchHandlerException { 20 | public NoSuchMethodHandlerException(String msg) { 21 | super(msg); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/exceptions/VMException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.exceptions; 18 | 19 | import com.javadeobfuscator.javavm.values.JavaWrapper; 20 | 21 | /** 22 | * This exception can be thrown when executing a method within the VM 23 | */ 24 | public class VMException extends RuntimeException { 25 | private JavaWrapper wrapped; 26 | 27 | public VMException(JavaWrapper inst) { 28 | super(new Throwable()); 29 | this.wrapped = inst; 30 | } 31 | 32 | public JavaWrapper getWrapped() { 33 | return this.wrapped; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/ext/net/DNSResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.ext.net; 18 | 19 | import java.net.InetAddress; 20 | import java.util.List; 21 | 22 | /** 23 | * Represents a DNS resolver 24 | */ 25 | public interface DNSResolver { 26 | /** 27 | * Resolve the given {@param host} into one or more {@link InetAddress}. The resolved InetAddress-es should be 28 | * added into the {@param result} list 29 | * 30 | * @return true to continue resolving with remaining resolvers, or false to continue resolving 31 | */ 32 | boolean resolve(String host, List result); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/ext/net/InterfaceAddress.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.ext.net; 18 | 19 | import java.net.Inet4Address; 20 | import java.net.InetAddress; 21 | 22 | public class InterfaceAddress { 23 | private InetAddress address = null; 24 | private Inet4Address broadcast = null; 25 | private short maskLength = 0; 26 | 27 | public InterfaceAddress() { 28 | } 29 | 30 | public InterfaceAddress(InetAddress address, Inet4Address broadcast, short maskLength) { 31 | this.address = address; 32 | this.broadcast = broadcast; 33 | this.maskLength = maskLength; 34 | } 35 | 36 | public InetAddress getAddress() { 37 | return address; 38 | } 39 | 40 | public void setAddress(InetAddress address) { 41 | this.address = address; 42 | } 43 | 44 | public Inet4Address getBroadcast() { 45 | return broadcast; 46 | } 47 | 48 | public void setBroadcast(Inet4Address broadcast) { 49 | this.broadcast = broadcast; 50 | } 51 | 52 | public short getMaskLength() { 53 | return maskLength; 54 | } 55 | 56 | public void setMaskLength(short maskLength) { 57 | this.maskLength = maskLength; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/ext/net/JSocket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.ext.net; 18 | 19 | import java.io.InputStream; 20 | import java.io.OutputStream; 21 | import java.util.concurrent.locks.ReadWriteLock; 22 | import java.util.concurrent.locks.ReentrantReadWriteLock; 23 | 24 | public class JSocket { 25 | private final int _fd; 26 | 27 | private volatile InputStream _fromExternal; 28 | private volatile OutputStream _toExternal; 29 | 30 | private final ReadWriteLock _streamRedirectorLock = new ReentrantReadWriteLock(); 31 | 32 | JSocket(int fd) { 33 | _fd = fd; 34 | } 35 | 36 | public int getFd() { 37 | return _fd; 38 | } 39 | 40 | /** 41 | * Set the source that this socket will read from. Can only be called once 42 | */ 43 | public void setInput(InputStream inputStream) { 44 | _streamRedirectorLock.writeLock().lock(); 45 | try { 46 | if (_fromExternal != null) { 47 | throw new IllegalArgumentException("input is already set"); 48 | } 49 | _fromExternal = inputStream; 50 | } finally { 51 | _streamRedirectorLock.writeLock().unlock(); 52 | } 53 | } 54 | 55 | /** 56 | * Set the destination that this socket will write to 57 | */ 58 | public void setOutput(OutputStream outputStream) { 59 | _streamRedirectorLock.writeLock().lock(); 60 | try { 61 | if (_toExternal != null) { 62 | throw new IllegalArgumentException("output is already set"); 63 | } 64 | _toExternal = outputStream; 65 | } finally { 66 | _streamRedirectorLock.writeLock().unlock(); 67 | } 68 | } 69 | 70 | public InputStream getInputStream() { 71 | _streamRedirectorLock.readLock().lock(); 72 | try { 73 | return _fromExternal; 74 | } finally { 75 | _streamRedirectorLock.readLock().unlock(); 76 | } 77 | } 78 | 79 | public OutputStream getOutputStream() { 80 | _streamRedirectorLock.readLock().lock(); 81 | try { 82 | return _toExternal; 83 | } finally { 84 | _streamRedirectorLock.readLock().unlock(); 85 | } 86 | } 87 | 88 | public boolean isConnected() { 89 | _streamRedirectorLock.readLock().lock(); 90 | try { 91 | return _fromExternal != null && _toExternal != null; 92 | } finally { 93 | _streamRedirectorLock.readLock().unlock(); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/ext/net/NetworkInterface.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.ext.net; 18 | 19 | import java.util.List; 20 | 21 | public class NetworkInterface { 22 | private String name; 23 | private String displayName; 24 | private List bindings; 25 | 26 | public NetworkInterface() { 27 | 28 | } 29 | 30 | public NetworkInterface(String name, String displayName, List bindings) { 31 | this.name = name; 32 | this.displayName = displayName; 33 | this.bindings = bindings; 34 | } 35 | 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | public void setName(String name) { 41 | this.name = name; 42 | } 43 | 44 | public String getDisplayName() { 45 | return displayName; 46 | } 47 | 48 | public void setDisplayName(String displayName) { 49 | this.displayName = displayName; 50 | } 51 | 52 | public List getBindings() { 53 | return bindings; 54 | } 55 | 56 | public void setBindings(List bindings) { 57 | this.bindings = bindings; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/ext/net/SocketConnectionEstablisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.ext.net; 18 | 19 | import java.io.InputStream; 20 | import java.io.OutputStream; 21 | import java.net.InetAddress; 22 | import java.net.InetSocketAddress; 23 | 24 | public interface SocketConnectionEstablisher { 25 | 26 | /** 27 | * Connect the provided socket to {@param target} by calling {@link JSocket#setInput(InputStream)} and {@link JSocket#setOutput(OutputStream)} 28 | * If the implementation cannot connect to the specified target, it should simply return 29 | */ 30 | void connect(JSocket socket, InetSocketAddress target); 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/ext/net/SystemDNSResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.ext.net; 18 | 19 | import java.net.InetAddress; 20 | import java.net.UnknownHostException; 21 | import java.util.Arrays; 22 | import java.util.List; 23 | 24 | /** 25 | * Resolves hosts using the system's DNS resolver 26 | */ 27 | public class SystemDNSResolver implements DNSResolver { 28 | @Override 29 | public boolean resolve(String host, List result) { 30 | try { 31 | InetAddress[] resolved = InetAddress.getAllByName(host); 32 | result.addAll(Arrays.asList(resolved)); 33 | } catch (UnknownHostException e) { 34 | } 35 | return true; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/hooks/HookedFieldGetter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.hooks; 18 | 19 | import com.javadeobfuscator.javavm.MethodExecution; 20 | import com.javadeobfuscator.javavm.values.JavaWrapper; 21 | 22 | public class HookedFieldGetter { 23 | private String _owner; 24 | private String _name; 25 | private String _desc; 26 | 27 | private HookedFieldGetter.Hook _handler; 28 | 29 | public HookedFieldGetter(String owner, String name, String desc) { 30 | this._owner = owner; 31 | this._name = name; 32 | this._desc = desc; 33 | } 34 | 35 | public HookedFieldGetter bind(HookedFieldGetter.Hook handler) { 36 | _handler = handler; 37 | return this; 38 | } 39 | 40 | public String getOwner() { 41 | return _owner; 42 | } 43 | 44 | public String getName() { 45 | return _name; 46 | } 47 | 48 | public String getDesc() { 49 | return _desc; 50 | } 51 | 52 | public JavaWrapper get(MethodExecution context, JavaWrapper instance) { 53 | return _handler.get(context, instance); 54 | } 55 | 56 | public interface Hook { 57 | JavaWrapper get(MethodExecution context, JavaWrapper instance); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/hooks/HookedFieldSetter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.hooks; 18 | 19 | import com.javadeobfuscator.javavm.MethodExecution; 20 | import com.javadeobfuscator.javavm.values.JavaWrapper; 21 | 22 | public class HookedFieldSetter { 23 | private String _owner; 24 | private String _name; 25 | private String _desc; 26 | 27 | private HookedFieldSetter.Hook _handler; 28 | 29 | public HookedFieldSetter(String owner, String name, String desc) { 30 | this._owner = owner; 31 | this._name = name; 32 | this._desc = desc; 33 | } 34 | 35 | public HookedFieldSetter bind(HookedFieldSetter.Hook handler) { 36 | _handler = handler; 37 | return this; 38 | } 39 | 40 | public String getOwner() { 41 | return _owner; 42 | } 43 | 44 | public String getName() { 45 | return _name; 46 | } 47 | 48 | public String getDesc() { 49 | return _desc; 50 | } 51 | 52 | public void set(MethodExecution context, JavaWrapper instance, JavaWrapper value) { 53 | _handler.set(context, instance, value); 54 | } 55 | 56 | public interface Hook { 57 | void set(MethodExecution context, JavaWrapper instance, JavaWrapper value); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/hooks/HookedMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.hooks; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.MethodExecution; 22 | import com.javadeobfuscator.javavm.values.JavaWrapper; 23 | import org.objectweb.asm.tree.AbstractInsnNode; 24 | 25 | public class HookedMethod { 26 | private String _owner; 27 | private String _name; 28 | private String _desc; 29 | private Cause _cause; 30 | private Effect _effect; 31 | 32 | private Hook _handler; 33 | 34 | public HookedMethod(String owner, String name, String desc) { 35 | this(owner, name, desc, Cause.ALL, Effect.ALL); 36 | } 37 | 38 | public HookedMethod(String owner, String name, String desc, Cause cause, Effect effect) { 39 | this._owner = owner; 40 | this._name = name; 41 | this._desc = desc; 42 | this._cause = cause; 43 | this._effect = effect; 44 | } 45 | 46 | public HookedMethod bind(Hook handler) { 47 | _handler = handler; 48 | return this; 49 | } 50 | 51 | public HookedMethod bind(VoidHook handler) { 52 | if (!this._desc.endsWith("V")) 53 | throw new IllegalArgumentException("Cannot bind non-returning handler with non-void function"); 54 | return bind((a, b, c) -> 55 | { 56 | handler.execute(a, b, c); 57 | return null; 58 | }); 59 | } 60 | 61 | public String getOwner() { 62 | return _owner; 63 | } 64 | 65 | public String getName() { 66 | return _name; 67 | } 68 | 69 | public String getDesc() { 70 | return _desc; 71 | } 72 | 73 | public Cause getCause() { 74 | return _cause; 75 | } 76 | 77 | public Effect getEffect() { 78 | return _effect; 79 | } 80 | 81 | public JavaWrapper execute(MethodExecution context, JavaWrapper instance, JavaWrapper[] args, AbstractInsnNode cur) { 82 | try { 83 | context.getVM().pushStacktrace(context.getClassNode(), context.getMethodNode(), cur); 84 | return _handler.execute(context, instance, args); 85 | } finally { 86 | context.getVM().popStacktrace(); 87 | } 88 | } 89 | 90 | public interface Hook { 91 | JavaWrapper execute(MethodExecution context, JavaWrapper instance, JavaWrapper[] args); 92 | } 93 | 94 | public interface VoidHook { 95 | void execute(MethodExecution context, JavaWrapper instance, JavaWrapper[] args); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/AconstNullInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import org.objectweb.asm.tree.AbstractInsnNode; 7 | 8 | import java.util.List; 9 | 10 | public class AconstNullInstruction extends Instruction { 11 | @Override 12 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 13 | stack.push(execution.getVM().getNull()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/ArrayLoadInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.internals.VMSymbols; 8 | import com.javadeobfuscator.javavm.utils.ExecutionUtils; 9 | import com.javadeobfuscator.javavm.values.JavaArray; 10 | import com.javadeobfuscator.javavm.values.JavaUnknown; 11 | import com.javadeobfuscator.javavm.values.JavaValueType; 12 | import com.javadeobfuscator.javavm.values.JavaWrapper; 13 | import org.objectweb.asm.Type; 14 | import org.objectweb.asm.tree.AbstractInsnNode; 15 | 16 | import java.util.List; 17 | 18 | public class ArrayLoadInstruction extends Instruction { 19 | private final int _sort; 20 | 21 | public ArrayLoadInstruction(int sort) { 22 | if (sort == Type.VOID || sort == Type.ARRAY || sort == Type.METHOD) { 23 | throw new InternalError("Tried to register ArrayLoadInstruction with illegal sort: " + sort); 24 | } 25 | this._sort = sort; 26 | } 27 | 28 | @Override 29 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 30 | JavaWrapper arrayIndex = stack.pop(); 31 | JavaWrapper arrayInstance = stack.pop(); 32 | 33 | if (!arrayInstance.is(JavaValueType.ARRAY)) { 34 | throw new ExecutionException("Expecting to find Array on type, instead found " + arrayInstance.getJavaClass() + " on " + arrayInstance); 35 | } 36 | 37 | if (arrayInstance.is(JavaValueType.NULL)) { 38 | throw execution.getVM().newThrowable(VMSymbols.java_lang_NullPointerException); 39 | } 40 | 41 | Type originalType = arrayInstance.getJavaClass().internalGetType(); 42 | Type resultingType = /*originalType.getElementType(1)*/Type.getType(originalType.getDescriptor().substring(1)); 43 | 44 | if (resultingType.getSort() != _sort) { 45 | if ((resultingType.getSort() == Type.ARRAY && _sort == Type.OBJECT)) { 46 | 47 | } else { 48 | if (_sort == Type.BYTE && (resultingType.getSort() == Type.BOOLEAN)) { 49 | // this is ok 50 | } else { 51 | throw new ExecutionException("Expected " + _sort + ", but found " + resultingType.getSort()); 52 | } 53 | } 54 | } 55 | 56 | if (!arrayIndex.is(JavaValueType.INTEGER)) { 57 | throw new ExecutionException("Expecting to find Integer on stack"); 58 | } 59 | 60 | if (ExecutionUtils.areValuesUnknown(arrayInstance, arrayIndex)) { 61 | stack.push(JavaWrapper.wrap(new JavaUnknown(execution.getVM(), arrayInstance.getJavaClass().getComponentType(), "Array load operation on (" + arrayInstance + ") index (" + arrayIndex + ")"))); 62 | return; 63 | } 64 | 65 | int index = arrayIndex.asInt(); 66 | JavaArray array = ((JavaArray) arrayInstance.get()); 67 | 68 | if (index >= array.length()) { 69 | throw execution.getVM().newThrowable(VMSymbols.java_lang_ArrayIndexOutOfBoundsException, String.valueOf(index)); 70 | } 71 | 72 | stack.push(array.get(index)); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/ArrayStoreInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.utils.ExecutionUtils; 8 | import com.javadeobfuscator.javavm.values.JavaArray; 9 | import com.javadeobfuscator.javavm.values.JavaUnknown; 10 | import com.javadeobfuscator.javavm.values.JavaValueType; 11 | import com.javadeobfuscator.javavm.values.JavaWrapper; 12 | import org.objectweb.asm.Type; 13 | import org.objectweb.asm.tree.AbstractInsnNode; 14 | 15 | import java.util.List; 16 | 17 | public class ArrayStoreInstruction extends Instruction { 18 | private final int _sort; 19 | 20 | public ArrayStoreInstruction(int sort) { 21 | if (sort == Type.VOID || sort == Type.ARRAY || sort == Type.METHOD) { 22 | throw new InternalError("Tried to register ArrayStoreInstruction with illegal sort: " + sort); 23 | } 24 | this._sort = sort; 25 | } 26 | 27 | @Override 28 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 29 | JavaWrapper storeValue = stack.pop(); 30 | JavaWrapper arrayIndexValue = stack.pop(); 31 | JavaWrapper arrayValue = stack.pop(); 32 | 33 | if (!arrayValue.is(JavaValueType.ARRAY)) { 34 | throw new ExecutionException("Expecting to find Array on type, instead found " + arrayValue.getJavaClass() + " on " + arrayValue); 35 | } 36 | 37 | if (ExecutionUtils.areValuesUnknown(arrayValue, arrayIndexValue)) { 38 | if (arrayValue.is(JavaValueType.UNKNOWN)) { 39 | ((JavaUnknown) arrayValue.get()).merge("Array store operation on this at " + arrayIndexValue + " value " + storeValue); 40 | } else if (arrayIndexValue.is(JavaValueType.UNKNOWN)) { 41 | arrayValue.set(new JavaUnknown(execution.getVM(), arrayValue.getJavaClass(), "Array store operation")); 42 | } else { 43 | throw new ExecutionException("An internal error occurred: Unhandled condition"); 44 | } 45 | return; 46 | } 47 | 48 | if (!arrayIndexValue.is(JavaValueType.INTEGER)) { 49 | throw new ExecutionException("Expecting to find Integer on stack"); 50 | } 51 | if (!arrayValue.is(JavaValueType.ARRAY)) { 52 | throw new ExecutionException("Expecting to find Array on stack, found " + arrayValue); 53 | } 54 | 55 | int index = arrayIndexValue.asInt(); 56 | JavaArray array = ((JavaArray) arrayValue.get()); 57 | 58 | array.set(index, storeValue); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/BipushInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import org.objectweb.asm.tree.AbstractInsnNode; 7 | import org.objectweb.asm.tree.IntInsnNode; 8 | 9 | import java.util.List; 10 | 11 | public class BipushInstruction extends Instruction { 12 | @Override 13 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 14 | IntInsnNode cast = (IntInsnNode) currentInsn; 15 | stack.push(execution.getVM().newByte((byte) cast.operand)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/CheckcastInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.internals.VMSymbols; 8 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 9 | import com.javadeobfuscator.javavm.utils.TypeHelper; 10 | import com.javadeobfuscator.javavm.values.JavaObject; 11 | import com.javadeobfuscator.javavm.values.JavaValueType; 12 | import com.javadeobfuscator.javavm.values.JavaWrapper; 13 | import org.objectweb.asm.Type; 14 | import org.objectweb.asm.tree.AbstractInsnNode; 15 | import org.objectweb.asm.tree.TypeInsnNode; 16 | 17 | import java.util.List; 18 | 19 | public class CheckcastInstruction extends Instruction { 20 | @Override 21 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 22 | TypeInsnNode cast = (TypeInsnNode) currentInsn; 23 | 24 | Type desc = TypeHelper.parseType(execution.getVM(), cast.desc); 25 | JavaClass other = JavaClass.forName(execution.getVM(), desc); 26 | JavaWrapper wrappedValue = stack.pop(); 27 | if (wrappedValue.is(JavaValueType.NULL)) { 28 | stack.push(wrappedValue); 29 | return; 30 | } 31 | 32 | stack.push(wrappedValue); 33 | // if (!wrappedValue.get().isInstanceOf(desc)) { 34 | // System.out.println(desc + " "+ other); 35 | // System.out.println(wrappedValue.getJavaClass().getName() + " cannot be cast to " + other.getName()); 36 | // throw new ExecutionException("asdf"); //execution.getVM().newThrowable(VMSymbols.java_lang_ClassCastException, wrappedValue.getJavaClass().getName() + " cannot be cast to " + other.getName()); 37 | // } 38 | // 39 | // if (wrappedValue.get() instanceof JavaObject) { 40 | // stack.push(JavaWrapper.wrap(wrappedValue.asObject().checkcast(other))); 41 | // } else { 42 | // stack.push(JavaWrapper.wrap(wrappedValue.asArray().checkcast(other))); 43 | // } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/DoubleMathInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.utils.BiDoubleFunction; 8 | import com.javadeobfuscator.javavm.utils.ExecutionUtils; 9 | import com.javadeobfuscator.javavm.values.JavaUnknown; 10 | import com.javadeobfuscator.javavm.values.JavaValue; 11 | import com.javadeobfuscator.javavm.values.JavaValueType; 12 | import com.javadeobfuscator.javavm.values.JavaWrapper; 13 | import org.objectweb.asm.tree.AbstractInsnNode; 14 | 15 | import java.util.List; 16 | 17 | public class DoubleMathInstruction extends Instruction { 18 | private final BiDoubleFunction _function; 19 | private final boolean _returnInt; 20 | 21 | public DoubleMathInstruction(BiDoubleFunction function, boolean returnInt) { 22 | this._function = function; 23 | this._returnInt = returnInt; 24 | } 25 | 26 | @Override 27 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 28 | JavaValue b = stack.pop().get(); 29 | JavaValue a = stack.pop().get(); 30 | 31 | if (ExecutionUtils.areValuesUnknown(a, b)) { 32 | stack.push(JavaWrapper.wrap(new JavaUnknown(execution.getVM(), execution.getVM().DOUBLE, JavaUnknown.UnknownCause.DOUBLE_MATH, b, a))); 33 | return; 34 | } 35 | 36 | if (!a.is(JavaValueType.DOUBLE) || !b.is(JavaValueType.DOUBLE)) { 37 | throw new ExecutionException("Expected to find double on stack"); 38 | } 39 | 40 | double result = _function.apply(a.asDouble(), b.asDouble()); 41 | if (!_returnInt) { 42 | stack.push(JavaWrapper.createDouble(execution.getVM(), result)); 43 | } else { 44 | stack.push(JavaWrapper.createInteger(execution.getVM(), (int) result)); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/DoublePredicateInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.utils.MaybeBoolean; 7 | import com.javadeobfuscator.javavm.values.JavaWrapper; 8 | import org.objectweb.asm.tree.AbstractInsnNode; 9 | import org.objectweb.asm.tree.JumpInsnNode; 10 | 11 | import java.util.List; 12 | import java.util.function.BiFunction; 13 | 14 | public class DoublePredicateInstruction extends Instruction { 15 | 16 | private final BiFunction _handler; 17 | 18 | public DoublePredicateInstruction(BiFunction handler) { 19 | this._handler = handler; 20 | } 21 | 22 | @Override 23 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 24 | JumpInsnNode jumpInsnNode = (JumpInsnNode) currentInsn; 25 | 26 | JavaWrapper top = stack.pop(); 27 | JavaWrapper bottom = stack.pop(); 28 | MaybeBoolean result = _handler.apply(bottom, top); 29 | switch (result) { 30 | case YES: 31 | branchTo.add(jumpInsnNode.label); 32 | break; 33 | case MAYBE: 34 | branchTo.add(jumpInsnNode.label); 35 | branchTo.add(jumpInsnNode.getNext()); 36 | break; 37 | case NO: 38 | break; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/FloatMathInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.utils.BiFloatInstruction; 8 | import com.javadeobfuscator.javavm.utils.ExecutionUtils; 9 | import com.javadeobfuscator.javavm.values.JavaUnknown; 10 | import com.javadeobfuscator.javavm.values.JavaValue; 11 | import com.javadeobfuscator.javavm.values.JavaValueType; 12 | import com.javadeobfuscator.javavm.values.JavaWrapper; 13 | import org.objectweb.asm.tree.AbstractInsnNode; 14 | 15 | import java.util.List; 16 | 17 | public class FloatMathInstruction extends Instruction { 18 | private final BiFloatInstruction _function; 19 | private final boolean _returnInt; 20 | 21 | public FloatMathInstruction(BiFloatInstruction function, boolean returnInt) { 22 | this._function = function; 23 | this._returnInt = returnInt; 24 | } 25 | 26 | @Override 27 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 28 | JavaValue b = stack.pop().get(); 29 | JavaValue a = stack.pop().get(); 30 | 31 | if (ExecutionUtils.areValuesUnknown(a, b)) { 32 | stack.push(JavaWrapper.wrap(new JavaUnknown(execution.getVM(), execution.getVM().FLOAT, JavaUnknown.UnknownCause.FLOAT_MATH, b, a))); 33 | return; 34 | } 35 | 36 | if (!a.is(JavaValueType.FLOAT) || !b.is(JavaValueType.FLOAT)) { 37 | throw new ExecutionException("Expected to find float on stack"); 38 | } 39 | 40 | float result = _function.apply(a.asFloat(), b.asFloat()); 41 | if (!_returnInt) { 42 | stack.push(JavaWrapper.createFloat(execution.getVM(), result)); 43 | } else { 44 | stack.push(JavaWrapper.createInteger(execution.getVM(), (int) result)); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/Instruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import org.objectweb.asm.tree.AbstractInsnNode; 7 | 8 | import java.util.List; 9 | 10 | public abstract class Instruction { 11 | public abstract void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/IntegerMathInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.internals.VMSymbols; 8 | import com.javadeobfuscator.javavm.utils.BiIntegerFunction; 9 | import com.javadeobfuscator.javavm.utils.ExecutionUtils; 10 | import com.javadeobfuscator.javavm.values.JavaUnknown; 11 | import com.javadeobfuscator.javavm.values.JavaValue; 12 | import com.javadeobfuscator.javavm.values.JavaValueType; 13 | import com.javadeobfuscator.javavm.values.JavaWrapper; 14 | import org.objectweb.asm.tree.AbstractInsnNode; 15 | 16 | import java.util.List; 17 | 18 | public class IntegerMathInstruction extends Instruction { 19 | private final BiIntegerFunction _function; 20 | private final boolean division; 21 | 22 | public IntegerMathInstruction(BiIntegerFunction function) { 23 | this._function = function; 24 | this.division = false; 25 | } 26 | 27 | public IntegerMathInstruction(BiIntegerFunction function, boolean division) { 28 | this._function = function; 29 | this.division = division; 30 | } 31 | 32 | @Override 33 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 34 | JavaValue b = stack.pop().get(); 35 | JavaValue a = stack.pop().get(); 36 | 37 | if (ExecutionUtils.areValuesUnknown(a, b)) { 38 | stack.push(JavaWrapper.wrap(new JavaUnknown(execution.getVM(), execution.getVM().INTEGER, JavaUnknown.UnknownCause.INTEGER_MATH, b, a))); 39 | return; 40 | } 41 | 42 | if (!a.is(JavaValueType.INTEGER) || !b.is(JavaValueType.INTEGER)) { 43 | throw new ExecutionException("Expected to find integer on stack"); 44 | } 45 | 46 | if (division && b.asInt() == 0) { 47 | throw execution.getVM().newThrowable(VMSymbols.java_lang_ArithmeticException, "/ by zero"); 48 | } 49 | 50 | stack.push(JavaWrapper.createInteger(execution.getVM(), _function.apply(a.asInt(), b.asInt()))); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/LdcInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 8 | import com.javadeobfuscator.javavm.utils.TypeHelper; 9 | import com.javadeobfuscator.javavm.values.JavaWrapper; 10 | import org.objectweb.asm.Type; 11 | import org.objectweb.asm.tree.AbstractInsnNode; 12 | import org.objectweb.asm.tree.LdcInsnNode; 13 | 14 | import java.util.List; 15 | 16 | public class LdcInstruction extends Instruction { 17 | @Override 18 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 19 | LdcInsnNode cast = (LdcInsnNode) currentInsn; 20 | 21 | Object load = cast.cst; 22 | if (load instanceof Type) { 23 | Type type = (Type) load; 24 | if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { 25 | String bytecodeName = type.getInternalName(); 26 | Type actualType = TypeHelper.parseType(execution.getVM(), bytecodeName); 27 | if (actualType == null) { 28 | throw new ExecutionException("An internal error occurred: Unexpected null Type while loading class"); 29 | } 30 | stack.push(JavaClass.forName(execution.getVM(), actualType).getOop()); 31 | } else { 32 | throw new ExecutionException("An internal error occurred: Unexpected sort on loaded type: " + load); 33 | } 34 | } else if (load instanceof Integer) { 35 | stack.push(JavaWrapper.createInteger(execution.getVM(), (Integer) load)); 36 | } else if (load instanceof Float) { 37 | stack.push(JavaWrapper.createFloat(execution.getVM(), (Float) load)); 38 | } else if (load instanceof Double) { 39 | stack.push(JavaWrapper.createDouble(execution.getVM(), (Double) load)); 40 | } else if (load instanceof Long) { 41 | stack.push(execution.getVM().newLong((Long) load)); 42 | } else if (load instanceof String) { 43 | stack.push(execution.getVM().getStringInterned((String) load)); 44 | } else { 45 | throw new ExecutionException("An internal error occurred: Unexpected ldc type " + (load == null ? "null" : load.getClass())); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/LoadOneWordInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.VirtualMachine; 7 | import com.javadeobfuscator.javavm.values.JavaWrapper; 8 | import org.objectweb.asm.tree.AbstractInsnNode; 9 | 10 | import java.util.List; 11 | import java.util.function.Function; 12 | 13 | public class LoadOneWordInstruction extends Instruction { 14 | private final Function _javaValueSupplier; 15 | 16 | public LoadOneWordInstruction(Function supplier) { 17 | _javaValueSupplier = supplier; 18 | } 19 | 20 | @Override 21 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 22 | stack.push(_javaValueSupplier.apply(execution.getVM())); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/LoadTwoWordInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.VirtualMachine; 7 | import com.javadeobfuscator.javavm.values.JavaWrapper; 8 | import org.objectweb.asm.tree.AbstractInsnNode; 9 | 10 | import java.util.List; 11 | import java.util.function.Function; 12 | 13 | public class LoadTwoWordInstruction extends Instruction { 14 | private final Function _javaValueSupplier; 15 | 16 | public LoadTwoWordInstruction(Function supplier) { 17 | _javaValueSupplier = supplier; 18 | } 19 | 20 | @Override 21 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 22 | stack.push(_javaValueSupplier.apply(execution.getVM())); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/LocalLoadInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.values.JavaValueType; 8 | import com.javadeobfuscator.javavm.values.JavaWrapper; 9 | import org.objectweb.asm.Type; 10 | import org.objectweb.asm.tree.AbstractInsnNode; 11 | import org.objectweb.asm.tree.VarInsnNode; 12 | 13 | import java.util.List; 14 | 15 | public class LocalLoadInstruction extends Instruction { 16 | 17 | private final int _sort; 18 | 19 | public LocalLoadInstruction(int sort) { 20 | if (sort == Type.VOID || sort == Type.ARRAY || sort == Type.METHOD || sort == Type.BYTE || sort == Type.BOOLEAN || sort == Type.SHORT || sort == Type.CHAR) { 21 | throw new InternalError("Tried to register LocalLoadInstruction with illegal sort: " + sort); 22 | } 23 | this._sort = sort; 24 | } 25 | 26 | @Override 27 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 28 | VarInsnNode varInsnNode = (VarInsnNode) currentInsn; 29 | JavaWrapper top = locals.get(varInsnNode.var); 30 | 31 | switch (_sort) { 32 | case Type.INT: 33 | if (!top.is(JavaValueType.INTEGER)) { 34 | throw new ExecutionException("Register " + varInsnNode.var + " contains wrong type. Expected INTEGER, got (" + top.get().getClass() + ")"); 35 | } 36 | stack.push(top); 37 | return; 38 | case Type.FLOAT: 39 | if (!top.is(JavaValueType.FLOAT)) { 40 | throw new ExecutionException("Register " + varInsnNode.var + " contains wrong type. Expected FLOAT, got (" + top.get().getClass() + ")"); 41 | } 42 | stack.push(top); 43 | return; 44 | case Type.OBJECT: 45 | if (!top.is(JavaValueType.OBJECT) && !top.is(JavaValueType.UNINITIALIZED)) { 46 | throw new ExecutionException("Register " + varInsnNode.var + " contains wrong type. Expected OBJECT, got (" + top.get().getClass() + ")"); 47 | } 48 | stack.push(top); 49 | return; 50 | case Type.DOUBLE: 51 | if (!top.is(JavaValueType.DOUBLE)) { 52 | throw new ExecutionException("Register " + varInsnNode.var + " contains wrong type. Expected DOUBLE, got (" + top.get().getClass() + ")"); 53 | } 54 | stack.push(top); 55 | return; 56 | case Type.LONG: 57 | if (!top.is(JavaValueType.LONG)) { 58 | throw new ExecutionException("Register " + varInsnNode.var + " contains wrong type. Expected LONG, got (" + top.get().getClass() + ")"); 59 | } 60 | stack.push(top); 61 | return; 62 | default: 63 | throw new ExecutionException("An internal error occurred: Unhandled sort " + _sort); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/LocalStoreInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.values.JavaValueType; 8 | import com.javadeobfuscator.javavm.values.JavaWrapper; 9 | import org.objectweb.asm.Type; 10 | import org.objectweb.asm.tree.AbstractInsnNode; 11 | import org.objectweb.asm.tree.VarInsnNode; 12 | 13 | import java.util.List; 14 | 15 | public class LocalStoreInstruction extends Instruction { 16 | 17 | private final int _sort; 18 | 19 | public LocalStoreInstruction(int sort) { 20 | if (sort == Type.VOID || sort == Type.ARRAY || sort == Type.METHOD || sort == Type.BYTE || sort == Type.BOOLEAN || sort == Type.SHORT || sort == Type.CHAR) { 21 | throw new InternalError("Tried to register LocalStoreInstruction with illegal sort: " + sort); 22 | } 23 | this._sort = sort; 24 | } 25 | 26 | @Override 27 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 28 | VarInsnNode varInsnNode = (VarInsnNode) currentInsn; 29 | JavaWrapper top = stack.pop(); 30 | 31 | switch (_sort) { 32 | case Type.INT: 33 | if (!top.is(JavaValueType.INTEGER)) { 34 | throw new ExecutionException("Register " + varInsnNode.var + " contains wrong type. Expected INTEGER, got (" + top.get().getClass() + ")"); 35 | } 36 | locals.set(varInsnNode.var, top); 37 | break; 38 | case Type.FLOAT: 39 | if (!top.is(JavaValueType.FLOAT)) { 40 | throw new ExecutionException("Register " + varInsnNode.var + " contains wrong type. Expected FLOAT, got (" + top.get().getClass() + ")"); 41 | } 42 | locals.set(varInsnNode.var, top); 43 | break; 44 | case Type.OBJECT: 45 | if (!top.is(JavaValueType.OBJECT) && !top.is(JavaValueType.UNINITIALIZED)) { 46 | throw new ExecutionException("Register " + varInsnNode.var + " contains wrong type. Expected OBJECT, got (" + top.get().getClass() + ")"); 47 | } 48 | locals.set(varInsnNode.var, top); 49 | break; 50 | case Type.DOUBLE: 51 | if (!top.is(JavaValueType.DOUBLE)) { 52 | throw new ExecutionException("Register " + varInsnNode.var + " contains wrong type. Expected DOUBLE, got (" + top.get().getClass() + ")"); 53 | } 54 | locals.set(varInsnNode.var, top); 55 | break; 56 | case Type.LONG: 57 | if (!top.is(JavaValueType.LONG)) { 58 | throw new ExecutionException("Register " + varInsnNode.var + " contains wrong type. Expected LONG, got (" + top.get().getClass() + ")"); 59 | } 60 | locals.set(varInsnNode.var, top); 61 | break; 62 | default: 63 | throw new ExecutionException("An internal error occurred: Unhandled sort " + _sort); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/LongIntegerMathInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.utils.BiLongIntegerFunction; 8 | import com.javadeobfuscator.javavm.utils.ExecutionUtils; 9 | import com.javadeobfuscator.javavm.values.JavaUnknown; 10 | import com.javadeobfuscator.javavm.values.JavaValue; 11 | import com.javadeobfuscator.javavm.values.JavaValueType; 12 | import com.javadeobfuscator.javavm.values.JavaWrapper; 13 | import org.objectweb.asm.tree.AbstractInsnNode; 14 | 15 | import java.util.List; 16 | 17 | public class LongIntegerMathInstruction extends Instruction { 18 | private final BiLongIntegerFunction _function; 19 | 20 | public LongIntegerMathInstruction(BiLongIntegerFunction function) { 21 | this._function = function; 22 | } 23 | 24 | @Override 25 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 26 | JavaValue b = stack.pop().get(); 27 | JavaValue a = stack.pop().get(); 28 | 29 | if (ExecutionUtils.areValuesUnknown(a, b)) { 30 | stack.push(JavaWrapper.wrap(new JavaUnknown(execution.getVM(), execution.getVM().LONG, JavaUnknown.UnknownCause.LONG_INTEGER_MATH, b, a))); 31 | return; 32 | } 33 | 34 | if (!b.is(JavaValueType.INTEGER)) { 35 | throw new ExecutionException("Expected to find integer on stack"); 36 | } 37 | if (!a.is(JavaValueType.LONG)) { 38 | throw new ExecutionException("Expected to find long on stack"); 39 | } 40 | 41 | stack.push(execution.getVM().newLong(_function.apply(a.asLong(), b.asInt()))); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/LongMathInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 7 | import com.javadeobfuscator.javavm.utils.BiLongFunction; 8 | import com.javadeobfuscator.javavm.utils.ExecutionUtils; 9 | import com.javadeobfuscator.javavm.values.JavaUnknown; 10 | import com.javadeobfuscator.javavm.values.JavaValue; 11 | import com.javadeobfuscator.javavm.values.JavaValueType; 12 | import com.javadeobfuscator.javavm.values.JavaWrapper; 13 | import org.objectweb.asm.tree.AbstractInsnNode; 14 | 15 | import java.util.List; 16 | 17 | public class LongMathInstruction extends Instruction { 18 | private final BiLongFunction _function; 19 | private final boolean _returnInt; 20 | 21 | public LongMathInstruction(BiLongFunction function, boolean returnInt) { 22 | this._function = function; 23 | this._returnInt = returnInt; 24 | } 25 | 26 | @Override 27 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 28 | JavaValue b = stack.pop().get(); 29 | JavaValue a = stack.pop().get(); 30 | 31 | if (ExecutionUtils.areValuesUnknown(a, b)) { 32 | stack.push(JavaWrapper.wrap(new JavaUnknown(execution.getVM(), execution.getVM().LONG, JavaUnknown.UnknownCause.LONG_MATH, b, a))); 33 | return; 34 | } 35 | 36 | if (!a.is(JavaValueType.LONG) || !b.is(JavaValueType.LONG)) { 37 | throw new ExecutionException("Expected to find long on stack"); 38 | } 39 | 40 | long result = _function.apply(a.asLong(), b.asLong()); 41 | if (!_returnInt) { 42 | stack.push(execution.getVM().newLong(result)); 43 | } else { 44 | stack.push(JavaWrapper.createInteger(execution.getVM(), (int) result)); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/NewArrayInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 7 | import com.javadeobfuscator.javavm.utils.ArrayHelper; 8 | import com.javadeobfuscator.javavm.values.JavaUnknown; 9 | import com.javadeobfuscator.javavm.values.JavaValue; 10 | import com.javadeobfuscator.javavm.values.JavaValueType; 11 | import com.javadeobfuscator.javavm.values.JavaWrapper; 12 | import org.objectweb.asm.Type; 13 | import org.objectweb.asm.tree.AbstractInsnNode; 14 | import org.objectweb.asm.tree.IntInsnNode; 15 | 16 | import java.util.List; 17 | 18 | import static org.objectweb.asm.Opcodes.*; 19 | 20 | public class NewArrayInstruction extends Instruction { 21 | private static Type[] MAPPING = new Type[12]; 22 | 23 | static { 24 | MAPPING[T_BOOLEAN] = Type.BOOLEAN_TYPE; 25 | MAPPING[T_CHAR] = Type.CHAR_TYPE; 26 | MAPPING[T_FLOAT] = Type.FLOAT_TYPE; 27 | MAPPING[T_DOUBLE] = Type.DOUBLE_TYPE; 28 | MAPPING[T_BYTE] = Type.BYTE_TYPE; 29 | MAPPING[T_SHORT] = Type.SHORT_TYPE; 30 | MAPPING[T_INT] = Type.INT_TYPE; 31 | MAPPING[T_LONG] = Type.LONG_TYPE; 32 | } 33 | 34 | @Override 35 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 36 | IntInsnNode cast = (IntInsnNode) currentInsn; 37 | 38 | JavaValue lengthValue = stack.pop().get(); 39 | 40 | if (!lengthValue.is(JavaValueType.UNKNOWN)) { 41 | stack.push(ArrayHelper.newInstance(execution.getVM(), MAPPING[cast.operand], lengthValue.asInt())); 42 | } else { 43 | stack.push(JavaWrapper.wrap(new JavaUnknown(execution.getVM(), JavaClass.forName(execution.getVM(), MAPPING[cast.operand]), JavaUnknown.UnknownCause.ANEWARRAY, lengthValue))); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/NewInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 7 | import com.javadeobfuscator.javavm.utils.TypeHelper; 8 | import com.javadeobfuscator.javavm.values.JavaWrapper; 9 | import org.objectweb.asm.Type; 10 | import org.objectweb.asm.tree.AbstractInsnNode; 11 | import org.objectweb.asm.tree.TypeInsnNode; 12 | 13 | import java.util.List; 14 | 15 | public class NewInstruction extends Instruction { 16 | @Override 17 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 18 | TypeInsnNode cast = (TypeInsnNode) currentInsn; 19 | 20 | Type descType = TypeHelper.parseType(execution.getVM(), cast.desc); 21 | JavaClass clazz = JavaClass.forName(execution.getVM(), descType); 22 | 23 | execution.getVM().initialize(clazz); 24 | 25 | stack.push(JavaWrapper.createUninitialized(clazz, cast.desc)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/NopInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import org.objectweb.asm.tree.AbstractInsnNode; 7 | 8 | import java.util.List; 9 | 10 | public class NopInstruction extends Instruction { 11 | @Override 12 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/SinglePredicateInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import com.javadeobfuscator.javavm.utils.MaybeBoolean; 7 | import com.javadeobfuscator.javavm.values.JavaWrapper; 8 | import org.objectweb.asm.tree.AbstractInsnNode; 9 | import org.objectweb.asm.tree.JumpInsnNode; 10 | 11 | import java.util.List; 12 | import java.util.function.Function; 13 | 14 | public class SinglePredicateInstruction extends Instruction { 15 | 16 | private final Function _handler; 17 | 18 | public SinglePredicateInstruction(Function handler) { 19 | this._handler = handler; 20 | } 21 | 22 | @Override 23 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 24 | JumpInsnNode jumpInsnNode = (JumpInsnNode) currentInsn; 25 | 26 | JavaWrapper top = stack.pop(); 27 | MaybeBoolean result = _handler.apply(top); 28 | switch (result) { 29 | case YES: 30 | branchTo.add(jumpInsnNode.label); 31 | break; 32 | case MAYBE: 33 | branchTo.add(jumpInsnNode.label); 34 | branchTo.add(jumpInsnNode.getNext()); 35 | break; 36 | case NO: 37 | break; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/instructions/SipushInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.instructions; 2 | 3 | import com.javadeobfuscator.javavm.Locals; 4 | import com.javadeobfuscator.javavm.MethodExecution; 5 | import com.javadeobfuscator.javavm.Stack; 6 | import org.objectweb.asm.tree.AbstractInsnNode; 7 | import org.objectweb.asm.tree.IntInsnNode; 8 | 9 | import java.util.List; 10 | 11 | public class SipushInstruction extends Instruction { 12 | @Override 13 | public void execute(MethodExecution execution, AbstractInsnNode currentInsn, Stack stack, Locals locals, List branchTo) { 14 | IntInsnNode cast = (IntInsnNode) currentInsn; 15 | stack.push(execution.getVM().newShort((short) cast.operand)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/internals/ClassLoaderData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.internals; 18 | 19 | import com.javadeobfuscator.javavm.values.JavaWrapper; 20 | 21 | import java.util.LinkedList; 22 | import java.util.Objects; 23 | 24 | public class ClassLoaderData { 25 | public static final ClassLoaderData NULL_LOADER_DATA = new ClassLoaderData(null, false, new Dependencies()); 26 | private static final LinkedList classLoaderDatas = new LinkedList<>(); 27 | private static final Object classLoaderDataLock = new Object(); 28 | private final Handle loader; 29 | private final boolean isAnonymous; 30 | private final Dependencies dependencies; 31 | 32 | private ClassLoaderData(Handle loader, boolean isAnonymous, Dependencies dependencies) { 33 | this.loader = loader; 34 | this.isAnonymous = isAnonymous; 35 | this.dependencies = dependencies; 36 | } 37 | 38 | public static ClassLoaderData classLoaderDataOrNull(JavaWrapper loader) { 39 | return loader == null ? NULL_LOADER_DATA : loader.getVM().getJavaLangClassLoader().loaderData(loader); 40 | } 41 | 42 | public static ClassLoaderData findOrCreate(Handle loader) { 43 | ClassLoaderData cachedData = loader.get().getVM().getJavaLangClassLoader().loaderData(loader.get()); 44 | if (cachedData != null) { 45 | return cachedData; 46 | } 47 | 48 | return add(loader, false); 49 | } 50 | 51 | private static ClassLoaderData add(Handle loader, boolean isAnonymous) { 52 | ClassLoaderData data = new ClassLoaderData(loader, isAnonymous, new Dependencies()); 53 | 54 | if (!isAnonymous) { 55 | ClassLoaderData old = loader.get().compareAndSwapMetadata(VMSymbols.METADATA_LOADER_DATA, data, null); 56 | if (old != null) { 57 | return old; 58 | } 59 | } 60 | 61 | synchronized (classLoaderDataLock) { 62 | classLoaderDatas.addFirst(data); 63 | } 64 | 65 | return data; 66 | } 67 | 68 | public static ClassLoaderData classLoaderData(JavaWrapper oop) { 69 | return classLoaderDataOrNull(oop); 70 | } 71 | 72 | @Override 73 | public boolean equals(Object o) { 74 | if (this == o) return true; 75 | if (o == null || getClass() != o.getClass()) return false; 76 | ClassLoaderData that = (ClassLoaderData) o; 77 | return Objects.equals(loader, that.loader); 78 | } 79 | 80 | @Override 81 | public int hashCode() { 82 | return Objects.hash(loader); 83 | } 84 | 85 | public static class Dependencies { 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/internals/FieldDescriptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.internals; 18 | 19 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 20 | import com.javadeobfuscator.javavm.mirrors.JavaField; 21 | 22 | import java.lang.reflect.Modifier; 23 | 24 | public class FieldDescriptor { 25 | private int flags; // todo make accessflags 26 | private int index; 27 | private Object constantPool; 28 | // javavm 29 | private JavaField field; 30 | 31 | public FieldDescriptor() { 32 | 33 | } 34 | 35 | public void reinitialize(JavaClass klass, int index) { 36 | flags = klass.getFieldById(index).getFieldNode().access; 37 | field = klass.getFieldById(index); 38 | this.index = index; 39 | } 40 | 41 | public int getFlags() { 42 | return flags; 43 | } 44 | 45 | public int getIndex() { 46 | return index; 47 | } 48 | 49 | public boolean is_static() { 50 | return Modifier.isStatic(flags); 51 | } 52 | 53 | public JavaClass fieldHolder() { 54 | return field.getDeclaringClass(); 55 | } 56 | 57 | public String signature() { 58 | return field.getFieldNode().desc; 59 | } 60 | 61 | public String name() { 62 | return field.getFieldNode().name; 63 | } 64 | 65 | public boolean hasField() { 66 | return field != null; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/internals/FieldType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.internals; 18 | 19 | public class FieldType { 20 | public static boolean isArray(String desc) { 21 | return desc.length() > 1 && desc.charAt(0) == '[' && isValidArraySignature(desc); 22 | } 23 | 24 | public static boolean isObject(String desc) { 25 | return desc.length() >= 2 && desc.charAt(0) == 'L' && desc.charAt(desc.length() - 1) == ';'; 26 | } 27 | 28 | private static boolean isValidArraySignature(String desc) { 29 | int i = 1; 30 | while (i < desc.length() - 1 && desc.charAt(i) == '[') i++; 31 | switch (desc.charAt(i)) { 32 | case 'B': 33 | case 'C': 34 | case 'D': 35 | case 'F': 36 | case 'I': 37 | case 'J': 38 | case 'S': 39 | case 'Z': 40 | return i + 1 == desc.length(); 41 | case 'L': 42 | return desc.charAt(desc.length() - 1) == ';'; 43 | } 44 | 45 | return false; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/internals/Handle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.internals; 18 | 19 | import com.javadeobfuscator.javavm.values.JavaWrapper; 20 | 21 | import java.util.Objects; 22 | 23 | public class Handle { 24 | private JavaWrapper handle; 25 | 26 | public Handle(JavaWrapper handle) { 27 | this.handle = handle; 28 | } 29 | 30 | public JavaWrapper get() { 31 | return this.handle; 32 | } 33 | 34 | public boolean notNull() { 35 | return handle != null; 36 | } 37 | 38 | public boolean isNull() { 39 | return handle == null; 40 | } 41 | 42 | @Override 43 | public boolean equals(Object o) { 44 | if (this == o) return true; 45 | if (o == null || getClass() != o.getClass()) return false; 46 | Handle handle1 = (Handle) o; 47 | return Objects.equals(handle, handle1.handle); 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | return Objects.hash(handle); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/internals/KlassHandle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.internals; 18 | 19 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 20 | 21 | // KlassHandle 22 | public class KlassHandle { 23 | private JavaClass handle; 24 | 25 | public KlassHandle(JavaClass handle) { 26 | this.handle = handle; 27 | } 28 | 29 | public JavaClass get() { 30 | return this.handle; 31 | } 32 | 33 | public boolean notNull() { 34 | return handle != null; 35 | } 36 | 37 | public boolean isNull() { 38 | return handle == null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/internals/MethodHandle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.internals; 18 | 19 | import com.javadeobfuscator.javavm.mirrors.JavaMethod; 20 | 21 | public class MethodHandle { 22 | private JavaMethod javaMethod; 23 | 24 | public MethodHandle() { 25 | 26 | } 27 | 28 | public MethodHandle(JavaMethod javaMethod) { 29 | this.javaMethod = javaMethod; 30 | } 31 | 32 | public JavaMethod get() { 33 | return javaMethod; 34 | } 35 | 36 | public void set(JavaMethod javaMethod) { 37 | this.javaMethod = javaMethod; 38 | } 39 | 40 | public boolean isNull() { 41 | return javaMethod == null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/mirrors/JavaExecutable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.mirrors; 18 | 19 | import java.lang.reflect.Modifier; 20 | 21 | public abstract class JavaExecutable { 22 | static final int ACCESS_MODIFIERS = 23 | Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE; 24 | 25 | void separateWithCommas(JavaClass[] types, StringBuilder sb) { 26 | for (int j = 0; j < types.length; j++) { 27 | sb.append(types[j].getTypeName()); 28 | if (j < (types.length - 1)) 29 | sb.append(","); 30 | } 31 | 32 | } 33 | 34 | void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) { 35 | int mod = getModifiers() & mask; 36 | 37 | if (mod != 0 && !isDefault) { 38 | sb.append(Modifier.toString(mod)).append(' '); 39 | } else { 40 | int access_mod = mod & ACCESS_MODIFIERS; 41 | if (access_mod != 0) 42 | sb.append(Modifier.toString(access_mod)).append(' '); 43 | if (isDefault) 44 | sb.append("default "); 45 | mod = (mod & ~ACCESS_MODIFIERS); 46 | if (mod != 0) 47 | sb.append(Modifier.toString(mod)).append(' '); 48 | } 49 | } 50 | 51 | /** 52 | * Generate toString header information specific to a method or 53 | * constructor. 54 | */ 55 | abstract void specificToStringHeader(StringBuilder sb); 56 | 57 | abstract int getModifiers(); 58 | 59 | String sharedToString(int modifierMask, 60 | boolean isDefault, 61 | JavaClass[] parameterTypes, 62 | JavaClass[] exceptionTypes) { 63 | try { 64 | StringBuilder sb = new StringBuilder(); 65 | 66 | printModifiersIfNonzero(sb, modifierMask, isDefault); 67 | specificToStringHeader(sb); 68 | 69 | sb.append('('); 70 | separateWithCommas(parameterTypes, sb); 71 | sb.append(')'); 72 | if (exceptionTypes.length > 0) { 73 | sb.append(" throws "); 74 | separateWithCommas(exceptionTypes, sb); 75 | } 76 | return sb.toString(); 77 | } catch (Exception e) { 78 | return "<" + e + ">"; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/mirrors/JavaMethodHandle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.mirrors; 18 | 19 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 20 | import com.javadeobfuscator.javavm.internals.VMSymbols; 21 | 22 | import static com.javadeobfuscator.javavm.internals.VMSymbols.*; 23 | 24 | public class JavaMethodHandle { 25 | public static VMSymbols.VMIntrinsics signaturePolymorphicNameId(String name) { 26 | switch (name) { 27 | case VMSymbols.INVOKE_NAME: 28 | return VMSymbols.VMIntrinsics.INVOKE_GENERIC; 29 | case VMSymbols.INVOKE_BASIC_NAME: 30 | return VMSymbols.VMIntrinsics.INVOKE_BASIC; 31 | case VMSymbols.LINK_TO_VIRTUAL_NAME: 32 | return VMSymbols.VMIntrinsics.LINK_TO_VIRTUAL; 33 | case LINK_TO_STATIC_NAME: 34 | return VMSymbols.VMIntrinsics.LINK_TO_STATIC; 35 | case LINK_TO_SPECIAL_NAME: 36 | return VMSymbols.VMIntrinsics.LINK_TO_SPECIAL; 37 | case LINK_TO_INTERFACE_NAME: 38 | return VMSymbols.VMIntrinsics.LINK_TO_INTERFACE; 39 | } 40 | 41 | // todo this is not official 42 | if (name.startsWith("invoke")) { 43 | return VMSymbols.VMIntrinsics.INVOKE_GENERIC; 44 | } 45 | 46 | return VMSymbols.VMIntrinsics.NONE; 47 | } 48 | 49 | public static String signaturePolymorphicIntrinsicName(VMSymbols.VMIntrinsics id) { 50 | switch (id) { 51 | case INVOKE_BASIC: 52 | return VMSymbols.INVOKE_BASIC_NAME; 53 | case LINK_TO_VIRTUAL: 54 | return VMSymbols.LINK_TO_VIRTUAL_NAME; 55 | case LINK_TO_STATIC: 56 | return LINK_TO_STATIC_NAME; 57 | case LINK_TO_SPECIAL: 58 | return VMSymbols.LINK_TO_SPECIAL_NAME; 59 | case LINK_TO_INTERFACE: 60 | return VMSymbols.LINK_TO_INTERFACE_NAME; 61 | } 62 | throw new ExecutionException("Unsupported vm intrinsic " + id); 63 | } 64 | 65 | public static boolean isSignaturePolymorphicIntrinsic(VMSymbols.VMIntrinsics id) { 66 | return id != VMSymbols.VMIntrinsics.INVOKE_GENERIC; 67 | } 68 | 69 | public static boolean isSignaturePolymorphicStatic(VMSymbols.VMIntrinsics id) { 70 | return id != null && id.ordinal() >= VMSymbols.VMIntrinsics.FIRST_MH_STATIC.ordinal() && id.ordinal() <= VMSymbols.VMIntrinsics.LAST_MH_SIG_POLY.ordinal(); 71 | } 72 | 73 | public static boolean isIntrinsicStatic(VMSymbols.VMIntrinsics id) { 74 | return id == VMSymbols.VMIntrinsics.LINK_TO_VIRTUAL 75 | || id == VMSymbols.VMIntrinsics.LINK_TO_INTERFACE 76 | || id == VMSymbols.VMIntrinsics.LINK_TO_SPECIAL 77 | || id == VMSymbols.VMIntrinsics.LINK_TO_STATIC; 78 | } 79 | } -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/mirrors/JavaThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.mirrors; 18 | 19 | public class JavaThread { 20 | 21 | public class JavaThreadImpl extends Thread { 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_awt_Font.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.values.JavaWrapper; 24 | 25 | public class java_awt_Font { 26 | public static void registerNatives(VirtualMachine vm) { 27 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, "java/awt/Font", "initIDs", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 28 | })); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_io_FileDescriptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.values.JavaWrapper; 24 | 25 | public class java_io_FileDescriptor { 26 | private static final String THIS = "java/io/FileDescriptor"; 27 | 28 | public static JavaWrapper getHandle(JavaWrapper fileDescriptor) { 29 | return fileDescriptor.asObject().getField("handle", "J"); 30 | } 31 | 32 | public static int getFd(JavaWrapper fileDescriptor) { 33 | return fileDescriptor.asObject().getField("fd", "I").asInt(); 34 | } 35 | 36 | public static void registerNatives(VirtualMachine vm) { 37 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, THIS, "initIDs", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 38 | })); 39 | 40 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "set", "(I)J", true, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 41 | return vm.newLong(args[0].asInt()); 42 | })); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_io_UnixFileSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.values.JavaWrapper; 24 | 25 | import java.io.File; 26 | 27 | public class java_io_UnixFileSystem { 28 | private static final String THIS = "java/io/UnixFileSystem"; 29 | 30 | public static void registerNatives(VirtualMachine vm) { 31 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, THIS, "initIDs", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 32 | })); 33 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, "java/io/UnixFileSystem", "getBooleanAttributes", "(Ljava/io/File;)I", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 34 | String path = vm.convertJavaObjectToString(args[0].asObject().getField("path", "Ljava/lang/String;")); 35 | File file = vm.getFilesystem().map(new File(path)); 36 | if (file != null && file.exists()) { 37 | System.out.println("[Filesystem] Getting boolean attributes of " + file + " (" + path + ")"); 38 | int result = 0x01; // BA_EXISTS; 39 | if (file.isDirectory()) { 40 | result |= 0x04; 41 | } 42 | if (file.isFile()) { 43 | result |= 0x02; 44 | } 45 | if (file.isHidden()) { 46 | result |= 0x08; 47 | } 48 | return vm.newInt(result); 49 | } 50 | System.out.println("[Filesystem] Could not get boolean attributes of file " + path); 51 | return vm.newInt(0); 52 | })); 53 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, "java/io/UnixFileSystem", "canonicalize0", "(Ljava/lang/String;)Ljava/lang/String;", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 54 | return args[0]; 55 | })); 56 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, "java/io/UnixFileSystem", "canonicalizeWithPrefix0", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 57 | return args[1]; 58 | })); 59 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, "java/io/UnixFileSystem", "getLastModifiedTime", "(Ljava/io/File;)J", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 60 | return vm.newLong(new File(vm.convertJavaObjectToString(args[0].asObject().getField("path", "Ljava/lang/String;"))).lastModified()); 61 | })); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_io_WinNTFileSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.values.JavaWrapper; 24 | 25 | import java.io.File; 26 | 27 | public class java_io_WinNTFileSystem { 28 | private static final String THIS = "java/io/WinNTFileSystem"; 29 | 30 | public static void registerNatives(VirtualMachine vm) { 31 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, THIS, "initIDs", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 32 | })); 33 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, "java/io/WinNTFileSystem", "getBooleanAttributes", "(Ljava/io/File;)I", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 34 | String path = vm.convertJavaObjectToString(args[0].asObject().getField("path", "Ljava/lang/String;")); 35 | File file = vm.getFilesystem().map(new File(path)); 36 | if (file != null && file.exists()) { 37 | System.out.println("[Filesystem] Getting boolean attributes of " + file + " (" + path + ")"); 38 | int result = 0x01; // BA_EXISTS; 39 | if (file.isDirectory()) { 40 | result |= 0x04; 41 | } 42 | if (file.isFile()) { 43 | result |= 0x02; 44 | } 45 | if (file.isHidden()) { 46 | result |= 0x08; 47 | } 48 | return vm.newInt(result); 49 | } 50 | System.out.println("[Filesystem] Could not get boolean attributes of file " + path); 51 | return vm.newInt(0); 52 | })); 53 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, "java/io/WinNTFileSystem", "canonicalize0", "(Ljava/lang/String;)Ljava/lang/String;", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 54 | return args[0]; 55 | })); 56 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, "java/io/WinNTFileSystem", "canonicalizeWithPrefix0", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 57 | return args[1]; 58 | })); 59 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, "java/io/WinNTFileSystem", "getLastModifiedTime", "(Ljava/io/File;)J", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 60 | return vm.newLong(new File(vm.convertJavaObjectToString(args[0].asObject().getField("path", "Ljava/lang/String;"))).lastModified()); 61 | })); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_Double.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.values.JavaWrapper; 24 | 25 | public class java_lang_Double { 26 | private static final String THIS = "java/lang/Double"; 27 | 28 | public static void registerNatives(VirtualMachine vm) { 29 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "doubleToRawLongBits", "(D)J", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 30 | return vm.newLong(Double.doubleToRawLongBits(args[0].asDouble())); 31 | })); 32 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "longBitsToDouble", "(J)D", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 33 | return JavaWrapper.createDouble(vm, Double.longBitsToDouble(args[0].asLong())); 34 | })); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_Float.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.values.JavaWrapper; 24 | 25 | public class java_lang_Float { 26 | private static final String THIS = "java/lang/Float"; 27 | 28 | public static void registerNatives(VirtualMachine vm) { 29 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "floatToRawIntBits", "(F)I", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 30 | return JavaWrapper.createInteger(vm, Float.floatToRawIntBits(args[0].asFloat())); 31 | })); 32 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "intBitsToFloat", "(F)I", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 33 | return JavaWrapper.createFloat(vm, Float.intBitsToFloat(args[0].asInt())); 34 | })); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_Runtime.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.hooks.HookedMethod; 24 | import com.javadeobfuscator.javavm.values.JavaWrapper; 25 | 26 | public class java_lang_Runtime { 27 | private final VirtualMachine _vm; 28 | 29 | public java_lang_Runtime(VirtualMachine vm) { 30 | _vm = vm; 31 | registerNatives(); 32 | } 33 | 34 | private void registerNatives() { 35 | _vm.hook(new HookedMethod("java/lang/Runtime", "availableProcessors", "()I", Cause.ALL, Effect.NONE).bind((ctx, inst, args) -> { 36 | return JavaWrapper.createInteger(_vm, 8); 37 | })); 38 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/lang/Runtime", "totalMemory", "()J", false, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 39 | return _vm.newLong((long) 8e+9); 40 | })); 41 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/lang/Runtime", "freeMemory", "()J", false, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 42 | return _vm.newLong((long) 8e+9); 43 | })); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_SecurityManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.StackTraceHolder; 22 | import com.javadeobfuscator.javavm.VirtualMachine; 23 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 24 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 25 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 26 | import com.javadeobfuscator.javavm.values.JavaArray; 27 | import com.javadeobfuscator.javavm.values.JavaWrapper; 28 | 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | 32 | public class java_lang_SecurityManager { 33 | 34 | private final VirtualMachine _vm; 35 | 36 | public java_lang_SecurityManager(VirtualMachine vm) { 37 | _vm = vm; 38 | registerNatives(); 39 | } 40 | 41 | private void registerNatives() { 42 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/lang/SecurityManager", "getClassContext", "()[Ljava/lang/Class;", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 43 | List stacktrace = _vm.getStacktrace(); 44 | stacktrace.remove(0); 45 | 46 | JavaWrapper array = JavaWrapper.createArray(JavaClass.forName(_vm, "[Ljava/lang/Class;"), new JavaWrapper[stacktrace.size()]); 47 | // todo remove hidden frames like NativeMethodAccessorImpl 48 | for (int i = 0; i < stacktrace.size(); i++) { 49 | StackTraceHolder holder = stacktrace.get(i); 50 | array.asArray().set(i, JavaClass.forName(_vm, holder.getClassNode().name).getOop()); 51 | } 52 | 53 | return array; 54 | })); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_StrictMath.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.values.JavaWrapper; 24 | 25 | public class java_lang_StrictMath { 26 | private static final String THIS = "java/lang/StrictMath"; 27 | 28 | public static void registerNatives(VirtualMachine vm) { 29 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "log", "(D)D", true, Cause.ALL, Effect.ALL, (ctx, inst, args) -> { 30 | return JavaWrapper.createDouble(vm, StrictMath.log(args[0].asDouble())); 31 | })); 32 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "cos", "(D)D", true, Cause.ALL, Effect.ALL, (ctx, inst, args) -> { 33 | return vm.newDouble(StrictMath.cos(args[0].asDouble())); 34 | })); 35 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "sqrt", "(D)D", true, Cause.ALL, Effect.ALL, (ctx, inst, args) -> { 36 | return vm.newDouble(StrictMath.sqrt(args[0].asDouble())); 37 | })); 38 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "pow", "(DD)D", true, Cause.ALL, Effect.ALL, (ctx, inst, args) -> { 39 | return JavaWrapper.createDouble(vm, StrictMath.pow(args[0].asDouble(), args[1].asDouble())); 40 | })); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_String.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.values.JavaWrapper; 24 | 25 | public class java_lang_String { 26 | private static final String THIS = "java/lang/String"; 27 | 28 | public static void registerNatives(VirtualMachine vm) { 29 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "intern", "()Ljava/lang/String;", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 30 | return vm.intern(inst); 31 | })); 32 | } 33 | 34 | public static boolean isInstance(VirtualMachine vm, JavaWrapper oop) { 35 | return oop != null && oop.getJavaClass() == vm.getSystemDictionary().getJavaLangString(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_Thread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.internals.VMSymbols; 24 | import com.javadeobfuscator.javavm.oops.ThreadOop; 25 | import com.javadeobfuscator.javavm.values.JavaWrapper; 26 | 27 | public class java_lang_Thread { 28 | private static final String THIS = "java/lang/Thread"; 29 | 30 | public static ThreadOop getThreadOop(JavaWrapper thread) { 31 | return thread.get().getMetadata("oop"); 32 | } 33 | 34 | public static void registerNatives(VirtualMachine vm) { 35 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "currentThread", "()Ljava/lang/Thread;", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 36 | return ThreadOop.forThread(Thread.currentThread()).getThread(); 37 | })); 38 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, THIS, "setPriority0", "(I)V", false, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 39 | getThreadOop(inst).setPriority(args[0].asInt()); 40 | })); 41 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "isAlive", "()Z", false, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 42 | return vm.newBoolean(getThreadOop(inst).isAlive()); 43 | })); 44 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, THIS, "start0", "()V", false, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 45 | getThreadOop(inst).start(); 46 | })); 47 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, THIS, "yield", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 48 | ThreadOop.forThread(Thread.currentThread()).yield(); 49 | })); 50 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, THIS, "sleep", "(J)V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 51 | try { 52 | Thread.sleep(args[0].asLong()); 53 | } catch (InterruptedException e) { 54 | throw vm.newThrowable(VMSymbols.java_lang_InterruptedExecption); 55 | } 56 | })); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_invoke_MemberName.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.values.JavaObject; 20 | import com.javadeobfuscator.javavm.values.JavaWrapper; 21 | 22 | public class java_lang_invoke_MemberName { 23 | public static JavaWrapper clazz(JavaWrapper memberName) { 24 | return memberName.asObject().getField("clazz", "Ljava/lang/Class;"); 25 | } 26 | 27 | public static JavaWrapper name(JavaWrapper memberName) { 28 | return memberName.asObject().getField("name", "Ljava/lang/String;"); 29 | } 30 | 31 | public static JavaWrapper type(JavaWrapper memberName) { 32 | return memberName.asObject().getField("type", "Ljava/lang/Object;"); 33 | } 34 | 35 | public static int flags(JavaWrapper memberName) { 36 | return ((JavaObject) memberName.get()).getField("flags", "I").asInt(); 37 | } 38 | 39 | public static void set_flags(JavaWrapper memberName, JavaWrapper flag) { 40 | memberName.asObject().setField("flags", "I", flag); 41 | } 42 | 43 | public static void set_vmtarget(JavaWrapper memberName, Object m) { 44 | memberName.asObject().setMetadata(JavaObject.VMTARGET, m); 45 | } 46 | 47 | public static void set_vmindex(JavaWrapper memberName, int vmindex) { 48 | memberName.asObject().setMetadata(JavaObject.VMINDEX, vmindex); 49 | } 50 | 51 | public static void set_clazz(JavaWrapper memberName, JavaWrapper oop) { 52 | memberName.asObject().setField("clazz", "Ljava/lang/Class;", oop); 53 | } 54 | 55 | public static void set_name(JavaWrapper memberName, JavaWrapper oop) { 56 | memberName.asObject().setField("name", "Ljava/lang/String;", oop); 57 | } 58 | 59 | public static void set_type(JavaWrapper memberName, JavaWrapper oop) { 60 | memberName.asObject().setField("type", "Ljava/lang/Object;", oop); 61 | } 62 | 63 | public static int vmindex(JavaWrapper memberName) { 64 | Integer x = (Integer) memberName.asObject().getMetadata(JavaObject.VMINDEX); 65 | return x == null ? 0 : x; 66 | } 67 | 68 | public static Object get_vmtarget(JavaWrapper vmentry) { 69 | return vmentry.asObject().getMetadata(JavaObject.VMTARGET); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_invoke_MethodType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.VirtualMachine; 20 | import com.javadeobfuscator.javavm.values.JavaArray; 21 | import com.javadeobfuscator.javavm.values.JavaObject; 22 | import com.javadeobfuscator.javavm.values.JavaWrapper; 23 | 24 | public class java_lang_invoke_MethodType { 25 | public static boolean isInstance(VirtualMachine vm, JavaWrapper oop) { 26 | return oop != null && oop.getJavaClass() == vm.getSystemDictionary().getJavaLangInvokeMethodType(); 27 | } 28 | 29 | public static String asSignature(JavaWrapper oop, boolean internIfNotFound) { 30 | StringBuilder stringBuilder = new StringBuilder(); 31 | printSignature(oop, stringBuilder); 32 | 33 | return stringBuilder.toString(); 34 | } 35 | 36 | public static JavaWrapper ptypes(JavaWrapper oop) { 37 | return ((JavaObject) oop.get()).getField("ptypes", "[Ljava/lang/Class;"); 38 | } 39 | 40 | public static JavaWrapper rtype(JavaWrapper oop) { 41 | return ((JavaObject) oop.get()).getField("rtype", "Ljava/lang/Class;"); 42 | } 43 | 44 | public static void printSignature(JavaWrapper oop, StringBuilder stringBuilder) { 45 | stringBuilder.append("("); 46 | 47 | JavaArray ptypes = ptypes(oop).asArray(); 48 | for (int i = 0, limit = ptypes.length(); i < limit; i++) { 49 | java_lang_Class.printSignature(ptypes.get(i), stringBuilder); 50 | } 51 | 52 | stringBuilder.append(")"); 53 | java_lang_Class.printSignature(rtype(oop), stringBuilder); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_reflect_Array.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 24 | import com.javadeobfuscator.javavm.values.JavaWrapper; 25 | import org.objectweb.asm.Type; 26 | 27 | public class java_lang_reflect_Array { 28 | private static final String THIS = "java/lang/reflect/Array"; 29 | 30 | public static void registerNatives(VirtualMachine vm) { 31 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "newArray", "(Ljava/lang/Class;I)Ljava/lang/Object;", true, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 32 | JavaClass type = java_lang_Class.getJavaClass(args[0]); 33 | return JavaWrapper.createArray(JavaClass.forName(vm, Type.getType("[" + type.internalGetType().getDescriptor())), new JavaWrapper[args[1].asInt()]); 34 | })); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_reflect_Constructor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.VirtualMachine; 20 | import com.javadeobfuscator.javavm.values.JavaWrapper; 21 | 22 | public class java_lang_reflect_Constructor { 23 | public static boolean isInstance(VirtualMachine vm, JavaWrapper oop) { 24 | return oop != null && oop.getJavaClass() == vm.getSystemDictionary().getJavaLangReflectConstructor(); 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_reflect_Field.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.VirtualMachine; 20 | import com.javadeobfuscator.javavm.values.JavaWrapper; 21 | 22 | public class java_lang_reflect_Field { 23 | public static boolean isInstance(VirtualMachine vm, JavaWrapper oop) { 24 | return oop != null && oop.getJavaClass() == vm.getSystemDictionary().getJavaLangReflectField(); 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_lang_reflect_Method.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.VirtualMachine; 20 | import com.javadeobfuscator.javavm.values.JavaWrapper; 21 | 22 | public class java_lang_reflect_Method { 23 | public static boolean isInstance(VirtualMachine vm, JavaWrapper oop) { 24 | return oop != null && oop.getJavaClass() == vm.getSystemDictionary().getJavaLangReflectMethod(); 25 | } 26 | 27 | public static JavaWrapper clazz(JavaWrapper oop) { 28 | return oop.asObject().getField("clazz", "Ljava/lang/Class;"); 29 | } 30 | 31 | public static int slot(JavaWrapper oop) { 32 | return oop.asObject().getField("slot", "I").asInt(); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_net_DualStackPlainSocketImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.internals.VMSymbols; 24 | 25 | import java.io.IOException; 26 | import java.net.InetSocketAddress; 27 | 28 | public class java_net_DualStackPlainSocketImpl { 29 | private final VirtualMachine _vm; 30 | 31 | public java_net_DualStackPlainSocketImpl(VirtualMachine vm) { 32 | _vm = vm; 33 | registerNatives(); 34 | } 35 | 36 | private void registerNatives() { 37 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "java/net/DualStackPlainSocketImpl", "initIDs", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 38 | })); 39 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/net/DualStackPlainSocketImpl", "socket0", "(ZZ)I", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 40 | return _vm.newInt(_vm.getNetwork().newSocket(args[0].asBoolean(), args[1].asBoolean()).getFd()); 41 | })); 42 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/net/DualStackPlainSocketImpl", "connect0", "(ILjava/net/InetAddress;I)I", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 43 | int fd = args[0].asInt(); 44 | boolean connected = _vm.getNetwork().connect(fd, new InetSocketAddress(_vm.getNetwork().getInetAddress(args[1]), args[2].asInt())); 45 | if (!connected) { 46 | throw _vm.newThrowable(VMSymbols.java_net_SocketException, "Could not connect"); 47 | } 48 | return _vm.newInt(0); 49 | })); 50 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/net/DualStackPlainSocketImpl", "localPort0", "(I)I", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 51 | System.out.println("[Networking] Getting local port of socket " + args[0].asInt()); 52 | return _vm.newInt(12345); 53 | })); 54 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "java/net/DualStackPlainSocketImpl", "setIntOption", "(III)V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 55 | System.out.println("[Networking] Setting option of socket " + args[0].asInt() + ": " + args[1].asInt() + " = " + args[2].asInt()); 56 | })); 57 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "java/net/DualStackPlainSocketImpl", "close0", "(I)V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 58 | System.out.println("[Networking] Closing socket " + args[0].asInt()); 59 | })); 60 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/net/DualStackPlainSocketImpl", "available0", "(I)I", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 61 | try { 62 | return _vm.newInt(_vm.getNetwork().socketAvailable(args[0].asInt())); 63 | } catch (IOException e) { 64 | throw _vm.newThrowable(VMSymbols.java_io_IOException); 65 | } 66 | })); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_net_Inet4Address.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | 24 | public class java_net_Inet4Address { 25 | private final VirtualMachine _vm; 26 | 27 | public java_net_Inet4Address(VirtualMachine vm) { 28 | _vm = vm; 29 | registerNatives(); 30 | } 31 | 32 | private void registerNatives() { 33 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "java/net/Inet4Address", "init", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 34 | 35 | })); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_net_Inet4AddressImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.internals.VMSymbols; 24 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 25 | import com.javadeobfuscator.javavm.values.JavaWrapper; 26 | 27 | import java.net.Inet4Address; 28 | import java.net.InetAddress; 29 | import java.util.List; 30 | 31 | public class java_net_Inet4AddressImpl { 32 | private final VirtualMachine _vm; 33 | 34 | public java_net_Inet4AddressImpl(VirtualMachine vm) { 35 | _vm = vm; 36 | registerNatives(); 37 | } 38 | 39 | private void registerNatives() { 40 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/net/Inet4AddressImpl", "lookupAllHostAddr", "(Ljava/lang/String;)[Ljava/net/InetAddress;", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 41 | String host = _vm.convertJavaObjectToString(args[0]); 42 | System.out.println("[Networking] Resolving host " + host); 43 | List resolved = _vm.getNetwork().resolve(host); 44 | 45 | if (resolved.isEmpty()) { 46 | throw _vm.newThrowable(VMSymbols.java_net_UnknownHostException, host); 47 | } 48 | 49 | JavaWrapper array = JavaWrapper.createArray(JavaClass.forName(_vm, "[Ljava/net/InetAddress;"), new JavaWrapper[resolved.size()]); 50 | for (int i = 0; i < resolved.size(); i++) { 51 | InetAddress address = resolved.get(i); 52 | if (address instanceof Inet4Address) { 53 | array.asArray().set(i, _vm.getNetwork().createInet4Address((Inet4Address) address)); 54 | } else { 55 | throw new UnsupportedOperationException("IPv6 addressees are not supported yet (" + address + ")"); 56 | } 57 | } 58 | return array; 59 | })); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_net_Inet6Address.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | 24 | public class java_net_Inet6Address { 25 | private final VirtualMachine _vm; 26 | 27 | public java_net_Inet6Address(VirtualMachine vm) { 28 | _vm = vm; 29 | registerNatives(); 30 | } 31 | 32 | private void registerNatives() { 33 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "java/net/Inet6Address", "init", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 34 | 35 | })); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_net_InetAddress.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | 24 | public class java_net_InetAddress { 25 | private final VirtualMachine _vm; 26 | 27 | public java_net_InetAddress(VirtualMachine vm) { 28 | _vm = vm; 29 | registerNatives(); 30 | } 31 | 32 | private void registerNatives() { 33 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "java/net/InetAddress", "init", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 34 | 35 | })); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_net_InetAddressImplFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | 24 | public class java_net_InetAddressImplFactory { 25 | private final VirtualMachine _vm; 26 | 27 | public java_net_InetAddressImplFactory(VirtualMachine vm) { 28 | _vm = vm; 29 | registerNatives(); 30 | } 31 | 32 | private void registerNatives() { 33 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/net/InetAddressImplFactory", "isIPv6Supported", "()Z", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 34 | return _vm.newBoolean(false); 35 | })); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_net_SocketInputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.internals.VMSymbols; 24 | import com.javadeobfuscator.javavm.utils.ArrayConversionHelper; 25 | 26 | import java.io.ByteArrayInputStream; 27 | import java.io.IOException; 28 | 29 | public class java_net_SocketInputStream { 30 | private final VirtualMachine _vm; 31 | 32 | public java_net_SocketInputStream(VirtualMachine vm) { 33 | _vm = vm; 34 | registerNatives(); 35 | } 36 | 37 | private void registerNatives() { 38 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "java/net/SocketInputStream", "init", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 39 | })); 40 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/net/SocketInputStream", "socketRead0", "(Ljava/io/FileDescriptor;[BIII)I", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 41 | byte[] bytes = ArrayConversionHelper.convertByteArray(args[1].asArray()); 42 | int read; 43 | try { 44 | read = _vm.getNetwork().socketRead(java_io_FileDescriptor.getFd(args[0]), bytes, args[2].asInt(), args[3].asInt()); 45 | } catch (IOException e) { 46 | throw _vm.newThrowable(VMSymbols.java_io_IOException); 47 | } 48 | for (int i = 0; i < bytes.length; i++) { 49 | args[1].asArray().set(i, _vm.newByte(bytes[i])); 50 | } 51 | return _vm.newInt(read); 52 | })); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_net_SocketOutputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.internals.VMSymbols; 24 | import com.javadeobfuscator.javavm.utils.ArrayConversionHelper; 25 | 26 | import java.io.IOException; 27 | 28 | public class java_net_SocketOutputStream { 29 | private final VirtualMachine _vm; 30 | 31 | public java_net_SocketOutputStream(VirtualMachine vm) { 32 | _vm = vm; 33 | registerNatives(); 34 | } 35 | 36 | private void registerNatives() { 37 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "java/net/SocketOutputStream", "init", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 38 | })); 39 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "java/net/SocketOutputStream", "socketWrite0", "(Ljava/io/FileDescriptor;[BII)V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 40 | byte[] bytes = ArrayConversionHelper.convertByteArray(args[1].asArray()); 41 | try { 42 | _vm.getNetwork().socketWrite(java_io_FileDescriptor.getFd(args[0]), bytes, args[2].asInt(), args[3].asInt()); 43 | } catch (IOException e) { 44 | throw _vm.newThrowable(VMSymbols.java_io_IOException); 45 | } 46 | })); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_util_jar_JarFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | 24 | public class java_util_jar_JarFile { 25 | private final VirtualMachine _vm; 26 | 27 | public java_util_jar_JarFile(VirtualMachine vm) { 28 | _vm = vm; 29 | registerNatives(); 30 | } 31 | 32 | private void registerNatives() { 33 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "java/util/jar/JarFile", "getMetaInfEntryNames", "()[Ljava/lang/String;", false, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 34 | return _vm.getFilesystem().getZipGetMetaInfEntryNames(inst.asObject().getField("jzfile", "J").asLong()); 35 | })); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/java_util_zip_CRC32.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.utils.ArrayConversionHelper; 24 | import com.javadeobfuscator.javavm.values.JavaArray; 25 | import com.javadeobfuscator.javavm.values.JavaWrapper; 26 | import com.jcraft.jzlib.CRC32; 27 | 28 | public class java_util_zip_CRC32 { 29 | private static final String THIS = "java/util/zip/CRC32"; 30 | 31 | public static void registerNatives(VirtualMachine vm) { 32 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "update", "(II)I", true, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 33 | CRC32 crc32 = new CRC32(); 34 | crc32.reset(args[0].asInt()); 35 | crc32.update(new byte[]{(byte) args[1].asInt()}, 0, 1); 36 | return JavaWrapper.createInteger(vm, (int) (crc32.getValue() & 0xffffffffL)); 37 | })); 38 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "updateBytes", "(I[BII)I", true, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 39 | CRC32 crc32 = new CRC32(); 40 | crc32.reset(args[0].asInt()); 41 | crc32.update(ArrayConversionHelper.convertByteArray((JavaArray) args[1].get()), args[2].asInt(), args[3].asInt()); 42 | return JavaWrapper.createInteger(vm, (int) (crc32.getValue() & 0xffffffffL)); 43 | })); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/sun_awt_windows_WToolkit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | 24 | public class sun_awt_windows_WToolkit { 25 | public static void registerNatives(VirtualMachine vm) { 26 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, "sun/awt/windows/WToolkit", "initIDs", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 27 | })); 28 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, "sun/awt/windows/WToolkit", "startToolkitThread", "(Ljava/lang/Runnable;Ljava/lang/ThreadGroup;)Z", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 29 | // stub 30 | args[0].asObject().setField("inited", "Z", vm.newBoolean(true)); 31 | return vm.newBoolean(true); 32 | })); 33 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, "sun/awt/windows/WToolkit", "setDynamicLayoutNative", "(Z)V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 34 | // stub 35 | })); 36 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, "sun/awt/windows/WToolkit", "setExtraMouseButtonsEnabledNative", "(Z)V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 37 | // stub 38 | })); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/sun_java2d_Disposer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | 24 | public class sun_java2d_Disposer { 25 | public static void registerNatives(VirtualMachine vm) { 26 | vm.hook(HookGenerator.generateUnknownHandlingVoidHook(vm, "sun/java2d/Disposer", "initIDs", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 27 | })); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/sun_misc_Perf.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 24 | 25 | public class sun_misc_Perf { 26 | private final VirtualMachine _vm; 27 | 28 | public sun_misc_Perf(VirtualMachine vm) { 29 | _vm = vm; 30 | registerNatives(); 31 | } 32 | 33 | private void registerNatives() { 34 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "sun/misc/Perf", "registerNatives", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 35 | registerNatives0(); 36 | })); 37 | } 38 | 39 | private void registerNatives0() { 40 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "sun/misc/Perf", "createLong", "(Ljava/lang/String;IIJ)Ljava/nio/ByteBuffer;", false, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 41 | long address = _vm.getMemory().allocateMemory(8); 42 | return _vm.newInstance(JavaClass.forName(_vm, "java/nio/DirectByteBuffer"), "(JI)V", _vm.newLong(address), _vm.newInt(8)); 43 | })); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/sun_misc_URLClassPath.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 23 | 24 | public class sun_misc_URLClassPath { 25 | private static final String THIS = "sun/misc/URLClassPath"; 26 | 27 | public static void registerNatives(VirtualMachine vm) { 28 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "getLookupCacheURLs", "(Ljava/lang/ClassLoader;)[Ljava/net/URL;", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 29 | // todo wat 30 | return vm.getNull(); 31 | })); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/sun_nio_fs_WindowsNativeDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.VirtualMachine; 22 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 23 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 24 | import com.javadeobfuscator.javavm.values.JavaWrapper; 25 | 26 | import java.io.File; 27 | import java.nio.ByteBuffer; 28 | import java.nio.CharBuffer; 29 | import java.nio.charset.StandardCharsets; 30 | 31 | public class sun_nio_fs_WindowsNativeDispatcher { 32 | private final VirtualMachine _vm; 33 | 34 | public sun_nio_fs_WindowsNativeDispatcher(VirtualMachine vm) { 35 | _vm = vm; 36 | registerNatives(); 37 | } 38 | 39 | private void registerNatives() { 40 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "sun/nio/fs/WindowsNativeDispatcher", "initIDs", "()V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 41 | // ignored 42 | })); 43 | _vm.hook(HookGenerator.generateUnknownHandlingVoidHook(_vm, "sun/nio/fs/WindowsNativeDispatcher", "FindFirstFile0", "(JLsun/nio/fs/WindowsNativeDispatcher$FirstFile;)V", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 44 | ByteBuffer buffer = _vm.getMemory().getBufferForAddress(args[0].asLong()); 45 | JavaWrapper dst = args[1]; 46 | 47 | buffer.position(0); 48 | CharBuffer charBuffer = buffer.asCharBuffer(); 49 | char[] data = new char[charBuffer.remaining()]; 50 | charBuffer.get(data); 51 | 52 | String fileName = new String(data); 53 | fileName = fileName.substring(0, fileName.indexOf("\u0000")); // it's null terminated 54 | 55 | throw new ExecutionException("unsupported"); 56 | })); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/sun_reflect_ConstantPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.ConstantPool; 21 | import com.javadeobfuscator.javavm.Effect; 22 | import com.javadeobfuscator.javavm.VirtualMachine; 23 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 24 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 25 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 26 | import com.javadeobfuscator.javavm.values.JavaWrapper; 27 | 28 | public class sun_reflect_ConstantPool { 29 | private static final String THIS = "sun/reflect/ConstantPool"; 30 | 31 | public static JavaClass getJavaClass(JavaWrapper constantPool) { 32 | return constantPool.getMetadata("oop"); 33 | } 34 | 35 | public static void setJavaClass(JavaWrapper constantPool, JavaClass javaClass) { 36 | constantPool.setMetadata("oop", javaClass); 37 | } 38 | 39 | public static void registerNatives(VirtualMachine vm) { 40 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "getSize0", "(Ljava/lang/Object;)I", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 41 | JavaClass javaClass = getJavaClass(inst); 42 | ConstantPool constantPool = vm.getConstantPool(javaClass.getClassNode()); 43 | if (constantPool == null) { 44 | throw new ExecutionException("No constantpool found for " + javaClass.getClassNode().name + " " + Integer.toHexString(System.identityHashCode(javaClass.getClassNode()))); 45 | } 46 | return vm.newInt(constantPool.getSize()); 47 | })); 48 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "getUTF8At0", "(Ljava/lang/Object;I)Ljava/lang/String;", false, Cause.ALL, Effect.NONE, (ctx, inst, args) -> { 49 | JavaClass javaClass = getJavaClass(inst); 50 | ConstantPool constantPool = vm.getConstantPool(javaClass.getClassNode()); 51 | if (constantPool == null) { 52 | throw new ExecutionException("No constantpool found for " + javaClass.getClassNode().name + " " + Integer.toHexString(System.identityHashCode(javaClass.getClassNode()))); 53 | } 54 | return vm.getStringInterned(constantPool.getUTF8At(args[1].asInt())); 55 | })); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/sun_reflect_Reflection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.StackTraceHolder; 22 | import com.javadeobfuscator.javavm.VirtualMachine; 23 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 24 | import com.javadeobfuscator.javavm.internals.VMSymbols; 25 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 26 | import com.javadeobfuscator.javavm.values.JavaWrapper; 27 | 28 | import java.util.List; 29 | 30 | public class sun_reflect_Reflection { 31 | private static final String THIS = "sun/reflect/Reflection"; 32 | 33 | public static void registerNatives(VirtualMachine vm) { 34 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "getCallerClass", "()Ljava/lang/Class;", true, Cause.ALL, Effect.ALL, (ctx, inst, args) -> { 35 | List stacktrace = vm.getStacktrace(); 36 | if (stacktrace.size() < 2) { 37 | return vm.getNull(); 38 | } 39 | 40 | StackTraceHolder shouldBeReflection = stacktrace.get(0); 41 | if (!shouldBeReflection.getClassNode().name.equals(THIS) || !shouldBeReflection.getMethod().name.equals("getCallerClass") || !shouldBeReflection.getMethod().desc.equals("()Ljava/lang/Class;")) { 42 | throw vm.newThrowable(VMSymbols.java_lang_InternalError, "JVM_GetCallerClass must only be called from Reflection.getCallerClass"); 43 | } 44 | // if (!shouldBeReflection.getMethod().isCallerSensitive()) { 45 | // throw new WrappedException(vm.newInternalError("CallerSensitive annotation expected at frame 0")); 46 | // } 47 | StackTraceHolder shouldBeCallerSensitive = stacktrace.get(1); 48 | // if (!shouldBeCallerSensitive.getMethod().isCallerSensitive()) { 49 | // throw new WrappedException(vm.newInternalError("CallerSensitive annotation expected at frame 0")); 50 | // } 51 | // todo is_ignored_by_security_walk 52 | return JavaClass.forName(vm, stacktrace.get(2).getClassNode().name).getOop(); 53 | })); 54 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "getCallerClass", "(I)Ljava/lang/Class;", true, Cause.ALL, Effect.ALL, (ctx, inst, args) -> { 55 | List stacktrace = vm.getStacktrace(); 56 | if (stacktrace.size() <= args[0].asInt()) { 57 | return vm.getNull(); 58 | } 59 | return JavaClass.forName(vm, stacktrace.get(args[0].asInt()).getClassNode().name).getOop(); 60 | })); 61 | vm.hook(HookGenerator.generateUnknownHandlingHook(vm, THIS, "getClassAccessFlags", "(Ljava/lang/Class;)I", true, Cause.ALL, Effect.ALL, (ctx, inst, args) -> { 62 | return JavaWrapper.createInteger(vm, java_lang_Class.getJavaClass(args[0]).getModifiers()); 63 | })); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/nativeimpls/sun_security_provider_NativeSeedGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.nativeimpls; 18 | 19 | import com.javadeobfuscator.javavm.Cause; 20 | import com.javadeobfuscator.javavm.Effect; 21 | import com.javadeobfuscator.javavm.StackTraceHolder; 22 | import com.javadeobfuscator.javavm.VirtualMachine; 23 | import com.javadeobfuscator.javavm.hooks.HookGenerator; 24 | import com.javadeobfuscator.javavm.internals.VMSymbols; 25 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 26 | import com.javadeobfuscator.javavm.utils.ArrayConversionHelper; 27 | import com.javadeobfuscator.javavm.values.JavaWrapper; 28 | 29 | import java.security.SecureRandom; 30 | import java.util.List; 31 | 32 | public class sun_security_provider_NativeSeedGenerator { 33 | private final VirtualMachine _vm; 34 | 35 | public sun_security_provider_NativeSeedGenerator(VirtualMachine vm) { 36 | _vm = vm; 37 | registerNatives(); 38 | } 39 | 40 | private void registerNatives() { 41 | _vm.hook(HookGenerator.generateUnknownHandlingHook(_vm, "sun/security/provider/NativeSeedGenerator", "nativeGenerateSeed", "([B)Z", true, Cause.NONE, Effect.NONE, (ctx, inst, args) -> { 42 | SecureRandom secureRandom = new SecureRandom(); 43 | byte[] bytes = ArrayConversionHelper.convertByteArray(args[0].asArray()); 44 | secureRandom.nextBytes(bytes); 45 | for (int i = 0; i < bytes.length; i++) { 46 | args[0].asArray().set(i, _vm.newByte(bytes[i])); 47 | } 48 | return _vm.newBoolean(true); 49 | })); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/oops/Oop.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.oops; 18 | 19 | import com.javadeobfuscator.javavm.VirtualMachine; 20 | 21 | public class Oop { 22 | private final VirtualMachine _vm; 23 | 24 | public Oop(VirtualMachine vm) { 25 | _vm = vm; 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/utils/ASMHelper.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.utils; 2 | 3 | import org.objectweb.asm.Attribute; 4 | import org.objectweb.asm.tree.ClassNode; 5 | import org.objectweb.asm.tree.FieldNode; 6 | import org.objectweb.asm.tree.InnerClassNode; 7 | import org.objectweb.asm.tree.MethodNode; 8 | 9 | public class ASMHelper { 10 | private ASMHelper() { 11 | 12 | } 13 | 14 | public static MethodNode findMethod(ClassNode owner, String name, String desc) { 15 | int size = owner.methods.size(); 16 | for (int i = 0; i < size; i++) { 17 | MethodNode methodNode = owner.methods.get(i); 18 | if (methodNode.name.equals(name) && methodNode.desc.equals(desc)) { 19 | return methodNode; 20 | } 21 | } 22 | 23 | return null; 24 | } 25 | 26 | public static FieldNode findField(ClassNode owner, String name, String desc) { 27 | int size = owner.fields.size(); 28 | for (int i = 0; i < size; i++) { 29 | FieldNode fieldNode = owner.fields.get(i); 30 | if (fieldNode.name.equals(name) && fieldNode.desc.equals(desc)) { 31 | return fieldNode; 32 | } 33 | } 34 | 35 | return null; 36 | } 37 | 38 | public static InnerClassNode findInnerClassNode(ClassNode classNode, String name) { 39 | if (classNode.innerClasses == null) { 40 | return null; 41 | } 42 | int size = classNode.innerClasses.size(); 43 | for (int i = 0; i < size; i++) { 44 | InnerClassNode innerClassNode = classNode.innerClasses.get(i); 45 | if (innerClassNode.name.equals(name)) { 46 | return innerClassNode; 47 | } 48 | } 49 | 50 | return null; 51 | } 52 | 53 | public static Attribute findAttribute(ClassNode classNode, String name) { 54 | if (classNode.attrs == null) { 55 | return null; 56 | } 57 | int size = classNode.attrs.size(); 58 | for (int i = 0; i < size; i++) { 59 | Attribute attribute = classNode.attrs.get(i); 60 | if (attribute.type.equals(name)) { 61 | return attribute; 62 | } 63 | } 64 | 65 | return null; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/utils/BiDoubleFunction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.utils; 2 | 3 | public interface BiDoubleFunction { 4 | double apply(double a, double b); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/utils/BiFloatInstruction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.utils; 2 | 3 | public interface BiFloatInstruction { 4 | float apply(float a, float b); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/utils/BiIntegerFunction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.utils; 2 | 3 | public interface BiIntegerFunction { 4 | int apply(int a, int b); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/utils/BiLongFunction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.utils; 2 | 3 | public interface BiLongFunction { 4 | long apply(long a, long b); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/utils/BiLongIntegerFunction.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.utils; 2 | 3 | public interface BiLongIntegerFunction { 4 | long apply(long a, int b); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/utils/ExecutionUtils.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.utils; 2 | 3 | import com.javadeobfuscator.javavm.values.JavaValue; 4 | import com.javadeobfuscator.javavm.values.JavaValueType; 5 | import com.javadeobfuscator.javavm.values.JavaWrapper; 6 | 7 | import java.util.List; 8 | 9 | public class ExecutionUtils { 10 | public static boolean areValuesUnknown(JavaValue instance, List args) { 11 | if (instance.is(JavaValueType.UNKNOWN)) 12 | return true; 13 | for (JavaValue value : args) { 14 | if (value.is(JavaValueType.UNKNOWN)) { 15 | return true; 16 | } 17 | } 18 | 19 | return false; 20 | } 21 | 22 | public static boolean areValuesUnknown(JavaValue... args) { 23 | for (JavaValue value : args) { 24 | if (value.is(JavaValueType.UNKNOWN)) { 25 | return true; 26 | } 27 | } 28 | 29 | return false; 30 | } 31 | 32 | public static boolean areValuesUnknown(JavaWrapper instance, JavaWrapper[] args) { 33 | if (instance != null && instance.get().is(JavaValueType.UNKNOWN)) 34 | return true; 35 | if (args != null) 36 | for (JavaWrapper value : args) { 37 | if (value.get().is(JavaValueType.UNKNOWN)) { 38 | return true; 39 | } 40 | } 41 | 42 | return false; 43 | } 44 | 45 | public static boolean areValuesUnknown(JavaWrapper instance, List args) { 46 | if (instance != null && instance.get().is(JavaValueType.UNKNOWN)) 47 | return true; 48 | if (args != null) 49 | for (JavaWrapper value : args) { 50 | if (value.get().is(JavaValueType.UNKNOWN)) { 51 | return true; 52 | } 53 | } 54 | 55 | return false; 56 | } 57 | 58 | public static boolean areValuesUnknown(List args) { 59 | for (JavaWrapper value : args) { 60 | if (value.get().is(JavaValueType.UNKNOWN)) { 61 | return true; 62 | } 63 | } 64 | 65 | return false; 66 | } 67 | 68 | public static boolean areValuesUnknown(JavaWrapper... args) { 69 | for (JavaWrapper value : args) { 70 | if (value != null && value.get().is(JavaValueType.UNKNOWN)) { 71 | return true; 72 | } 73 | } 74 | 75 | return false; 76 | } 77 | 78 | // public static String hash(String owner, String name, String desc) { 79 | // return owner + "." + name + "." + desc; 80 | // } 81 | // 82 | // public static JavaValue[] convert(Object[] arr, JavaClass type, String orig) { 83 | // JavaValue[] converted = new JavaValue[arr.length]; 84 | // for (int i = 0; i < arr.length; i++) { 85 | // converted[i] = new JavaObject(arr[i], type, orig); 86 | // } 87 | // return converted; 88 | // } 89 | // 90 | // public static T[] convert(JavaValue[] arr, Class type) { 91 | // T[] t = (T[]) ArrayHelper.newInstance(type, arr.length); 92 | // for (int i = 0; i < arr.length; i++) { 93 | // t[i] = (T) arr[i].value(); 94 | // } 95 | // return t; 96 | // } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/utils/MaybeBoolean.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm.utils; 2 | 3 | public enum MaybeBoolean { 4 | YES, 5 | MAYBE, 6 | NO 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/utils/NameHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.utils; 18 | 19 | import org.apache.commons.lang3.StringEscapeUtils; 20 | 21 | public class NameHelper { 22 | 23 | public static String nameAndType(String name, String type) { 24 | return name + "." + type; 25 | } 26 | 27 | public static String prettyOwnerNameDesc(String owner, String name, String desc) { 28 | return StringEscapeUtils.escapeJava(owner) + "." + StringEscapeUtils.escapeJava(name) + "." + StringEscapeUtils.escapeJava(desc); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/utils/PrimitiveUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.utils; 18 | 19 | import org.objectweb.asm.Opcodes; 20 | import org.objectweb.asm.Type; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | public class PrimitiveUtils { 26 | private static final Map> nameToPrimitive = new HashMap<>(); 27 | private static final Map, Object> defaultPrimitiveValues = new HashMap<>(); 28 | 29 | static { 30 | defaultPrimitiveValues.put(Integer.TYPE, 0); 31 | defaultPrimitiveValues.put(Long.TYPE, 0L); 32 | defaultPrimitiveValues.put(Double.TYPE, 0D); 33 | defaultPrimitiveValues.put(Float.TYPE, 0F); 34 | defaultPrimitiveValues.put(Boolean.TYPE, false); 35 | defaultPrimitiveValues.put(Character.TYPE, '\0'); 36 | defaultPrimitiveValues.put(Byte.TYPE, (byte) 0); 37 | defaultPrimitiveValues.put(Short.TYPE, (short) 0); 38 | defaultPrimitiveValues.put(Object.class, null); 39 | nameToPrimitive.put("int", Integer.TYPE); 40 | nameToPrimitive.put("long", Long.TYPE); 41 | nameToPrimitive.put("double", Double.TYPE); 42 | nameToPrimitive.put("float", Float.TYPE); 43 | nameToPrimitive.put("boolean", Boolean.TYPE); 44 | nameToPrimitive.put("char", Character.TYPE); 45 | nameToPrimitive.put("byte", Byte.TYPE); 46 | nameToPrimitive.put("short", Short.TYPE); 47 | nameToPrimitive.put("void", Void.TYPE); 48 | } 49 | 50 | public static Class getPrimitiveByName(String name) { 51 | return nameToPrimitive.get(name); 52 | } 53 | 54 | public static Object getDefaultValue(Class primitive) { 55 | return defaultPrimitiveValues.get(primitive); 56 | } 57 | 58 | public static Class getPrimitiveByNewArrayId(int id) { 59 | switch (id) { 60 | case Opcodes.T_BOOLEAN: 61 | return boolean.class; 62 | case Opcodes.T_CHAR: 63 | return char.class; 64 | case Opcodes.T_FLOAT: 65 | return float.class; 66 | case Opcodes.T_DOUBLE: 67 | return double.class; 68 | case Opcodes.T_BYTE: 69 | return byte.class; 70 | case Opcodes.T_SHORT: 71 | return short.class; 72 | case Opcodes.T_INT: 73 | return int.class; 74 | case Opcodes.T_LONG: 75 | return long.class; 76 | } 77 | throw new IllegalArgumentException("Unknown type " + id); 78 | } 79 | 80 | public static boolean isPrimitive(Type type) { 81 | return type.getSort() >= Type.BOOLEAN && type.getSort() <= Type.DOUBLE; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/JavaAddress.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values; 18 | 19 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 20 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 21 | import org.objectweb.asm.tree.AbstractInsnNode; 22 | 23 | import java.util.EnumSet; 24 | 25 | public class JavaAddress extends JavaValue { 26 | private static final EnumSet TYPES = EnumSet.of(JavaValueType.ADDRESS); 27 | private final AbstractInsnNode value; 28 | 29 | 30 | public JavaAddress(AbstractInsnNode value) { 31 | this.value = value; 32 | } 33 | 34 | @Override 35 | public boolean is(JavaValueType type) { 36 | return TYPES.contains(type); 37 | } 38 | 39 | @Override 40 | public JavaClass getJavaClass() { 41 | throw new ExecutionException("cannot get class of javaaddress"); 42 | } 43 | 44 | @Override 45 | public int getSize() { 46 | return 1; 47 | } 48 | 49 | public AbstractInsnNode getReturnAddres() { 50 | return value; 51 | } 52 | 53 | public String toString() { 54 | return "JavaAddress(addr=" + value + ")"; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/JavaArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values; 18 | 19 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 20 | 21 | public class JavaArray extends JavaValue { 22 | 23 | private JavaClass originalClazz; 24 | private JavaClass clazz; 25 | private JavaWrapper[] values; 26 | 27 | public JavaArray(JavaClass clazz, JavaWrapper[] values) { 28 | this.originalClazz = clazz; 29 | this.clazz = clazz; 30 | this.values = values; 31 | } 32 | 33 | @Override 34 | public boolean is(JavaValueType type) { 35 | return type == JavaValueType.ARRAY || type == JavaValueType.OBJECT; 36 | } 37 | 38 | @Override 39 | public JavaClass getJavaClass() { 40 | return this.clazz; 41 | } 42 | 43 | @Override 44 | public JavaClass getOriginalClass() { 45 | return this.originalClazz; 46 | } 47 | 48 | @Override 49 | public int getSize() { 50 | return 1; 51 | } 52 | 53 | public void set(int index, JavaWrapper copy) { 54 | values[index] = copy; 55 | } 56 | 57 | public JavaWrapper get(int index) { 58 | JavaWrapper val = values[index]; 59 | return val == null ? JavaValue.forPrimitive(clazz.getVM(), clazz.internalGetType()) : val; 60 | } 61 | 62 | public int length() { 63 | return values.length; 64 | } 65 | 66 | public JavaWrapper[] rawArray() { 67 | return this.values; 68 | } 69 | 70 | public JavaValue checkcast(JavaClass other) { 71 | this.clazz = other; 72 | return this; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/JavaNull.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values; 18 | 19 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 20 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 21 | import org.objectweb.asm.Type; 22 | 23 | public class JavaNull extends JavaValue { 24 | @Override 25 | public boolean is(JavaValueType type) { 26 | return type == JavaValueType.NULL || type == JavaValueType.OBJECT || type == JavaValueType.ARRAY; 27 | } 28 | 29 | @Override 30 | public JavaClass getJavaClass() { 31 | throw new ExecutionException("GetClass of null"); 32 | } 33 | 34 | @Override 35 | public int getSize() { 36 | return 1; 37 | } 38 | 39 | @Override 40 | public boolean isInstanceOf(Type type) { 41 | return false; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/JavaTop.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values; 18 | 19 | import com.javadeobfuscator.javavm.exceptions.ExecutionException; 20 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 21 | 22 | import java.util.EnumSet; 23 | 24 | public class JavaTop extends JavaValue { 25 | private static final EnumSet TYPES = EnumSet.of(JavaValueType.TOP); 26 | 27 | @Override 28 | public boolean is(JavaValueType type) { 29 | return TYPES.contains(type); 30 | } 31 | 32 | public String toString() { 33 | return "JavaTop()"; 34 | } 35 | 36 | @Override 37 | public JavaClass getJavaClass() { 38 | throw new ExecutionException("Cannot get JavaClass of JavaTop"); 39 | } 40 | 41 | @Override 42 | public int getSize() { 43 | return 1; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/JavaUninitialized.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values; 18 | 19 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 20 | 21 | import java.util.EnumSet; 22 | 23 | public class JavaUninitialized extends JavaValue { 24 | private static final EnumSet TYPES = EnumSet.of(JavaValueType.UNINITIALIZED); 25 | private final JavaClass _class; 26 | private final String _bytecodeType; 27 | private JavaObject value; 28 | public JavaUninitialized(JavaClass clazz, String originalType) { 29 | this._class = clazz; 30 | this._bytecodeType = originalType; 31 | this.value = new JavaObject(clazz, originalType); 32 | } 33 | 34 | @Override 35 | public boolean is(JavaValueType type) { 36 | return TYPES.contains(type); 37 | } 38 | 39 | public JavaObject initializedValue() { 40 | return this.value; 41 | } 42 | 43 | @Override 44 | public JavaClass getJavaClass() { 45 | return this._class; 46 | } 47 | 48 | @Override 49 | public int getSize() { 50 | return 1; 51 | } 52 | 53 | @Override 54 | public String type() { 55 | return this._bytecodeType; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "JavaUninitialized(type=" + _bytecodeType + ", val=" + value + ")"; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/JavaValueType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values; 18 | 19 | public enum JavaValueType { 20 | UNINITIALIZED, 21 | ADDRESS, 22 | PRIMITIVE, 23 | OBJECT, 24 | NULL, 25 | TOP, 26 | UNKNOWN, 27 | WIDE, 28 | 29 | FLOAT, 30 | LONG, 31 | DOUBLE, 32 | INTEGER, 33 | BOOLEAN, 34 | BYTE, 35 | CHARACTER, 36 | SHORT, ARRAY, 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/prim/JDouble.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values.prim; 18 | 19 | import com.javadeobfuscator.javavm.VirtualMachine; 20 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 21 | import com.javadeobfuscator.javavm.values.JavaValueType; 22 | import org.objectweb.asm.Type; 23 | 24 | public class JDouble extends JPrimitive { 25 | private final VirtualMachine _vm; 26 | 27 | private final double _value; 28 | 29 | public JDouble(VirtualMachine vm, double value) { 30 | this._value = value; 31 | this._vm = vm; 32 | } 33 | 34 | @Override 35 | public final boolean asBoolean() { 36 | return this._value != 0; 37 | } 38 | 39 | @Override 40 | public final char asChar() { 41 | return (char) _value; 42 | } 43 | 44 | @Override 45 | public final byte asByte() { 46 | return (byte) _value; 47 | } 48 | 49 | @Override 50 | public final short asShort() { 51 | return (short) _value; 52 | } 53 | 54 | @Override 55 | public final int asInt() { 56 | return (int) _value; 57 | } 58 | 59 | @Override 60 | public final float asFloat() { 61 | return (float) _value; 62 | } 63 | 64 | @Override 65 | public final long asLong() { 66 | return (long) _value; 67 | } 68 | 69 | @Override 70 | public final double asDouble() { 71 | return (double) _value; 72 | } 73 | 74 | @Override 75 | public final int getSize() { 76 | return 2; 77 | } 78 | 79 | @Override 80 | public final JavaClass getJavaClass() { 81 | return _vm.DOUBLE; 82 | } 83 | 84 | public final Type getType() { 85 | return Type.DOUBLE_TYPE; 86 | } 87 | 88 | @Override 89 | public final Object rawValue() { 90 | return _value; 91 | } 92 | 93 | @Override 94 | public final String toString() { 95 | return "JavaDouble(value=" + _value + ")"; 96 | } 97 | 98 | @Override 99 | public boolean is(JavaValueType type) { 100 | return type == JavaValueType.PRIMITIVE || type == JavaValueType.DOUBLE || type == JavaValueType.WIDE; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/prim/JFloat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values.prim; 18 | 19 | import com.javadeobfuscator.javavm.VirtualMachine; 20 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 21 | import com.javadeobfuscator.javavm.values.JavaValueType; 22 | import org.objectweb.asm.Type; 23 | 24 | public class JFloat extends JPrimitive { 25 | private final VirtualMachine _vm; 26 | 27 | private final float _value; 28 | 29 | public JFloat(VirtualMachine vm, float value) { 30 | this._value = value; 31 | this._vm = vm; 32 | } 33 | 34 | @Override 35 | public final boolean asBoolean() { 36 | return this._value != 0; 37 | } 38 | 39 | @Override 40 | public final char asChar() { 41 | return (char) _value; 42 | } 43 | 44 | @Override 45 | public final byte asByte() { 46 | return (byte) _value; 47 | } 48 | 49 | @Override 50 | public final short asShort() { 51 | return (short) _value; 52 | } 53 | 54 | @Override 55 | public final int asInt() { 56 | return (int) _value; 57 | } 58 | 59 | @Override 60 | public final float asFloat() { 61 | return (float) _value; 62 | } 63 | 64 | @Override 65 | public final long asLong() { 66 | return (long) _value; 67 | } 68 | 69 | @Override 70 | public final double asDouble() { 71 | return (double) _value; 72 | } 73 | 74 | @Override 75 | public final int getSize() { 76 | return 1; 77 | } 78 | 79 | @Override 80 | public final JavaClass getJavaClass() { 81 | return _vm.INTEGER; 82 | } 83 | 84 | public final Type getType() { 85 | return Type.FLOAT_TYPE; 86 | } 87 | 88 | @Override 89 | public final Object rawValue() { 90 | return _value; 91 | } 92 | 93 | @Override 94 | public final String toString() { 95 | return "JavaFloat(value=" + _value + ")"; 96 | } 97 | 98 | @Override 99 | public boolean is(JavaValueType type) { 100 | return type == JavaValueType.PRIMITIVE || type == JavaValueType.FLOAT; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/prim/JInteger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values.prim; 18 | 19 | import com.javadeobfuscator.javavm.VirtualMachine; 20 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 21 | import com.javadeobfuscator.javavm.values.JavaValueType; 22 | import org.objectweb.asm.Type; 23 | 24 | public final class JInteger extends JPrimitive { 25 | private final VirtualMachine _vm; 26 | 27 | private final Type _type; // can be INTEGER, CHARACTER, SHORT, BYTE, BOOLEAN 28 | private final int _value; 29 | 30 | @Deprecated 31 | public JInteger(VirtualMachine vm, int value) { 32 | this._vm = vm; 33 | this._value = value; 34 | _type = null; 35 | } 36 | 37 | public JInteger(VirtualMachine vm, Type type, int value) { 38 | _vm = vm; 39 | _type = type; 40 | _value = value; 41 | } 42 | 43 | @Override 44 | public final boolean asBoolean() { 45 | return this._value != 0; 46 | } 47 | 48 | @Override 49 | public final char asChar() { 50 | return (char) _value; 51 | } 52 | 53 | @Override 54 | public final byte asByte() { 55 | return (byte) _value; 56 | } 57 | 58 | @Override 59 | public final short asShort() { 60 | return (short) _value; 61 | } 62 | 63 | @Override 64 | public final int asInt() { 65 | return (int) _value; 66 | } 67 | 68 | @Override 69 | public final float asFloat() { 70 | return (float) _value; 71 | } 72 | 73 | @Override 74 | public final long asLong() { 75 | return (long) _value; 76 | } 77 | 78 | @Override 79 | public final double asDouble() { 80 | return (double) _value; 81 | } 82 | 83 | @Override 84 | public final int getSize() { 85 | return 1; 86 | } 87 | 88 | @Override 89 | public final JavaClass getJavaClass() { 90 | return _vm.INTEGER; 91 | } 92 | 93 | public final Type getType() { 94 | return _type; 95 | } 96 | 97 | @Override 98 | public final Object rawValue() { 99 | return _value; 100 | } 101 | 102 | @Override 103 | public final String toString() { 104 | return "JavaInteger(value=" + _value + ")"; 105 | } 106 | 107 | @Override 108 | public boolean is(JavaValueType type) { 109 | return type == JavaValueType.PRIMITIVE || type == JavaValueType.INTEGER || type == JavaValueType.BOOLEAN || type == JavaValueType.BYTE || type == JavaValueType.CHARACTER || type == JavaValueType.SHORT; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/prim/JLong.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values.prim; 18 | 19 | import com.javadeobfuscator.javavm.VirtualMachine; 20 | import com.javadeobfuscator.javavm.mirrors.JavaClass; 21 | import com.javadeobfuscator.javavm.values.JavaValueType; 22 | import org.objectweb.asm.Type; 23 | 24 | public class JLong extends JPrimitive { 25 | private final VirtualMachine _vm; 26 | 27 | private final long _value; 28 | 29 | public JLong(VirtualMachine vm, long value) { 30 | this._value = value; 31 | this._vm = vm; 32 | } 33 | 34 | @Override 35 | public final boolean asBoolean() { 36 | return this._value != 0; 37 | } 38 | 39 | @Override 40 | public final char asChar() { 41 | return (char) _value; 42 | } 43 | 44 | @Override 45 | public final byte asByte() { 46 | return (byte) _value; 47 | } 48 | 49 | @Override 50 | public final short asShort() { 51 | return (short) _value; 52 | } 53 | 54 | @Override 55 | public final int asInt() { 56 | return (int) _value; 57 | } 58 | 59 | @Override 60 | public final float asFloat() { 61 | return (float) _value; 62 | } 63 | 64 | @Override 65 | public final long asLong() { 66 | return (long) _value; 67 | } 68 | 69 | @Override 70 | public final double asDouble() { 71 | return (double) _value; 72 | } 73 | 74 | @Override 75 | public final int getSize() { 76 | return 2; 77 | } 78 | 79 | @Override 80 | public final JavaClass getJavaClass() { 81 | return _vm.INTEGER; 82 | } 83 | 84 | public final Type getType() { 85 | return Type.LONG_TYPE; 86 | } 87 | 88 | @Override 89 | public final Object rawValue() { 90 | return _value; 91 | } 92 | 93 | @Override 94 | public final String toString() { 95 | return "JavaLong(value=" + _value + ")"; 96 | } 97 | 98 | @Override 99 | public boolean is(JavaValueType type) { 100 | return type == JavaValueType.PRIMITIVE || type == JavaValueType.LONG || type == JavaValueType.WIDE; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/javadeobfuscator/javavm/values/prim/JPrimitive.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Sam Sun 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.javadeobfuscator.javavm.values.prim; 18 | 19 | import com.javadeobfuscator.javavm.values.JavaValue; 20 | 21 | public abstract class JPrimitive extends JavaValue { 22 | 23 | public abstract boolean asBoolean(); 24 | 25 | public abstract char asChar(); 26 | 27 | public abstract byte asByte(); 28 | 29 | public abstract short asShort(); 30 | 31 | public abstract int asInt(); 32 | 33 | public abstract float asFloat(); 34 | 35 | public abstract long asLong(); 36 | 37 | public abstract double asDouble(); 38 | 39 | public abstract Object rawValue(); 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/javadeobfuscator/javavm/TestHelper.java: -------------------------------------------------------------------------------- 1 | package com.javadeobfuscator.javavm; 2 | 3 | import org.objectweb.asm.tree.*; 4 | import org.objectweb.asm.ClassReader; 5 | 6 | import java.io.*; 7 | import java.net.*; 8 | import java.util.*; 9 | import java.util.zip.*; 10 | 11 | public class TestHelper { 12 | 13 | private static byte[] extractStream(InputStream in) throws IOException { 14 | byte[] buf = new byte[128]; 15 | int len; 16 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 17 | while ((len = in.read(buf)) >= 0) { 18 | out.write(buf, 0, len); 19 | } 20 | return out.toByteArray(); 21 | } 22 | 23 | public static List loadBytes(File input) { 24 | List result = new ArrayList<>(); 25 | 26 | if (input.getName().endsWith(".jar")) { 27 | try (ZipFile zipIn = new ZipFile(input)) { 28 | Enumeration e = zipIn.entries(); 29 | while (e.hasMoreElements()) { 30 | ZipEntry next = e.nextElement(); 31 | if (next.getName().endsWith(".class")) { 32 | try (InputStream in = zipIn.getInputStream(next)) { 33 | result.add(extractStream(in)); 34 | } catch (IllegalArgumentException x) { 35 | System.out.println("Could not parse " + next.getName() + " (is it a class?)"); 36 | } 37 | } 38 | } 39 | } catch (IOException e) { 40 | e.printStackTrace(System.out); 41 | } 42 | } else if (input.getName().endsWith(".class")) { 43 | try (InputStream in = new FileInputStream(input)) { 44 | result.add(extractStream(in)); 45 | } catch (Throwable x) { 46 | System.out.println("Could not parse " + input.getName() + " (is it a class?)"); 47 | } 48 | } 49 | 50 | return result; 51 | } 52 | 53 | public static Map load(File file) throws IOException { 54 | Map map = new HashMap<>(); 55 | 56 | ClassReader reader = new ClassReader(new FileInputStream(file)); 57 | ClassNode node = new ClassNode(); 58 | reader.accept(node, 0 | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); 59 | map.put(node.name, node); 60 | 61 | return map; 62 | } 63 | } --------------------------------------------------------------------------------