private static void doStuff(ref byte[] bytes) { uint[] rva = masker.GetRVA(ref bytes); if (rva.Length < 3) return; int[] locs = masker.GetAddressMaskLocs(ref bytes, rva); UnmanagedBuffer buffer = new UnmanagedBuffer(ref bytes); BeaEngine._Disasm disasm = new BeaEngine._Disasm(); ulong begin = (ulong)buffer.Ptr.ToInt64(); disasm.InstructionPointer = (UIntPtr)(begin + rva[0]); disasm.Options |= BeaEngine.SpecialInfo.NasmSyntax; ulong loc; int result; string bytesStr; for (int counter = 0; counter < 100; counter++) // First 100 lines of disassembly code. { result = BeaEngine.Disassemble(ref disasm); if (result == BeaEngine.UnknownOpcode || result == BeaEngine.OutOfBlock) break; loc = disasm.InstructionPointer.ToUInt64() - begin; bytesStr = ""; for (int i = 0; i < result; i++) bytesStr += (Array.IndexOf<int>(locs, (int)loc + i) < 0) ? bytes[loc + (ulong)i].ToString("X2") + " " : "?? "; Console.WriteLine(string.Format("0x{0,-6:X} {1,-30} {2}", loc, bytesStr.Trim(), disasm.CompleteInstr)); disasm.InstructionPointer = (UIntPtr)(disasm.InstructionPointer.ToUInt64() + (ulong)result); } }
public static int[] GetAddressMaskLocs(ref byte[] bytes, uint[] rva) // Returns: list of address byte locations { if (rva.Length < 3) { return new int[] { } } ; UnmanagedBuffer buffer = new UnmanagedBuffer(ref bytes); BeaEngine._Disasm disasm = new BeaEngine._Disasm(); ulong begin = (ulong)buffer.Ptr.ToInt64(); ulong end = begin + (ulong)(rva[1] + rva[2]); disasm.InstructionPointer = (UIntPtr)(begin + rva[1]); // We start from section start, rather than entry point int result, off, n; List <int> locs = new List <int>(); while (disasm.InstructionPointer.ToUInt64() < end) { result = BeaEngine.Disassemble(ref disasm, true); if (result == BeaEngine.UnknownOpcode) // This is not good practice, but not sure, what else I can do { Console.WriteLine("UnknownOpcode (" + bytes[(int)(disasm.InstructionPointer.ToUInt64() - begin)].ToString("X2") + ") at: " + (disasm.InstructionPointer.ToUInt64() - begin).ToString() + " skipping 1 byte."); result = 1; } if (result == BeaEngine.OutOfBlock) { break; } //if (result < 5) // Does not contain address if (result > 4) // Mask addresses { off = result % 4; n = result - off; off += (int)(disasm.InstructionPointer.ToUInt64() - begin); for (int i = 0; i < n; i++) { locs.Add(off + i); } } disasm.InstructionPointer = (UIntPtr)(disasm.InstructionPointer.ToUInt64() + (ulong)result); } return(locs.ToArray()); } }
// Returns: list of address byte locations public static int[] GetAddressMaskLocs(ref byte[] bytes, uint[] rva) { if (rva.Length < 3) return new int[] { }; UnmanagedBuffer buffer = new UnmanagedBuffer(ref bytes); BeaEngine._Disasm disasm = new BeaEngine._Disasm(); ulong begin = (ulong)buffer.Ptr.ToInt64(); ulong end = begin + (ulong)(rva[1] + rva[2]); disasm.InstructionPointer = (UIntPtr)(begin + rva[1]); // We start from section start, rather than entry point int result, off, n; List<int> locs = new List<int>(); while (disasm.InstructionPointer.ToUInt64() < end) { result = BeaEngine.Disassemble(ref disasm, true); if (result == BeaEngine.UnknownOpcode) // This is not good practice, but not sure, what else I can do { Console.WriteLine("UnknownOpcode (" + bytes[(int)(disasm.InstructionPointer.ToUInt64() - begin)].ToString("X2") + ") at: " + (disasm.InstructionPointer.ToUInt64() - begin).ToString() + " skipping 1 byte."); result = 1; } if (result == BeaEngine.OutOfBlock) break; //if (result < 5) // Does not contain address if (result > 4) // Mask addresses { off = result % 4; n = result - off; off += (int)(disasm.InstructionPointer.ToUInt64() - begin); for (int i = 0; i < n; i++) locs.Add(off + i); } disasm.InstructionPointer = (UIntPtr)(disasm.InstructionPointer.ToUInt64() + (ulong)result); } return locs.ToArray(); }