コード例 #1
0
 public DmdDataStreamImpl(ProcessBinaryReader reader) => this.reader = reader;
コード例 #2
0
ファイル: ProcessDataStream.cs プロジェクト: haise0/dnSurgeon
 public ProcessDataStream(ProcessBinaryReader reader)
 {
     this.reader = reader;
     basePos     = reader.Position;
 }
コード例 #3
0
        public IBinaryReader CreateBodyReader(uint bodyRva, uint mdToken)
        {
            // bodyRva can be 0 if it's a dynamic module. this.module.Address will also be 0.
            if (!module.IsDynamic && bodyRva == 0)
            {
                return(null);
            }

            var func   = module.CorModule.GetFunctionFromToken(mdToken);
            var ilCode = func?.ILCode;

            if (ilCode == null)
            {
                return(null);
            }
            ulong addr = ilCode.Address;

            if (addr == 0)
            {
                return(null);
            }

            Debug.Assert(addr >= FAT_HEADER_SIZE);
            if (addr < FAT_HEADER_SIZE)
            {
                return(null);
            }

            if (module.IsDynamic)
            {
                // It's always a fat header, see COMDynamicWrite::SetMethodIL() (coreclr/src/vm/comdynamic.cpp)
                addr -= FAT_HEADER_SIZE;
                var reader = new ProcessBinaryReader(new CorProcessReader(module.Process), 0);
                Debug.Assert((reader.Position = (long)addr) == (long)addr);
                Debug.Assert((reader.ReadByte() & 7) == 3);
                Debug.Assert((reader.Position = (long)addr + 4) == (long)addr + 4);
                Debug.Assert(reader.ReadUInt32() == ilCode.Size);
                reader.Position = (long)addr;
                return(reader);
            }
            else
            {
                uint codeSize = ilCode.Size;
                // The address to the code is returned but we want the header. Figure out whether
                // it's the 1-byte or fat header.
                var  reader       = new ProcessBinaryReader(new CorProcessReader(module.Process), 0);
                uint locVarSigTok = func.LocalVarSigToken;
                bool isBig        = codeSize >= 0x40 || (locVarSigTok & 0x00FFFFFF) != 0;
                if (!isBig)
                {
                    reader.Position = (long)addr - 1;
                    byte b    = reader.ReadByte();
                    var  type = b & 7;
                    if ((type == 2 || type == 6) && (b >> 2) == codeSize)
                    {
                        // probably small header
                        isBig = false;
                    }
                    else
                    {
                        reader.Position = (long)addr - (long)FAT_HEADER_SIZE + 4;
                        uint headerCodeSize     = reader.ReadUInt32();
                        uint headerLocVarSigTok = reader.ReadUInt32();
                        bool valid = headerCodeSize == codeSize &&
                                     (locVarSigTok & 0x00FFFFFF) == (headerLocVarSigTok & 0x00FFFFFF) &&
                                     ((locVarSigTok & 0x00FFFFFF) == 0 || locVarSigTok == headerLocVarSigTok);
                        Debug.Assert(valid);
                        if (!valid)
                        {
                            return(null);
                        }
                        isBig = true;
                    }
                }

                reader.Position = (long)addr - (long)(isBig ? FAT_HEADER_SIZE : 1);
                return(reader);
            }
        }