Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
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);
 }
Beispiel #6
0
        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);
        }