Пример #1
0
        internal void Encrypt()
        {
            Contract.Requires(CurrentState == State.Empty || CurrentState == State.Decrypted);
            Contract.Ensures(CurrentState == State.Encrypted);

            var aes = new AESManaged();

            aes.SetEncryptKey(Owner.Credential.SFSEncryptKey, 128);
            Contract.Assert(Arch.ArchDefinition.PageSize % AESManaged.AES_BLOCK_SIZE == 0);

            for (int i = 0; i < Arch.ArchDefinition.PageSize / AESManaged.AES_BLOCK_SIZE; ++i)
            {
                var block = Buffer.Slice(i * AESManaged.AES_BLOCK_SIZE, AESManaged.AES_BLOCK_SIZE);
                aes.Encrypt(block, block);
            }

            CurrentState = State.Encrypted;
        }
Пример #2
0
        private int Write(Process process, Pointer dst, int length)
        {
            var bytesLeft = length;

            var src     = _value;
            var dst_buf = new ByteBufferRef(dst.ToIntPtr(), length);
            var cursor  = 0;

            while (bytesLeft > 0)
            {
                var region = process.Space.Find(src);

                // Invalid mapping
                if (region == null || region.IsFixed)
                {
                    return(bytesLeft);
                }

                var off         = Arch.ArchDefinition.PageOffset(src.ToUInt32());
                var virtualAddr = process.Space.UserToVirt(new UserPtr(src));

                if (virtualAddr == Pointer.Zero)
                {
                    // Page isn't present, try to bring it in.
                    uint permission;

                    Pager.HandlePageFault(process, MemoryRegion.FAULT_MASK, src, Pointer.Zero, out virtualAddr, out permission);

                    if (virtualAddr == Pointer.Zero)
                    {
                        break;
                    }
                }

                var virtual_page = Arch.ArchDefinition.PageIndex(virtualAddr.ToUInt32());
                var page_buf     = new ByteBufferRef(new IntPtr(virtual_page), Arch.ArchDefinition.PageSize);

                var b = Arch.ArchDefinition.PageSize - off;
                var bytesTobeCopied = b > bytesLeft ? bytesLeft : b;

                var dst_buf_page = page_buf.Slice(off, bytesTobeCopied);
                for (var i = 0; i < bytesTobeCopied; ++i)
                {
                    dst_buf_page.Set(i, dst_buf.Get(cursor + i));
                }

                bytesLeft -= bytesTobeCopied;
                src       += bytesTobeCopied;
                cursor    += bytesTobeCopied;
            }

            return(bytesLeft);
        }
Пример #3
0
        private static int UnmarshalDataEntries(Thread current, ByteBufferRef buf, ref sys_binder_write_desc desc)
        {
            var cursor = desc.read_consumed;
            var i      = 0;

            while (i < desc.patch_table_entries && cursor < buf.Length)
            {
                if (cursor + 2 * sizeof(uint) > buf.Length)
                {
                    return(-1);
                }

                var offset = Deserializer.ReadUInt(buf, cursor);
                cursor += sizeof(uint);
                var length = (int)Deserializer.ReadUInt(buf, cursor);
                cursor += sizeof(int);

                if (cursor + length > buf.Length)
                {
                    return(-1);
                }

                //Arch.Console.Write("UnmarshalDataEntries: offset=");
                //Arch.Console.Write(offset);
                //Arch.Console.Write(" length=");
                //Arch.Console.Write(length);
                //Arch.Console.WriteLine();

                //BinderIPCMarshaler.DumpBuf(marshaledPtr, length);
                var b = buf.Slice(cursor, length);

                if (b.Length + offset > current.Parent.binderVMSize)
                {
                    return(-1);
                }

                Contract.Assert(offset + b.Length <= current.Parent.binderVMSize);
                if ((current.Parent.binderVMStart + offset).Write(current, b) != 0)
                {
                    return(-1);
                }

                cursor += length;
                i++;
            }
            return(0);
        }
Пример #4
0
        public static int UnmarshalReadBuffer(Thread thr, ByteBufferRef completionBuf, ref sys_binder_write_desc desc, UserPtr readBuffer, int readBufferSize)
        {
            var proc         = thr.Parent;
            var marshaledPtr = new Pointer(completionBuf.Location);

            //Arch.Console.Write("read_consumed:");
            //Arch.Console.Write(desc.read_consumed);
            //BinderIPCMarshaler.DumpBuf(new Pointer(completionBuf.Location), (int)desc.read_consumed);

            if (proc.binderVMStart == UserPtr.Zero)
            {
                Arch.Console.WriteLine("proc.binderVMStart == UserPtr.Zero");
                return(-ErrorCode.EFAULT);
            }

            if (UnmarshalDataEntries(thr, completionBuf, ref desc) != 0)
            {
                Arch.Console.WriteLine("UnmarshalDataEntries failed");
                return(-ErrorCode.ENOMEM);
            }

            if (desc.read_consumed > completionBuf.Length)
            {
                Arch.Console.WriteLine("UnmarshalReadBuffer: bad input");
                return(-ErrorCode.ENOMEM);
            }

            // Patch pointers and convert file descriptors
            var b = completionBuf.Slice(0, desc.read_consumed);

            if (PatchReadBuffer(thr, b) != 0)
            {
                Arch.Console.WriteLine("Failed to patch read buffer");
                return(-ErrorCode.EINVAL);
            }

            if (readBuffer.Write(thr, marshaledPtr, desc.read_consumed) != 0)
            {
                Arch.Console.WriteLine("readBuffer.Write failed");
                return(-ErrorCode.ENOMEM);
            }

            return(0);
        }
Пример #5
0
        public static int UnmarshalReadBuffer(Thread thr, ByteBufferRef completionBuf, ref sys_binder_write_desc desc, UserPtr readBuffer, int readBufferSize)
        {
            var proc = thr.Parent;
            var marshaledPtr = new Pointer(completionBuf.Location);

            //Arch.Console.Write("read_consumed:");
            //Arch.Console.Write(desc.read_consumed);
            //BinderIPCMarshaler.DumpBuf(new Pointer(completionBuf.Location), (int)desc.read_consumed);

            if (proc.binderVMStart == UserPtr.Zero)
            {
                Arch.Console.WriteLine("proc.binderVMStart == UserPtr.Zero");
                return -ErrorCode.EFAULT;
            }

            if (UnmarshalDataEntries(thr, completionBuf, ref desc) != 0)
            {
                Arch.Console.WriteLine("UnmarshalDataEntries failed");
                return -ErrorCode.ENOMEM;
            }

            if (desc.read_consumed > completionBuf.Length)
            {
                Arch.Console.WriteLine("UnmarshalReadBuffer: bad input");
                return -ErrorCode.ENOMEM;
            }

            // Patch pointers and convert file descriptors
            var b = completionBuf.Slice(0, desc.read_consumed);
            if (PatchReadBuffer(thr, b) != 0)
            {
                Arch.Console.WriteLine("Failed to patch read buffer");
                return -ErrorCode.EINVAL;
            }

            if (readBuffer.Write(thr, marshaledPtr, desc.read_consumed) != 0)
            {
                Arch.Console.WriteLine("readBuffer.Write failed");
                return -ErrorCode.ENOMEM;
            }

            return 0;
        }
Пример #6
0
        private int MarshalDataSegments(int size, ref UserPtr data, int offset)
        {
            Contract.Requires(size >= 0);
            Contract.Ensures(ReadCursor == Contract.OldValue(ReadCursor));

            if (size == 0)
            {
                return(0);
            }

            if (size > buf.Length - WriteCursor)
            {
                return(-ErrorCode.ENOMEM);
            }

            var b = buf.Slice(WriteCursor, size);

            // Post condition for ByteBufferRef
            Contract.Assume(b.Length == size);
            var r = data.Read(current, b, size);

            if (r != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            data         = new UserPtr((uint)WriteCursor);
            WriteCursor += size;

            // Add patch entry
            if (CurrentPatchEntry >= kPatchTableSize)
            {
                return(-ErrorCode.ENOMEM);
            }

            patchTable[CurrentPatchEntry++] = ReadCursor + offset;

            return(0);
        }
Пример #7
0
        private int Write(Process process, Pointer dst, int length)
        {
            var bytesLeft = length;

            var src = _value;
            var dst_buf = new ByteBufferRef(dst.ToIntPtr(), length);
            var cursor = 0;
            while (bytesLeft > 0)
            {
                var region = process.Space.Find(src);

                // Invalid mapping
                if (region == null || region.IsFixed)
                {
                    return bytesLeft;
                }

                var off = Arch.ArchDefinition.PageOffset(src.ToUInt32());
                var virtualAddr = process.Space.UserToVirt(new UserPtr(src));

                if (virtualAddr == Pointer.Zero)
                {
                    // Page isn't present, try to bring it in.
                    uint permission;

                    Pager.HandlePageFault(process, MemoryRegion.FAULT_MASK, src, Pointer.Zero, out virtualAddr, out permission);

                    if (virtualAddr == Pointer.Zero)
                        break;
                }

                var virtual_page = Arch.ArchDefinition.PageIndex(virtualAddr.ToUInt32());
                var page_buf = new ByteBufferRef(new IntPtr(virtual_page), Arch.ArchDefinition.PageSize);

                var b = Arch.ArchDefinition.PageSize - off;
                var bytesTobeCopied = b > bytesLeft ? bytesLeft : b;

                var dst_buf_page = page_buf.Slice(off, bytesTobeCopied);
                for (var i = 0; i < bytesTobeCopied; ++i)
                {
                    dst_buf_page.Set(i, dst_buf.Get(cursor + i));
                }

                bytesLeft -= bytesTobeCopied;
                src += bytesTobeCopied;
                cursor += bytesTobeCopied;
            }

            return bytesLeft;
        }
Пример #8
0
        private int Read(Process process, ByteBufferRef buffer, bool is_string)
        {
            var bytesLeft = is_string ? buffer.Length - 1 : buffer.Length;
            var bytesRead = 0;

            var src = _value;

            while (bytesLeft > 0)
            {
                var region = process.Space.Find(src);

                // Invalid mapping
                if (region == null || region.IsFixed)
                    break;

                var off = Arch.ArchDefinition.PageOffset(src.ToUInt32());
                var virtualAddr = process.Space.UserToVirt(new UserPtr(src));

                if (virtualAddr == Pointer.Zero)
                {
                    uint permission;

                    Pager.HandlePageFault(process, MemoryRegion.FAULT_MASK, _value, Pointer.Zero, out virtualAddr, out permission);

                    if (virtualAddr == Pointer.Zero)
                        break;
                }

                var virtual_page = Arch.ArchDefinition.PageIndex(virtualAddr.ToUInt32());
                var page_buf = new ByteBufferRef(new IntPtr(virtual_page), Arch.ArchDefinition.PageSize);

                var b = Arch.ArchDefinition.PageSize - off;
                var bytesTobeCopied = b > bytesLeft ? bytesLeft : b;

                var src_buf = page_buf.Slice(off, bytesTobeCopied);

                if (is_string)
                {
                    var res = Util.CopyString(ref buffer, bytesRead, src_buf);
                    bytesRead += res;

                    if (res < bytesTobeCopied)
                    {
                        // We're done.
                        break;
                    }
                }
                else
                {
                    for (var i = 0; i < bytesTobeCopied; ++i)
                    {
                        buffer.Set(i + bytesRead, src_buf.Get(i));
                    }
                    bytesRead += bytesTobeCopied;
                }

                bytesLeft -= bytesTobeCopied;
                src += bytesTobeCopied;
            }

            if (is_string)
            {
                buffer.Set(bytesRead, 0);
            }
            return bytesRead;
        }
Пример #9
0
        private int Read(Process process, ByteBufferRef buffer, bool is_string)
        {
            var bytesLeft = is_string ? buffer.Length - 1 : buffer.Length;
            var bytesRead = 0;

            var src = _value;

            while (bytesLeft > 0)
            {
                var region = process.Space.Find(src);

                // Invalid mapping
                if (region == null || region.IsFixed)
                {
                    break;
                }

                var off         = Arch.ArchDefinition.PageOffset(src.ToUInt32());
                var virtualAddr = process.Space.UserToVirt(new UserPtr(src));

                if (virtualAddr == Pointer.Zero)
                {
                    uint permission;

                    Pager.HandlePageFault(process, MemoryRegion.FAULT_MASK, _value, Pointer.Zero, out virtualAddr, out permission);

                    if (virtualAddr == Pointer.Zero)
                    {
                        break;
                    }
                }

                var virtual_page = Arch.ArchDefinition.PageIndex(virtualAddr.ToUInt32());
                var page_buf     = new ByteBufferRef(new IntPtr(virtual_page), Arch.ArchDefinition.PageSize);

                var b = Arch.ArchDefinition.PageSize - off;
                var bytesTobeCopied = b > bytesLeft ? bytesLeft : b;

                var src_buf = page_buf.Slice(off, bytesTobeCopied);

                if (is_string)
                {
                    var res = Util.CopyString(ref buffer, bytesRead, src_buf);
                    bytesRead += res;

                    if (res < bytesTobeCopied)
                    {
                        // We're done.
                        break;
                    }
                }
                else
                {
                    for (var i = 0; i < bytesTobeCopied; ++i)
                    {
                        buffer.Set(i + bytesRead, src_buf.Get(i));
                    }
                    bytesRead += bytesTobeCopied;
                }

                bytesLeft -= bytesTobeCopied;
                src       += bytesTobeCopied;
            }

            if (is_string)
            {
                buffer.Set(bytesRead, 0);
            }
            return(bytesRead);
        }
Пример #10
0
        private static int UnmarshalDataEntries(Thread current, ByteBufferRef buf, ref sys_binder_write_desc desc)
        {
            var cursor = desc.read_consumed;
            var i = 0;
            while (i < desc.patch_table_entries && cursor < buf.Length)
            {
                if (cursor + 2 * sizeof(uint) > buf.Length)
                    return -1;

                var offset = Deserializer.ReadUInt(buf, cursor);
                cursor += sizeof(uint);
                var length = (int)Deserializer.ReadUInt(buf, cursor);
                cursor += sizeof(int);

                if (cursor + length > buf.Length)
                    return -1;

                //Arch.Console.Write("UnmarshalDataEntries: offset=");
                //Arch.Console.Write(offset);
                //Arch.Console.Write(" length=");
                //Arch.Console.Write(length);
                //Arch.Console.WriteLine();

                //BinderIPCMarshaler.DumpBuf(marshaledPtr, length);
                var b = buf.Slice(cursor, length);

                if ((current.Parent.binderVMStart + offset).Write(current, b) != 0)
                    return -1;

                cursor += length;
                i++;
            }
            return 0;
        }