예제 #1
0
        public static IOVector Deserialize(byte[] buf, int offset)
        {
            Contract.Requires(offset >= 0);
            Contract.Requires(offset + Size <= buf.Length);

            IOVector r;

            r.iov_base = new UserPtr(Deserializer.ReadUInt(buf, offset)); offset += sizeof(uint);
            r.iov_len  = Deserializer.ReadInt(buf, offset);
            return(r);
        }
예제 #2
0
        public static ELF32ProgramHeader Read(byte[] buf)
        {
            Contract.Requires(buf.Length == Size);
            var r = new ELF32ProgramHeader();

            r.type       = Deserializer.ReadUInt(buf, 0);
            r.offset     = Deserializer.ReadUInt(buf, sizeof(uint));
            r.vaddr      = Deserializer.ReadUInt(buf, sizeof(uint) * 2);
            r.paddr      = Deserializer.ReadUInt(buf, sizeof(uint) * 3);
            r.FileSize   = Deserializer.ReadInt(buf, sizeof(uint) * 4);
            r.MemorySize = Deserializer.ReadInt(buf, sizeof(uint) * 5);
            r.flags      = Deserializer.ReadUInt(buf, sizeof(uint) * 6);
            r.align      = Deserializer.ReadUInt(buf, sizeof(uint) * 7);
            return(r);
        }
예제 #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 binder_transaction_data Deserialize(ByteBufferRef buf, int offset)
        {
            Contract.Requires(offset >= 0);
            Contract.Requires(offset + Size <= buf.Length);

            binder_transaction_data r;

            r.HandleOrPtr  = new UserPtr(Deserializer.ReadUInt(buf, offset)); offset += sizeof(uint);
            r.cookie       = new UserPtr(Deserializer.ReadUInt(buf, offset)); offset += sizeof(uint);
            r.code         = Deserializer.ReadUInt(buf, offset); offset += sizeof(uint);
            r.flags        = Deserializer.ReadUInt(buf, offset); offset += sizeof(uint);
            r.sender_pid   = Deserializer.ReadUInt(buf, offset); offset += sizeof(uint);
            r.sender_euid  = Deserializer.ReadUInt(buf, offset); offset += sizeof(uint);
            r.data_size    = Deserializer.ReadUInt(buf, offset); offset += sizeof(uint);
            r.offsets_size = Deserializer.ReadUInt(buf, offset); offset += sizeof(uint);
            r.data_buffer  = new UserPtr(Deserializer.ReadUInt(buf, offset)); offset += sizeof(uint);
            r.data_offsets = new UserPtr(Deserializer.ReadUInt(buf, offset)); offset += sizeof(uint);
            return(r);
        }
예제 #5
0
        private static ELF32Header Read(byte[] buf)
        {
            var r   = new ELF32Header();
            int off = 0;

            r.ident1              = Deserializer.ReadLong(buf, off); off += sizeof(long);
            r.ident2              = Deserializer.ReadLong(buf, off); off += sizeof(long);
            r.type                = Deserializer.ReadUShort(buf, off); off += sizeof(ushort);
            r.machine             = Deserializer.ReadUShort(buf, off); off += sizeof(ushort);
            r.version             = Deserializer.ReadUInt(buf, off); off += sizeof(uint);
            r.EntryPoint          = Deserializer.ReadUInt(buf, off); off += sizeof(uint);
            r.ProgramHeaderOffest = Deserializer.ReadUInt(buf, off); off += sizeof(uint);
            r.SectionHeaderOffset = Deserializer.ReadUInt(buf, off); off += sizeof(uint);
            r.flags               = Deserializer.ReadUInt(buf, off); off += sizeof(uint);
            r.ELFHeaderSize       = Deserializer.ReadUShort(buf, off); off += sizeof(ushort);
            r.ProgramHeaderSize   = Deserializer.ReadUShort(buf, off); off += sizeof(ushort);
            r.NumOfProgramHeader  = Deserializer.ReadUShort(buf, off); off += sizeof(ushort);
            r.SectionHeaderSize   = Deserializer.ReadUShort(buf, off); off += sizeof(ushort);
            r.NumOfSectionHeader  = Deserializer.ReadUShort(buf, off); off += sizeof(ushort);
            r.shstrndx            = Deserializer.ReadUShort(buf, off); off += sizeof(ushort);
            return(r);
        }
예제 #6
0
        internal int Marshal(UserPtr writeBuf, int size)
        {
            if (size < 0 || size > buf.Length)
            {
                return(-ErrorCode.EINVAL);
            }

            ReadCursor = 0;

            // Copy the full data into the buffer, but don't increment the read pointer yet.
            var r = writeBuf.Read(current, buf, size);

            if (r != 0)
            {
                return(-1);
            }

            // Advance the cursor
            WriteCursor = size;
            // parse the command
            while (ReadCursor < size)
            {
                if (ReadCursor + sizeof(uint) > buf.Length)
                {
                    return(-ErrorCode.ENOMEM);
                }

                var cmd = Deserializer.ReadUInt(buf, ReadCursor);
                ReadCursor += sizeof(uint);

                switch (cmd)
                {
                case BinderINode.BC_INCREFS:
                case BinderINode.BC_ACQUIRE:
                case BinderINode.BC_RELEASE:
                case BinderINode.BC_DECREFS:
                    ReadCursor += sizeof(int);
                    break;

                case BinderINode.BC_INCREFS_DONE:
                case BinderINode.BC_ACQUIRE_DONE:
                case BinderINode.BC_REQUEST_DEATH_NOTIFICATION:
                case BinderINode.BC_CLEAR_DEATH_NOTIFICATION:
                    ReadCursor += Pointer.Size * 2;
                    break;

                case BinderINode.BC_ATTEMPT_ACQUIRE:
                case BinderINode.BC_ACQUIRE_RESULT:
                    // Unimplemented in Android IPC
                    return(-ErrorCode.EINVAL);

                case BinderINode.BC_FREE_BUFFER:
                {
                    if (ReadCursor + sizeof(uint) > buf.Length)
                    {
                        return(-ErrorCode.ENOMEM);
                    }

                    var addr    = Deserializer.ReadUInt(buf, ReadCursor);
                    var new_val = addr - current.Parent.binderVMStart.Value.ToUInt32() + current.Parent.ShadowBinderVMStart;
                    Deserializer.WriteUInt(new_val, buf, ReadCursor);
                    ReadCursor += Pointer.Size;
                    break;
                }

                case BinderINode.BC_TRANSACTION:
                case BinderINode.BC_REPLY:
                {
                    var ret = MarshalTransaction();
                    if (ret < 0)
                    {
                        return(ret);
                    }

                    break;
                }

                case BinderINode.BC_REGISTER_LOOPER:
                case BinderINode.BC_ENTER_LOOPER:
                case BinderINode.BC_EXIT_LOOPER:
                    break;

                default:
                    Arch.Console.Write("binder: unsupported IPC primitive ");
                    Arch.Console.Write(cmd);
                    Arch.Console.WriteLine();
                    return(-1);
                }
            }

            r = AppendPatchTable();
            if (r != 0)
            {
                return(-1);
            }

            //Arch.Console.Write("Dump write buffer ");
            //Arch.Console.Write(current.Tid);
            //Arch.Console.WriteLine();
            //DumpBuf(new Pointer(buf.Location), size);
            return(0);
        }
예제 #7
0
 private static uint GetU32(byte[] b, int offset)
 {
     return(Deserializer.ReadUInt(b, offset));
 }
예제 #8
0
 private static uint GetU32(ByteBufferRef b, int offset)
 {
     return(Deserializer.ReadUInt(b, offset));
 }
예제 #9
0
        // Handling unpatch buffer(i.e. offset relative to the start of the buffer

        private static int PatchReadBuffer(Thread current, ByteBufferRef marshaledBuffer)
        {
            Contract.Requires(current.Parent != null);
            var cursor = 0;

            while (cursor < marshaledBuffer.Length)
            {
                if (cursor + sizeof(uint) > marshaledBuffer.Length)
                {
                    return(-ErrorCode.ENOMEM);
                }

                /*
                 * Here the code extend the value from uint to ulong to work around a bug
                 * in code contract.
                 *
                 * See http://social.msdn.microsoft.com/Forums/en-US/codecontracts/thread/ca123a3e-6e0d-4045-9caf-a95b49df223e
                 * for more details.
                 */
                var cmd = (ulong)Deserializer.ReadUInt(marshaledBuffer, cursor);
                cursor += sizeof(uint);

                switch (cmd)
                {
                case BinderINode.BR_INCREFS:
                case BinderINode.BR_ACQUIRE:
                case BinderINode.BR_RELEASE:
                case BinderINode.BR_DECREFS:
                    cursor += 2 * sizeof(uint);
                    break;

                case BinderINode.BR_NOOP:
                case BinderINode.BR_TRANSACTION_COMPLETE:
                case BinderINode.BR_SPAWN_LOOPER:
                    break;

                case BinderINode.BR_TRANSACTION:
                case BinderINode.BR_REPLY:
                {
                    if (cursor + binder_transaction_data.Size > marshaledBuffer.Length)
                    {
                        return(-ErrorCode.ENOMEM);
                    }

                    var tr = binder_transaction_data.Deserialize(marshaledBuffer, cursor);

                    var ret = PatchReadTransaction(current, new Pointer(marshaledBuffer.Location), ref tr);
                    if (ret < 0)
                    {
                        return(ret);
                    }

                    tr.Write(marshaledBuffer, cursor);
                    cursor += binder_transaction_data.Size;
                    break;
                }

                default:
                    Arch.Console.Write("binder::patchReadBuffer: unsupported IPC primitive ");
                    Arch.Console.Write(cmd);
                    Arch.Console.WriteLine();
                    return(-1);
                }
            }
            return(0);
        }