├── .gitignore
├── LICENSE
├── README.md
├── bin
└── .gitignore
├── bitconfigs_db.ini
├── configs_db.ini
├── gui
├── bg.png
└── options.ini
├── instructions_db.ini
├── lib
├── forms-1.3.0-src.zip
└── forms-1.3.0.jar
├── opcodes_db.ini
├── run-GUI.bat
├── scripts.zip
├── scripts_db.ini
└── src
├── mgi
└── tools
│ └── jagdecs2
│ ├── Beautifier.java
│ ├── CS2.java
│ ├── CS2Decoder.java
│ ├── CS2Decompiler.java
│ ├── CS2Stack.java
│ ├── CS2Type.java
│ ├── CodePrinter.java
│ ├── Constants.java
│ ├── DecompilerException.java
│ ├── FlowBlocksGenerator.java
│ ├── FlowBlocksSolver.java
│ ├── ICS2Provider.java
│ ├── LocalVariablesAnalyzerT1.java
│ ├── LocalVariablesAnalyzerT2.java
│ ├── ast
│ ├── AbstractCodeNode.java
│ ├── ArrayLoadNode.java
│ ├── ArrayStoreNode.java
│ ├── BitConfigurationLoadNode.java
│ ├── BitConfigurationStoreNode.java
│ ├── BreakNode.java
│ ├── BuildStringNode.java
│ ├── CallExpressionNode.java
│ ├── CaseAnnotation.java
│ ├── CastNode.java
│ ├── CommentNode.java
│ ├── ConditionalExpressionNode.java
│ ├── ConditionalFlowBlockJump.java
│ ├── ConfigurationLoadNode.java
│ ├── ConfigurationStoreNode.java
│ ├── ContinueNode.java
│ ├── ExpressionNode.java
│ ├── FlowBlock.java
│ ├── FunctionExpressionNode.java
│ ├── FunctionNode.java
│ ├── IBreakableNode.java
│ ├── IConstantNode.java
│ ├── IContinueableNode.java
│ ├── IControllableFlowNode.java
│ ├── IFlowControlNode.java
│ ├── ILabelableNode.java
│ ├── IfElseNode.java
│ ├── IntExpressionNode.java
│ ├── LoadNamedDataNode.java
│ ├── LocalVariable.java
│ ├── LongExpressionNode.java
│ ├── LoopNode.java
│ ├── NewArrayNode.java
│ ├── NotExpressionNode.java
│ ├── PopableNode.java
│ ├── ReturnNode.java
│ ├── ScopeNode.java
│ ├── StoreNamedDataNode.java
│ ├── StringExpressionNode.java
│ ├── StructConstructExpr.java
│ ├── StructPartLoadNode.java
│ ├── SwitchFlowBlockJump.java
│ ├── SwitchNode.java
│ ├── UnconditionalFlowBlockJump.java
│ ├── VariableAssignationNode.java
│ └── VariableLoadNode.java
│ ├── gui
│ ├── EditorPanel.java
│ ├── EditorPrinter.java
│ ├── Main.java
│ ├── OptionsPanel.java
│ └── Window.java
│ ├── instructions
│ ├── AbstractInstruction.java
│ ├── BitConfigInstruction.java
│ ├── BooleanInstruction.java
│ ├── ConfigInstruction.java
│ ├── IntInstruction.java
│ ├── JumpInstruction.java
│ ├── Label.java
│ ├── LongInstruction.java
│ ├── Opcodes.java
│ ├── StringInstruction.java
│ └── SwitchInstruction.java
│ └── util
│ ├── ArrayQueue.java
│ ├── BitConfigInfo.java
│ ├── ByteBuffer.java
│ ├── ConfigInfo.java
│ ├── ConfigsDatabase.java
│ ├── DecompilerUtils.java
│ ├── FunctionDatabase.java
│ ├── FunctionInfo.java
│ ├── GenericsUtils.java
│ ├── IOUtils.java
│ ├── InstructionInfo.java
│ ├── InstructionsDatabase.java
│ ├── OpcodeUtils.java
│ ├── Options.java
│ ├── TextUtils.java
│ └── UnsafeSerializer.java
└── tests
├── .gitignore
├── DecompileAll.java
├── GenDatabases.java
└── TestProvider.java
/.gitignore:
--------------------------------------------------------------------------------
1 | /scripts/
2 | /sources/
3 | /.classpath
4 | /.project
5 | /db_missing.txt
6 | /instr_read_original.txt
7 | /instr_read.txt
8 | /instr_readx.txt
9 | /.settings/
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CS2-Decompiler
2 |
3 |
4 | ## Instructions
5 |
6 | Create scripts/ directory
7 |
8 | Extract scripts.zip there
9 |
10 | Run!
11 |
12 |
13 |
--------------------------------------------------------------------------------
/bin/.gitignore:
--------------------------------------------------------------------------------
1 | /mgi/
2 | /src.rar
3 | /tests/
4 |
--------------------------------------------------------------------------------
/configs_db.ini:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Someone52/CS2-Decompiler/dea1a70a973efc2fb475603deb28e831afc1387e/configs_db.ini
--------------------------------------------------------------------------------
/gui/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Someone52/CS2-Decompiler/dea1a70a973efc2fb475603deb28e831afc1387e/gui/bg.png
--------------------------------------------------------------------------------
/gui/options.ini:
--------------------------------------------------------------------------------
1 | # Auto generated options - DO NOT EDIT
2 |
3 |
4 |
5 | scripts_db_path scripts_db.ini
6 |
7 | scripts_path scripts/
8 |
9 | instructions_db_path instructions_db.ini
10 |
11 | opcodes_db_path opcodes_db.ini
12 |
13 |
--------------------------------------------------------------------------------
/lib/forms-1.3.0-src.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Someone52/CS2-Decompiler/dea1a70a973efc2fb475603deb28e831afc1387e/lib/forms-1.3.0-src.zip
--------------------------------------------------------------------------------
/lib/forms-1.3.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Someone52/CS2-Decompiler/dea1a70a973efc2fb475603deb28e831afc1387e/lib/forms-1.3.0.jar
--------------------------------------------------------------------------------
/run-GUI.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | start javaw -cp lib/mgiutils_v4.jar;bin; mgi.tools.jagdecs2.gui.Main
--------------------------------------------------------------------------------
/scripts.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Someone52/CS2-Decompiler/dea1a70a973efc2fb475603deb28e831afc1387e/scripts.zip
--------------------------------------------------------------------------------
/src/mgi/tools/jagdecs2/CS2.java:
--------------------------------------------------------------------------------
1 | /*
2 | This program is free software: you can redistribute it and/or modify
3 | it under the terms of the GNU General Public License as published by
4 | the Free Software Foundation, either version 3 of the License, or
5 | (at your option) any later version.
6 |
7 | This program is distributed in the hope that it will be useful,
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | GNU General Public License for more details.
11 |
12 | You should have received a copy of the GNU General Public License
13 | along with this program. If not, see .
14 | */
15 |
16 |
17 | package mgi.tools.jagdecs2;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | import mgi.tools.jagdecs2.instructions.AbstractInstruction;
23 | import mgi.tools.jagdecs2.instructions.Label;
24 | import mgi.tools.jagdecs2.instructions.SwitchInstruction;
25 |
26 | public class CS2 {
27 |
28 | private String name;
29 | private CS2Type[] argumentsTypes;
30 | private String[] argumentNames;
31 | private CS2Type returnType = CS2Type.UNKNOWN;
32 | private int intLocalsSize, stringLocalsSize, longLocalsSize;
33 | private int intArgumentsCount, stringArgumentsCount, longArgumentsCount;
34 | private AbstractInstruction[] instructions;
35 |
36 | public CS2(String name, CS2Type[] args, int intls, int stringls, int longls, int intac, int stringtac, int longac, int codeSize) {
37 | this.name = name;
38 | this.argumentsTypes = args;
39 | this.intLocalsSize = intls;
40 | this.stringLocalsSize = stringls;
41 | this.longLocalsSize = longls;
42 | this.intArgumentsCount = intac;
43 | this.stringArgumentsCount = stringtac;
44 | this.longArgumentsCount = longac;
45 | this.instructions = new AbstractInstruction[codeSize * 2];
46 | }
47 |
48 | public String getName() {
49 | return name;
50 | }
51 |
52 | public void setName(String name) {
53 | this.name = name;
54 | }
55 |
56 | public void setReturnType(CS2Type returnType) {
57 | this.returnType = returnType;
58 | }
59 |
60 | public CS2Type getReturnType() {
61 | return returnType;
62 | }
63 |
64 | public void setArgumentTypes(CS2Type[] arguments) {
65 | this.argumentsTypes = arguments;
66 | }
67 |
68 | public CS2Type[] getArgumentTypes() {
69 | return argumentsTypes;
70 | }
71 |
72 | public void setArgumentNames(String[] names) {
73 | this.argumentNames = names;
74 | }
75 |
76 | public String[] getArgumentNames() {
77 | return argumentNames;
78 | }
79 |
80 | public int getIntLocalsSize() {
81 | return intLocalsSize;
82 | }
83 |
84 | public int getStringLocalsSize() {
85 | return stringLocalsSize;
86 | }
87 |
88 | public int getLongLocalsSize() {
89 | return longLocalsSize;
90 | }
91 |
92 | public int getIntArgumentsCount() {
93 | return intArgumentsCount;
94 | }
95 |
96 | public int getStringArgumentsCount() {
97 | return stringArgumentsCount;
98 | }
99 |
100 | public int getLongArgumentsCount() {
101 | return longArgumentsCount;
102 | }
103 |
104 | public AbstractInstruction[] getInstructions() {
105 | return instructions;
106 | }
107 |
108 |
109 | @Deprecated
110 | public int addressOf(AbstractInstruction instr) {
111 | for (int i = 0; i < instructions.length; i++)
112 | if (instructions[i] == instr)
113 | return i;
114 | return -1;
115 | }
116 |
117 |
118 | public void prepareInstructions() {
119 | int nonLabelsAmt = instructions.length / 2;
120 | for (int i = 0; i < nonLabelsAmt; i++) {
121 | if (instructions[i * 2 + 1] instanceof SwitchInstruction) {
122 | SwitchInstruction instr = (SwitchInstruction) instructions[i * 2 + 1];
123 | if (((i + 1) * 2 + 1) >= instructions.length) {
124 | AbstractInstruction[] buf = new AbstractInstruction[(nonLabelsAmt + 1) * 2];
125 | System.arraycopy(instructions, 0, buf, 0, instructions.length);
126 | this.instructions = buf;
127 | }
128 |
129 | if (instructions[(i + 1) * 2] == null)
130 | instructions[(i + 1) * 2] = new Label();
131 | instr.attachDefault((Label)instructions[(i + 1) * 2]);
132 | }
133 | }
134 |
135 |
136 | List buffer = new ArrayList();
137 | for (int i = 0; i < this.instructions.length; i++)
138 | if (this.instructions[i] != null)
139 | buffer.add(this.instructions[i]);
140 |
141 | this.instructions = new AbstractInstruction[buffer.size()];
142 | int write = 0;
143 | for (AbstractInstruction instr : buffer)
144 | this.instructions[write++] = instr;
145 | for (int i = 0; i < instructions.length; i++)
146 | instructions[i].setAddress(i);
147 | for (int i = 0,labelsFound = 0; i < instructions.length; i++)
148 | if (instructions[i] instanceof Label)
149 | ((Label)instructions[i]).setLabelID(labelsFound++);
150 | for (int i = 0; i < instructions.length; i++)
151 | if (instructions[i] instanceof SwitchInstruction)
152 | ((SwitchInstruction)instructions[i]).sort();
153 | }
154 |
155 | public int countOf(Class extends AbstractInstruction> type) {
156 | int total = 0;
157 | for (int i = 0; i < instructions.length; i++)
158 | if (instructions[i].getClass() == type)
159 | total++;
160 | return total;
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/src/mgi/tools/jagdecs2/CS2Decoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | This program is free software: you can redistribute it and/or modify
3 | it under the terms of the GNU General Public License as published by
4 | the Free Software Foundation, either version 3 of the License, or
5 | (at your option) any later version.
6 |
7 | This program is distributed in the hope that it will be useful,
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | GNU General Public License for more details.
11 |
12 | You should have received a copy of the GNU General Public License
13 | along with this program. If not, see .
14 | */
15 |
16 |
17 | package mgi.tools.jagdecs2;
18 |
19 | import java.io.File;
20 | import java.io.FileInputStream;
21 | import java.io.FileNotFoundException;
22 | import java.io.IOException;
23 | import java.util.HashMap;
24 | import java.util.Map;
25 |
26 | import mgi.tools.jagdecs2.instructions.BitConfigInstruction;
27 | import mgi.tools.jagdecs2.instructions.BooleanInstruction;
28 | import mgi.tools.jagdecs2.instructions.ConfigInstruction;
29 | import mgi.tools.jagdecs2.instructions.IntInstruction;
30 | import mgi.tools.jagdecs2.instructions.JumpInstruction;
31 | import mgi.tools.jagdecs2.instructions.Label;
32 | import mgi.tools.jagdecs2.instructions.LongInstruction;
33 | import mgi.tools.jagdecs2.instructions.Opcodes;
34 | import mgi.tools.jagdecs2.instructions.StringInstruction;
35 | import mgi.tools.jagdecs2.instructions.SwitchInstruction;
36 | import mgi.tools.jagdecs2.util.BitConfigInfo;
37 | import mgi.tools.jagdecs2.util.ByteBuffer;
38 | import mgi.tools.jagdecs2.util.ConfigInfo;
39 | import mgi.tools.jagdecs2.util.ConfigsDatabase;
40 | import mgi.tools.jagdecs2.util.InstructionInfo;
41 | import mgi.tools.jagdecs2.util.InstructionsDatabase;
42 |
43 | public class CS2Decoder {
44 |
45 | @SuppressWarnings({"unchecked", "rawtypes"})
46 | public static final CS2 readScript(InstructionsDatabase idb, ConfigsDatabase cdb, File file) throws IOException {
47 | if (!file.exists() || !file.isFile() || !file.canRead())
48 | throw new FileNotFoundException("Script file " + file + " does not exist.");
49 | FileInputStream stream = new FileInputStream(file);
50 | byte[] data = new byte[(int) file.length()];
51 | int readed = stream.read(data);
52 | stream.close();
53 | if (readed != data.length)
54 | throw new IOException("Reading failed.");
55 | ByteBuffer buffer = new ByteBuffer(data);
56 |
57 | buffer.setPosition(data.length - 2);
58 | int switchBlocksSize = buffer.readUnsignedShort();
59 | int codeBlockEnd = data.length - switchBlocksSize - 16 - 2;
60 | buffer.setPosition(codeBlockEnd);
61 | int codeSize = buffer.readInt();
62 | int intLocalsCount = buffer.readUnsignedShort();
63 | int stringLocalsCount = buffer.readUnsignedShort();
64 | int longLocalsCount = buffer.readUnsignedShort();
65 |
66 | int intArgsCount = buffer.readUnsignedShort();
67 | int stringArgsCount = buffer.readUnsignedShort();
68 | int longArgsCount = buffer.readUnsignedShort();
69 |
70 | int switchesCount = buffer.readUByte();
71 | Map[] switches = new HashMap[switchesCount];
72 | for (int i = 0; i < switchesCount; i++) {
73 | int numCases = buffer.readUnsignedShort();
74 | switches[i] = new HashMap(numCases);
75 | while (numCases-- > 0) {
76 | switches[i].put(buffer.readInt(), buffer.readInt());
77 | }
78 | }
79 | buffer.setPosition(0);
80 | String scriptName = buffer.readNullString();
81 | int[] intPool = new int[codeSize];
82 | Object[] objectPool = new Object[codeSize];
83 | long[] longPool = new long[codeSize];
84 | InstructionInfo[] instructions = new InstructionInfo[codeSize];
85 |
86 | int writeOffset = 0;
87 | while (buffer.getPosition() < codeBlockEnd) {
88 | int opcode = buffer.readUnsignedShort();
89 | InstructionInfo info = idb.getByScrampled(opcode);
90 | if (info == null)
91 | throw new RuntimeException("Unknown opcode:" + opcode);
92 | opcode = info.getOpcode();
93 |
94 | if (opcode == Opcodes.LOAD_CONFIG || opcode == Opcodes.STORE_CONFIG) {
95 | int domainType = buffer.readUByte();
96 | int id = buffer.readUnsignedShort();
97 | ConfigInfo cfg = cdb.getConfigInfo(domainType, id);
98 | if (cfg == null)
99 | throw new RuntimeException("Unknown config:" + domainType + "," + id);
100 | intPool[writeOffset] = buffer.readUByte();
101 | objectPool[writeOffset] = cfg;
102 | }
103 | else if (opcode == Opcodes.PUSH_STR) {
104 | int baseType = buffer.readUByte();
105 | if (baseType == 0) {
106 | info = idb.getByUnscrampled(opcode = Opcodes.PUSH_INT);
107 | intPool[writeOffset] = buffer.readInt();
108 | }
109 | else if (baseType == 1) {
110 | info = idb.getByUnscrampled(opcode = Opcodes.PUSH_LONG);
111 | longPool[writeOffset] = buffer.readLong();
112 | }
113 | else if (baseType == 2)
114 | objectPool[writeOffset] = buffer.readString();
115 | else
116 | throw new RuntimeException("Unknown base type:" + baseType);
117 | }
118 | else if (opcode == Opcodes.LOAD_BITCONFIG || opcode == Opcodes.STORE_BITCONFIG) {
119 | int id = buffer.readUnsignedShort();
120 | BitConfigInfo cfg = cdb.getBitConfigInfo(id);
121 | if (cfg == null)
122 | throw new RuntimeException("Unknown bitconfig:" + id);
123 | intPool[writeOffset] = buffer.readUByte();
124 | objectPool[writeOffset] = cfg;
125 | }
126 | else {
127 | intPool[writeOffset] = info.hasIntConstant() ? buffer.readInt() : buffer.readUByte();
128 | }
129 |
130 | instructions[writeOffset++] = info;
131 | }
132 |
133 | CS2Type[] args = new CS2Type[intArgsCount + stringArgsCount + longArgsCount];
134 | int write = 0;
135 | for (int i = 0; i < intArgsCount; i++)
136 | args[write++] = CS2Type.INT;
137 | for (int i = 0; i < stringArgsCount; i++)
138 | args[write++] = CS2Type.STRING;
139 | for (int i = 0; i < longArgsCount; i++)
140 | args[write++] = CS2Type.LONG;
141 |
142 | CS2 script = new CS2(scriptName, args, intLocalsCount, stringLocalsCount, longLocalsCount, intArgsCount, stringArgsCount,longArgsCount,codeSize);
143 | for (int i = 0; i < codeSize; i++) {
144 | InstructionInfo info = instructions[i];
145 | int opcode = info.getOpcode();
146 | if (opcode == Opcodes.PUSH_STR)
147 | script.getInstructions()[(i * 2) + 1] = new StringInstruction(info, (String) objectPool[i]);
148 | else if (opcode == Opcodes.PUSH_LONG)
149 | script.getInstructions()[(i * 2) + 1] = new LongInstruction(info, longPool[i]);
150 | else if (opcode == Opcodes.SWITCH) { // switch
151 | Map block = switches[intPool[i]];
152 | int[] cases = new int[block.size()];
153 | Label[] targets = new Label[block.size()];
154 | int w = 0;
155 | for (Object key : block.keySet()) {
156 | cases[w] = (Integer) key;
157 | Object addr = block.get(key);
158 | int full = i + ((Integer) addr).intValue() + 1;
159 | if (script.getInstructions()[full * 2] == null)
160 | script.getInstructions()[full * 2] = new Label();
161 | targets[w++] = (Label) script.getInstructions()[full * 2];
162 | }
163 | script.getInstructions()[(i * 2) + 1] = new SwitchInstruction(info, cases, targets);
164 | }
165 | else if (opcode >= Opcodes.GOTO && opcode <= Opcodes.LONG_GE) {
166 | int fullAddr = i + intPool[i] + 1;
167 | if (script.getInstructions()[fullAddr * 2] == null)
168 | script.getInstructions()[fullAddr * 2] = new Label();
169 | script.getInstructions()[(i * 2) + 1] = new JumpInstruction(info, (Label) script.getInstructions()[fullAddr * 2]);
170 | }
171 | else if (opcode == Opcodes.LOAD_CONFIG || opcode == Opcodes.STORE_CONFIG)
172 | script.getInstructions()[(i * 2) + 1] = new ConfigInstruction(info, (ConfigInfo)objectPool[i], intPool[i] == 1);
173 | else if (opcode == Opcodes.LOAD_BITCONFIG || opcode == Opcodes.STORE_BITCONFIG)
174 | script.getInstructions()[(i * 2) + 1] = new BitConfigInstruction(info, (BitConfigInfo)objectPool[i], intPool[i] == 1);
175 | else if (opcode < 150)
176 | script.getInstructions()[(i * 2) + 1] = new IntInstruction(info, intPool[i]);
177 | else
178 | script.getInstructions()[(i * 2) + 1] = new BooleanInstruction(info, intPool[i] == 1);
179 | }
180 |
181 | script.prepareInstructions();
182 | return script;
183 | }
184 |
185 | }
186 |
--------------------------------------------------------------------------------
/src/mgi/tools/jagdecs2/CS2Decompiler.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Someone52/CS2-Decompiler/dea1a70a973efc2fb475603deb28e831afc1387e/src/mgi/tools/jagdecs2/CS2Decompiler.java
--------------------------------------------------------------------------------
/src/mgi/tools/jagdecs2/CS2Stack.java:
--------------------------------------------------------------------------------
1 | /*
2 | This program is free software: you can redistribute it and/or modify
3 | it under the terms of the GNU General Public License as published by
4 | the Free Software Foundation, either version 3 of the License, or
5 | (at your option) any later version.
6 |
7 | This program is distributed in the hope that it will be useful,
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | GNU General Public License for more details.
11 |
12 | You should have received a copy of the GNU General Public License
13 | along with this program. If not, see .
14 | */
15 |
16 |
17 | package mgi.tools.jagdecs2;
18 |
19 | import mgi.tools.jagdecs2.ast.ExpressionNode;
20 |
21 | public class CS2Stack {
22 |
23 | private ExpressionNode[][] stack;
24 | private int[][] pushOrders;
25 | private int[] size;
26 | private int timesPushed;
27 | public static final int STACK_TYPES_COUNT = 3;
28 | public static final int BUFFER_SIZE = 500;
29 |
30 | public CS2Stack() {
31 | stack = new ExpressionNode[STACK_TYPES_COUNT][BUFFER_SIZE];
32 | pushOrders = new int[STACK_TYPES_COUNT][BUFFER_SIZE];
33 | size = new int[STACK_TYPES_COUNT];
34 | }
35 |
36 | public ExpressionNode pop() {
37 | if (getSize() <= 0)
38 | throw new RuntimeException("Stack underflow");
39 | int order = -1;
40 | int stackType = -1;
41 | for (int a = 0; a < STACK_TYPES_COUNT; a++) {
42 | if (size[a] > 0 && pushOrders[a][size[a] - 1] > order)
43 | stackType = a;
44 | }
45 | return pop(stackType);
46 | }
47 |
48 | public ExpressionNode peek() {
49 | if (getSize() <= 0)
50 | throw new RuntimeException("Stack underflow");
51 | int order = -1;
52 | int stackType = -1;
53 | for (int a = 0; a < STACK_TYPES_COUNT; a++) {
54 | if (size[a] > 0 && pushOrders[a][size[a] - 1] > order)
55 | stackType = a;
56 | }
57 | return peek(stackType);
58 | }
59 |
60 | public ExpressionNode pop(int stackType) {
61 | if (size[stackType] <= 0)
62 | throw new RuntimeException("Stack underflow");
63 | return stack[stackType][--size[stackType]];
64 | }
65 |
66 | public ExpressionNode peek(int stackType) {
67 | if (size[stackType] <= 0)
68 | throw new RuntimeException("Stack underflow");
69 | return stack[stackType][size[stackType] - 1];
70 | }
71 |
72 | public void push(ExpressionNode expr,int stackType) {
73 | if ((size[stackType] + 1) >= BUFFER_SIZE)
74 | throw new RuntimeException("Stack overflow");
75 | pushOrders[stackType][size[stackType]] = timesPushed++;
76 | stack[stackType][size[stackType]++] = expr;
77 | }
78 |
79 | public CS2Stack copy() {
80 | CS2Stack stack = new CS2Stack();
81 | for (int a = 0; a < STACK_TYPES_COUNT; a++) {
82 | stack.size[a] = this.size[a];
83 | for (int i = 0; i < BUFFER_SIZE; i++) {
84 | if (this.stack[a][i] != null)
85 | stack.stack[a][i] = this.stack[a][i].copy();
86 | stack.pushOrders[a][i] = this.pushOrders[a][i];
87 | }
88 | }
89 | return stack;
90 | }
91 |
92 |
93 | public int getSize() {
94 | int total = 0;
95 | for (int i = 0; i < STACK_TYPES_COUNT; i++)
96 | total += size[i];
97 | return total;
98 | }
99 |
100 | public int getSize(int stackType) {
101 | return size[stackType];
102 | }
103 |
104 | public void clear() {
105 | for (int i = 0; i < STACK_TYPES_COUNT; i++)
106 | size[i] = 0;
107 | }
108 |
109 |
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/src/mgi/tools/jagdecs2/CodePrinter.java:
--------------------------------------------------------------------------------
1 | /*
2 | This program is free software: you can redistribute it and/or modify
3 | it under the terms of the GNU General Public License as published by
4 | the Free Software Foundation, either version 3 of the License, or
5 | (at your option) any later version.
6 |
7 | This program is distributed in the hope that it will be useful,
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | GNU General Public License for more details.
11 |
12 | You should have received a copy of the GNU General Public License
13 | along with this program. If not, see .
14 | */
15 |
16 |
17 | package mgi.tools.jagdecs2;
18 |
19 | import java.io.StringWriter;
20 |
21 | import mgi.tools.jagdecs2.ast.AbstractCodeNode;
22 |
23 | public class CodePrinter {
24 |
25 | protected StringWriter writer;
26 | private int tabs;
27 |
28 |
29 | public CodePrinter() {
30 | writer = new StringWriter();
31 | tabs = 0;
32 | }
33 |
34 | /**
35 | * Method , unused by default that notifies that specific node is
36 | * about to be printed.
37 | */
38 | public void beginPrinting(AbstractCodeNode node) { }
39 |
40 | /**
41 | * Method, unused by default that notifies that specific node was
42 | * printed.
43 | */
44 | public void endPrinting(AbstractCodeNode node) { }
45 |
46 |
47 | public void print(CharSequence str) {
48 | for (int i = 0; i < str.length(); i++)
49 | print(str.charAt(i));
50 | }
51 |
52 | public void print(char c) {
53 | writer.append(c);
54 | if (c == '\n')
55 | writer.append(getTabs());
56 | }
57 |
58 | protected String getTabs() {
59 | StringBuilder tabs = new StringBuilder();
60 | for (int i = 0; i < this.tabs; i++)
61 | tabs.append('\t');
62 | return tabs.toString();
63 | }
64 |
65 | public void tab() {
66 | tabs++;
67 | }
68 |
69 | public void untab() {
70 | if (tabs <= 0)
71 | throw new RuntimeException("Not tabbed!");
72 | tabs--;
73 | }
74 |
75 | @Override
76 | public String toString() {
77 | writer.flush();
78 | return writer.toString();
79 | }
80 |
81 | public static String print(AbstractCodeNode node) {
82 | CodePrinter printer = new CodePrinter();
83 | node.print(printer);
84 | return printer.toString();
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/src/mgi/tools/jagdecs2/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | This program is free software: you can redistribute it and/or modify
3 | it under the terms of the GNU General Public License as published by
4 | the Free Software Foundation, either version 3 of the License, or
5 | (at your option) any later version.
6 |
7 | This program is distributed in the hope that it will be useful,
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | GNU General Public License for more details.
11 |
12 | You should have received a copy of the GNU General Public License
13 | along with this program. If not, see .
14 | */
15 |
16 |
17 | package mgi.tools.jagdecs2;
18 |
19 | public class Constants {
20 |
21 | public Constants() {
22 | // TODO Auto-generated constructor stub
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/mgi/tools/jagdecs2/DecompilerException.java:
--------------------------------------------------------------------------------
1 | /*
2 | This program is free software: you can redistribute it and/or modify
3 | it under the terms of the GNU General Public License as published by
4 | the Free Software Foundation, either version 3 of the License, or
5 | (at your option) any later version.
6 |
7 | This program is distributed in the hope that it will be useful,
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | GNU General Public License for more details.
11 |
12 | You should have received a copy of the GNU General Public License
13 | along with this program. If not, see .
14 | */
15 |
16 |
17 | package mgi.tools.jagdecs2;
18 |
19 | public class DecompilerException extends RuntimeException {
20 | private static final long serialVersionUID = 7195887685185051968L;
21 |
22 | public DecompilerException(String string) {
23 | super(string);
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/mgi/tools/jagdecs2/ICS2Provider.java:
--------------------------------------------------------------------------------
1 | /*
2 | This program is free software: you can redistribute it and/or modify
3 | it under the terms of the GNU General Public License as published by
4 | the Free Software Foundation, either version 3 of the License, or
5 | (at your option) any later version.
6 |
7 | This program is distributed in the hope that it will be useful,
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | GNU General Public License for more details.
11 |
12 | You should have received a copy of the GNU General Public License
13 | along with this program. If not, see .
14 | */
15 |
16 |
17 | package mgi.tools.jagdecs2;
18 |
19 | import mgi.tools.jagdecs2.util.ConfigsDatabase;
20 | import mgi.tools.jagdecs2.util.FunctionDatabase;
21 | import mgi.tools.jagdecs2.util.InstructionsDatabase;
22 |
23 | public interface ICS2Provider {
24 |
25 | CS2 getCS2(InstructionsDatabase idb, ConfigsDatabase cdb, FunctionDatabase sdb, FunctionDatabase odb, int id);
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/mgi/tools/jagdecs2/LocalVariablesAnalyzerT2.java:
--------------------------------------------------------------------------------
1 | /*
2 | This program is free software: you can redistribute it and/or modify
3 | it under the terms of the GNU General Public License as published by
4 | the Free Software Foundation, either version 3 of the License, or
5 | (at your option) any later version.
6 |
7 | This program is distributed in the hope that it will be useful,
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | GNU General Public License for more details.
11 |
12 | You should have received a copy of the GNU General Public License
13 | along with this program. If not, see .
14 | */
15 |
16 |
17 | package mgi.tools.jagdecs2;
18 |
19 | import java.util.ArrayList;
20 | import java.util.HashMap;
21 | import java.util.List;
22 | import java.util.Map;
23 |
24 | import mgi.tools.jagdecs2.ast.AbstractCodeNode;
25 | import mgi.tools.jagdecs2.ast.ConditionalFlowBlockJump;
26 | import mgi.tools.jagdecs2.ast.FlowBlock;
27 | import mgi.tools.jagdecs2.ast.FunctionNode;
28 | import mgi.tools.jagdecs2.ast.LocalVariable;
29 | import mgi.tools.jagdecs2.ast.ReturnNode;
30 | import mgi.tools.jagdecs2.ast.SwitchFlowBlockJump;
31 | import mgi.tools.jagdecs2.ast.UnconditionalFlowBlockJump;
32 | import mgi.tools.jagdecs2.ast.VariableAssignationNode;
33 |
34 | public class LocalVariablesAnalyzerT2 {
35 |
36 | @SuppressWarnings("unused")
37 | private CS2Decompiler decompiler;
38 | private FunctionNode function;
39 | private FlowBlock[] blocks;
40 |
41 |
42 | private boolean[] processed;
43 | private FlowBlockState[] states;
44 |
45 | private Map> assigns;
46 |
47 | public LocalVariablesAnalyzerT2(CS2Decompiler decompiler, FunctionNode function, FlowBlock[] blocks) {
48 | this.decompiler = decompiler;
49 | this.function = function;
50 | this.blocks = blocks;
51 | }
52 |
53 |
54 |
55 | public void analyze() throws DecompilerException {
56 | init();
57 | process();
58 | end();
59 | }
60 |
61 |
62 | private void init() {
63 | processed = new boolean[blocks.length];
64 | states = new FlowBlockState[blocks.length];
65 | assigns = new HashMap>();
66 |
67 | FlowBlockState s = new FlowBlockState();
68 | for (LocalVariable arg : function.getArgumentLocals()) {
69 | Object o = s.set(null, arg);
70 | if (!assigns.containsKey(arg))
71 | assigns.put(arg, new ArrayList