private static unsafe void Main(string[] args) { var buf = new byte[4]; buf[0] = (byte) 0xc3; buf[1] = (byte) 0x33; buf[2] = (byte) 0xc0; buf[3] = (byte) 0xc3; var ci = new CodeInfo((long) 0x1000, buf, DecodeType.Decode32Bits, 0); var dr = new DecodedResult(10); diStorm3.Decode(ci, dr); foreach (var x in dr.Instructions) { var s = String.Format("{0:X} {1} {2}", x.Offset, x.Mnemonic, x.Operands); Console.WriteLine(s); } var dr2 = new DecomposedResult(10); diStorm3.Decompose(ci, dr2); foreach (var y in dr2.Instructions) { if (y.Opcode != Opcode.RET) { var x = diStorm3.Format(ci, y); var s = String.Format("{0:X} {1} {2}", x.Offset, x.Mnemonic, x.Operands); Console.WriteLine(s); } } }
private static unsafe _CodeInfo *AcquireCodeInfoStruct(CodeInfo nci, out GCHandle gch) { var ci = (_CodeInfo *)Malloc(sizeof(_CodeInfo)); if (ci == null) { throw new OutOfMemoryException(); } Memset(ci, 0, sizeof(_CodeInfo)); ci->codeOffset = new IntPtr(nci._codeOffset); gch = GCHandle.Alloc(nci._code, GCHandleType.Pinned); ci->code = (byte *)gch.AddrOfPinnedObject().ToPointer(); ci->codeLen = nci._code.Length; ci->dt = nci._decodeType; ci->features = nci._features; return(ci); }
private static void Main(string[] args) { var buf = new byte[4]; buf[0] = (byte) 0xc3; buf[1] = (byte) 0x33; buf[2] = (byte) 0xc0; buf[3] = (byte) 0xc3; var ci = new CodeInfo((long) 0x1000, buf, DecodeType.Decode32Bits, 0); using (var decoded = DiStorm3.Decode(ci, 10)) { foreach (var x in decoded.Instructions) { var s = String.Format("{0:X} {1} {2}", x.Offset, x.Mnemonic, x.Operands); Console.WriteLine(s); } } using (var decomposed = DiStorm3.Decompose(ci, 10)) { foreach (var y in decomposed.Instructions) { if (y.Opcode == Opcode.RET) continue; var x = DiStorm3.Format(ci, y); var s = String.Format("{0:X} {1} {2}", x.Offset, x.Mnemonic, x.Operands); Console.WriteLine(s); } } }
public static unsafe void Decode(CodeInfo nci, DecodedResult dr) { _CodeInfo* ci = null; _DecodedInst* insts = null; var gch = new GCHandle(); uint usedInstructionsCount = 0; try { if ((ci = AcquireCodeInfoStruct(nci, out gch)) == null) throw new OutOfMemoryException(); var maxInstructions = dr.MaxInstructions; if ((insts = (_DecodedInst*) Malloc(maxInstructions*sizeof (_DecodedInst))) == null) throw new OutOfMemoryException(); distorm_decode64(ci->codeOffset, ci->code, ci->codeLen, ci->dt, insts, (uint) maxInstructions, &usedInstructionsCount); var dinsts = new DecodedInst[usedInstructionsCount]; for (var i = 0; i < usedInstructionsCount; i++) dinsts[i] = CreateDecodedInstObj(&insts[i]); dr.Instructions = dinsts; } finally { /* In case of an error, jInsts will get cleaned automatically. */ if (gch.IsAllocated) gch.Free(); if (ci != null) Free(ci); if (insts != null) Free(insts); } }
public static unsafe DecodedInst Format(CodeInfo nci, DecomposedInst ndi) { var input = new _DInst(); _CodeInfo * ci = null; var gch = new GCHandle(); DecodedInst di; try { ci = AcquireCodeInfoStruct(nci, out gch); if (ci == null) { throw new OutOfMemoryException(); } input.addr = ndi.Address; input.flags = ndi.Flags; input.size = (byte)ndi.Size; input.segment = (byte)ndi._segment; input.ibase = (byte)ndi.Base; input.scale = (byte)ndi.Scale; input.opcode = (ushort)ndi.Opcode; /* unusedPrefixesMask is unused indeed, lol. */ input.meta = (ushort)ndi.Meta; /* Nor usedRegistersMask. */ int opsCount = ndi.Operands.Length; for (var i = 0; i < opsCount; i++) { var op = ndi.Operands[i]; if (op == null) { continue; } input.ops[i].index = (byte)op.Index; input.ops[i].type = op.Type; input.ops[i].size = (ushort)op.Size; } if (ndi.Imm != null) { input.imm.qword = ndi.Imm.Imm; } if (ndi.Disp != null) { input.disp = ndi.Disp.Displacement; input.dispSize = (byte)ndi.Disp.Size; } _DecodedInst output; distorm_format64(ci, &input, &output); di = CreateDecodedInstObj(&output); } finally { if (gch.IsAllocated) { gch.Free(); } if (ci != null) { Free(ci); } } return(di); }
public static unsafe void Decompose(CodeInfo nci, DecomposedResult ndr) { _CodeInfo *ci = null; _DInst * insts = null; var gch = new GCHandle(); var usedInstructionsCount = 0; try { if ((ci = AcquireCodeInfoStruct(nci, out gch)) == null) { throw new OutOfMemoryException(); } var maxInstructions = ndr.MaxInstructions; if ((insts = (_DInst *)Malloc(maxInstructions * sizeof(_DInst))) == null) { throw new OutOfMemoryException(); } distorm_decompose64(ci, insts, maxInstructions, &usedInstructionsCount); var dinsts = new DecomposedInst[usedInstructionsCount]; for (var i = 0; i < usedInstructionsCount; i++) { var di = new DecomposedInst { Address = insts[i].addr, Flags = insts[i].flags, Size = insts[i].size, _segment = insts[i].segment, Base = insts[i].ibase, Scale = insts[i].scale, Opcode = (Opcode)insts[i].opcode, UnusedPrefixesMask = insts[i].unusedPrefixesMask, Meta = insts[i].meta, RegistersMask = insts[i].usedRegistersMask, ModifiedFlagsMask = insts[i].modifiedFlagsMask, TestedFlagsMask = insts[i].testedFlagsMask, UndefinedFlagsMask = insts[i].undefinedFlagsMask }; /* Simple fields: */ /* Immediate variant. */ var immVariant = new DecomposedInst.ImmVariant { Imm = insts[i].imm.qword, Size = 0 }; /* The size of the immediate is in one of the operands, if at all. Look for it below. Zero by default. */ /* Count operands. */ var operandsNo = 0; for (operandsNo = 0; operandsNo < _DInst.OPERANDS_NO; operandsNo++) { if (insts[i].ops[operandsNo].type == OperandType.None) { break; } } var ops = new Operand[operandsNo]; for (var j = 0; j < operandsNo; j++) { if (insts[i].ops[j].type == OperandType.Imm) { /* Set the size of the immediate operand. */ immVariant.Size = insts[i].ops[j].size; } var op = new Operand { Type = insts[i].ops[j].type, Index = insts[i].ops[j].index, Size = insts[i].ops[j].size }; ops[j] = op; } di.Operands = ops; /* Attach the immediate variant. */ di.Imm = immVariant; /* Displacement variant. */ var disp = new DecomposedInst.DispVariant { Displacement = insts[i].disp, Size = insts[i].dispSize }; di.Disp = disp; dinsts[i] = di; } ndr.Instructions = dinsts; } finally { if (gch.IsAllocated) { gch.Free(); } if (ci != null) { Free(ci); } if (insts != null) { Free(insts); } } }
private static unsafe CodeInfoStruct* AcquireCodeInfoStruct(CodeInfo nci, out GCHandle gch) { var ci = (CodeInfoStruct*) Malloc(sizeof (CodeInfoStruct)); if (ci == null) throw new OutOfMemoryException(); Memset(ci, 0, sizeof (CodeInfoStruct)); ci->codeOffset = new IntPtr(nci._codeOffset); if (nci._code == null && nci._codePtr != null && nci._codeLength > 0) { ci->code = nci._codePtr; ci->codeLen = nci._codeLength; gch = new GCHandle(); } else { gch = GCHandle.Alloc(nci._code, GCHandleType.Pinned); ci->code = (byte*) gch.AddrOfPinnedObject().ToPointer(); ci->codeLen = nci._code.Length; } ci->dt = nci._decodeType; ci->features = nci._features; return ci; }
public static unsafe DecodedInstruction Format(CodeInfo nci, DecomposedInstruction ndi) { var input = new DecomposedInstructionStruct(); CodeInfoStruct *ci = null; var gch = new GCHandle(); DecodedInstruction di; try { ci = AcquireCodeInfoStruct(nci, out gch); if (ci == null) throw new OutOfMemoryException(); input.Address = ndi.Address; input.Flags = ndi.Flags; input.Size = (byte) ndi.Size; input.segment = (byte) ndi._segment; input.ibase = (byte) ndi.Base; input.scale = (byte) ndi.Scale; input.Opcode = ndi.Opcode; /* unusedPrefixesMask is unused indeed, lol. */ input.meta = (byte) ndi.Meta; /* Nor usedRegistersMask. */ int opsCount = ndi.Operands.Length; for (var i = 0; i < opsCount; i++) { var op = ndi.Operands[i]; if (op == null) continue; input.Operands[i].index = (byte) op.Index; input.Operands[i].Type = op.Type; input.Operands[i].Size = (ushort) op.Size; } if (ndi.ImmediateValue != null) input.ImmediateValue = ndi.ImmediateValue.ImmediateValue; if (ndi.Displacement != null) { input.Displacement = ndi.Displacement.Displacement; input.dispSize = (byte) ndi.Displacement.Size; } DecodedInstructionStruct output; distorm_format64(ci, &input, &output); di = DecodedInstruction.FromUnsafe(&output); } finally { if (gch.IsAllocated) gch.Free(); if (ci != null) Free(ci); } return di; }
public static unsafe DecomposedResult Decompose(CodeInfo nci, int maxInstructions) { CodeInfoStruct* ci = null; DecomposedInstructionStruct* insts = null; var gch = new GCHandle(); var usedInstructionsCount = 0; try { if ((ci = AcquireCodeInfoStruct(nci, out gch)) == null) throw new OutOfMemoryException(); var dr = new DecomposedResult(maxInstructions); distorm_decompose64(ci, dr.InstructionsPointer, maxInstructions, &usedInstructionsCount); dr.UsedInstructions = usedInstructionsCount; return dr; } finally { if (gch.IsAllocated) gch.Free(); if (ci != null) Free(ci); } }
public static unsafe DecodedResult Decode(CodeInfo nci, int maxInstructions) { var gch = new GCHandle(); uint usedInstructionsCount = 0; CodeInfoStruct* ci = null; try { ci = AcquireCodeInfoStruct(nci, out gch); var dr = new DecodedResult(maxInstructions); distorm_decode64(ci->codeOffset, ci->code, ci->codeLen, ci->dt, dr.InstructionsPointer, (uint) maxInstructions, &usedInstructionsCount); dr.UsedInstructionCount = (int) usedInstructionsCount; return dr; } finally { if (gch.IsAllocated) gch.Free(); if (ci != null) Free(ci); } }
public static unsafe DecodedInst Format(CodeInfo nci, DecomposedInst ndi) { var input = new _DInst(); _CodeInfo *ci = null; var gch = new GCHandle(); DecodedInst di; try { ci = AcquireCodeInfoStruct(nci, out gch); if (ci == null) throw new OutOfMemoryException(); input.addr = ndi.Address; input.flags = ndi.Flags; input.size = (byte) ndi.Size; input.segment = (byte) ndi._segment; input.ibase = (byte) ndi.Base; input.scale = (byte) ndi.Scale; input.opcode = (ushort) ndi.Opcode; /* unusedPrefixesMask is unused indeed, lol. */ input.meta = (byte) ndi.Meta; /* Nor usedRegistersMask. */ int opsCount = ndi.Operands.Length; for (var i = 0; i < opsCount; i++) { var op = ndi.Operands[i]; if (op == null) continue; input.ops[i].index = (byte) op.Index; input.ops[i].type = op.Type; input.ops[i].size = (ushort) op.Size; } if (ndi.Imm != null) input.imm.qword = ndi.Imm.Imm; if (ndi.Disp != null) { input.disp = ndi.Disp.Displacement; input.dispSize = (byte) ndi.Disp.Size; } _DecodedInst output; distorm_format64(ci, &input, &output); di = CreateDecodedInstObj(&output); } finally { if (gch.IsAllocated) gch.Free(); if (ci != null) Free(ci); } return di; }
public static unsafe void Decompose(CodeInfo nci, DecomposedResult ndr) { _CodeInfo* ci = null; _DInst* insts = null; var gch = new GCHandle(); var usedInstructionsCount = 0; try { if ((ci = AcquireCodeInfoStruct(nci, out gch)) == null) throw new OutOfMemoryException(); var maxInstructions = ndr.MaxInstructions; if ((insts = (_DInst*) Malloc(maxInstructions*sizeof (_DInst))) == null) throw new OutOfMemoryException(); distorm_decompose64(ci, insts, maxInstructions, &usedInstructionsCount); var dinsts = new DecomposedInst[usedInstructionsCount]; for (var i = 0; i < usedInstructionsCount; i++) { var di = new DecomposedInst { Address = insts[i].addr, Flags = insts[i].flags, Size = insts[i].size, _segment = insts[i].segment, Base = insts[i].ibase, Scale = insts[i].scale, Opcode = (Opcode) insts[i].opcode, UnusedPrefixesMask = insts[i].unusedPrefixesMask, Meta = insts[i].meta, RegistersMask = insts[i].usedRegistersMask, ModifiedFlagsMask = insts[i].modifiedFlagsMask, TestedFlagsMask = insts[i].testedFlagsMask, UndefinedFlagsMask = insts[i].undefinedFlagsMask }; /* Simple fields: */ /* Immediate variant. */ var immVariant = new DecomposedInst.ImmVariant { Imm = insts[i].imm.qword, Size = 0 }; /* The size of the immediate is in one of the operands, if at all. Look for it below. Zero by default. */ /* Count operands. */ var operandsNo = 0; for (operandsNo = 0; operandsNo < _DInst.OPERANDS_NO; operandsNo++) { if (insts[i].ops[operandsNo].type == OperandType.None) break; } var ops = new Operand[operandsNo]; for (var j = 0; j < operandsNo; j++) { if (insts[i].ops[j].type == OperandType.Imm) { /* Set the size of the immediate operand. */ immVariant.Size = insts[i].ops[j].size; } var op = new Operand { Type = insts[i].ops[j].type, Index = insts[i].ops[j].index, Size = insts[i].ops[j].size }; ops[j] = op; } di.Operands = ops; /* Attach the immediate variant. */ di.Imm = immVariant; /* Displacement variant. */ var disp = new DecomposedInst.DispVariant { Displacement = insts[i].disp, Size = insts[i].dispSize }; di.Disp = disp; dinsts[i] = di; } ndr.Instructions = dinsts; } finally { if (gch.IsAllocated) gch.Free(); if (ci != null) Free(ci); if (insts != null) Free(insts); } }