예제 #1
0
        private void SerializeMetadata(ByteBufferRef buf, int cursor)
        {
            Deserializer.WriteULong(HeaderMagic, buf, cursor);
            cursor += sizeof(ulong);
            var hmac = CalculateHMAC(DataPageOffset, FileSize, Signatures);

            buf.CopyFrom(cursor, hmac);
            cursor += HMACSize;
            Deserializer.WriteInt(DataPageOffset, buf, cursor);
            cursor += sizeof(int);
            Deserializer.WriteUInt(FileSize, buf, cursor);
            cursor += sizeof(uint);
            Deserializer.WriteInt(Signatures.Length, buf, cursor);
            cursor += sizeof(int);
            buf.CopyFrom(cursor, Signatures);
        }
예제 #2
0
        public void Write(ByteBufferRef buf, int offset)
        {
            Contract.Requires(offset >= 0);
            Contract.Requires(offset + Size <= buf.Length);

            Deserializer.WriteUInt(HandleOrPtr.Value.ToUInt32(), buf, offset); offset += sizeof(uint);
            Deserializer.WriteUInt(cookie.Value.ToUInt32(), buf, offset); offset      += sizeof(uint);
            Deserializer.WriteUInt(code, buf, offset); offset         += sizeof(uint);
            Deserializer.WriteUInt(flags, buf, offset); offset        += sizeof(uint);
            Deserializer.WriteUInt(sender_pid, buf, offset); offset   += sizeof(uint);
            Deserializer.WriteUInt(sender_euid, buf, offset); offset  += sizeof(uint);
            Deserializer.WriteUInt(data_size, buf, offset); offset    += sizeof(uint);
            Deserializer.WriteUInt(offsets_size, buf, offset); offset += sizeof(uint);
            Deserializer.WriteUInt(data_buffer.Value.ToUInt32(), buf, offset); offset  += sizeof(uint);
            Deserializer.WriteUInt(data_offsets.Value.ToUInt32(), buf, offset); offset += sizeof(uint);
        }
예제 #3
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);
        }
예제 #4
0
 private static void SetU32(ByteBufferRef arr, int off, uint val)
 {
     Deserializer.WriteUInt(val, arr, off);
 }