Skip to content

Instantly share code, notes, and snippets.

@ChrisPooh
Forked from AKosterin/DexGuardDecoder.java
Created February 9, 2016 08:20
Show Gist options
  • Select an option

  • Save ChrisPooh/d5a3f94a3c8dbaefb7e4 to your computer and use it in GitHub Desktop.

Select an option

Save ChrisPooh/d5a3f94a3c8dbaefb7e4 to your computer and use it in GitHub Desktop.

Revisions

  1. @AKosterin AKosterin created this gist Feb 8, 2016.
    1,201 changes: 1,201 additions & 0 deletions DexGuardDecoder.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,1201 @@
    import jeb.api.IScript;
    import jeb.api.JebInstance;
    import jeb.api.ast.*;
    import jeb.api.ast.Class;
    import jeb.api.dex.*;
    import jeb.api.ui.JavaView;
    import jeb.api.ui.View;

    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.regex.Pattern;

    /**
    * Created by AKosterin on 31/01/16.
    */
    public class DexGuardDecoder implements IScript {
    private static JebInstance mJebInstance;

    private static HashMap<String,byte[]> staticByteArrays;
    private static HashMap<String,Integer> staticIntegers;

    private static String decoderMethodSignature;

    private static boolean debug = false;

    @Override
    public void run(JebInstance jebInstance) {
    mJebInstance = jebInstance;
    mJebInstance.print("DexGuardDecoder_Start");

    if (!mJebInstance.isFileLoaded()) {
    mJebInstance.print("Please load a dex file");
    return;
    }

    Dex mDex = mJebInstance.getDex();

    JavaView view = (JavaView) jebInstance.getUI().getView(View.Type.JAVA);

    String signature = view.getCodePosition().getSignature();
    if (debug) mJebInstance.print(getClassFromSignature(signature));

    Class mClass = mJebInstance.getDecompiledClassTree(getClassFromSignature(signature));
    defineDecoderMethodSignature(mClass);

    if(!decoderMethodSignature.isEmpty()){
    normalizeDecoderMethod();
    initDecoderValues(mClass);

    for (Method mMethod : (List<Method>) mClass.getMethods()) {
    decodeMethod(mMethod);
    }
    }

    jebInstance.getUI().getView(View.Type.JAVA).refresh();

    jebInstance.print("DexGuardStringDecoder_End");
    // printAllOperators();
    }

    private static void defineDecoderMethodSignature(Class mClass){
    for (Method mMethod : (List<Method>) mClass.getMethods()) {
    String mMethodSignature = mMethod.getSignature();

    if(mMethod.isStatic() && Pattern.matches("^.*[(][IBS]{3}[)]Ljava[/]lang[/]String[;]$",mMethodSignature.split(">")[1])){
    decoderMethodSignature = mMethodSignature;
    if (debug) mJebInstance.print("decoderMethodSignature = " + decoderMethodSignature);
    return;
    }
    }
    }

    private static void normalizeDecoderMethod(){
    Method mMethod = mJebInstance.getDecompiledMethodTree(decoderMethodSignature);
    Block mMethodBodyBlock = mMethod.getBody();

    int ifStmLine = 0;

    while(!(mMethodBodyBlock.get(ifStmLine) instanceof IfStm)){
    ifStmLine++;
    if(ifStmLine == mMethodBodyBlock.size()){
    return;
    }
    }

    Block mElseBlock = ((IfStm)mMethodBodyBlock.get(ifStmLine)).getDefaultBlock();
    Block mWhileBlock = Block.build();

    int labelLine = 0;

    while(!(mElseBlock.get(0) instanceof Label)){
    mMethodBodyBlock.insert(ifStmLine + labelLine, mElseBlock.get(0));
    mElseBlock.remove(0);
    labelLine++;
    }


    for (int i = 0; i < mElseBlock.size() - 1; i++) {
    if(mElseBlock.get(i+1) instanceof IfStm){
    IfStm mIfStm = (IfStm) mElseBlock.get(i+1);
    Predicate mIfPredicate = mIfStm.getBranchPredicate(0);
    Block mIfIfBlock = mIfStm.getBranchBody(0);
    Block mIfElseBlock = mIfStm.getDefaultBlock();

    mWhileBlock.insert(mWhileBlock.size(), IfStm.build(mIfPredicate,mIfIfBlock));
    for (int k = 0; k < mIfElseBlock.size(); k++) {
    mWhileBlock.insert(mWhileBlock.size(), mIfElseBlock.get(k));
    }
    } else {
    mWhileBlock.insert(mWhileBlock.size(), mElseBlock.get(i + 1));
    }
    }

    int size = mMethodBodyBlock.size() - ifStmLine - labelLine - 2;

    for (int i = 0; i < size; i++) {
    mWhileBlock.insert(mWhileBlock.size(), mMethodBodyBlock.get(ifStmLine + labelLine + 1));
    mMethodBodyBlock.remove(ifStmLine+labelLine + 1);
    }

    mMethodBodyBlock.remove(ifStmLine + labelLine + 1);

    IExpression mIExpression = new Constant.Builder(mJebInstance).buildInt(1);

    Predicate mTruePredicate = Predicate.build(mIExpression, Operator.EQ, mIExpression);

    WhileStm mWhileStm = WhileStm.build(mTruePredicate,mWhileBlock);
    mMethodBodyBlock.replaceSubElement(mMethodBodyBlock.get(ifStmLine+labelLine), mWhileStm);
    }

    private static void initDecoderValues(Class mClass) {
    staticByteArrays = new HashMap<String,byte[]>();
    staticIntegers = new HashMap<String, Integer>();

    for (Method mMethod : (List<Method>) mClass.getMethods()) {
    if (mMethod.getName().equals("<clinit>")) {
    Block clinitMethodBlock = mMethod.getBody();
    for (int i = 0; i < clinitMethodBlock.size(); i++) {
    if(clinitMethodBlock.get(i) instanceof Assignment){
    Assignment mAssignment = (Assignment) clinitMethodBlock.get(i);

    IExpression mLeftExpression = mAssignment.getLeft();
    IExpression mRightExpression = mAssignment.getRight();

    if(mLeftExpression instanceof StaticField) {
    StaticField mStaticField = (StaticField) mLeftExpression;

    if (mStaticField.getField().getType().equals("[B")) {
    byte[] b = getByteArrayValue(mRightExpression, staticIntegers, staticByteArrays);

    if (b == null){
    mJebInstance.print("Incorrect static byte[] " + mStaticField.getField().getName() + " define - initDecoderValues");
    return;
    }

    staticByteArrays.put(mStaticField.getField().getName(), b);

    if (debug) mJebInstance.print("static byte[] " + mStaticField.getField().getName());
    } else if (mStaticField.getField().getType().equals("I") || mStaticField.getField().getType().equals("S") || mStaticField.getField().getType().equals("B")) {
    int a = getIntValueOfExpression(mRightExpression, staticIntegers, staticByteArrays);

    if(a == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect int " + mStaticField.getField().getName());
    return;
    }

    staticIntegers.put(mStaticField.getField().getName(), a);

    if (debug) mJebInstance.print("static int " + mStaticField.getField().getName() + " = " + a);
    }
    }
    }
    }
    }
    }
    }

    private static void decodeMethod(Method mMethod){
    if (debug) mJebInstance.print("Start decode " + mMethod.getSignature());

    HashMap<String, Integer> intValues = new HashMap<String,Integer>();
    intValues.putAll(staticIntegers);
    HashMap<String, byte[]> byteArrayValues = new HashMap<String, byte[]>();
    byteArrayValues.putAll(staticByteArrays);

    for (int i = 0; i < mMethod.getBody().size(); i++){
    if(!mMethod.getSignature().equals(decoderMethodSignature)) decodeIElement(mMethod.getBody().get(i), mMethod.getBody(), intValues, byteArrayValues, 1);
    }
    }

    public static String repeat(String str, int times){
    return new String(new char[times]).replace("\0", str);
    }

    private static void decodeIElement(IElement mIElement, IElement mParentIElement, HashMap<String, Integer> intValues, HashMap<String, byte[]> byteArrayValues, int level){
    if (debug) mJebInstance.print(repeat("\t", level) + "decodeIElement(" + mIElement.getClass().getName() + ", " + mParentIElement.getClass().getName() + ", ... )");

    if (mIElement instanceof Assignment){
    Assignment mAssignment = (Assignment) mIElement;

    IExpression mLeftExpression = mAssignment.getLeft();
    IExpression mRightExpression = mAssignment.getRight();

    if (mAssignment.isSimpleAssignment()) {
    if (mLeftExpression instanceof Definition) {
    Definition mDefinition = (Definition) mLeftExpression;

    String type = mDefinition.getType();

    if (type.equals("I") || type.equals("B") || type.equals("S")) {
    int val = getIntValueOfExpression(mRightExpression, intValues, byteArrayValues);

    if (val == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect mRightExpression int " + mDefinition.getIdentifier().getName() + " == " + val + " for SimpleAssignment - decodeIElement");
    return;
    }

    intValues.put(mDefinition.getIdentifier().getName(), val);

    if (debug)
    mJebInstance.print("\t\tint " + mDefinition.getIdentifier().getName() + " = " + val);
    } /*else if (type.equals("[B")) {
    byte[] val = getByteArrayValue(mRightExpression, intValues, byteArrayValues);
    if (val == null) {
    mJebInstance.print("Incorrect mRightExpression byte[] " + mDefinition.getIdentifier().getName() + " == " + val + " for SimpleAssignment - decodeIElement");
    return;
    }
    byteArrayValues.put(mDefinition.getIdentifier().getName(), val);
    if (debug)
    mJebInstance.print("\t\tbyte[] " + mDefinition.getIdentifier().getName() + " = " + Arrays.toString(val));
    }*/
    } else if (mLeftExpression instanceof Identifier) {
    Identifier mIdentifier = (Identifier) mLeftExpression;

    if (intValues.containsKey(mIdentifier.getName())) {
    int val = getIntValueOfExpression(mRightExpression, intValues, byteArrayValues);

    if (val == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect mRightExpression " + mIdentifier.getName() + " == " + val + " for SimpleAssignment - decodeIElement");
    return;
    }

    intValues.put(mIdentifier.getName(), val);

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " = " + val);
    } /*else if (byteArrayValues.containsKey(mIdentifier.getName())) {
    byte[] val = getByteArrayValue(mRightExpression, intValues, byteArrayValues);
    if (val == null) {
    mJebInstance.print("Incorrect mRightExpression " + mIdentifier.getName() + " == " + val + " for SimpleAssignment - decodeIElement");
    return;
    }
    byteArrayValues.put(mIdentifier.getName(), val);
    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " = " + val);
    }*/
    } /*else if (mLeftExpression instanceof ArrayElt) {
    ArrayElt mArrayElt = (ArrayElt) mLeftExpression;
    if (mArrayElt.getArray() instanceof Identifier) {
    String arrayName = ((Identifier) mArrayElt.getArray()).getName();
    if (!byteArrayValues.containsKey(arrayName)) {
    mJebInstance.print("Unavailable byte[] " + arrayName + " for SimpleAssignment - decodeIElement");
    return;
    }
    int position = getIntValueOfExpression(mArrayElt.getIndex(), intValues, byteArrayValues);
    if (position < 0 || position >= byteArrayValues.get(arrayName).length) {
    mJebInstance.print("Incorrect position " + position + " for SimpleAssignment - decodeIElement");
    return;
    }
    byte[] result = byteArrayValues.get(arrayName);
    int val = getIntValueOfExpression(mRightExpression, intValues, byteArrayValues);
    if (val == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect mRightExpression " + arrayName + "[" + position + "] == " + val + " for SimpleAssignment - decodeIElement");
    return;
    }
    result[position] = (byte) val;
    if (debug) mJebInstance.print("\t\t" + arrayName + "[" + position + "] = " + val);
    byteArrayValues.put(arrayName, result);
    }
    }*/
    } else if (mAssignment.isCombinedOperatorAssignment()) {
    if (!(mLeftExpression instanceof Identifier)) {
    mJebInstance.print("Incorrect left IExpression type " + mLeftExpression.getClass().getName() + " for CombinedOperatorAssignment - decodeIElement");
    return;
    }

    if (mRightExpression == null) {
    mJebInstance.print("Incorrect right IExpression " + mRightExpression.getClass().getName() + " == null for CombinedOperatorAssignment - decodeIElement");
    return;
    }

    Identifier mIdentifier = (Identifier) mLeftExpression;

    if (intValues.containsKey(mIdentifier.getName())) {
    int val = getIntValueOfExpression(mRightExpression, intValues, byteArrayValues);

    if (val == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect mRightExpression int value " + val + " for CombinedOperatorAssignment - decodeIElement");
    return;
    }

    Operator mOperator = mAssignment.getCombinedOperator();

    if(mOperator.equals(Operator.ADD)){
    int val2 = intValues.get(mIdentifier.getName());

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " += " + val2);

    intValues.put(mIdentifier.getName(), val2 + val);
    } else if (mOperator.equals(Operator.SUB)){
    int val2 = intValues.get(mIdentifier.getName());

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " -= " + val2);

    intValues.put(mIdentifier.getName(), val - val2);
    } else if (mOperator.equals(Operator.MUL)){
    int val2 = intValues.get(mIdentifier.getName());

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " *= " + val2);

    intValues.put(mIdentifier.getName(), val * val2);
    }
    }

    } else if (mAssignment.isUnaryOperatorAssignment()) {
    if (!(mLeftExpression instanceof Identifier)) {
    mJebInstance.print("Incorrect left IExpretion type " + mLeftExpression.getClass().getName() + " for UnaryOperatorAssignment - decodeIElement");
    return;
    }

    if (mRightExpression != null) {
    mJebInstance.print("Incorrect right IExpretion " + mRightExpression.getClass().getName() + " != null for UnaryOperatorAssignment - decodeIElement");
    return;
    }

    Identifier mIdentifier = (Identifier) mLeftExpression;

    if (intValues.containsKey(mIdentifier.getName())) {
    boolean[] unaryFlags = new boolean[2];

    mAssignment.getUnaryOperator(unaryFlags);

    if (unaryFlags[0]) {
    intValues.put(mIdentifier.getName(), intValues.get(mIdentifier.getName()) + 1);
    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + "++");
    } else {
    intValues.put(mIdentifier.getName(), intValues.get(mIdentifier.getName()) - 1);
    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + "--");
    }
    }
    }
    } else if (mIElement instanceof Call) {
    Call mCall = (Call) mIElement;
    String methodSignature = mCall.getMethod().getSignature();

    if(methodSignature.equals(decoderMethodSignature) && !(mParentIElement instanceof Block)){
    List<IExpression> params = mCall.getArguments();

    int param1 = getIntValueOfExpression(params.get(0),intValues,byteArrayValues);
    int param2 = getIntValueOfExpression(params.get(1),intValues,byteArrayValues);
    int param3 = getIntValueOfExpression(params.get(2),intValues,byteArrayValues);

    String result = decodeDexGuardString(param1,param2,param3);

    mJebInstance.print("decodeDexGuardString(" + param1 + ", " + param2 + ", " + param3 + ") = " + result);

    if(result != null) mParentIElement.replaceSubElement(mIElement, (new Constant.Builder(mJebInstance)).buildString(result));
    } else {
    for(int i = 0; i < mIElement.getSubElements().size(); i++){
    decodeIElement((IElement)mIElement.getSubElements().get(i), mIElement, intValues, byteArrayValues, level+1);
    }
    }
    }

    for (IElement element : (List<IElement>) mIElement.getSubElements()) {
    if (!((element instanceof Class) || (element instanceof Field) || (element instanceof Method))) {
    decodeIElement(element, mIElement, intValues, byteArrayValues, level + 1);
    }
    }
    }

    private static String decodeDexGuardString(int param1, int param2, int param3) {
    if (debug) mJebInstance.print("decodeDexGuardString(" + param1 + ", " + param2 + ", " + param3 + ")");

    Method mMethod = mJebInstance.getDecompiledMethodTree(decoderMethodSignature);
    List<Definition> params = mMethod.getParameters();

    Block mMethodBlock = mMethod.getBody();

    HashMap<String, Integer> intValuesMap = new HashMap<String, Integer>();
    intValuesMap.put(params.get(0).getIdentifier().getName(), param1);
    intValuesMap.put(params.get(1).getIdentifier().getName(), param2);
    intValuesMap.put(params.get(2).getIdentifier().getName(), param3);
    intValuesMap.putAll(staticIntegers);

    HashMap<String, byte[]> byteArrayValuesMap = new HashMap<String, byte[]>();
    byteArrayValuesMap.putAll(staticByteArrays);

    for (int i = 0; i < mMethodBlock.size(); i++) {
    if (debug) mJebInstance.print(mMethodBlock.get(i).getClass().getName());

    if(mMethodBlock.get(i) instanceof Definition){
    Definition mDefinition = (Definition) mMethodBlock.get(i);

    String type = mDefinition.getType();

    if (type.equals("I") || type.equals("B") || type.equals("S")){
    intValuesMap.put(mDefinition.getIdentifier().getName(), Integer.MIN_VALUE);

    if (debug) mJebInstance.print("\t\tint " + mDefinition.getIdentifier().getName());
    } else if (type.equals("[B")){
    byteArrayValuesMap.put(mDefinition.getIdentifier().getName(), null);

    if (debug) mJebInstance.print("\t\tbyte[] " + mDefinition.getIdentifier().getName());
    } else {
    mJebInstance.print("Unsupported Definition variable " + mDefinition.getIdentifier().getName() + " type \"" + type + "\" - decodeDexGuardString / Definition");
    return null;
    }
    } else if (mMethodBlock.get(i) instanceof Assignment){
    Assignment mAssignment = (Assignment) mMethodBlock.get(i);

    IExpression mLeftExpression = mAssignment.getLeft();
    IExpression mRightExpression = mAssignment.getRight();

    if (mAssignment.isSimpleAssignment()) {
    if (mLeftExpression instanceof Definition) {
    Definition mDefinition = (Definition) mLeftExpression;

    String type = mDefinition.getType();

    if (type.equals("I") || type.equals("B") || type.equals("S")) {
    int val = getIntValueOfExpression(mRightExpression, intValuesMap, byteArrayValuesMap);

    if (val == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect mRightExpression int " + mDefinition.getIdentifier().getName() + " == " + val + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    intValuesMap.put(mDefinition.getIdentifier().getName(), val);

    if (debug)
    mJebInstance.print("\t\tint " + mDefinition.getIdentifier().getName() + " = " + val);
    } else if (type.equals("[B")) {
    byte[] val = getByteArrayValue(mRightExpression, intValuesMap, byteArrayValuesMap);

    if (val == null) {
    mJebInstance.print("Incorrect mRightExpression byte[] " + mDefinition.getIdentifier().getName() + " == " + val + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    byteArrayValuesMap.put(mDefinition.getIdentifier().getName(), val);

    if (debug)
    mJebInstance.print("\t\tbyte[] " + mDefinition.getIdentifier().getName() + " = " + Arrays.toString(val));
    } else {
    mJebInstance.print("Unsupported Definition variable " + mDefinition.getIdentifier().getName() + " type \"" + type + "\" - decodeDexGuardString / Definition");
    return null;
    }
    } else if (mLeftExpression instanceof Identifier) {
    Identifier mIdentifier = (Identifier) mLeftExpression;

    if (intValuesMap.containsKey(mIdentifier.getName())) {
    int val = getIntValueOfExpression(mRightExpression, intValuesMap, byteArrayValuesMap);

    if (val == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect mRightExpression " + mIdentifier.getName() + " == " + val + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    intValuesMap.put(mIdentifier.getName(), val);

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " = " + val);
    } else if (byteArrayValuesMap.containsKey(mIdentifier.getName())) {
    byte[] val = getByteArrayValue(mRightExpression, intValuesMap, byteArrayValuesMap);

    if (val == null) {
    mJebInstance.print("Incorrect mRightExpression " + mIdentifier.getName() + " == " + val + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    byteArrayValuesMap.put(mIdentifier.getName(), val);

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " = " + val);
    } else {
    mJebInstance.print("Unknown variable " + mIdentifier.getName() + " type - decodeDexGuardString / Definition");
    return null;
    }
    } else if (mLeftExpression instanceof ArrayElt) {
    ArrayElt mArrayElt = (ArrayElt) mLeftExpression;

    if(mArrayElt.getArray() instanceof Identifier) {
    String arrayName = ((Identifier)mArrayElt.getArray()).getName();

    if(!byteArrayValuesMap.containsKey(arrayName)){
    mJebInstance.print("Unavailable byte[] " + arrayName + " for SimpleAssignment - decodeDexGuardString / Assignment / ArrayElt");
    return null;
    }

    int position = getIntValueOfExpression(mArrayElt.getIndex(), intValuesMap, byteArrayValuesMap);

    if(position < 0 || position >= byteArrayValuesMap.get(arrayName).length){
    mJebInstance.print("Incorrect position " + position + " for SimpleAssignment - decodeDexGuardString / Assignment / ArrayElt");
    return null;
    }

    byte[] result = byteArrayValuesMap.get(arrayName);

    int val = getIntValueOfExpression(mRightExpression, intValuesMap, byteArrayValuesMap);

    if (val == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect mRightExpression " + arrayName + "[" + position + "] == " + val + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    result[position] = (byte) val;

    if (debug) mJebInstance.print("\t\t" + arrayName + "[" + position + "] = " + val);
    byteArrayValuesMap.put(arrayName, result);
    } else {
    mJebInstance.print("Incorrect Array IExpression type " + mArrayElt.getArray().getClass().getName() + " for SimpleAssignment - decodeDexGuardString / Assignment / ArrayElt");
    return null;
    }
    } else {
    mJebInstance.print("Incorrect left IExpression type " + mLeftExpression.getClass().getName() + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }
    } else if (mAssignment.isCombinedOperatorAssignment()){
    if(!(mLeftExpression instanceof Identifier)){
    mJebInstance.print("Incorrect left IExpression type " + mLeftExpression.getClass().getName() + " for CombinedOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    if(mRightExpression == null){
    mJebInstance.print("Incorrect right IExpression " + mRightExpression.getClass().getName() + " == null for CombinedOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    Identifier mIdentifier = (Identifier) mLeftExpression;

    if(!intValuesMap.containsKey(mIdentifier.getName())){
    mJebInstance.print("Unavailable int " + mIdentifier.getName() + " for CombinedOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    int val = getIntValueOfExpression(mRightExpression, intValuesMap, byteArrayValuesMap);

    if(val == Integer.MIN_VALUE){
    mJebInstance.print("Incorrect mRightExpression int value " + val + " for CombinedOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    Operator mOperator = mAssignment.getCombinedOperator();

    if(mOperator.equals(Operator.ADD)){
    int val2 = intValuesMap.get(mIdentifier.getName());

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " += " + val2);

    intValuesMap.put(mIdentifier.getName(), val2 + val);
    } else if (mOperator.equals(Operator.SUB)){
    int val2 = intValuesMap.get(mIdentifier.getName());

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " -= " + val2);

    intValuesMap.put(mIdentifier.getName(), val - val2);
    } else if (mOperator.equals(Operator.MUL)){
    int val2 = intValuesMap.get(mIdentifier.getName());

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " *= " + val2);

    intValuesMap.put(mIdentifier.getName(), val * val2);
    } else {
    mJebInstance.print("Unsopported combinedOperator type \"" + mOperator.toString() + "=\" for CombinedOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }
    } else if (mAssignment.isUnaryOperatorAssignment()){
    if(!(mLeftExpression instanceof Identifier)){
    mJebInstance.print("Incorrect left IExpretion type " + mLeftExpression.getClass().getName() + " for UnaryOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    if(mRightExpression != null){
    mJebInstance.print("Incorrect right IExpretion " + mRightExpression.getClass().getName() + " != null for UnaryOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    Identifier mIdentifier = (Identifier) mLeftExpression;

    if(!intValuesMap.containsKey(mIdentifier.getName())){
    mJebInstance.print("Unavailable int " + mIdentifier.getName() + " - decodeDexGuardString / Assignment");
    return null;
    }

    boolean[] unaryFlags = new boolean[2];

    mAssignment.getUnaryOperator(unaryFlags);

    if(unaryFlags[0]){
    intValuesMap.put(mIdentifier.getName(), intValuesMap.get(mIdentifier.getName()) + 1);
    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + "++");
    } else {
    intValuesMap.put(mIdentifier.getName(), intValuesMap.get(mIdentifier.getName()) - 1);
    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + "--");
    }
    } else {
    mJebInstance.print("Incorrect type Assignment - decodeDexGuardString");
    }
    } else if (mMethodBlock.get(i) instanceof WhileStm){
    WhileStm mWhileStm = (WhileStm)mMethodBlock.get(i);

    Block mWhileBlock = mWhileStm.getBody();

    int controller = 0;

    while (controller < 70) {
    controller++;

    for (int j = 0; j < mWhileBlock.size(); j++) {
    if (debug) mJebInstance.print("\t\t\t\t"+ mWhileBlock.get(j).getClass().getName());

    if(mWhileBlock.get(j) instanceof Definition){
    Definition mDefinition = (Definition) mWhileBlock.get(j);

    String type = mDefinition.getType();

    if (type.equals("I") || type.equals("B") || type.equals("S")){
    intValuesMap.put(mDefinition.getIdentifier().getName(), Integer.MIN_VALUE);

    if (debug) mJebInstance.print("\t\t\t\t\t\tint " + mDefinition.getIdentifier().getName());
    } else if (type.equals("[B")){
    byteArrayValuesMap.put(mDefinition.getIdentifier().getName(), null);

    if (debug) mJebInstance.print("\t\t\t\t\t\tbyte[] " + mDefinition.getIdentifier().getName());
    } else {
    mJebInstance.print("Unsupported Definition variable " + mDefinition.getIdentifier().getName() + " type \"" + type + "\" - decodeDexGuardString / Definition");
    return null;
    }
    } else if (mWhileBlock.get(j) instanceof Assignment){
    Assignment mAssignment = (Assignment) mWhileBlock.get(j);

    IExpression mLeftExpression = mAssignment.getLeft();
    IExpression mRightExpression = mAssignment.getRight();

    if (mAssignment.isSimpleAssignment()){
    if(mLeftExpression instanceof Definition){
    Definition mDefinition = (Definition) mLeftExpression;

    String type = mDefinition.getType();

    if (type.equals("I") || type.equals("B") || type.equals("S")){
    int val = getIntValueOfExpression(mRightExpression, intValuesMap, byteArrayValuesMap);

    if (val == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect mRightExpression int " + mDefinition.getIdentifier().getName() + " == " + val + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    intValuesMap.put(mDefinition.getIdentifier().getName(), val);

    if (debug) mJebInstance.print("\t\t\t\t\t\tint " + mDefinition.getIdentifier().getName() + " = " + val);
    } else if (type.equals("[B")){
    byte[] val = getByteArrayValue(mRightExpression, intValuesMap, byteArrayValuesMap);

    if (val == null) {
    mJebInstance.print("Incorrect mRightExpression byte[] " + mDefinition.getIdentifier().getName() + " == " + val + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    byteArrayValuesMap.put(mDefinition.getIdentifier().getName(), val);

    if (debug) mJebInstance.print("\t\t\t\t\t\tbyte[] " + mDefinition.getIdentifier().getName() + " = " + Arrays.toString(val));
    } else {
    mJebInstance.print("Unsupported Definition variable " + mDefinition.getIdentifier().getName() + " type \"" + type + "\" - decodeDexGuardString / Definition");
    return null;
    }
    } else if (mLeftExpression instanceof Identifier) {
    Identifier mIdentifier = (Identifier) mLeftExpression;

    if (intValuesMap.containsKey(mIdentifier.getName())){
    int val = getIntValueOfExpression(mRightExpression, intValuesMap, byteArrayValuesMap);

    if (val == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect mRightExpression " + mIdentifier.getName() + " == " + val + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    intValuesMap.put(mIdentifier.getName(), val);

    if (debug) mJebInstance.print("\t\t\t\t\t\t" + mIdentifier.getName() + " = " + val);
    } else if (byteArrayValuesMap.containsKey(mIdentifier.getName())){
    byte[] val = getByteArrayValue(mRightExpression, intValuesMap, byteArrayValuesMap);

    if (val == null) {
    mJebInstance.print("Incorrect mRightExpression " + mIdentifier.getName() + " == " + val + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    byteArrayValuesMap.put(mIdentifier.getName(), val);

    if (debug) mJebInstance.print("\t\t\t\t\t\t" + mIdentifier.getName() + " = " + val);
    } else {
    mJebInstance.print("Unknown variable " + mIdentifier.getName() + " type - decodeDexGuardString / Definition");
    return null;
    }
    } else if (mLeftExpression instanceof ArrayElt) {
    ArrayElt mArrayElt = (ArrayElt) mLeftExpression;

    if(mArrayElt.getArray() instanceof Identifier) {
    String arrayName = ((Identifier)mArrayElt.getArray()).getName();

    if(!byteArrayValuesMap.containsKey(arrayName)){
    mJebInstance.print("Unavailable byte[] " + arrayName + " for SimpleAssignment - decodeDexGuardString / Assignment / ArrayElt");
    return null;
    }

    int position = getIntValueOfExpression(mArrayElt.getIndex(), intValuesMap, byteArrayValuesMap);

    if(position < 0 || position >= byteArrayValuesMap.get(arrayName).length){
    mJebInstance.print("Incorrect position " + position + " for SimpleAssignment - decodeDexGuardString / Assignment / ArrayElt");
    return null;
    }

    byte[] result = byteArrayValuesMap.get(arrayName);

    int val = getIntValueOfExpression(mRightExpression, intValuesMap, byteArrayValuesMap);

    if (val == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect mRightExpression " + arrayName + "[" + position + "] == " + val + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    result[position] = (byte) val;

    if (debug) mJebInstance.print("\t\t" + arrayName + "[" + position + "] = " + val);
    byteArrayValuesMap.put(arrayName, result);
    } else {
    mJebInstance.print("Incorrect Array IExpression type " + mArrayElt.getArray().getClass().getName() + " for SimpleAssignment - decodeDexGuardString / Assignment / ArrayElt");
    return null;
    }
    } else {
    mJebInstance.print("Incorrect left IExpression type " + mLeftExpression.getClass().getName() + " for SimpleAssignment - decodeDexGuardString / Assignment");
    return null;
    }
    } else if (mAssignment.isCombinedOperatorAssignment()){
    if(!(mLeftExpression instanceof Identifier)){
    mJebInstance.print("Incorrect left IExpression type " + mLeftExpression.getClass().getName() + " for CombinedOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    if(mRightExpression == null){
    mJebInstance.print("Incorrect right IExpression " + mRightExpression.getClass().getName() + " == null for CombinedOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    Identifier mIdentifier = (Identifier) mLeftExpression;

    if(!intValuesMap.containsKey(mIdentifier.getName())){
    mJebInstance.print("Unavailable int " + mIdentifier.getName() + " for CombinedOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    int val = getIntValueOfExpression(mRightExpression, intValuesMap, byteArrayValuesMap);

    if(val == Integer.MIN_VALUE){
    mJebInstance.print("Incorrect mRightExpression int value " + val + " for CombinedOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    Operator mOperator = mAssignment.getCombinedOperator();

    if(mOperator.equals(Operator.ADD)){
    int val2 = intValuesMap.get(mIdentifier.getName());

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " += " + val2);

    intValuesMap.put(mIdentifier.getName(), val2 + val);
    } else if (mOperator.equals(Operator.SUB)){
    int val2 = intValuesMap.get(mIdentifier.getName());

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " -= " + val2);

    intValuesMap.put(mIdentifier.getName(), val - val2);
    } else if (mOperator.equals(Operator.MUL)){
    int val2 = intValuesMap.get(mIdentifier.getName());

    if (debug) mJebInstance.print("\t\t" + mIdentifier.getName() + " *= " + val2);

    intValuesMap.put(mIdentifier.getName(), val * val2);
    } else {
    mJebInstance.print("Unsopported combinedOperator type \"" + mOperator.toString() + "=\" for CombinedOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }
    } else if (mAssignment.isUnaryOperatorAssignment()){
    if(!(mLeftExpression instanceof Identifier)){
    mJebInstance.print("Incorrect left IExpretion type " + mLeftExpression.getClass().getName() + " for UnaryOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    if(mRightExpression != null){
    mJebInstance.print("Incorrect right IExpretion " + mRightExpression.getClass().getName() + " != null for UnaryOperatorAssignment - decodeDexGuardString / Assignment");
    return null;
    }

    Identifier mIdentifier = (Identifier) mLeftExpression;

    if(!intValuesMap.containsKey(mIdentifier.getName())){
    mJebInstance.print("Unavailable int " + mIdentifier.getName() + " - decodeDexGuardString / Assignment");
    return null;
    }

    boolean[] unaryFlags = new boolean[2];

    mAssignment.getUnaryOperator(unaryFlags);

    if(unaryFlags[0]){
    intValuesMap.put(mIdentifier.getName(), intValuesMap.get(mIdentifier.getName()) + 1);
    if (debug) mJebInstance.print("\t\t\t\t\t\t" + mIdentifier.getName() + "++");
    } else {
    intValuesMap.put(mIdentifier.getName(), intValuesMap.get(mIdentifier.getName()) - 1);
    if (debug) mJebInstance.print("\t\t\t\t\t\t" + mIdentifier.getName() + "--");
    }
    } else {
    mJebInstance.print("Incorrect type Assignment - decodeDexGuardString");
    }
    } else if (mWhileBlock.get(j) instanceof IfStm){
    IfStm mIfStm = (IfStm) mWhileBlock.get(j);

    Predicate mPredicate = mIfStm.getBranchPredicate(0);
    String lVarName = ((Identifier) mPredicate.getLeft()).getName();
    String rVarName = ((Identifier) mPredicate.getRight()).getName();

    Block ifBlock = mIfStm.getBranchBody(0);

    if(intValuesMap.get(lVarName).equals(intValuesMap.get(rVarName))){
    String resultByteArray = "";

    for (int k = 0; k < ifBlock.size(); k++) {
    if(ifBlock.get(k) instanceof Return){
    Return mReturn = (Return) ifBlock.get(k);

    if(mReturn.getExpression() instanceof New){
    New mNew = (New) mReturn.getExpression();

    List args = mNew.getArguments();

    if (args.size() > 0 && args.get(0) instanceof Identifier) {
    Identifier mIdentifier = (Identifier) args.get(0);

    resultByteArray = mIdentifier.getName();
    } else {
    mJebInstance.print("String init params incorrect");

    return null;
    }
    } else if (mReturn.getExpression() instanceof Call) {
    Call mCall = (Call) mReturn.getExpression();

    List<IExpression> par = mCall.getArguments();

    if(par.size() <= 0) {
    mJebInstance.print("Unavailable String Creater");

    return null;
    }

    if (par.get(0) instanceof New) {
    New mNew = (New) par.get(0);

    List args = mNew.getArguments();

    if (args.size() > 0 && args.get(0) instanceof Identifier) {
    Identifier mIdentifier = (Identifier) args.get(0);

    resultByteArray = mIdentifier.getName();
    } else {
    mJebInstance.print("String init params incorrect");

    return null;
    }
    } else {
    mJebInstance.print("Unavailable String Creater in Call");

    return null;
    }

    } else {
    mJebInstance.print("Incorrect Return Expression " + mReturn.getExpression().getClass().getName());

    return null;
    }
    } else {
    mJebInstance.print("Statement is not Return (" + ifBlock.get(k).getClass().getName() + ")");

    return null;
    }
    }

    //mJebInstance.print("t4 - " + resultByteArray + " = " + Arrays.toString(byteArrayValuesMap.get(resultByteArray)) + " " + new String(byteArrayValuesMap.get(resultByteArray)));

    return new String(byteArrayValuesMap.get(resultByteArray));
    }
    } else {
    mJebInstance.print("Unsupported Statement type " + mWhileBlock.get(j).getClass().getName() + " - decodeDexGuardString / Assignment");
    return null;
    }

    }
    }
    } else {
    mJebInstance.print("Unsupported Statement type " + mMethodBlock.get(i).getClass().getName() + " - decodeDexGuardString / Assignment");
    return null;
    }

    }

    return "";
    }

    private static byte[] getByteArrayValue(IExpression mIExpression, HashMap<String,Integer> intValues, HashMap<String, byte[]> byteArrayValues){
    if (debug) mJebInstance.print("\t\t\t\t\t\t\t\tgetByteArrayValue for " + mIExpression.getClass().getName());

    if (mIExpression instanceof Call) {
    //TODO
    mJebInstance.print("Unsupported IExpression parametr type - getByteArrayValue of Call");
    return null;
    } else if (mIExpression instanceof Identifier) {
    Identifier mIdentifier = (Identifier) mIExpression;

    if(!byteArrayValues.containsKey(mIdentifier.getName())) {
    mJebInstance.print("Unavailable byte[] " + mIdentifier.getName() + " - getByteArrayValue of Identifier");
    return null;
    }

    return byteArrayValues.get(mIdentifier.getName());
    } else if (mIExpression instanceof InstanceField) {
    //TODO
    mJebInstance.print("Unsupported IExpression parametr type - getByteArrayValue of InstanceField");
    return null;
    } else if (mIExpression instanceof NewArray) {
    NewArray mNewArray = (NewArray) mIExpression;

    if(!mNewArray.getType().equals("[B")){
    mJebInstance.print("Unsupported NewArray type " + mNewArray.getType() + " - getByteArrayValue of NewArray");
    return null;
    }

    if(mNewArray.getInitialValues() != null){
    List<Constant> initialValues = mNewArray.getInitialValues();

    if(initialValues.isEmpty()){
    return null;
    }

    byte[] rezult = new byte[initialValues.size()];

    for (int i = 0; i < initialValues.size(); i++) {
    rezult[i] = initialValues.get(i).getByte();
    }

    return rezult;
    } else if (mNewArray.getSizes() != null) {

    if (mNewArray.getSizes().size() > 1) {
    mJebInstance.print("Unsupported NewArray multiSizes array " + mNewArray.getSizes().size() + " - getByteArrayValue of NewArray");
    return null;
    }

    IExpression mSizeIExpression = (IExpression) mNewArray.getSizes().get(0);
    int sizeArray = getIntValueOfExpression(mSizeIExpression, intValues, byteArrayValues);

    if (sizeArray < 0) {
    mJebInstance.print("Incorrect array size " + sizeArray + " - getByteArrayValue of NewArray");
    return null;
    }

    return new byte[sizeArray];
    } else {
    mJebInstance.print("Error - getByteArrayValue of NewArray");
    return null;
    }
    } else if (mIExpression instanceof StaticField) {
    StaticField mStaticField = (StaticField) mIExpression;

    String fType = mStaticField.getField().getType();

    if(!fType.equals("[B")){
    mJebInstance.print("Incorrect StaticField type " + fType + " - getByteArrayValue of StaticField");
    return null;
    }

    if(!byteArrayValues.containsKey(mStaticField.getField().getName())){
    mJebInstance.print("Unavailable byte[] " + mStaticField.getField().getName() + " - getByteArrayValue of StaticField");
    return null;
    }

    return byteArrayValues.get(mStaticField.getField().getName());
    } else {
    mJebInstance.print("Unsupported IExpression parametr type - getByteArrayValue of " + mIExpression.getClass().getName());
    return null;
    }
    }

    private static int getIntValueOfExpression(IExpression mIExpression, HashMap<String, Integer> intValues, HashMap<String,byte[]> byteArrayValues) {
    if (debug) mJebInstance.print("\t\t\t\t\t\t\t\tgetIntValueOfExpression for " + mIExpression.getClass().getName());

    if(mIExpression instanceof ArrayElt){
    ArrayElt mArrayElt = (ArrayElt) mIExpression;

    if(!(mArrayElt.getArray() instanceof Identifier || mArrayElt.getArray() instanceof StaticField)){
    mJebInstance.print("Unsupported type of Array " + mArrayElt.getArray().getClass().getName() + " - getIntValueOfExpression of ArrayElt");
    return Integer.MIN_VALUE;
    }

    String byteArrayName = (mArrayElt.getArray() instanceof Identifier) ? ((Identifier)mArrayElt.getArray()).getName() : ((StaticField)mArrayElt.getArray()).getField().getName();

    if(!byteArrayValues.containsKey(byteArrayName)){
    mJebInstance.print("Unavailable byteArray " + byteArrayName + " - getIntValueOfExpression of ArrayElt");
    return Integer.MIN_VALUE;
    }

    byte[] mBytes = byteArrayValues.get(byteArrayName);

    int position = getIntValueOfExpression(mArrayElt.getIndex(), intValues, byteArrayValues);

    if(mBytes.length <= position){
    mJebInstance.print("Incorrect position (byte[].length " + mBytes.length + " <= position " + position + ") - getIntValueOfExpression of ArrayElt");
    return Integer.MIN_VALUE;
    } else if (position < 0){
    mJebInstance.print("Incorrect position (position " + position + " < 0) - getIntValueOfExpression of ArrayElt");
    return Integer.MIN_VALUE;
    }

    return mBytes[position];
    } else if (mIExpression instanceof Call) {
    //TODO
    mJebInstance.print("Unsupported IExpression parametr type - getIntValueOfExpression of Call");
    return Integer.MIN_VALUE;
    } else if (mIExpression instanceof Constant) {
    Constant mConstant = (Constant) mIExpression;

    if(mConstant.isFalse() || mConstant.isNull() || mConstant.isTrue() || mConstant.isString()){
    mJebInstance.print("Unsupported type of Constant - getIntValueOfExpression of Constant");
    return Integer.MIN_VALUE;
    }

    String type = ((Constant) mIExpression).getType();

    if(type.equals("B")){
    return (int) ((Constant) mIExpression).getByte();
    } else if (type.equals("S")){
    return (int) ((Constant) mIExpression).getShort();
    } else {
    return ((Constant) mIExpression).getInt();
    }
    } else if (mIExpression instanceof Expression) {
    Expression mExpression = (Expression) mIExpression;

    int lValue = Integer.MIN_VALUE;

    if(mExpression.getLeft() != null) {
    lValue = getIntValueOfExpression(mExpression.getLeft(), intValues, byteArrayValues);
    if (lValue == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect lValue " + lValue + " - getIntValueOfExpression of Expression");
    return Integer.MIN_VALUE;
    }
    }

    int rValue = getIntValueOfExpression(mExpression.getRight(), intValues, byteArrayValues);
    if (rValue == Integer.MIN_VALUE) {
    mJebInstance.print("Incorrect rValue " + rValue + " - getIntValueOfExpression of Expression");
    return Integer.MIN_VALUE;
    }

    Operator mOperator = mExpression.getOperator();

    if(mOperator.equals(Operator.ADD)){
    return lValue + rValue;
    } else if (mOperator.equals(Operator.SUB)){
    return lValue - rValue;
    } else if (mOperator.equals(Operator.MUL)){
    return lValue * rValue;
    } else if (mOperator.equals(Operator.DIV)){
    return lValue / rValue;
    } else if (mOperator.equals(Operator.REM)){
    return lValue % rValue;
    } else if (mOperator.equals(Operator.OR)){
    return lValue | rValue;
    } else if (mOperator.equals(Operator.AND)){
    return lValue & rValue;
    } else if (mOperator.equals(Operator.XOR)){
    return lValue ^ rValue;
    } else if (mOperator.equals(Operator.SHL)){
    return lValue << rValue;
    } else if (mOperator.equals(Operator.SHR)){
    return lValue >> rValue;
    } else if (mOperator.equals(Operator.USHR)){
    return lValue >>> rValue;
    } else if (mOperator.equals(Operator.NEG)) {
    return -rValue;
    } else if (mOperator.equals(Operator.CAST_TO_BYTE)) {
    return rValue;
    } else if (mOperator.equals(Operator.CAST_TO_SHORT)) {
    return rValue;
    } else if (mOperator.equals(Operator.CAST_TO_INT)) {
    return rValue;
    } else {
    mJebInstance.print("Unsupported operation type \"" + mOperator.toString() + "\" - getIntValueOfExpression of Expression");
    return Integer.MIN_VALUE;
    }
    } else if (mIExpression instanceof Identifier) {
    Identifier mIdentifier = (Identifier) mIExpression;

    if(!intValues.containsKey(mIdentifier.getName())){
    mJebInstance.print("intValues.keys = " + Arrays.toString(intValues.keySet().toArray()));

    mJebInstance.print("Unavailable int " + mIdentifier.getName() + " - getIntValueOfExpression of Identifier");
    return Integer.MIN_VALUE;
    }

    return intValues.get(mIdentifier.getName());
    } else if (mIExpression instanceof InstanceField) {
    //TODO
    mJebInstance.print("Unsupported IExpression parametr type - getIntValueOfExpression of InstanceField");
    return Integer.MIN_VALUE;
    } else if (mIExpression instanceof StaticField) {
    StaticField mStaticField = (StaticField) mIExpression;

    String fType = mStaticField.getField().getType();

    if(!(fType.equals("I") || fType.equals("B") || fType.equals("S") )){
    mJebInstance.print("Incorrect StaticField type " + fType + " - getIntValueOfExpression of StaticField");
    return Integer.MIN_VALUE;
    }

    if(!intValues.containsKey(mStaticField.getField().getName())){
    mJebInstance.print("Unavailable int " + mStaticField.getField().getName() + " - getIntValueOfExpression of StaticField");
    return Integer.MIN_VALUE;
    }

    return intValues.get(mStaticField.getField().getName());
    } else {
    mJebInstance.print("Unsupported IExpression parametr type - getIntValueOfExpression of " + mIExpression.getClass().getName());
    return Integer.MIN_VALUE;
    }
    }

    private static void printAllOperators(){
    mJebInstance.print("ADD " + Operator.ADD.toString());
    mJebInstance.print("SUB " + Operator.SUB.toString());
    mJebInstance.print("MUL " + Operator.MUL.toString());
    mJebInstance.print("DIV " + Operator.DIV.toString());
    mJebInstance.print("REM " + Operator.REM.toString());
    mJebInstance.print("AND " + Operator.AND.toString());
    mJebInstance.print("OR " + Operator.OR.toString());
    mJebInstance.print("XOR " + Operator.XOR.toString());
    mJebInstance.print("SHL " + Operator.SHL.toString());
    mJebInstance.print("SHR " + Operator.SHR.toString());
    mJebInstance.print("USHR " + Operator.USHR.toString());
    mJebInstance.print("NEG " + Operator.NEG.toString());
    mJebInstance.print("NOT " + Operator.NOT.toString());
    mJebInstance.print("LOG_IDENT " + Operator.LOG_IDENT.toString());
    mJebInstance.print("LOG_NOT " + Operator.LOG_NOT.toString());
    mJebInstance.print("LOG_OR " + Operator.LOG_OR.toString());
    mJebInstance.print("LOG_AND " + Operator.LOG_AND.toString());
    mJebInstance.print("INSTANCEOF " + Operator.INSTANCEOF.toString());
    mJebInstance.print("EQ " + Operator.EQ.toString());
    mJebInstance.print("NE " + Operator.NE.toString());
    mJebInstance.print("LT " + Operator.LT.toString());
    mJebInstance.print("GE " + Operator.GE.toString());
    mJebInstance.print("GT " + Operator.GT.toString());
    mJebInstance.print("LE " + Operator.LE.toString());
    mJebInstance.print("CAST_TO_BYTE " + Operator.CAST_TO_BYTE.toString());
    mJebInstance.print("CAST_TO_CHAR " + Operator.CAST_TO_CHAR.toString());
    mJebInstance.print("CAST_TO_SHORT " + Operator.CAST_TO_SHORT.toString());
    mJebInstance.print("CAST_TO_INT " + Operator.CAST_TO_INT.toString());
    mJebInstance.print("CAST_TO_LONG " + Operator.CAST_TO_LONG.toString());
    mJebInstance.print("CAST_TO_FLOAT " + Operator.CAST_TO_FLOAT.toString());
    mJebInstance.print("CAST_TO_DOUBLE " + Operator.CAST_TO_DOUBLE.toString());
    mJebInstance.print("CAST_TO_BOOLEAN " + Operator.CAST_TO_BOOLEAN.toString());
    mJebInstance.print("CONCAT " + Operator.CONCAT.toString());
    }

    private static String getClassFromSignature(String signature){
    String pattern = "^(L[a-zA-Z/$]*[;])(.*)$";
    return signature.replaceAll(pattern, "$1");
    }
    }