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(); }
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; }
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); }
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); }
//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; }
//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; }
//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); } }
//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); }
//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); } } } }
//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; }
//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); }
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; }
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; }