public static unsafe DecomposedInstruction FromUnsafe(DecomposedInstructionStruct* srcInst)
        {
            var di = new DecomposedInstruction {
            Address = srcInst->Address,
            Flags = srcInst->Flags,
            Size = srcInst->Size,
            _segment = srcInst->segment,
            Base = srcInst->ibase,
            Scale = srcInst->scale,
            Opcode = srcInst->Opcode,
            UnusedPrefixesMask = srcInst->UnusedPrefixesMask,
            Meta = srcInst->meta,
            RegistersMask = srcInst->UsedRegistersMask,
            ModifiedFlagsMask = srcInst->modifiedFlagsMask,
            TestedFlagsMask = srcInst->testedFlagsMask,
            UndefinedFlagsMask = srcInst->undefinedFlagsMask
              };

              /* Simple fields: */

              /* Immediate variant. */
              var immVariant = new ImmVariant {
            ImmediateValue = srcInst->ImmediateValue,
            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 < DecomposedInstructionStruct.OPERANDS_NO; operandsNo++)
              {
            if (srcInst->Operands[operandsNo].Type == OperandType.None)
              break;
              }

              var ops = new Operand[operandsNo];

              for (var j = 0; j < operandsNo; j++)
              {
            var srcOp = srcInst->Operands[j];
            if (srcOp.Type == OperandType.Immediate)
            {
              /* Set the size of the immediate operand. */
              immVariant.Size = srcInst->Operands[j].Size;
            }

            var op = new Operand
            {
              Type = srcOp.Type,
              Index = srcOp.index,
              Size = srcOp.Size
            };

            ops[j] = op;
              }
              di.Operands = ops;

              /* Attach the immediate variant. */
              di.ImmediateValue = immVariant;

              /* Displacement variant. */
              var disp = new DispVariant
              {
            Displacement = srcInst->Displacement,
            Size = srcInst->dispSize
              };

              di.Displacement = disp;
              return di;
        }
Esempio n. 2
0
    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);
      }
    }