Пример #1
0
        private byte[] ReadArgumentBytes(DkmStackWalkFrame frame)
        {
            // In the x64 calling convention, the first 4 arguments are passed in registers, and the
            // remaining arguments are passed on the stack.  However, space for all arguments is
            // allocated on the stack, even if the argument is passed one of the first 4 which is passed
            // by register.  Furthermore, a minimum of 4*WordSize bytes is allocated on the stack for
            // function parameters, even if the function accepts less than 4 arguments.
            int bytesRequired = 0;

            foreach (FunctionParameter param in _parameters)
            {
                bytesRequired += param.GetPaddedSize(WordSize);
            }
            byte[] stack = new byte[bytesRequired];

            ulong rsp = frame.Registers.GetStackPointer();

            // The first word on the stack is the return address, similar to in x86 calling conventions.
            frame.Process.ReadMemory(rsp + 8, DkmReadMemoryFlags.None, stack);

            // Since everything is padded, we should have a multiple-of-8 bytes.  The first four
            // arguments may or may not actually be on the stack since it's register spill-over space,
            // but they are guaranteed to be in RCX, RDX, R8, and R9 respectively.  So get their values
            // from the registers and then write them into our copy of the stack.
            Invariants.Assert(bytesRequired % 8 == 0);
            if (bytesRequired > 0)
            {
                ulong rcx = frame.VscxGetRegisterValue64(CpuRegister.Rcx);
                BitConverter.GetBytes(rcx).CopyTo(stack, 0);
            }
            if (bytesRequired > 8)
            {
                ulong rdx = frame.VscxGetRegisterValue64(CpuRegister.Rdx);
                BitConverter.GetBytes(rdx).CopyTo(stack, 8);
            }
            if (bytesRequired > 16)
            {
                ulong r8 = frame.VscxGetRegisterValue64(CpuRegister.R8);
                BitConverter.GetBytes(r8).CopyTo(stack, 16);
            }
            if (bytesRequired > 24)
            {
                ulong r9 = frame.VscxGetRegisterValue64(CpuRegister.R9);
                BitConverter.GetBytes(r9).CopyTo(stack, 24);
            }

            return(stack);
        }
Пример #2
0
    private byte[] ReadArgumentBytes(DkmStackWalkFrame frame) {
      // In the x64 calling convention, the first 4 arguments are passed in registers, and the 
      // remaining arguments are passed on the stack.  However, space for all arguments is
      // allocated on the stack, even if the argument is passed one of the first 4 which is passed 
      // by register.  Furthermore, a minimum of 4*WordSize bytes is allocated on the stack for
      // function parameters, even if the function accepts less than 4 arguments.
      int bytesRequired = 0;
      foreach (FunctionParameter param in _parameters)
        bytesRequired += param.GetPaddedSize(WordSize);
      byte[] stack = new byte[bytesRequired];

      ulong rsp = frame.Registers.GetStackPointer();
      // The first word on the stack is the return address, similar to in x86 calling conventions.
      frame.Process.ReadMemory(rsp + 8, DkmReadMemoryFlags.None, stack);

      // Since everything is padded, we should have a multiple-of-8 bytes.  The first four
      // arguments may or may not actually be on the stack since it's register spill-over space,
      // but they are guaranteed to be in RCX, RDX, R8, and R9 respectively.  So get their values 
      // from the registers and then write them into our copy of the stack.
      Debug.Assert(bytesRequired % 8 == 0);
      if (bytesRequired > 0) {
        ulong rcx = frame.VscxGetRegisterValue64(CpuRegister.Rcx);
        BitConverter.GetBytes(rcx).CopyTo(stack, 0);
      }
      if (bytesRequired > 8) {
        ulong rdx = frame.VscxGetRegisterValue64(CpuRegister.Rdx);
        BitConverter.GetBytes(rdx).CopyTo(stack, 8);
      }
      if (bytesRequired > 16) {
        ulong r8 = frame.VscxGetRegisterValue64(CpuRegister.R8);
        BitConverter.GetBytes(r8).CopyTo(stack, 16);
      }
      if (bytesRequired > 24) {
        ulong r9 = frame.VscxGetRegisterValue64(CpuRegister.R9);
        BitConverter.GetBytes(r9).CopyTo(stack, 24);
      }

      return stack;
    }