TamperBlocks FindTamperBlocks(Blocks blocks, IList<Block> allBlocks) { var tamperBlocks = new TamperBlocks(); if (!FindFirstBlocks(tamperBlocks, allBlocks, blocks.Locals)) return null; var second = tamperBlocks.second; var badBlock = second.Block.LastInstr.IsBrfalse() ? second.Block.Targets[0] : second.Block.FallThrough; tamperBlocks.bad = FindBadBlock(badBlock); if (tamperBlocks.bad == null) return null; return tamperBlocks; }
void RemoveTamperV1(TamperBlocks tamperBlocks) { var first = tamperBlocks.first; var second = tamperBlocks.second; var bad = tamperBlocks.bad; var goodBlock = second.Block.LastInstr.IsBrtrue() ? second.Block.Targets[0] : second.Block.FallThrough; if (first.Block.Targets.Count != 1 || first.Block.Targets[0] != bad.Block) { throw new ApplicationException("Invalid state"); } first.Block.Remove(first.Start, first.End - first.Start + 1); first.Block.ReplaceLastInstrsWithBranch(0, goodBlock); RemoveDeadBlock(second.Block); RemoveDeadBlock(bad.Block); }
bool FindFirstBlocks(TamperBlocks tamperBlocks, IList <Block> allBlocks, IList <Local> locals) { foreach (var b in allBlocks) { try { if (FindFirstBlocks(b, tamperBlocks, allBlocks, locals)) { return(true); } } catch (ArgumentOutOfRangeException) { continue; } } return(false); }
TamperBlocks FindTamperBlocks(Blocks blocks, IList <Block> allBlocks) { var tamperBlocks = new TamperBlocks(); if (!FindFirstBlocks(tamperBlocks, allBlocks, blocks.Locals)) { return(null); } var second = tamperBlocks.second; var badBlock = second.Block.LastInstr.IsBrfalse() ? second.Block.Targets[0] : second.Block.FallThrough; tamperBlocks.bad = FindBadBlock(badBlock); if (tamperBlocks.bad == null) { return(null); } return(tamperBlocks); }
void removeTamperV2(TamperBlocks tamperBlocks) { var first = tamperBlocks.first; var second = tamperBlocks.second.Block; var bad = tamperBlocks.bad.Block; var firstFallthrough = first.Block.FallThrough; var goodBlock = second.LastInstr.isBrtrue() ? second.Targets[0] : second.FallThrough; if (first.Block.Targets.Count != 1 || first.Block.Targets[0] != bad) throw new ApplicationException("Invalid state"); first.Block.remove(first.Start, first.End - first.Start + 1); first.Block.replaceLastInstrsWithBranch(0, goodBlock); removeDeadBlock(firstFallthrough); removeDeadBlock(second); removeDeadBlock(bad); }
bool findFirstBlocks(Block block, TamperBlocks tamperBlocks, IList<Block> allBlocks, IList<Local> locals) { if (!block.LastInstr.isBrfalse()) return false; /* * ldc.i4.0 * stloc X * call GetExecutingAssembly() * stloc Y * ldloc Y * callvirt Location * ldc.i4.1 * ldloca X * call StrongNameSignatureVerificationEx * pop / brfalse bad_code * ldloc X * brfalse bad_code * ldloc Y * callvirt FullName() * ldstr "......" * callvirt EndsWith(string) * brfalse bad_code / brtrue good_code */ var instrs = block.Instructions; int end = instrs.Count - 1; Instr instr; IMethod method; tamperBlocks.type = Type.V1; int index = 0; int start = findCallMethod(block, index, true, (calledMethod) => calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()"); if (start < 0) return false; index = start + 1; instr = instrs[--start]; if (!instr.isStloc()) return false; var loc0 = Instr.getLocalVar(locals, instr); instr = instrs[--start]; if (!instr.isLdcI4()) return false; index = findCallMethod(block, index, false, (calledMethod) => calledMethod.ToString() == "System.String System.Reflection.Assembly::get_Location()"); if (index < 0) return false; index++; index = findCallMethod(block, index, false, (calledMethod) => { tamperBlocks.pinvokeMethod = DotNetUtils.getMethod(module, calledMethod); return DotNetUtils.isPinvokeMethod(tamperBlocks.pinvokeMethod, "mscorwks", "StrongNameSignatureVerificationEx"); }); if (index < 0) return false; index++; if (!instrs[index].isBrfalse()) { if (instrs[index].OpCode.Code != Code.Pop) return false; instr = instrs[index + 1]; if (!instr.isLdloc() || Instr.getLocalVar(locals, instr) != loc0) return false; if (!instrs[index + 2].isBrfalse()) return false; tamperBlocks.type = Type.V1; tamperBlocks.first = new BlockInfo { Block = block, Start = start, End = end, }; } else { tamperBlocks.type = Type.V2; tamperBlocks.first = new BlockInfo { Block = block, Start = start, End = end, }; block = block.FallThrough; if (block == null) return false; instrs = block.Instructions; index = 0; instr = instrs[index]; if (!instr.isLdloc() || Instr.getLocalVar(locals, instr) != loc0) return false; if (!instrs[index + 1].isBrfalse()) return false; } block = block.FallThrough; instrs = block.Instructions; start = end = 0; instr = instrs[end++]; if (!instr.isLdloc()) return false; instr = instrs[end++]; if (instr.OpCode != OpCodes.Callvirt) return false; method = instr.Operand as IMethod; if (method == null || method.ToString() != "System.String System.Reflection.Assembly::get_FullName()") return false; instr = instrs[end++]; if (instr.OpCode != OpCodes.Ldstr) return false; instr = instrs[end++]; if (instr.OpCode != OpCodes.Callvirt) return false; method = instr.Operand as IMethod; if (method == null || method.ToString() != "System.Boolean System.String::EndsWith(System.String)") return false; instr = instrs[end++]; if (!instr.isBrfalse() && !instr.isBrtrue()) return false; end--; tamperBlocks.second = new BlockInfo { Block = block, Start = start, End = end, }; return true; }
bool findFirstBlocks(TamperBlocks tamperBlocks, IList<Block> allBlocks, IList<Local> locals) { foreach (var b in allBlocks) { try { if (findFirstBlocks(b, tamperBlocks, allBlocks, locals)) return true; } catch (ArgumentOutOfRangeException) { continue; } } return false; }
bool FindFirstBlocks(Block block, TamperBlocks tamperBlocks, IList <Block> allBlocks, IList <Local> locals) { if (!block.LastInstr.IsBrfalse()) { return(false); } /* * ldc.i4.0 * stloc X * call GetExecutingAssembly() * stloc Y * ldloc Y * callvirt Location * ldc.i4.1 * ldloca X * call StrongNameSignatureVerificationEx * pop / brfalse bad_code * ldloc X * brfalse bad_code * ldloc Y * callvirt FullName() * ldstr "......" * callvirt EndsWith(string) * brfalse bad_code / brtrue good_code */ var instrs = block.Instructions; int end = instrs.Count - 1; Instr instr; IMethod method; tamperBlocks.type = Type.V1; int index = 0; int start = FindCallMethod(block, index, true, (calledMethod) => calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()"); if (start < 0) { return(false); } index = start + 1; instr = instrs[--start]; if (!instr.IsStloc()) { return(false); } var loc0 = Instr.GetLocalVar(locals, instr); instr = instrs[--start]; if (!instr.IsLdcI4()) { return(false); } index = FindCallMethod(block, index, false, (calledMethod) => calledMethod.ToString() == "System.String System.Reflection.Assembly::get_Location()"); if (index < 0) { return(false); } index++; index = FindCallMethod(block, index, false, (calledMethod) => { tamperBlocks.pinvokeMethod = DotNetUtils.GetMethod(module, calledMethod); return(DotNetUtils.IsPinvokeMethod(tamperBlocks.pinvokeMethod, "mscorwks", "StrongNameSignatureVerificationEx")); }); if (index < 0) { return(false); } index++; if (!instrs[index].IsBrfalse()) { if (instrs[index].OpCode.Code != Code.Pop) { return(false); } instr = instrs[index + 1]; if (!instr.IsLdloc() || Instr.GetLocalVar(locals, instr) != loc0) { return(false); } if (!instrs[index + 2].IsBrfalse()) { return(false); } tamperBlocks.type = Type.V1; tamperBlocks.first = new BlockInfo { Block = block, Start = start, End = end, }; } else { tamperBlocks.type = Type.V2; tamperBlocks.first = new BlockInfo { Block = block, Start = start, End = end, }; block = block.FallThrough; if (block == null) { return(false); } instrs = block.Instructions; index = 0; instr = instrs[index]; if (!instr.IsLdloc() || Instr.GetLocalVar(locals, instr) != loc0) { return(false); } if (!instrs[index + 1].IsBrfalse()) { return(false); } } block = block.FallThrough; instrs = block.Instructions; start = end = 0; instr = instrs[end++]; if (!instr.IsLdloc()) { return(false); } instr = instrs[end++]; if (instr.OpCode != OpCodes.Callvirt) { return(false); } method = instr.Operand as IMethod; if (method == null || method.ToString() != "System.String System.Reflection.Assembly::get_FullName()") { return(false); } instr = instrs[end++]; if (instr.OpCode != OpCodes.Ldstr) { return(false); } instr = instrs[end++]; if (instr.OpCode != OpCodes.Callvirt) { return(false); } method = instr.Operand as IMethod; if (method == null || method.ToString() != "System.Boolean System.String::EndsWith(System.String)") { return(false); } instr = instrs[end++]; if (!instr.IsBrfalse() && !instr.IsBrtrue()) { return(false); } end--; tamperBlocks.second = new BlockInfo { Block = block, Start = start, End = end, }; return(true); }