private string AdjustGoto(IlIns il, bool isDecompile) { long lv = IlIns.LabelToValue(il.Value); string label = null; if (switchBlocks.ContainsKey(lv)) { FlowGraphNode gnode = switchBlocks[lv]; DAGNode dnode = switchExpressions[gnode.EndLabelValue]; while (dnode is ReferenceNode) { dnode = dnode.NextNodes[0]; } if (dnode is LeafNode) { DAGNode r = GetVarReference(dnode.Data); if (r != null) { int v = (int)ConstUtility.ParseLong(r.Data); IlIns switchIl = ilLines[gnode.EndLabelValue]; SwitchOperand op = switchIl.Operand as SwitchOperand; if (v >= 0 && v < op.Labels.Count) { label = op.Labels[v]; lv = IlIns.LabelToValue(op.Labels[v]); } } } } string label2 = AdjustGoto(il.LabelValue, lv, isDecompile); if (label2 != null) { return(label2); } else if (label != null) { return(label); } return(null); }
private void BuildFlowGraph() { flowGraph = new FlowGraph(); FlowGraphNode curNode = null; FlowGraphNode prevNode = null; bool nextIsBlock = true; for (int i = 0; i < ilLines.Count; i++) { IlIns il = ilLines.Values[i]; if (nextIsBlock) { nextIsBlock = false; FlowGraphNode node = flowGraph.NewNode(il.LabelValue); curNode = node; if (prevNode != null) { prevNode.AddNext(node); } } else { if (flowGraph.IsNode(il.LabelValue)) { FlowGraphNode node = flowGraph[il.LabelValue]; curNode.EndLabelValue = GetPrevIlLabelValue(il.LabelValue); curNode.AddNext(node); curNode = node; } } IlOpcode op0 = IlOpcodes.GetEH(il.Opcode); if (op0 != IlOpcode.Prefixref) { switch (op0) { case IlOpcode.TRY: { FlowGraphNode node = flowGraph.NewNode(il.LabelValue); if (curNode != null) { curNode.AddNext(node); } curNode = node; } break; case IlOpcode.CATCH: { FlowGraphNode node = flowGraph.NewNode(il.LabelValue); curNode = node; } break; case IlOpcode.FINALLY: { FlowGraphNode node = flowGraph.NewNode(il.LabelValue); curNode = node; } break; case IlOpcode.FILTER: { FlowGraphNode node = flowGraph.NewNode(il.LabelValue); curNode = node; } break; case IlOpcode.FAULT: { FlowGraphNode node = flowGraph.NewNode(il.LabelValue); curNode = node; } break; case IlOpcode.ENDTRY: case IlOpcode.ENDCATCH: case IlOpcode.ENDFINALLY: case IlOpcode.ENDFILTER: case IlOpcode.ENDFAULT: { curNode.EndLabelValue = il.LabelValue; prevNode = null; nextIsBlock = true; } break; } } else { OpCode op = IlOpcodes.Get(il.Opcode); switch ((IlOpcode)op.Value) { case IlOpcode.Br: case IlOpcode.Br_S: { long val = IlIns.LabelToValue(il.Value); FlowGraphNode node = null; if (val > il.LabelValue) { node = flowGraph.NewNode(val); curNode.AddNext(node); } else { long prevVal = GetPrevIlLabelValue(val); FlowGraphNode d = flowGraph.Find(val); node = flowGraph.Split(val, prevVal); if (curNode != d) { curNode.AddNext(node); } else { node.AddNext(node); curNode = node; } } curNode.EndLabelValue = il.LabelValue; prevNode = null; nextIsBlock = true; } break; case IlOpcode.Brtrue: case IlOpcode.Brfalse: case IlOpcode.Brtrue_S: case IlOpcode.Brfalse_S: case IlOpcode.Beq_S: case IlOpcode.Bge_S: case IlOpcode.Bgt_S: case IlOpcode.Ble_S: case IlOpcode.Blt_S: case IlOpcode.Bne_Un_S: case IlOpcode.Bge_Un_S: case IlOpcode.Bgt_Un_S: case IlOpcode.Ble_Un_S: case IlOpcode.Blt_Un_S: case IlOpcode.Beq: case IlOpcode.Bge: case IlOpcode.Bgt: case IlOpcode.Ble: case IlOpcode.Blt: case IlOpcode.Bne_Un: case IlOpcode.Bge_Un: case IlOpcode.Bgt_Un: case IlOpcode.Ble_Un: case IlOpcode.Blt_Un: { long val = IlIns.LabelToValue(il.Value); FlowGraphNode node = null; if (val > il.LabelValue) { node = flowGraph.NewNode(val); curNode.AddNext(node); } else { long prevVal = GetPrevIlLabelValue(val); FlowGraphNode d = flowGraph.Find(val); node = flowGraph.Split(val, prevVal); if (curNode != d) { curNode.AddNext(node); } else { node.AddNext(node); curNode = node; } } curNode.EndLabelValue = il.LabelValue; prevNode = curNode; nextIsBlock = true; } break; case IlOpcode.Switch: { SwitchOperand opVal = il.Operand as SwitchOperand; foreach (string label in opVal.Labels) { long val = IlIns.LabelToValue(label); FlowGraphNode node = null; if (val > il.LabelValue) { node = flowGraph.NewNode(val); curNode.AddNext(node); } else { long prevVal = GetPrevIlLabelValue(val); FlowGraphNode d = flowGraph.Find(val); node = flowGraph.Split(val, prevVal); if (curNode != d) { curNode.AddNext(node); } else { node.AddNext(node); curNode = node; } } } curNode.EndLabelValue = il.LabelValue; prevNode = curNode; nextIsBlock = true; } break; case IlOpcode.Ret: case IlOpcode.Break: case IlOpcode.Throw: case IlOpcode.Rethrow: case IlOpcode.Leave: case IlOpcode.Leave_S: case IlOpcode.Endfilter: case IlOpcode.Endfinally: { curNode.EndLabelValue = il.LabelValue; prevNode = null; nextIsBlock = true; } break; } } } }
public static void Set(IlIns il) { il.Operand = temp; temp = new SwitchOperand(); }