Beispiel #1
0
        public void LoadFile(string FName)
        {
            byte[]              sf_prefixes = new byte[Dasmer.MAX_INSTRUCTION_LEN];
            IInstruction        instr1;// = new mediana.INSTRUCTION();
            DISASM_INOUT_PARAMS param = new DISASM_INOUT_PARAMS();

            RaiseLogEvent(this, "Loading " + FName);
            IntPtr tmp = assembly.LoadFile(FName);
            //MeDisasm = new medi.mediana(assembly);
            int i = 0;

            foreach (Section1 sect in assembly.Sections())
            {
                RaiseLogEvent(this, i.ToString() + ". Creating a new segment " + sect.RVA.ToString("X8") + " - " + (sect.RVA + sect.VirtualSize).ToString("X8") + "... ... OK");
                i++;
            }

            TFunc fnc = new TFunc(assembly.ImageBase() + assembly.Entrypoint(), 0, 0, "main");

            param.arch        = Dasmer.ARCH_ALL;
            param.sf_prefixes = sf_prefixes;
            param.mode        = DISMODE.DISASSEMBLE_MODE_32;
            param.options     = (byte)(Dasmer.DISASM_OPTION_APPLY_REL | Dasmer.DISASM_OPTION_OPTIMIZE_DISP);
            param.bas         = assembly.ImageBase();
            MeDisasm.disassemble(RVA2FO(fnc.Addr), out instr1, ref param);
            Console.WriteLine(instr1.mnemonic);
            //MeDisasm.medi_dump(instr, buff, OUT_BUFF_SIZE, DUMP_OPTION_IMM_UHEX | DUMP_OPTION_DISP_HEX);
            FullProcList.AddFunc(fnc);
            foreach (ExportMethod1 func in assembly.LibraryExports())
            {
                TFunc tmpfunc = new TFunc((uint)assembly.ImageBase() + (uint)func.RVA, 2, (uint)func.Ordinal, func.Name);
                FullProcList.AddFunc(tmpfunc);
            }
            foreach (LibraryReference1 lib in assembly.LibraryImports())
            {
                foreach (ImportMethods1 func in lib.ImportMethods)
                {
                    TFunc tmpfunc = new TFunc((uint)assembly.ImageBase() + func.RVA, 3, func.Ordinal, func.Name, lib.LibraryName);
                    FullProcList.AddFunc(tmpfunc);
                }
            }
            bw.WorkerSupportsCancellation = true;
            bw.WorkerReportsProgress      = false;
            bw.DoWork             += bw_DoWork;
            bw.RunWorkerCompleted += bw_RunWorkerCompleted;
            bw.RunWorkerAsync();
        }
Beispiel #2
0
        public UInt32 disassemble(ulong offset, out IInstruction instr, ref DISASM_INOUT_PARAMS param)
        {
            byte[] bt = assembly.ReadBytes(offset, 10);
            dsm = new TUP.AsmResolver.ASM.x86Disassembler(bt);
            dsm.CurrentOffset = 0;
            Instr instr1 = new Instr();
            instr1.Addr = offset;
            instr1.ins = dsm.DisassembleNextInstruction();
            instr1.bytes = assembly.ReadBytes(offset, instr1.ins.Size);

            if (instr1.bytes[0] == 0xFF)
                if (instr1.bytes[1] == 0x15)
                    if (instr1.ins.Operand1 != null)
                        instr1.disp.value.d64 = ((Offset)instr1.ins.Operand1.Value).Va;//Call ExitProcess probably

            instr = instr1;
            return (UInt32)instr1.ins.Size;
        }
Beispiel #3
0
        public UInt32 disassemble(ulong offset, out IInstruction instr, ref DISASM_INOUT_PARAMS param)
        {
            byte[] bt = assembly.ReadBytes(offset, 10);
            dsm = new TUP.AsmResolver.ASM.x86Disassembler(bt);
            dsm.CurrentOffset = 0;
            Instr instr1 = new Instr();

            instr1.Addr  = offset;
            instr1.ins   = dsm.DisassembleNextInstruction();
            instr1.bytes = assembly.ReadBytes(offset, instr1.ins.Size);

            if (instr1.bytes[0] == 0xFF)
            {
                if (instr1.bytes[1] == 0x15)
                {
                    if (instr1.ins.Operand1 != null)
                    {
                        instr1.disp.value.d64 = ((Offset)instr1.ins.Operand1.Value).Va;//Call ExitProcess probably
                    }
                }
            }
            instr = instr1;
            return((UInt32)instr1.ins.Size);
        }
Beispiel #4
0
        public ulong DisasmFunc(List <Stroka> lst, ulong addr, MyDictionary ProcList)
        {
            //List<Stroka> lst = new List<Stroka>();
            List <ulong>        Tasks     = new List <ulong>();
            List <ulong>        DTasks    = new List <ulong>();
            List <int>          LabelList = new List <int>();
            ulong               StartAdr  = addr;
            ulong               EndAddr   = addr;
            DISASM_INOUT_PARAMS param     = new DISASM_INOUT_PARAMS();
            uint Len = 0;

            byte[] sf_prefixes = new byte[Dasmer.MAX_INSTRUCTION_LEN];
            param.arch        = Dasmer.ARCH_ALL;
            param.sf_prefixes = sf_prefixes;
            param.mode        = DISMODE.DISASSEMBLE_MODE_32;
            param.options     = (byte)(Dasmer.DISASM_OPTION_APPLY_REL | Dasmer.DISASM_OPTION_OPTIMIZE_DISP);
            param.bas         = assembly.ImageBase() + 2000;
            IInstruction instr1 = new mediana.INSTRUCTION();

            Tasks.Add(addr);
            for (uint i = 0; Tasks.Count > 0; i++)
            {
                //instr1 = new mediana.INSTRUCTION();
                Len = MeDisasm.disassemble(Tasks[0], out instr1, ref param);
                if (EndAddr < (Tasks[0] + Len))
                {
                    EndAddr = Tasks[0] + Len;
                }
                Console.WriteLine(instr1.mnemonic);
                DTasks.Add(Tasks[0]);
                Tasks.Remove(Tasks[0]);
                lst.Add(new Stroka(this, instr1));
                if (Len > 0)
                {
                    switch (instr1.bytes[0])
                    {
                    case 0x0F: switch (instr1.bytes[1])
                        {
                        case 0x84:    //jz
                        case 0x85:    //jz
                        case 0x86:    //jbe
                            int val = (int)((int)instr1.bytes[2] + (int)instr1.Addr + Len);
                            if (!LabelList.Contains(val))
                            {
                                if ((!DTasks.Contains((uint)val)) && (!Tasks.Contains((uint)val)))
                                {
                                    Tasks.Add((uint)val);
                                }
                                //Tasks.Add((uint)val);//Add jmp adress to disasm tasks
                                val = (int)FO2RVA((ulong)val);
                                instr1.ops[0].value.imm.imm64 = (ulong)val;
                                LabelList.Add(val);
                            }
                            break;
                        }
                        break;

                    case 0x74: //Jz
                    case 0x75: //Jnz
                    {
                        int val = (int)((int)instr1.bytes[1] + (int)instr1.Addr + Len);
                        if (!LabelList.Contains(val))
                        {
                            if ((!DTasks.Contains((uint)val)) && (!Tasks.Contains((uint)val)))
                            {
                                Tasks.Add((uint)val);
                            }
                            //Tasks.Add((uint)val);//Add jmp adress to disasm tasks
                            val = (int)FO2RVA((ulong)val);
                            instr1.ops[0].value.imm.imm64 = (ulong)val;
                            LabelList.Add(val);
                        }
                    } break;

                    case 0xC2:     //retn XX;
                    case 0xC3:     //retn
                        goto _end; //Костыль

                    //continue;// Don't disasm after it
                    case 0xE8://Call;
                        int val3 = (int)instr1.bytes[1] + (int)Len + (int)instr1.Addr;
                        val3 = (int)FO2RVA((ulong)val3);
                        instr1.ops[0].value.imm.imm64 = (ulong)val3;
                        break;

                    case 0xEB://jmp;
                        int val1 = (int)instr1.bytes[1] + (int)Len + (int)instr1.Addr;
                        if (!LabelList.Contains(val1))
                        {
                            LabelList.Add(val1);
                            if ((!DTasks.Contains((uint)val1)) && (!Tasks.Contains((uint)val1)))
                            {
                                Tasks.Add((uint)val1);
                            }
                            //Tasks.Add((uint)val1);//Add jmp adress to disasm tasks
                        }
                        continue; // Don't disasm after it

                    case 0xE9:    //jmp;

                        int val2 = (int)instr1.bytes[1] + (int)Len + (int)instr1.Addr;
                        if (!LabelList.Contains(val2))
                        {
                            if ((!DTasks.Contains((uint)val2)) && (!Tasks.Contains((uint)val2)))
                            {
                                Tasks.Add((uint)val2);
                            }
                            //Tasks.Add((uint)val2);//Add jmp adress to disasm tasks
                            val2 = (int)FO2RVA((ulong)val2);
                            instr1.ops[0].value.imm.imm64 = (ulong)val2;
                            LabelList.Add(val2);
                        }
                        continue;// Don't disasm after it

                    case 0xFF:
                        if (instr1.bytes[1] == 0x15)//Call
                        {
                            ulong a = instr1.disp.value.d64;
                            Console.WriteLine(a.ToString("X"));
                            if (ProcList.ContainsKey(a))
                            {
                                if (ProcList[a].FName.Contains("ExitProcess"))
                                {
                                    continue;
                                }
                            }
                        }
                        break;
                    }
                }
                //Tasks.Add( instruction.Offset.FileOffset + (uint)instruction.Size);
                if ((!DTasks.Contains(instr1.Addr + Len)) && (!Tasks.Contains(instr1.Addr + Len)))
                {
                    Tasks.Add(instr1.Addr + Len);
                }
                instr1.Addr = FO2RVA(instr1.Addr);
                //                 += assembly.NTHeader.OptionalHeader.ImageBase;
            }
_end:
            instr1.Addr = FO2RVA((ulong)instr1.Addr);
            lst.Sort(delegate(Stroka x, Stroka y)
            {
                if (x.addr > y.addr)
                {
                    return(1);
                }
                if (x.addr == y.addr)
                {
                    return(0);
                }
                return(-1);
            });
            foreach (uint Addr in LabelList)
            {
                Stroka result = lst.Find(
                    delegate(Stroka sstr){ return(sstr.addr == Addr); }
                    );
                if (result != null)
                {
                    result.Label = "Loc_" + result.Inst.Addr.ToString("X8").Remove(0, 2);
                }
            }
            return(EndAddr - StartAdr);
        }
Beispiel #5
0
        //Main function for parsing prefixes. Reads input stream until meets non-prefix byte
        // or maximum instruction length is exceeded. The function checks if a prefix of the same group
        // was already met and if so, replaces old prefix with a new one.
        // Old prefix is added to superfluous prefixes array.
        // The function also checks if a prefix is opcode-extension.
        static UInt32 parse_prefixes(ulong offset, ref INSTRUCTION instr, INTERNAL_DATA idata, byte ext_table_index, byte ext_pref_index, ref DISASM_INOUT_PARAMS param)
        {
            byte pref_code;
            byte rex_found;
            byte pref_id;
            byte pref_index;
            UInt32 res;
            UInt32 tmp;
            OPCODE_DESCRIPTOR ptr;

            res = 0;
            rex_found = 0;

            while(true)
            {

            //pref_code = *offset;
            pref_code = assembly.ReadBytes(offset, 1)[0];

            if (res > Dasmer.MAX_INSTRUCTION_LEN)
            {
            idata.severe_err = ERRS.ERR_TOO_LONG;//error: instruction too long.
            break;
            }

            ptr = tables[IDX_1BYTE].opcodes[pref_code];
            if ( !( ((ptr.groups & GRP_PREFIX)!=0) ||
                (param.mode == DISMODE.DISASSEMBLE_MODE_64 && (pref_code >= 0x40) && (pref_code <= 0x4F) && (rex_found == 0))))
            {
            break;
            }
            else
            {
            if (rex_found!=0)
            {
                idata.severe_err = ERRS.ERR_REX_NOOPCD;//error: an opcode should follow after rex.
                break;
            }

            if ((rex_found != 0) && (param.mode == DISMODE.DISASSEMBLE_MODE_64))
            {
                if ( (pref_code >= 0x40) && (pref_code <= 0x4F) )
                {
                    idata.prefixes[PREF_REX_INDEX] = PREF_REX_ID;
                    instr.rex = pref_code;
                    rex_found = 1;

                    res++;
                    offset++;
                    continue;
                }
            }

            tmp = tq_handlers[ptr.ops[0].type](0, 0, ref instr, 0, new OPERAND_SIZE(), new INTERNAL_DATA(), param.mode);
            pref_index = (byte)(tmp >> 8);
            pref_id = (byte)tmp;// &0xFF;
            if (idata.prefixes[pref_index] != 0xFF)
            {
                add_sf_prefix(idata.prefixes, pref_index, ref instr, ref param);
            }
            idata.prefixes[pref_index] = pref_id;

            //Used later for prefix table switch.
            if (ptr.id == ID_66 || ptr.id == ID_REPZ || ptr.id == ID_REPNZ)
            {
                ext_table_index =(byte)(ptr.props);
                ext_pref_index = pref_index;
            }

            res++;
            offset++;
            }
            }

            return res;
        }
Beispiel #6
0
        //Main function for parsing opcode and prefixes. First of all it parses all prefixes and then
        // looks up for struct OPCODE_DESCRIPTOR. The following algorithm is used to handle instructions that
        // use prefixes as opcode extension:
        //
        // * Have we prefix that may be opcode extension?
        //   No: Lookup starts from 1byte table.
        //       * Is instruction found?
        //         No: Error.
        //         Yes: Success.
        //   Yes: Lookup starts from 'ext_table_index' table.
        //        * Is instruction found?
        //          No: Lookup starts from 1byte table.
        //              * Is instruction found?
        //                No: Error.
        //                Yes: Success.
        //          Yes: Success.
        static UInt32 parse_opcode(ulong offset, ref OPCODE_DESCRIPTOR opcode_descr, ref INSTRUCTION instr, INTERNAL_DATA idata, ref DISASM_INOUT_PARAMS param)
        {
            byte ext_table_index  = 0xFF;
            byte ext_prefix_index = 0;
            UInt32 res;
            UInt32 tmp;

            res = parse_prefixes(offset, ref instr, idata, ext_table_index, ext_prefix_index, ref param);
            if (idata.severe_err==0)
            {
            instr.opcode_offset = (byte)res;
            offset += res;

            if ((ext_table_index != 0xFF) && (offset == 0xF))
            {
            tmp = lookup_opcode(offset, ext_table_index, ref opcode_descr, idata);
            if ((idata.severe_err==0) && (opcode_descr.id != ID_NULL))
            {
                idata.prefixes[ext_prefix_index] = 0xFF;
                check_ext_sf_prefixes(idata.prefixes, ref instr, ref param);
                res += tmp;
            }
            else
            {
                idata.severe_err = 0;
                res += lookup_opcode(offset, IDX_1BYTE, ref opcode_descr, idata);
            }
            }
            else
            {
            res += lookup_opcode(offset, IDX_1BYTE, ref opcode_descr, idata);
            }

            if ((idata.severe_err==0) && (opcode_descr.id == ID_NULL))
            {
            idata.severe_err = ERRS.ERR_BADCODE;//error: invalid opcode.
            }
            }
            return res;
        }
Beispiel #7
0
        //Checks if segment override prefix is superfluous.
        static void check_seg_sf_prefixes(INSTRUCTION instr, byte[] prefixes, DISASM_INOUT_PARAMS param)
        {
            uint i;
            bool mem_op_found = false;

            if (prefixes[PREF_SEG_INDEX] != 0xFF)
            {
            for (i = 0; i < 3; i++)
            {
            if ((instr.ops[i].flags & (byte)OP_TYPE.OPERAND_TYPE_MEM)!=0)
            {
                if (param.mode == DISMODE.DISASSEMBLE_MODE_64)
                {
                    if ( !((prefixes[PREF_SEG_INDEX] == PREF_FS_ID) || (prefixes[PREF_SEG_INDEX] == PREF_GS_ID)) )
                    {
                        add_sf_prefix(prefixes, PREF_SEG_INDEX, ref instr, ref param);
                    }
                }
                else
                {
                    if ( (instr.ops[i].value.addr.mod & ADDR_MOD_BASE)==0 )
                    {
                        if (instr.ops[i].value.addr.seg == SREG_CODE_DS)
                            add_sf_prefix(prefixes, PREF_SEG_INDEX, ref instr, ref param);
                    }
                    else
                    {
                        if ((instr.ops[i].value.addr.bas == REG_CODE_BP) || (instr.ops[i].value.addr.bas == REG_CODE_SP))
                        {
                            if (instr.ops[i].value.addr.seg == SREG_CODE_SS)
                                add_sf_prefix(prefixes, PREF_SEG_INDEX, ref instr, ref param);
                        }
                        else
                        {
                            if (instr.ops[i].value.addr.seg == SREG_CODE_DS)
                                add_sf_prefix(prefixes, PREF_SEG_INDEX, ref instr, ref param);
                        }
                    }
                }

                mem_op_found = true;
            }
            }

            if (!mem_op_found)
            add_sf_prefix(prefixes, PREF_SEG_INDEX, ref instr, ref param);
            }
        }
Beispiel #8
0
 //Checks opcode-extension prefixes (repz, repnz, opsize) are superfluous.
 static void check_ext_sf_prefixes(byte[] prefixes, ref INSTRUCTION instr, ref DISASM_INOUT_PARAMS param)
 {
     if (prefixes[PREF_OPSIZE_INDEX] != 0xFF)
     add_sf_prefix(prefixes, PREF_OPSIZE_INDEX, ref instr, ref param);
     if (prefixes[PREF_REP_INDEX] != 0xFF)
     add_sf_prefix(prefixes, PREF_OPSIZE_INDEX, ref instr, ref param);
 }
Beispiel #9
0
        //Applies disassembling options.
        static void apply_disasm_options(ref INSTRUCTION instr, UInt32 len, DISASM_INOUT_PARAMS param)
        {
            for (int i = 0; i < 3; i++)
            {
            if ((param.options & Dasmer.DISASM_OPTION_APPLY_REL) != 0)
            {
            if ((instr.ops[i].flags & OPERAND_FLAG_REL)!=0)
            {
                instr.ops[i].value.imm.imm64 += len + param.bas;
            }
            }

            if ((param.options & Dasmer.DISASM_OPTION_OPTIMIZE_DISP) != 0)
            {
            if (((instr.ops[i].flags & (byte)OP_TYPE.OPERAND_TYPE_MEM)!=0) && (instr.ops[i].value.addr.mod != ADDR_MOD_DISP))
            {
                if (instr.disp.value.d64 == 0x0)
                    instr.ops[i].value.addr.mod &= (byte)(~(uint)ADDR_MOD_DISP);
            }
            }
            }
        }
Beispiel #10
0
        //If DISASM_INOUT_PARAMS.sf_prefixes != NULL, copies superfluous prefix's value to the array.
        static void add_sf_prefix_value(byte[] prefixes, int index, byte value, ref INSTRUCTION instr, ref DISASM_INOUT_PARAMS param)
        {
            instr.flags |= INSTR_FLAG_SF_PREFIXES;

            //if (param.sf_prefixes!=0)
            param.sf_prefixes[param.sf_prefixes_len++] = value;
            prefixes[index] = 0xFF;
        }
Beispiel #11
0
 //Gets superfluous prefix's value by its index and call to function above :).
 static void add_sf_prefix(byte[] prefixes, int index, ref INSTRUCTION instr, ref DISASM_INOUT_PARAMS param)
 {
     add_sf_prefix_value(prefixes, index, pref_opcodes[prefixes[index]], ref instr, ref param);
 }
Beispiel #12
0
        public UInt32 disassemble(ulong offset, ref IInstruction instr1, ref DISASM_INOUT_PARAMS param)
        {
            UInt32 len;
            UInt32 res;
            OPCODE_DESCRIPTOR opcode = new OPCODE_DESCRIPTOR();
            INTERNAL_DATA idata = new INTERNAL_DATA(0xFF);
            INSTRUCTION instr = instr1 as INSTRUCTION;
            //Setup everything.
            //memset(instr, 0x0, sizeof(*instr));
            //memset(&idata, 0x0, sizeof(idata));
            //memset(idata.prefixes, 0xFF, sizeof(idata.prefixes));
            param.sf_prefixes_len = 0;
            param.errcode = 0;
            len = res = 0;
            //Lookup opcode.
            res = parse_opcode(offset, ref opcode, ref instr, idata, ref param);
            if (idata.severe_err != ERRS.ERR_OK)
            {
                param.errcode = idata.severe_err;
                return 0;
            }
            len += res;

            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
            param.errcode = ERRS.ERR_TOO_LONG;
            return 0;
            }

            get_address_size(ref instr, idata.prefixes, param.mode);

            //Parse MODRM and SIB bytes.
            len += parse_modrm_sib(offset + len, ref instr, opcode);
            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
            param.errcode = ERRS.ERR_TOO_LONG;
            return 0;
            }

            //Copy flags, eflags, id, groups.
            copy_eflags(ref instr, ref opcode);
            copy_instr_flags(ref instr, ref opcode);
            instr.id = opcode.id;
            instr.groups = opcode.groups;

            //Parse mnemonic.
            parse_mnemonic(opcode, instr, idata, param.mode);
            if (idata.severe_err != ERRS.ERR_OK)
            {
            param.errcode = idata.severe_err;
            return 0;
            }

            //Deal with operands.
            res = parse_operand(offset, offset + len, opcode.ops[0], instr, 0, idata, param.mode);
            if (idata.severe_err != ERRS.ERR_OK)
            {
            param.errcode = idata.severe_err;
            return 0;
            }
            len += res;
            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
            param.errcode = ERRS.ERR_TOO_LONG;
            return 0;
            }

            res = parse_operand(offset, offset + len, opcode.ops[1], instr, 1, idata, param.mode);
            if (idata.severe_err != ERRS.ERR_OK)
            {
            param.errcode = idata.severe_err;
            return 0;
            }
            len += res;
            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
            param.errcode = ERRS.ERR_TOO_LONG;
            return 0;
            }

            res = parse_operand(offset, offset + len, opcode.ops[2], instr, 2, idata, param.mode);
            if (idata.severe_err != ERRS.ERR_OK)
            {
            param.errcode = idata.severe_err;
            return 0;
            }
            len += res;
            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
            param.errcode = ERRS.ERR_TOO_LONG;
            return 0;
            }

            //Do postprocessing if necessary.
            if ((opcode.props & PROP_POST_PROC)!=0)
            {
            res = postprocs[opcode.props >> POST_PROC_SHIFT](offset, offset, ref instr, idata, param.mode);
            if (idata.severe_err != ERRS.ERR_OK)
            {
            param.errcode = idata.severe_err;
            return 0;
            }
            if (res>0)
            {
            len = res;
            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
                param.errcode = ERRS.ERR_TOO_LONG;
                return 0;
            }
            }
            }

            //Check if REX is superfluous.
            if ((param.mode == DISMODE.DISASSEMBLE_MODE_64) && (idata.is_rex_used != 0))
            add_sf_prefix_value(idata.prefixes, PREF_REX_INDEX, instr.rex, ref instr, ref param);
            //Check if segment prefix is superfluous.
            check_seg_sf_prefixes(instr, idata.prefixes, param);
            //Check if opsize is superfluous.
            if ((idata.is_opsize_used!=0) && idata.prefixes[PREF_OPSIZE_INDEX] != 0xFF)
            add_sf_prefix(idata.prefixes, PREF_OPSIZE_INDEX, ref instr, ref param);
            //Check if addrsize is superfluous.
            if ((idata.is_addrsize_used!=0) && idata.prefixes[PREF_ADDRSIZE_INDEX] != 0xFF)
            add_sf_prefix(idata.prefixes, PREF_ADDRSIZE_INDEX, ref instr, ref param);

            //Convert prefixes to output representation.
            convert_prefixes(instr, idata.prefixes);

            //Copy error if exists.
            param.errcode = idata.err;

            //And post checks.
            if ((param.arch & opcode.arch)!=0)
            param.errcode = ERRS.ERR_ANOT_ARCH;//error: another architecture.
            else if ( ((instr.prefixes & INSTR_PREFIX_LOCK)!=0) && ((opcode.props & PROP_LOCK)==0) )
            param.errcode = ERRS.ERR_NON_LOCKABLE;//error: prefix lock non-lockable instruction.
            else if (((opcode.props & PROP_I64) != 0) && (param.mode == DISMODE.DISASSEMBLE_MODE_64))
            param.errcode = ERRS.ERR_16_32_ONLY;//error: instruction is 16/32bit mode only.
            else if (((opcode.props & PROP_O64) != 0) && (param.mode != DISMODE.DISASSEMBLE_MODE_64))
            param.errcode = ERRS.ERR_64_ONLY;//error: instruction is 64bit mode only.

            apply_disasm_options(ref instr, len, param);
            instr.bytes = assembly.ReadBytes(offset, (int)len);

            instr.Addr = (ulong)offset;
            return len;
        }
Beispiel #13
0
        public ulong DisasmFunc(List<Stroka> lst, ulong addr, MyDictionary ProcList)
        {
            //List<Stroka> lst = new List<Stroka>();
            List<ulong> Tasks = new List<ulong>();
            List<ulong> DTasks = new List<ulong>();
            List<int> LabelList = new List<int>();
            ulong StartAdr = addr;
            ulong EndAddr = addr;
            DISASM_INOUT_PARAMS param = new DISASM_INOUT_PARAMS();
            uint Len = 0;
            byte[] sf_prefixes = new byte[Dasmer.MAX_INSTRUCTION_LEN];
            param.arch = Dasmer.ARCH_ALL;
            param.sf_prefixes = sf_prefixes;
            param.mode = DISMODE.DISASSEMBLE_MODE_32;
            param.options = (byte)(Dasmer.DISASM_OPTION_APPLY_REL | Dasmer.DISASM_OPTION_OPTIMIZE_DISP);
            param.bas = assembly.ImageBase()+2000;
            IInstruction instr1 = new mediana.INSTRUCTION();

            Tasks.Add(addr);
            for (uint i = 0; Tasks.Count > 0; i++)
            {
                //instr1 = new mediana.INSTRUCTION();
                Len = MeDisasm.disassemble(Tasks[0], out instr1, ref param);
                if (EndAddr < (Tasks[0] + Len)) EndAddr = Tasks[0] + Len;
                Console.WriteLine(instr1.mnemonic);
                DTasks.Add(Tasks[0]);
                Tasks.Remove(Tasks[0]);
                lst.Add(new Stroka(this, instr1));
                if(Len>0)
                switch (instr1.bytes[0])
                {
                    case 0x0F: switch(instr1.bytes[1])
                        {
                            case 0x84://jz
                            case 0x85://jz
                            case 0x86://jbe
                                int val = (int)((int)instr1.bytes[2] + (int)instr1.Addr + Len);
                                if (!LabelList.Contains(val))
                                {
                                    if ((!DTasks.Contains((uint)val)) && (!Tasks.Contains((uint)val))) Tasks.Add((uint)val);
                                    //Tasks.Add((uint)val);//Add jmp adress to disasm tasks
                                    val = (int)FO2RVA((ulong)val);
                                    instr1.ops[0].value.imm.imm64 = (ulong)val;
                                    LabelList.Add(val);
                                }break;
                        }
                        break;
                    case 0x74://Jz
                    case 0x75://Jnz
                        {
                            int val = (int)((int)instr1.bytes[1] + (int)instr1.Addr + Len);
                            if (!LabelList.Contains(val))
                            {
                                if ((!DTasks.Contains((uint)val)) && (!Tasks.Contains((uint)val))) Tasks.Add((uint)val);
                                //Tasks.Add((uint)val);//Add jmp adress to disasm tasks
                                val = (int)FO2RVA((ulong)val);
                                instr1.ops[0].value.imm.imm64 = (ulong)val;
                                LabelList.Add(val);
                            }
                        } break;
                    case 0xC2://retn XX;
                    case 0xC3://retn
                        goto _end;//Костыль
                        //continue;// Don't disasm after it
                    case 0xE8://Call;
                        int val3 = (int)instr1.bytes[1] + (int)Len + (int)instr1.Addr;
                        val3 = (int)FO2RVA((ulong)val3);
                        instr1.ops[0].value.imm.imm64 = (ulong)val3;
                        break;
                    case 0xEB://jmp;
                        int val1 = (int)instr1.bytes[1] + (int)Len + (int)instr1.Addr;
                        if (!LabelList.Contains(val1))
                        {
                            LabelList.Add(val1);
                            if((!DTasks.Contains((uint)val1)) && (!Tasks.Contains((uint)val1))) Tasks.Add((uint)val1);
                            //Tasks.Add((uint)val1);//Add jmp adress to disasm tasks
                        }
                        continue;// Don't disasm after it
                    case 0xE9://jmp;

                        int val2 = (int)instr1.bytes[1] + (int)Len + (int)instr1.Addr;
                        if (!LabelList.Contains(val2))
                        {
                            if ((!DTasks.Contains((uint)val2)) && (!Tasks.Contains((uint)val2))) Tasks.Add((uint)val2);
                            //Tasks.Add((uint)val2);//Add jmp adress to disasm tasks
                            val2 = (int)FO2RVA((ulong)val2);
                            instr1.ops[0].value.imm.imm64 = (ulong)val2;
                            LabelList.Add(val2);
                        }
                        continue;// Don't disasm after it
                    case 0xFF:
                        if (instr1.bytes[1] == 0x15)//Call
                        {
                                ulong a = instr1.disp.value.d64;
                                Console.WriteLine(a.ToString("X"));
                                if(ProcList.ContainsKey(a))
                                    if(ProcList[a].FName.Contains("ExitProcess"))continue;
                            }
                            break;
                }
                //Tasks.Add( instruction.Offset.FileOffset + (uint)instruction.Size);
                if ((!DTasks.Contains(instr1.Addr + Len)) && (!Tasks.Contains(instr1.Addr + Len)))
                    Tasks.Add(instr1.Addr + Len);
                instr1.Addr = FO2RVA(instr1.Addr);
                //                 += assembly.NTHeader.OptionalHeader.ImageBase;
            }
            _end:
            instr1.Addr = FO2RVA((ulong)instr1.Addr);
            lst.Sort(delegate(Stroka x, Stroka y)
            {
                if (x.addr > y.addr) return 1;
                if (x.addr == y.addr) return 0;
                return -1;
            });
            foreach (uint Addr in LabelList)
            {
                Stroka result = lst.Find(
                     delegate(Stroka sstr){return sstr.addr == Addr;}
                    );
                if (result != null)
                {
                    result.Label = "Loc_" + result.Inst.Addr.ToString("X8").Remove(0, 2);
                }
            }
            return EndAddr-StartAdr;
        }
Beispiel #14
0
        public void LoadFile(string FName)
        {
            byte[] sf_prefixes = new byte[Dasmer.MAX_INSTRUCTION_LEN];
            IInstruction instr1;// = new mediana.INSTRUCTION();
            DISASM_INOUT_PARAMS param = new DISASM_INOUT_PARAMS();

            RaiseLogEvent(this, "Loading " + FName);
            IntPtr tmp = assembly.LoadFile(FName);
            //MeDisasm = new medi.mediana(assembly);
            int i = 0;
            foreach (Section1 sect in assembly.Sections())
            {
                RaiseLogEvent(this, i.ToString() + ". Creating a new segment " + sect.RVA.ToString("X8") + " - " + (sect.RVA + sect.VirtualSize).ToString("X8") + "... ... OK");
                i++;
            }

            TFunc fnc = new TFunc(assembly.ImageBase() + assembly.Entrypoint(), 0, 0, "main");

            param.arch = Dasmer.ARCH_ALL;
            param.sf_prefixes = sf_prefixes;
            param.mode = DISMODE.DISASSEMBLE_MODE_32;
            param.options = (byte)(Dasmer.DISASM_OPTION_APPLY_REL | Dasmer.DISASM_OPTION_OPTIMIZE_DISP);
            param.bas = assembly.ImageBase();
            MeDisasm.disassemble(RVA2FO(fnc.Addr), out instr1, ref param);
            Console.WriteLine(instr1.mnemonic);
            //MeDisasm.medi_dump(instr, buff, OUT_BUFF_SIZE, DUMP_OPTION_IMM_UHEX | DUMP_OPTION_DISP_HEX);
            FullProcList.AddFunc(fnc);
            foreach (ExportMethod1 func in assembly.LibraryExports())
            {

                TFunc tmpfunc = new TFunc((uint)assembly.ImageBase() + (uint)func.RVA, 2, (uint)func.Ordinal, func.Name);
                FullProcList.AddFunc(tmpfunc);
            }
            foreach (LibraryReference1 lib in assembly.LibraryImports())
            {
                foreach (ImportMethods1 func in lib.ImportMethods)
                {
                    TFunc tmpfunc = new TFunc((uint)assembly.ImageBase() + func.RVA, 3, func.Ordinal, func.Name, lib.LibraryName);
                    FullProcList.AddFunc(tmpfunc);
                }
            }
            bw.WorkerSupportsCancellation = true;
            bw.WorkerReportsProgress = false;
            bw.DoWork += bw_DoWork;
            bw.RunWorkerCompleted += bw_RunWorkerCompleted;
            bw.RunWorkerAsync();
        }