public void LastBlockOnFlatScopeWithSingleItemShouldReturnFirstBasicBlockInList() { var scope = new ScopeBlock <int>(); scope.Blocks.Add(new BasicBlock <int>()); Assert.Same(scope.Blocks[0], scope.GetLastBlock()); }
public void AddHelpers() { var scope = new ScopeBlock(); var initBlock = new BasicBlock <IRInstrList>(1, new IRInstrList { new IRInstruction(IROpCode.RET) }); scope.Content.Add(initBlock); var retnBlock = new BasicBlock <IRInstrList>(0, new IRInstrList { new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(rt.Descriptor.Runtime.VMCall[VMCalls.EXIT])) }); scope.Content.Add(initBlock); CompileHelpers(methodINIT, scope); var info = rt.Descriptor.Data.LookupInfo(methodINIT); scope.ProcessBasicBlocks <ILInstrList>(block => { if (block.Id == 1) { AddHelper(null, methodINIT, (ILBlock)block); var blockKey = info.BlockKeys[block]; info.EntryKey = blockKey.EntryKey; info.ExitKey = blockKey.ExitKey; } rt.AddBlock(methodINIT, (ILBlock)block); }); }
private static ScopeBlock <TInstruction> BuildBlocksFromSortedNodes <TInstruction>( ControlFlowGraph <TInstruction> cfg, IEnumerable <ControlFlowNode <TInstruction> > sorting) { // We maintain a stack of scope information. Every time we enter a new region, we enter a new scope, // and similarly, we leave a scope when we leave a region. var rootScope = new ScopeBlock <TInstruction>(); var scopeStack = new IndexableStack <ScopeInfo <TInstruction> >(); scopeStack.Push(new ScopeInfo <TInstruction>(cfg, rootScope)); // Add the nodes in the order of the sorting. foreach (var node in sorting) { var currentScope = scopeStack.Peek(); if (node.ParentRegion != currentScope.Region) { UpdateScopeStack(scopeStack, node); currentScope = scopeStack.Peek(); } currentScope.AddBlock(node.Contents); } return(rootScope); }
public void FirstBlockOnNonEmptyFlatScopeShouldReturnFirstBasicBlockInList() { var scope = new ScopeBlock <int>(); scope.Blocks.Add(new BasicBlock <int>()); Assert.Same(scope.Blocks[0], scope.GetFirstBlock()); }
// 컴파일 public string GetSource() { try { GEntry entry = new GEntry(); List <GBase> list = new List <GBase>(); foreach (VariableBlock variableBlock in GetGlobalVariableBlockList()) { entry.Append(new GDefine(variableBlock.GVariable)); } foreach (var block in Master.Children) { if (block is ScopeBlock) { ScopeBlock scopeBlock = block as ScopeBlock; entry.Append(scopeBlock.GScope); } } return(entry.ToSource().TrimStart()); } catch (ToObjectException e) { return(e.Message); } }
internal AnnotationOutsideType(ScopeBlock parentBlock, string annotation) { ParentBlock = parentBlock; Annotations = new List <string> { annotation }; }
public void Translate(ScopeBlock rootScope) { var blockMap = rootScope.UpdateBasicBlocks <IRInstrList, ILInstrList>( block => { return(Translate(block.Content)); }, (id, content) => new ILBlock(id, content)); rootScope.ProcessBasicBlocks <ILInstrList>(block => { foreach (var instr in block.Content) { if (instr.Operand is ILBlockTarget) { var op = (ILBlockTarget)instr.Operand; op.Target = blockMap[(BasicBlock <IRInstrList>)op.Target]; } else if (instr.Operand is ILJumpTable) { var op = (ILJumpTable)instr.Operand; for (int i = 0; i < op.Targets.Length; i++) { op.Targets[i] = blockMap[(BasicBlock <IRInstrList>)op.Targets[i]]; } } } }); }
private EHMap MapEHs(ScopeBlock rootScope) { var map = new EHMap(); this.MapEHsInternal(rootScope, map); return(map); }
private static void EnterGenericRegion <TInstruction>(IndexableStack <ScopeInfo <TInstruction> > scopeStack, IControlFlowRegion <TInstruction> enteredRegion) { var scopeBlock = new ScopeBlock <TInstruction>(); scopeStack.Peek().AddBlock(scopeBlock); scopeStack.Push(new ScopeInfo <TInstruction>(enteredRegion, scopeBlock)); }
List <BaseBlock> UpdateParent(List <BaseBlock> lb, ScopeBlock parent) { foreach (var bb in lb) { bb.Parent = parent; } return(lb); }
IEnumerable <ScopeBlock> getAllScopeBlocks(ScopeBlock scopeBlock) { var list = new List <ScopeBlock>(); list.Add(scopeBlock); list.AddRange(scopeBlock.getAllScopeBlocks()); return(list); }
int ToCalculable(int i) { ScopeBlock expectedScope = new ScopeBlock(); expectedScope.start.line = ToCalculable(31); expectedScope.start.column = ToCalculable(1); expectedScope.end.line = ToCalculable(32); expectedScope.end.column = ToCalculable(1);
public IRTransformer(ScopeBlock rootScope, IRContext ctx, DarksVMRuntime runtime) { RootScope = rootScope; Context = ctx; Runtime = runtime; Annotations = new Dictionary <object, object>(); InitPipeline(); }
private void AddTryStart(IRTransformer tr) { var tryStartInstrs = new List <IRInstruction>(); for (int i = 0; i < this.thisScopes.Length; i++) { ScopeBlock scope = this.thisScopes[i]; if (scope.Type != ScopeType.Try) { continue; } if (scope.GetBasicBlocks().First() != tr.Block) { continue; } // Search for handler/filter IBasicBlock handler = null, filter = null; this.SearchForHandlers(tr.RootScope, scope.ExceptionHandler, ref handler, ref filter); Debug.Assert(handler != null && (scope.ExceptionHandler.HandlerType != ExceptionHandlerType.Filter || filter != null)); // Add instructions tryStartInstrs.Add(new IRInstruction(IROpCode.PUSH, new IRBlockTarget(handler))); IIROperand tryOperand = null; int ehType; if (scope.ExceptionHandler.HandlerType == ExceptionHandlerType.Catch) { tryOperand = IRConstant.FromI4((int)tr.VM.Data.GetId(scope.ExceptionHandler.CatchType)); ehType = tr.VM.Runtime.RTFlags.EH_CATCH; } else if (scope.ExceptionHandler.HandlerType == ExceptionHandlerType.Filter) { tryOperand = new IRBlockTarget(filter); ehType = tr.VM.Runtime.RTFlags.EH_FILTER; } else if (scope.ExceptionHandler.HandlerType == ExceptionHandlerType.Fault) { ehType = tr.VM.Runtime.RTFlags.EH_FAULT; } else if (scope.ExceptionHandler.HandlerType == ExceptionHandlerType.Finally) { ehType = tr.VM.Runtime.RTFlags.EH_FINALLY; } else { throw new InvalidProgramException(); } tryStartInstrs.Add(new IRInstruction(IROpCode.TRY, IRConstant.FromI4(ehType), tryOperand) { Annotation = new EHInfo(scope.ExceptionHandler) }); } tr.Instructions.InsertRange(0, tryStartInstrs); }
public ILPostTransformer(MethodDef method, ScopeBlock rootScope, DarksVMRuntime runtime) { this.RootScope = rootScope; this.Method = method; this.Runtime = runtime; this.Annotations = new Dictionary <object, object>(); this.pipeline = this.InitPipeline(); }
public ILPostTransformer(MethodDef method, ScopeBlock rootScope, VMRuntime runtime) { RootScope = rootScope; Method = method; Runtime = runtime; Annotations = new Dictionary <object, object>(); pipeline = InitPipeline(); }
public List <BaseBlock> GetBlocks(ScopeBlock parent) { if (blocksLeft.Count == 0) { return(new List <BaseBlock>()); } var lb = GetBlocks(0, blocksLeft[blocksLeft.Count - 1].endInstr, out int startIndex, out int endIndex); return(UpdateParent(lb, parent)); }
/// <summary> /// Converts a method block into instructions /// </summary> /// <param name="methodBlock"></param> /// <param name="instructions"></param> /// <param name="exceptionHandlers"></param> /// <param name="locals"></param> public static void Generate(ScopeBlock methodBlock, out IList <Instruction> instructions, out IList <ExceptionHandler> exceptionHandlers, out IList <Local> locals) { var generator = new CodeGenerator(); generator.Layout(methodBlock); instructions = generator.GenerateInstructions(); exceptionHandlers = generator.GenerateExceptionHandlers(); locals = GenerateLocals((List <Instruction>)instructions); generator.Cleanup(); }
public void deobfuscate(ScopeBlock scopeBlock) { while (true) { var switchObfuscationInfo = new SwitchObfuscationInfo((instr) => getLocalVar(instr)); if (!findSwitchObfuscation(scopeBlock, switchObfuscationInfo)) break; switchObfuscationInfo.fixSwitchBranches(scopeBlock); scopeBlock.removeDeadBlocks(new List<Block>(switchObfuscationInfo.SwitchTargetBlocks)); scopeBlock.mergeBlocks(); } }
private ILASTBuilder(MethodDef method, CilBody body, ScopeBlock scope) { this.method = method; this.body = body; this.scope = scope; this.basicBlocks = scope.GetBasicBlocks().Cast <CILBlock>().ToList(); this.blockHeaders = this.basicBlocks.ToDictionary(block => block.Content[0], block => block); this.blockStates = new Dictionary <CILBlock, BlockState>(); this.instrReferences = new List <ILASTExpression>(); Debug.Assert(this.basicBlocks.Count > 0); }
/// <summary> /// Restores <see cref="MethodDef"/> from method block /// </summary> /// <param name="methodDef"></param> /// <param name="methodBlock"></param> public static void FromMethodBlock(this MethodDef methodDef, ScopeBlock methodBlock) { var body = methodDef.Body; CodeGenerator.Generate(methodBlock, out var instructions, out var exceptionHandlers, out var locals); body.Instructions.Clear(); body.Instructions.AddRange(instructions); body.ExceptionHandlers.Clear(); body.ExceptionHandlers.AddRange(exceptionHandlers); body.Variables.Clear(); body.Variables.AddRange(locals); }
public void Transform(IRTransformer tr) { this.thisScopes = tr.RootScope.SearchBlock(tr.Block); this.AddTryStart(tr); if (this.thisScopes[this.thisScopes.Length - 1].Type == ScopeType.Handler) { ScopeBlock tryScope = this.SearchForTry(tr.RootScope, this.thisScopes[this.thisScopes.Length - 1].ExceptionHandler); ScopeBlock[] scopes = tr.RootScope.SearchBlock(tryScope.GetBasicBlocks().First()); this.thisScopes = scopes.TakeWhile(s => s != tryScope).ToArray(); } tr.Instructions.VisitInstrs(this.VisitInstr, tr); }
/// <summary> /// Inlines all basic blocks as much as possible. /// </summary> /// <param name="methodBlock"></param> /// <returns></returns> public static int Inline(ScopeBlock methodBlock) { if (methodBlock is null) { throw new ArgumentNullException(nameof(methodBlock)); } if (methodBlock.Type != BlockType.Method) { throw new ArgumentException($"{nameof(methodBlock)} is not a method block"); } return(Shared.BlockInliner.Inline(methodBlock, (x, y) => ((BasicBlock)x).Redirect((BasicBlock)y), (x, y) => ((BasicBlock)x).Concat((BasicBlock)y), t => ((BasicBlock)t).Erase())); }
public void TestFindsSingleLineScope() { ScopeBlock expectedScope = new ScopeBlock(); expectedScope.end.Line = ToCalculable(3); expectedScope.start.Line = ToCalculable(3); expectedScope.start.Column = ToCalculable(1); expectedScope.end.Column = ToCalculable(3); expectedScope.scope = ScopeBlock.Scope.Other; ScopeBlock scope = scopeFinder.FindScope(finder.Find("B")); Assert.AreEqual(expectedScope, scope); }
/// <summary> /// Removes all unused blocks /// </summary> /// <param name="methodBlock"></param> /// <returns></returns> public static int RemoveUnusedBlocks(ScopeBlock methodBlock) { if (methodBlock is null) { throw new ArgumentNullException(nameof(methodBlock)); } if (methodBlock.Type != BlockType.Method) { throw new ArgumentException($"{nameof(methodBlock)} is not a method block"); } return(Shared.BlockCleaner.RemoveUnusedBlocks(methodBlock, t => ((BasicBlock)t).Erase())); }
private static void EnterNextRegion <TInstruction>( IndexableStack <ScopeInfo <TInstruction> > scopeStack, IControlFlowRegion <TInstruction>[] activeRegions) { var enteredRegion = activeRegions[scopeStack.Count]; // Add new scope block to the current scope. var currentScope = scopeStack.Peek(); if (enteredRegion is ExceptionHandlerRegion <TInstruction> ehRegion) { // We entered an exception handler region. var ehBlock = new ExceptionHandlerBlock <TInstruction>(); currentScope.AddBlock(ehBlock); scopeStack.Push(new ScopeInfo <TInstruction>(ehRegion, ehBlock)); } else if (enteredRegion.ParentRegion is ExceptionHandlerRegion <TInstruction> parentEhRegion) { // We entered one of the exception handler sub regions. Figure out which one it is. ScopeBlock <TInstruction> enteredBlock; if (!(currentScope.Block is ExceptionHandlerBlock <TInstruction> ehBlock)) { throw new InvalidOperationException("The parent scope is not an exception handler scope."); } if (parentEhRegion.ProtectedRegion == enteredRegion) { // We entered the protected region. enteredBlock = ehBlock.ProtectedBlock; } else { // We entered a handler region. enteredBlock = new ScopeBlock <TInstruction>(); ehBlock.HandlerBlocks.Add(enteredBlock); } // Push the entered scope. scopeStack.Push(new ScopeInfo <TInstruction>(parentEhRegion.ProtectedRegion, enteredBlock)); } else { // Fall back method: just enter a new scope block. var scopeBlock = new ScopeBlock <TInstruction>(); currentScope.AddBlock(scopeBlock); scopeStack.Push(new ScopeInfo <TInstruction>(enteredRegion, scopeBlock)); } }
public void TestIgnoresMultipleTrailingLowerScope() { ScopeBlock expectedScope = new ScopeBlock(); expectedScope.start.Line = ToCalculable(13); expectedScope.start.Column = ToCalculable(1); expectedScope.end.Line = ToCalculable(13); expectedScope.end.Column = ToCalculable(9); expectedScope.scope = ScopeBlock.Scope.Other; ScopeBlock scope = scopeFinder.FindScope(finder.Find("F")); Console.WriteLine(scope); Assert.AreEqual(expectedScope, scope); }
public void TestFindsMultiLineScope() { ScopeBlock expectedScope = new ScopeBlock(); expectedScope.start.Line = ToCalculable(5); expectedScope.start.Column = ToCalculable(1); expectedScope.end.Line = ToCalculable(7); expectedScope.end.Column = ToCalculable(1); expectedScope.scope = ScopeBlock.Scope.Other; ScopeBlock scope = scopeFinder.FindScope(finder.Find("C")); Console.WriteLine(scope); Assert.AreEqual(expectedScope, scope); }
public void AddMethod(MethodDef method, ScopeBlock rootScope) { ILBlock entry = null; foreach (ILBlock block in rootScope.GetBasicBlocks()) { if (block.Id == 0) { entry = block; } basicBlocks.Add(Tuple.Create(method, block)); } Debug.Assert(entry != null); methodMap[method] = Tuple.Create(rootScope, entry); }
public void TestIgnoresLineComments() { ScopeBlock expectedScope = new ScopeBlock(); expectedScope.start.line = ToCalculable(31); expectedScope.start.column = ToCalculable(1); expectedScope.end.line = ToCalculable(32); expectedScope.end.column = ToCalculable(1); expectedScope.scope = ScopeBlock.Scope.Other; ScopeBlock scope = scopeFinder.FindScope(finder.Find("H")); Console.WriteLine(scope); Assert.AreEqual(expectedScope, scope); }
private ScopeBlock SearchForTry(ScopeBlock scope, ExceptionHandler eh) { if (scope.ExceptionHandler == eh && scope.Type == ScopeType.Try) { return(scope); } foreach (var child in scope.Children) { var s = SearchForTry(child, eh); if (s != null) { return(s); } } return(null); }
bool findSwitchObfuscation(ScopeBlock scopeBlock, SwitchObfuscationInfo switchObfuscationInfo) { foreach (var bb in scopeBlock.getBaseBlocks()) { var block = bb as Block; if (block == null || foundBlocks.ContainsKey(block)) continue; if (block.Instructions.Count != 2 || !block.Instructions[0].isLdloc() || block.Instructions[1].OpCode != OpCodes.Switch) continue; switchObfuscationInfo.switchBlock = block; switchObfuscationInfo.stateVar = getLocalVar(block.Instructions[0]); var typeName = switchObfuscationInfo.stateVar.VariableType.FullName; if (typeName != "System.Int32" && typeName != "System.UInt32") continue; foundBlocks[block] = true; return true; } return false; }
List<BaseBlock> UpdateParent(List<BaseBlock> lb, ScopeBlock parent) { foreach (var bb in lb) bb.Parent = parent; return lb; }
public List<BaseBlock> GetBlocks(ScopeBlock parent) { if (blocksLeft.Count == 0) return new List<BaseBlock>(); int startIndex, endIndex; var lb = GetBlocks(0, blocksLeft[blocksLeft.Count - 1].endInstr, out startIndex, out endIndex); return UpdateParent(lb, parent); }
// Replace the BaseBlocks with a new BaseBlock, returning the old ones. public List<BaseBlock> Replace(int startInstr, int endInstr, ScopeBlock bb) { if (endInstr < startInstr) return new List<BaseBlock>(); int startIndex, endIndex; var rv = GetBlocks(startInstr, endInstr, out startIndex, out endIndex); UpdateParent(rv, bb); var bbi = new BaseBlockInfo(blocksLeft[startIndex].startInstr, blocksLeft[endIndex].endInstr, bb); blocksLeft.RemoveRange(startIndex, endIndex - startIndex + 1); blocksLeft.Insert(startIndex, bbi); return rv; }
public BrTrueDeobfuscator(ScopeBlock scopeBlock, IEnumerable<Block> blocks) : base(scopeBlock, blocks) { }
public CondBranchDeobfuscator(ScopeBlock scopeBlock, IEnumerable<Block> blocks) { this.scopeBlock = scopeBlock; this.blocks = blocks; }
void AddTargets(List<BaseBlock> dest, ScopeBlock scopeBlock) { foreach (var block in scopeBlock.GetAllBlocks()) AddTargets(dest, block.GetTargets()); }
public Sorter(ScopeBlock scopeBlock, IList<BaseBlock> validBlocks, bool skipFirstBlock) { this.scopeBlock = scopeBlock; this.validBlocks = validBlocks; this.skipFirstBlock = skipFirstBlock; }
public BlockState(ScopeBlock scopeBlock) { this.scopeBlock = scopeBlock; }
public BlocksSorter(ScopeBlock scopeBlock) { this.scopeBlock = scopeBlock; }
public ForwardScanOrder(ScopeBlock scopeBlock, IList<BaseBlock> sorted) { this.scopeBlock = scopeBlock; this.sorted = sorted; }
void addScopeBlock(ScopeBlock scopeBlock) { scopeBlocksToCheck.Push(scopeBlock); }
public ScopeBlockInfo(ScopeBlock scopeBlock) { this.scopeBlock = scopeBlock; }
void processScopeBlock(ScopeBlock scopeBlock) { if (scopeBlock == null || checkedScopeBlocks.ContainsKey(scopeBlock)) return; checkedScopeBlocks[scopeBlock] = true; addBaseBlock(scopeBlock); if (scopeBlock is TryBlock) { var tryBlock = (TryBlock)scopeBlock; foreach (var handler in tryBlock.TryHandlerBlocks) addScopeBlock(handler); } else if (scopeBlock is TryHandlerBlock) { var tryHandlerBlock = (TryHandlerBlock)scopeBlock; addScopeBlock(tryHandlerBlock.FilterHandlerBlock); addScopeBlock(tryHandlerBlock.HandlerBlock); } }
IEnumerable<ScopeBlock> GetAllScopeBlocks(ScopeBlock scopeBlock) { var list = new List<ScopeBlock>(); list.Add(scopeBlock); list.AddRange(scopeBlock.GetAllScopeBlocks()); return list; }
public void fixSwitchBranches(ScopeBlock scopeBlock) { findAllSwitchTargetBlocks(); foreach (var switchTargetBlock in new List<Block>(switchTargetBlocks.Keys)) { foreach (var block in new List<Block>(switchTargetBlock.Sources)) { int numInstrs; Block switchTarget; if (getSwitchIndex(block, out numInstrs, out switchTarget)) block.replaceLastInstrsWithBranch(numInstrs, switchTarget); } } }