private void button4_Click(object sender, EventArgs e) { try { string[] buffs = textBox2.Text.Split(new char[] { ' ' }); byte[] bytes = new byte[buffs.Length]; uint j = 0; byte curbyte; for (uint i = 0; i < buffs.Length; i++) { while (!byte.TryParse(buffs[j], System.Globalization.NumberStyles.HexNumber, null, out curbyte)) { j++; } bytes[i] = curbyte; j++; } asmInstruction curins = disassembler.disassemble(bytes); MessageBox.Show(curins.ToString()); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
public static void Callibrate(ProcessHandler clientprocess) { uint entrypoint; Stack <string> errstack = new Stack <string>(); asmInstruction curinsn = null; asmChunk curchunk = null; entrypoint = clientprocess.MainModule.EntryPointAddress; if ((entrypoint == 0) || (entrypoint == 0xFFFFFFFF)) { throw new Exception("Failed to obtain entrypoint address!"); } clientprocess.Position = (long)entrypoint; if (System.IO.File.Exists("Callibrations.xml")) { CallibrationFile.Load("Callibrations.xml"); } else//fall back to the embedded callibrations { CallibrationFile.Load(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("UOAIBasic.Callibrations.xml")); } if (!ActionList.actionlists["ActionList1"].ExecuteActionList(clientprocess, Callibrations, ref curchunk, ref curinsn, errstack)) { throw BuildCallibrationException(errstack); } }
public bool Check(asmInstruction tocompare, BinaryTree <uint, long> knowns) { foreach (Filter f in filters) { if (!f.Check(tocompare, knowns)) { return(false); } } return(true); }
private bool CheckOpData(asmInstruction tocheck, int opnumber, uint opdata, bool negate) { if ((opnumber < 0) || (opnumber >= tocheck.Operands.Count)) { return(false); } switch (tocheck.Operands[opnumber].Type) { case x86_op_type.op_immediate: case x86_op_type.op_absolute: if (!negate) { return(GetOpDataAsUInt(tocheck.Operands[opnumber]) == opdata); } else { return(!(GetOpDataAsUInt(tocheck.Operands[opnumber]) == opdata)); } case x86_op_type.op_expression: if (!negate) { return(tocheck.Operands[opnumber].Data.expression.disp == opdata); } else { return(!(tocheck.Operands[opnumber].Data.expression.disp == opdata)); } case x86_op_type.op_offset: if (!negate) { return(tocheck.Operands[opnumber].Data.offset == opdata); } else { return(!(tocheck.Operands[opnumber].Data.offset == opdata)); } case x86_op_type.op_relative_far: if (!negate) { return(((uint)(((int)tocheck.Address + tocheck.Instruction.size + tocheck.Operands[opnumber].Data.relative_far))) == opdata); } else { return(!(((uint)(((int)tocheck.Address + tocheck.Instruction.size + tocheck.Operands[opnumber].Data.relative_far))) == opdata)); } case x86_op_type.op_relative_near: if (!negate) { return(((uint)(((int)tocheck.Address + tocheck.Instruction.size + tocheck.Operands[opnumber].Data.relative_near)) == opdata)); } else { return(!(((uint)(((int)tocheck.Address + tocheck.Instruction.size + tocheck.Operands[opnumber].Data.relative_near)) == opdata))); } default: return(false); } }
public bool ExecuteActionList(Stream onstream, BinaryTree <uint, long> knowns, ref asmChunk curChunk, ref asmInstruction curInstruction, Stack <string> ErrorStack) { bool backwards = false; Tools.StreamHandler sh = new Tools.StreamHandler(onstream); knowns.Add(0, onstream.Position); uint i = 0; //first action must be chunk or func parse foreach (Action currentaction in Actions) { switch (currentaction.m_type) { case ActionType.DISASM_CHUNK: if (!knowns.ContainsKey((uint)currentaction.knownpar)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] Missing Dependency: " + currentaction.knownpar.ToString()); return(false); } onstream.Position = knowns[(uint)currentaction.knownpar]; curChunk = disassembler.disassemble_chunk(onstream); break; case ActionType.DISASM_FUNCTION: if (!knowns.ContainsKey((uint)currentaction.knownpar)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] Missing Dependency: " + currentaction.knownpar.ToString()); return(false); } onstream.Position = knowns[(uint)currentaction.knownpar]; curChunk = disassembler.disassemble_function(onstream); break; case ActionType.FIND_SEQUENCE: if (curChunk == null) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No disassembled code chunk available to search!"); return(false); } if (!currentaction.seqpar.Find(curChunk, backwards, knowns, out curInstruction)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] Failed to find sequence: " + currentaction.seqpar.name); return(false); } break; case ActionType.FOLLOW_CALL: if ((curInstruction == null) || (curInstruction.Instruction.type != x86_insn_type.insn_call)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] Need a call instruction to follow!"); return(false); } onstream.Position = curInstruction.ReadAddressOperand(); if (currentaction.boolpar) { curChunk = disassembler.disassemble_chunk(onstream); } else { curChunk = disassembler.disassemble_function(onstream); } break; case ActionType.JUMP_KNOWN: if (!knowns.ContainsKey((uint)currentaction.knownpar)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] Missing Dependency: " + currentaction.knownpar.ToString()); return(false); } knowns.Remove(0); knowns.Add(0, knowns[(uint)currentaction.knownpar]); onstream.Position = knowns[(uint)currentaction.knownpar]; break; case ActionType.RETURN_ADDRESS: if (curInstruction == null) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No Current Instruction!"); return(false); } knowns.Remove((uint)currentaction.knownpar); knowns.Add((uint)currentaction.knownpar, curInstruction.Address); break; case ActionType.RETURN_DATA: if ((curInstruction == null) || ((int)currentaction.uintpar > (curInstruction.Operands.Count - 1))) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No Suitable Current Instruction!"); return(false); } knowns.Remove((uint)currentaction.knownpar); if (curInstruction.Operands[(int)currentaction.uintpar].Type == x86_op_type.op_expression) { knowns.Add((uint)currentaction.knownpar, (long)curInstruction.Operands[(int)currentaction.uintpar].Data.expression.disp); } else if (curInstruction.Operands[(int)currentaction.uintpar].Type == x86_op_type.op_offset) { knowns.Add((uint)currentaction.knownpar, (long)curInstruction.Operands[(int)currentaction.uintpar].Data.offset); } else { knowns.Add((uint)currentaction.knownpar, (long)curInstruction.Operands[(int)currentaction.uintpar].Data.dword); } break; case ActionType.RETURN_DISP: if ((curInstruction == null) || ((int)currentaction.uintpar > (curInstruction.Operands.Count - 1))) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No Suitable Current Instruction!"); return(false); } knowns.Remove((uint)currentaction.knownpar); knowns.Add((uint)currentaction.knownpar, (long)curInstruction.Operands[(int)currentaction.uintpar].Data.expression.disp); break; case ActionType.SET_BACKWARDS: if (backwards != currentaction.boolpar) { backwards = currentaction.boolpar; } break; case ActionType.TO_END: if (curChunk == null) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No disassembled code chunk available!"); return(false); } curChunk.ToEnd(); break; case ActionType.TO_START: if (curChunk == null) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No disassembled code chunk available!"); return(false); } curChunk.ToStart(); break; case ActionType.RETURN_TARGETADDRESS: if ((curInstruction == null) || ((int)currentaction.uintpar > (curInstruction.Operands.Count - 1))) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No Suitable Current Instruction!"); return(false); } knowns.Remove((uint)currentaction.knownpar); knowns.Add((uint)currentaction.knownpar, curInstruction.ReadAddressOperand()); break; case ActionType.FUNC_FIND: if (curChunk == null) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No disassembled code chunk available!"); return(false); } if (!FuncFind(onstream, curChunk, currentaction.uintpar, backwards, out curInstruction)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] Failed to find stdcall function with stacksize 0x" + currentaction.uintpar.ToString("X") + "!"); return(false); } break; case ActionType.SWITCH: if (!knowns.ContainsKey((uint)currentaction.knownpar)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] Missing Dependency: " + currentaction.knownpar.ToString()); return(false); } sh.Position = (knowns[(uint)currentaction.knownpar] + 4 * currentaction.uintpar); onstream.Position = (long)sh.Read <uint>(); if (currentaction.boolpar) { curChunk = disassembler.disassemble_chunk(onstream); } else { curChunk = disassembler.disassemble_function(onstream); } break; case ActionType.CONDITIONAL: if (currentaction.actlist != null) { if (currentaction.actlist.ExecuteActionList(onstream, knowns, ref curChunk, ref curInstruction, new Stack <string>())) { if (currentaction.ontrue != null) { if (!currentaction.ontrue.ExecuteActionList(onstream, knowns, ref curChunk, ref curInstruction, ErrorStack)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] OnTrue handler (" + currentaction.ontrue.name + ") of Condition " + currentaction.actlist.ToString() + " failed!"); return(false); } } } else { if (currentaction.onfalse != null) { if (!currentaction.onfalse.ExecuteActionList(onstream, knowns, ref curChunk, ref curInstruction, ErrorStack)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] OnFalse handler (" + currentaction.onfalse.name + ") of Condition " + currentaction.actlist.ToString() + " failed!"); return(false); } } } } break; case ActionType.ASSIGN_VALUE: if (knowns.ContainsKey((uint)currentaction.knownpar)) { knowns.Remove((uint)currentaction.knownpar); } knowns.Add((uint)currentaction.knownpar, (long)currentaction.uintpar); break; case ActionType.ASSIGN_KNOWN: if (knowns.ContainsKey((uint)currentaction.knownpar)) { knowns.Remove((uint)currentaction.knownpar); } if (!knowns.ContainsKey((uint)currentaction.knownpar2)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] Missing Dependency: " + currentaction.knownpar2.ToString()); return(false); } knowns.Add((uint)currentaction.knownpar, knowns[(uint)currentaction.knownpar2]); break; case ActionType.CHECK_INSTRUCTION: if (curInstruction == null) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No Suitable Current Instruction!"); return(false); } if (!currentaction.tocheck.Check(curInstruction, knowns)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] Instruction verification failed!"); return(false); } break; case ActionType.EXECUTE_ACTIONSLIST: if (!currentaction.actlist.ExecuteActionList(onstream, knowns, ref curChunk, ref curInstruction, ErrorStack)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] ActionList " + currentaction.actlist.name + " failed!"); return(false); } break; case ActionType.TRY_ACTIONLIST: if (!currentaction.actlist.ExecuteActionList(onstream, knowns, ref curChunk, ref curInstruction, ErrorStack)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] (Try) ActionList " + currentaction.actlist.name + " failed!"); } break; case ActionType.FOLLOW_JMP: if ((curInstruction == null) || (!((curInstruction.Instruction.type == x86_insn_type.insn_jmp) || (curInstruction.Instruction.type == x86_insn_type.insn_jcc)))) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No Suitable Current Instruction!"); return(false); } onstream.Position = curInstruction.ReadAddressOperand(); if (currentaction.boolpar) { curChunk = disassembler.disassemble_chunk(onstream); } else { curChunk = disassembler.disassemble_function(onstream); } break; case ActionType.RETURN_SCALE: if ((curInstruction == null) || ((int)currentaction.uintpar > (curInstruction.Operands.Count - 1))) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No Suitable Current Instruction!"); return(false); } knowns.Add((uint)currentaction.knownpar, (long)curInstruction.Operands[(int)currentaction.uintpar].Data.expression.scale); break; case ActionType.FIND_LOOP: if (curChunk != null) { if (!curChunk.FindLoop(out curInstruction)) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] Failed to find a loop in the current code chunk!"); return(false); } } break; case ActionType.RETURN_CHUNK_ADDRESS: if (curChunk == null) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No disassembled code chunk available!"); return(false); } knowns.Add((uint)currentaction.knownpar, curChunk.Address); break; case ActionType.MOVE_NEXT: if (curChunk == null) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No disassembled code chunk available!"); return(false); } curChunk.MoveNext(); break; case ActionType.MOVE_PREVIOUS: if (curChunk == null) { ErrorStack.Push("[#" + i.ToString() + " : " + currentaction.name + "] No disassembled code chunk available!"); return(false); } curChunk.MovePrevious(); break; } i++; } return(true); }
private static bool FuncFind(Stream onstream, asmChunk fromfunction, uint required_stacksize, bool backwards, out asmInstruction found) { asmChunk curfunc; found = null; while (fromfunction.FindByType(x86_insn_type.insn_call, backwards, out found)) { onstream.Position = found.ReadAddressOperand(); curfunc = disassembler.disassemble_chunk(onstream); if (StackSize(curfunc) == required_stacksize) { return(true); } fromfunction.MoveNext(); } return(false); }
public bool Find(asmChunk onchunk, bool backwards, BinaryTree <uint, long> knowns, out asmInstruction found) { found = null; for (int i = 0; i < CodeBlocks.Count; i++) { if (!CodeBlocks[i].Find(onchunk, backwards, knowns, out found)) { return(false); } if (i != (CodeBlocks.Count - 1)) { if (backwards) { onchunk.MovePrevious(); } else { onchunk.MoveNext(); } } } return(true); }
public bool Find(asmChunk onchunk, bool backwards, BinaryTree <uint, long> knowns, out asmInstruction found) { bool _found = true; asmInstruction backup, fullbackup; fullbackup = onchunk.Current; found = null; while (onchunk.Current != null) { backup = onchunk.Current; _found = true; for (int i = 0; i < FilterLists.Count; i++) { if (!FilterLists[i].Check(onchunk.Current, knowns)) { _found = false; break; } if (i != (FilterLists.Count - 1)) { onchunk.MoveNext(); if (onchunk.Current == null) { _found = false; break; } } } onchunk.Current = backup; if (_found) { found = onchunk.Current; return(true); } if (backwards) { onchunk.MovePrevious(); } else { onchunk.MoveNext(); } } onchunk.Current = fullbackup; return(false); }
public bool Check(asmInstruction tocompare, BinaryTree <uint, long> knowns) { switch (type) { case FilterType.OpKnownData: if (knowns != null) { if (((int)uintpar) < tocompare.Operands.Count) { if ((knowns.ContainsKey(enumpar)) && CheckOpData(tocompare, (int)uintpar, (uint)knowns[enumpar], false)) { return(true); } } } break; case FilterType.FilterOr: foreach (Filter f in filterlistpar.filters) { if (f.Check(tocompare, knowns)) { return(true); } } break; case FilterType.ExplicitOpCount: if (tocompare.Instruction.explicit_count == uintpar) { return(true); } break; case FilterType.OpCount: if (((int)uintpar) < tocompare.Operands.Count) { if (tocompare.Instruction.operand_count == uintpar) { return(true); } } break; case FilterType.OpData: if (((int)uintpar) < tocompare.Operands.Count) { if (CheckOpData(tocompare, (int)uintpar, uintpar2, false)) { return(true); } } break; case FilterType.OpDataType: if (((int)uintpar) < tocompare.Operands.Count) { if (tocompare.Operands[(int)uintpar].DataType == (x86_op_datatype)enumpar) { return(true); } } break; case FilterType.OpType: if (((int)uintpar) < tocompare.Operands.Count) { if (tocompare.Operands[(int)uintpar].Type == (x86_op_type)enumpar) { return(true); } } break; case FilterType.Size: if (uintpar == tocompare.Instruction.size) { return(true); } break; case FilterType.Type: if (tocompare.Instruction.type == (x86_insn_type)enumpar) { return(true); } break; case FilterType.OpDataNotEqual: if (((int)uintpar) < tocompare.Operands.Count) { if (CheckOpData(tocompare, (int)uintpar, uintpar2, true)) { return(true); } } break; } return(false); }
private LocalHook(uint address, ushort stack_cleanup_size, bool IsVtblEntry) { uint skip_call_address; asmInstruction curinsn = null; ProcessHandler curprocess = ProcessHandler.CurrentProcess; StreamHandler sh = new StreamHandler(curprocess); CallRelative crel; JmpRelative jrel; int readsize = 0; m_Address = address; m_VtblHook = IsVtblEntry; //read original target address curprocess.Position = address; if (IsVtblEntry) { original_address = sh.Read <uint>(); } else { curinsn = disassembler.disassemble(curprocess); if (curinsn.Instruction.type == x86_insn_type.insn_call) { original_address = (uint)curinsn.ReadAddressOperand(); } else { original_address = 0;//not hooking a call readsize = curinsn.Instruction.size; while (readsize < 5) { curinsn = disassembler.disassemble(curprocess); readsize += curinsn.Instruction.size; } copied_instructions = new byte[readsize]; curprocess.Position = address; curprocess.Read(copied_instructions, 0, readsize); } } //allocate required space (60 bytes) m_HookMemory = Allocator.AllocateBuffer((uint)(46 + 32 + readsize)); m_EspBackup = Allocator.AllocateBuffer(4); skip_call_address = (uint)(m_HookMemory.Address.ToInt32() + 35 + readsize); //build unmanaged function pointer m_Delegate = new InternalHookDelegate(ActualHook); m_LateDelegate = new InternalHookDelegate(ActualLateHook); IntPtr unmanaged_hook_pointer = Marshal.GetFunctionPointerForDelegate(m_Delegate); IntPtr unmanaged_hook_pointerb = Marshal.GetFunctionPointerForDelegate(m_LateDelegate); //build hook code AsmBuilder hookcode = new AsmBuilder(); hookcode.Instructions.Add(new PushAll()); hookcode.Instructions.Add(new BackupEsp((uint)m_EspBackup.Address.ToInt32())); hookcode.Instructions.Add(new PushImmediate(address)); hookcode.Instructions.Add(new CallRelative(unmanaged_hook_pointer.ToInt32())); hookcode.Instructions.Add(new TestEaxEax()); hookcode.Instructions.Add(new JzRelativeShort((int)skip_call_address)); hookcode.Instructions.Add(new RestoreEsp((uint)m_EspBackup.Address.ToInt32())); hookcode.Instructions.Add(new PopAll()); //switch vtbl: return, non-call : jmp address+readsize, call, jmp original hookcode.Write(curprocess, m_HookMemory.Address.ToInt32()); if (original_address == 0) { curprocess.Position = m_HookMemory.Address.ToInt32() + 30; curprocess.Write(copied_instructions, 0, readsize); hookcode = new AsmBuilder(); hookcode.Instructions.Add(new JmpRelative((int)address + readsize)); } else { hookcode = new AsmBuilder(); hookcode.Instructions.Add(new JmpRelative((int)original_address)); } //end_code hookcode.Instructions.Add(new RestoreEsp((uint)m_EspBackup.Address.ToInt32())); hookcode.Instructions.Add(new PopAll()); if (stack_cleanup_size == 0) { hookcode.Instructions.Add(new Rtn()); } else { hookcode.Instructions.Add(new RtnStackSize(stack_cleanup_size)); } hookcode.Write(curprocess, (int)m_HookMemory.Address.ToInt32() + 30 + readsize); hookcode = new AsmBuilder(); hookcode.Instructions.Add(new PushImmediate(0)); hookcode.Instructions.Add(new PushAll()); hookcode.Instructions.Add(new BackupEsp((uint)m_EspBackup.Address.ToInt32())); hookcode.Instructions.Add(new PushImmediate(address)); hookcode.Instructions.Add(new CallRelative(unmanaged_hook_pointerb.ToInt32())); hookcode.Instructions.Add(new RestoreEsp((uint)m_EspBackup.Address.ToInt32())); hookcode.Instructions.Add(new PopAll()); hookcode.Instructions.Add(new Rtn()); hookcode.Write(curprocess, (int)m_HookMemory.Address.ToInt32() + 46 + readsize); m_LateHookAddress = (uint)(m_HookMemory.Address.ToInt32() + 46 + readsize); //install hook if (original_address != 0) { if (IsVtblEntry) { //vtbl_hook sh.Position = address; sh.Write <int>(m_HookMemory.Address.ToInt32()); } else { crel = new CallRelative((int)m_HookMemory.Address.ToInt32()); if (crel.Size != curinsn.Instruction.size) { throw new Exception("Can only hook call instructions with size equal to " + crel.Size.ToString()); } crel.Write(curprocess, (int)address); curprocess.Position = address + crel.Size; } } else { //random hook jrel = new JmpRelative((int)m_HookMemory.Address.ToInt32()); jrel.Write(curprocess, (int)address); curprocess.Position = address + jrel.Size; for (uint i = 0; i < (readsize - jrel.Size); i++) { curprocess.WriteByte(0x90);//NOP } } m_Hooks.Add(address, this); }