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 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); }
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); }
private static uint StackSize(asmChunk tocheck) { asmOperand curop; asmInstruction found; tocheck.ToStart(); if (tocheck.FindByType(x86_insn_type.insn_return, false, out found)) { for (int i = 0; i < found.Operands.Count; i++) { curop = found.Operands[i]; if (curop.Type == x86_op_type.op_immediate) { return((uint)curop.Data); } } } return(0); }
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 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); }