private bool ParseSection(ParseTreeNode node, AssemblyCode rootCode, out Section res) { res = new Section(); res.AssemblePosition = new Assemble.AssemblePosition(this.ParsingFilePath, node); res.ParentBlock = null; res.RootCode = rootCode; { //section + name + { + attributes + contents + } //Name res.Name = node.ChildNodes[1].Token.Text; //Attributes if (!ParseSectionAttributes(node.ChildNodes[3], out res.Attributes)) { return(false); } //Contents Block blockedRes = res; if (!ParseBlockContents(node.ChildNodes[4], ref blockedRes)) { return(false); } } return(true); }
private InlineHook(QHackContext ctx, AssemblyCode code, HookParameters parameters) { Context = ctx; Code = code.Copy(); MemoryAllocation = new MemoryAllocation(ctx); Parameters = parameters; byte[] headInstBytes = GetHeadBytes(Context.DataAccess.ReadBytes(Parameters.TargetAddress, 32)); nuint allocAddr = MemoryAllocation.AllocationBase; nuint safeFreeFlagAddr = allocAddr + (uint)HookInfo.Offset_SafeFreeFlag; nuint onceFlagAddr = allocAddr + (uint)HookInfo.Offset_OnceFlag; nuint codeAddr = allocAddr + (uint)HookInfo.HeaderSize; nuint retAddr = Parameters.TargetAddress + (uint)headInstBytes.Length; HookInfo info = new(allocAddr, headInstBytes); Assembler assembler = new(); assembler.Emit(DataHelper.GetBytes(info)); //emit the header before runnable code assembler.Emit((Instruction)$"mov dword ptr [{safeFreeFlagAddr}],1"); assembler.Emit(Parameters.IsOnce ? GetOnceCheckedCode(Code, onceFlagAddr) : Code); //once or not if (Parameters.Original) { assembler.Emit(headInstBytes); //emit the raw code replaced by hook jmp } assembler.Emit((Instruction)$"mov dword ptr [{safeFreeFlagAddr}],0"); assembler.Emit((Instruction)$"jmp {retAddr}"); Context.DataAccess.WriteBytes(allocAddr, assembler.GetByteCode(allocAddr)); JmpHeadBytes = new byte[headInstBytes.Length]; Array.Fill <byte>(JmpHeadBytes, 0x90); Assembler.Assemble($"jmp {codeAddr}", Parameters.TargetAddress).CopyTo(JmpHeadBytes, 0); }
public static InlineHook Hook(QHackContext ctx, AssemblyCode code, HookParameters parameters) { var hook = new InlineHook(ctx, code, parameters); hook.Attach(); return(hook); }
private RemoteThread(QHackContext ctx, AssemblyCode asm, uint size = 0x1000) { Context = ctx; Allocation = new MemoryAllocation(ctx, size); Header = new RemoteThreadHeader(Allocation.AllocationBase); Assembler assembler = new(); assembler.Emit(DataHelper.GetBytes(Header)); assembler.Emit((Instruction)$"mov dword ptr [{Header.Address_SafeFreeFlag}],1"); assembler.Emit(asm); assembler.Emit((Instruction)$"mov dword ptr [{Header.Address_SafeFreeFlag}],0"); assembler.Emit((Instruction)"ret"); Context.DataAccess.WriteBytes(Header.AllocationAddress, assembler.GetByteCode(Header.AllocationAddress)); }
public bool ParseAndAdd(ParseTreeNode root, string filePath, AssemblyCode res, out List <string> includeFiles) { includeFiles = new List <string>(); this.ParsingFilePath = filePath; ParseTreeNode fileroot = root; //Find rootdefs ParseTreeNode rootdefs; if (fileroot.ChildNodes.Count != 1 || fileroot.ChildNodes[0].Term.Name != "root-defines") { ReportError("Root", "root-defines not found.", fileroot); return(false); } rootdefs = fileroot.ChildNodes[0]; //Parse rootdefs for (int i = 0; i < rootdefs.ChildNodes.Count; i++) { ParseTreeNode rootdef = rootdefs.ChildNodes[i]; if (rootdef.ChildNodes[0].Term.Name == "using-description") { includeFiles.Add((string)rootdef.ChildNodes[0].ChildNodes[1].Token.Value); } else if (rootdef.ChildNodes[0].Term.Name == "sectiondef") { Section sec; if (!ParseSection(rootdef.ChildNodes[0], res, out sec)) { return(false); } res.Sections.Add(sec); } else if (rootdef.ChildNodes[0].Term.Name == "memorysize-description") { res.MinMemorySize = Math.Max(res.MinMemorySize, (int)rootdef.ChildNodes[0].ChildNodes[1].Token.Value); } else if (rootdef.ChildNodes[0].Term.Name == "targetisa-description") { res.TargetISAName = (string)rootdef.ChildNodes[0].ChildNodes[1].Token.Value; } } return(true); }
public AssemblyCode Parse(string code) { var assemblyCode = new AssemblyCode { Code = code }; foreach (var token in GlobalTokens) { token.Parse(code); switch (token.Type) { case TokenTypes.Namespace: assemblyCode.AssemblyName = token.Value; break; } } return(assemblyCode); }
public CompilerResult Compile(AssemblyCode assemblyCode) { var dir = Path.GetDirectoryName(assemblyCode.SavePath); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } if (File.Exists(assemblyCode.SavePath)) { File.Delete(assemblyCode.SavePath); } var syntaxTrees = SyntaxFactory.ParseSyntaxTree(assemblyCode.Code); var references = DefaultReferences.Microsoft; var referencesMetadata = references.Select(x => MetadataReference.CreateFromFile(x.AssemblyPath)); var compilationOptions = new CSharpCompilationOptions(assemblyCode.OutputKind); var compilation = CSharpCompilation.Create(assemblyCode.AssemblyName) .WithOptions(compilationOptions) .AddReferences(referencesMetadata) .AddSyntaxTrees(syntaxTrees); var emitResult = compilation.Emit(assemblyCode.SavePath); var errors = emitResult.Diagnostics .Where(d => d.Severity == DiagnosticSeverity.Error) .Select(d => d.GetMessage()); var warnings = emitResult.Diagnostics .Where(d => d.Severity == DiagnosticSeverity.Warning) .Select(d => d.GetMessage()); return(new CompilerResult(emitResult.Success, warnings, errors, assemblyCode.SavePath)); }
private void CreateFunctions(List <MethodInfo> fs, byte[] hash) { int i = NativeFunctions.VirtualAllocEx(Context.Handle, 0, 1024, NativeFunctions.AllocationType.Commit, NativeFunctions.MemoryProtection.ExecuteReadWrite); NativeFunctions.WriteProcessMemory(Context.Handle, i, hash, hash.Length, 0); i += hash.Length; int len = fs.Count; NativeFunctions.WriteProcessMemory(Context.Handle, i, ref len, 4, 0); i += 4; foreach (var s in fs) { int addr = NativeFunctions.VirtualAllocEx(Context.Handle, 0, (int)s.CustomAttributes.First(v => v.AttributeType == typeof(CustomFunctionAttribute)).ConstructorArguments[0].Value, NativeFunctions.AllocationType.Commit, NativeFunctions.MemoryProtection.ExecuteReadWrite); AssemblyCode code = (AssemblyCode)s.Invoke(null, null); var bCode = code.GetByteCode(addr); NativeFunctions.WriteProcessMemory(Context.Handle, addr, bCode, bCode.Length, 0); NativeFunctions.WriteProcessMemory(Context.Handle, i, ref addr, 4, 0); i += 4; Functions[s.Name] = addr; } }
public ActionOnManagedThread(GameContext ctx, AssemblyCode code, uint size = 0x1000) { Context = ctx; Code = code; Size = size; }
public override bool SetupFromAssembly(AssemblyCode code) { throw new NotImplementedException(); }
internal Instruction(ref Udis86.ud u, bool keepBinary) { this.Offset = u.insn_offset; this.PC = u.pc; this.Mnemonic = u.mnemonic; // Add operands List <Operand> operands = new List <Operand>(4); if (u.operand[0].type != Udis86.ud_type.UD_NONE) { operands.Add(new Operand(u.operand[0])); if (u.operand[1].type != Udis86.ud_type.UD_NONE) { operands.Add(new Operand(u.operand[1])); if (u.operand[2].type != Udis86.ud_type.UD_NONE) { operands.Add(new Operand(u.operand[2])); if (u.operand[3].type != Udis86.ud_type.UD_NONE) { operands.Add(new Operand(u.operand[3])); } } } } this.Operands = operands.ToArray(); this.Length = u.inp_ctr; // Copy the instruction bytes if (keepBinary) { this.Bytes = AssemblyCode.CopyToBytes(u.inp_buf, u.inp_buf_index - this.Length, this.Length); } if (u.error > 0) { this.Error = true; this.ErrorMessage = u.errorMessage; } else if (this.Mnemonic == Udis86.ud_mnemonic_code.UD_Iinvalid) { this.Error = true; this.ErrorMessage = "Invalid instruction"; } this.itab_entry = u.itab_entry; this.dis_mode = (ArchitectureMode)u.dis_mode; this.pfx_rex = u.pfx_rex; this.pfx_seg = u.pfx_seg; this.pfx_opr = u.pfx_opr; this.pfx_adr = u.pfx_adr; this.pfx_lock = u.pfx_lock; this.pfx_str = u.pfx_str; this.pfx_rep = u.pfx_rep; this.pfx_repe = u.pfx_repe; this.pfx_repne = u.pfx_repne; this.opr_mode = u.opr_mode; this.adr_mode = u.adr_mode; this.br_far = u.br_far; this.br_near = u.br_near; this.have_modrm = u.have_modrm; this.modrm = u.modrm; this.primary_opcode = u.primary_opcode; }
/// <summary> /// Allocates space and fills the code in before calling <see cref="RunOnNativeThread"/> to start a remote native thread.<br/> /// To avoid a memory leak, call <see cref="Dispose"/> to release the allocated space when the thread is not running. /// </summary> /// <param name="ctx"></param> /// <param name="asm"></param> /// <returns></returns> public static RemoteThread Create(QHackContext ctx, AssemblyCode asm) => new(ctx, asm);
private void button_Click(object sender, RoutedEventArgs e) { label.Content = ""; variables = new Dictionary <string, string>(); labels = new Dictionary <string, int>(); pc = 0; replace_lines = 1; try { int b = 0; string current = ""; for (int i = 0; i < AssemblyCode.LineCount; i++) { String line = AssemblyCode.GetLineText(i); string[] temp = line.Split('#'); line = temp[0]; current = line; b = i; line = line.Replace("\n", ""); line = line.Replace("\t", ""); line = line.Replace("\r", ""); line = line.Replace(",", ""); if (line == "" || line == " ") { continue; } IsInstruction(line, i); } } catch (Exception ex) { MessageBox.Show("line number: " + b + "\ninstruction " + current + "\nmessage: " + ex.Message); MessageBox.Show(ex.ToString()); } pc = 0; try { BinaryCode.Text = ""; for (int i = 0; i < AssemblyCode.LineCount; i++) { String line = AssemblyCode.GetLineText(i); if (i > 80) { Console.WriteLine("dkjf"); } string[] temp = line.Split('#'); line = temp[0]; current = line; b = i; line = line.Replace("\n", ""); line = line.Replace("\t", ""); line = line.Replace("\r", ""); line = line.Replace(",", ""); if (line == "" || line == " ") { continue; } string bin = ProcessLine(line, i + 1); if (bin != "") { //BinaryCode.Text += bin + "\n"; string real_bin = ""; int count = 0; if (checkBox.IsChecked == false) { foreach (char c in bin) { if (count == 4) { real_bin += "_"; count = 0; } real_bin += c; count++; } } string retbin = real_bin; //convert to hex if (checkBox.IsChecked == true) { retbin = ""; string but = ""; retbin = ""; foreach (char d in bin) { but += d; if (but.Length == 4) { retbin += Convert.ToInt32(but, 2).ToString("X"); but = ""; } } } label.Content = "Replace lines 1 through \n" + replace_lines + " in the memory file"; replace_lines++; BinaryCode.Text += retbin + "\n"; } } }catch (Exception ex) { MessageBox.Show("line number: " + b + "\ninstruction " + current + "\nmessage: " + ex.Message); MessageBox.Show(ex.ToString()); } }
public bool Parse(ParseTreeNode root, string filePath, out AssemblyCode res, out List <string> includeFiles) { res = new AssemblyCode(); return(ParseAndAdd(root, filePath, res, out includeFiles)); }
public void Run(string path) { Console.WriteLine("Generating Asssembly...."); AssemblyCode.Add(".model flat,stdcall"); AssemblyCode.Add("option casemap:none"); AssemblyCode.Add("include msvcrt.inc"); AssemblyCode.Add("includelib msvcrt.lib"); foreach (var item in ILCode) { switch (item.Operator) { case ILOperator.Module: ILDivMod(item, "edx"); break; case ILOperator.Add: ILSimpleBinary(item, "add"); break; case ILOperator.ArrayAccess: ILArrayAccess(item); break; case ILOperator.ArrayAssign: ILArrayAssign(item); break; case ILOperator.ArrayDefine: ILArrayDefine(item); break; case ILOperator.Assign: ILAssign(item); break; case ILOperator.Call: ILCall(item); break; case ILOperator.DataBegin: ILDataBegin(item); break; case ILOperator.DataEnd: ILDataEnd(item); break; case ILOperator.Decrease: ILDecrease(item); break; case ILOperator.Division: ILDivMod(item, "eax"); break; case ILOperator.Je: ILJc(item, "je"); break; case ILOperator.Jne: ILJc(item, "jne"); break; case ILOperator.Jg: ILJc(item, "jg"); break; case ILOperator.Jge: ILJc(item, "jge"); break; case ILOperator.Increase: ILIncrease(item); break; case ILOperator.Jmp: ILJmp(item); break; case ILOperator.JmpTarget: ILJmpTarget(item); break; case ILOperator.Jl: ILJc(item, "jl"); break; case ILOperator.Jle: ILJc(item, "jle"); break; case ILOperator.LoadAddress: ILLoadAddress(item); break; case ILOperator.Multiply: ILMultiply(item); break; case ILOperator.Jnz: ILJc(item, "jnz"); break; case ILOperator.Param: ILParam(item); break; case ILOperator.ProcBegin: LSymbols = new Dictionary <string, string>(); isLocal = true; ILProcBegin(item); ProcSegment = new List <string>(); break; case ILOperator.ProcEnd: isLocal = false; CodeSegment.AddRange(ProcSegment); ILProcEnd(item); break; case ILOperator.Push: ILPush(item); break; case ILOperator.Return: ILReturn(item); break; case ILOperator.Subtract: ILSimpleBinary(item, "sub"); break; case ILOperator.VarDefine: ILVarDefine(item); break; default: break; } } AssemblyCode.AddRange(DataSegment); AssemblyCode.AddRange(CodeSegment); AssemblyCode.Add("end main"); WriteToFile(path); }