Ejemplo n.º 1
0
        /*
         * Testing whether the current process is getting the focus.
         *
         * See frameworks/base/core/java/android/view/IWindow.aidl and
         * frameworks/base/services/java/com/android/server/WindowManagerService.java
         * for more details.
         */
        private static bool GainingWindowFocus(Thread current, binder_transaction_data tr)
        {
            const int OP_windowFocusChanged = 5;

            if (tr.code != OP_windowFocusChanged || tr.data_size != 0x3c)
            {
                return(false);
            }

            var buf = InspectionBuffer;

            tr.data_buffer.Read(current, buf);

            bool header_matched = true;

            for (var i = 0; i < WindowFocusChangedHeader.Length && header_matched; ++i)
            {
                if (buf[i] != WindowFocusChangedHeader[i])
                {
                    header_matched = false;
                }
            }

            if (!header_matched)
            {
                return(false);
            }

            int get_focus;

            (tr.data_buffer + WindowFocusChangedHeader.Length).Read(current, out get_focus);
            return(get_focus == 1);
        }
Ejemplo n.º 2
0
        /*
         * Heuristic for determing whether a transaction is mapping the screen buffer
         * into the process.
         *
         * See frameworks/base/libs/ui/GraphicBuffer.cpp for more details.
         */
        private static bool IsScreenSharingTransaction(Thread current, ref binder_transaction_data tr)
        {
            int        a0, a1, a2;
            const uint SystemEuid = 1000;

            if (tr.sender_euid != SystemEuid || tr.data_size != 0x54 || tr.offsets_size != 4)
            {
                return(false);
            }

            tr.data_buffer.Read(current, out a0);
            (tr.data_buffer + sizeof(int)).Read(current, out a1);
            (tr.data_buffer + sizeof(int) * 2).Read(current, out a2);

            return(a0 == 0x3c && a1 == 0x1 && a2 == 0x47424652);
        }
Ejemplo n.º 3
0
        /*
         * Testing whether the current process is getting the focus.
         *
         * See frameworks/base/core/java/android/view/IWindow.aidl and
         * frameworks/base/services/java/com/android/server/WindowManagerService.java
         * for more details.
         */
        private static bool GainingWindowFocus(Thread current, binder_transaction_data tr)
        {
            const int OP_windowFocusChanged = 5;
            if (tr.code != OP_windowFocusChanged || tr.data_size != 0x3c)
                return false;

            var buf = InspectionBuffer;
            tr.data_buffer.Read(current, buf, buf.Length);

            bool header_matched = true;
            for (var i = 0; i < WindowFocusChangedHeader.Length && header_matched; ++i)
            {
                if (buf[i] != WindowFocusChangedHeader[i])
                    header_matched = false;
            }

            if (!header_matched)
                return false;

            int get_focus;
            (tr.data_buffer + WindowFocusChangedHeader.Length).Read(current, out get_focus);
            return get_focus == 1;
        }
Ejemplo n.º 4
0
        private static int PatchReadTransaction(Thread current, Pointer marshaledBufferStart, ref binder_transaction_data tr)
        {
            if (tr.data_size != 0)
                tr.data_buffer += current.Parent.binderVMStart.Value.ToUInt32();

            if (tr.offsets_size != 0)
                tr.data_offsets += current.Parent.binderVMStart.Value.ToUInt32();

            if (GainingWindowFocus(current, tr))
                Globals.SecurityManager.OnActiveProcessChanged(current.Parent);

            for (var off_ptr = tr.data_offsets; off_ptr < tr.data_offsets + tr.offsets_size; off_ptr += 4)
            {
                var fp = new flat_binder_object();
                int off;
                if (off_ptr.Read(current, out off) != 0)
                {
                    Arch.Console.Write("Can't get offset");
                    return -1;
                }

                var fp_ptr = tr.data_buffer + off;
                if (fp_ptr.Read(current, out fp) != 0)
                {
                    Arch.Console.Write("Read fp failed, ptr:");
                    Arch.Console.Write(fp_ptr.Value.ToInt32());
                    Arch.Console.WriteLine();
                    return -1;
                }

                //Arch.Console.Write("off_ptr:");
                //Arch.Console.Write(tr->data_offsets.Value.ToUInt32());
                //Arch.Console.Write(" Off end:");
                //Arch.Console.Write((tr->data_offsets + tr->offsets_size).Value.ToUInt32());
                //Arch.Console.WriteLine();

                switch (fp.type)
                {
                    case BinderINode.BINDER_TYPE_FD:
                        {
                            var proc = current.Parent;
                            var linux_fd = fp.binderOrHandle.Value.ToInt32();

                            GenericINode inode;
                            if (IsScreenSharingTransaction(current, ref tr))
                                inode = new ScreenBufferINode(linux_fd, proc.helperPid);
                            else
                                inode = new BinderSharedINode(linux_fd, proc.helperPid);

                            int fd = proc.GetUnusedFd();
                            proc.InstallFd(fd, new File(proc, inode, FileSystem.O_RDWR, 0));
                            // Patch the data structure
                            (fp_ptr + flat_binder_object.OFFSET_OF_HANDLE).Write(current, fd);
                        }
                        break;

                    case BinderINode.BINDER_TYPE_HANDLE:
                        // sliently ignore it (it seems safe)
                        break;

                    default:
                        Arch.Console.Write("BinderINode::PatchReadTransaction ignoring ");
                        Arch.Console.Write(fp.type);
                        Arch.Console.WriteLine();
                        break;
                }
            }

            return 0;
        }
Ejemplo n.º 5
0
        /*
         * Heuristic for determing whether a transaction is mapping the screen buffer
         * into the process.
         *
         * See frameworks/base/libs/ui/GraphicBuffer.cpp for more details.
         */
        private static bool IsScreenSharingTransaction(Thread current, ref binder_transaction_data tr)
        {
            int a0, a1, a2;
            const uint SystemEuid = 1000;
            if (tr.sender_euid != SystemEuid || tr.data_size != 0x54 || tr.offsets_size != 4)
                return false;

            tr.data_buffer.Read(current, out a0);
            (tr.data_buffer + sizeof(int)).Read(current, out a1);
            (tr.data_buffer + sizeof(int) * 2).Read(current, out a2);

            return a0 == 0x3c && a1 == 0x1 && a2 == 0x47424652;
        }
Ejemplo n.º 6
0
        private static int PatchReadTransaction(Thread current, Pointer marshaledBufferStart, ref binder_transaction_data tr)
        {
            Contract.Requires(current.Parent != null);

            if (tr.data_size != 0)
            {
                tr.data_buffer += current.Parent.binderVMStart.Value.ToUInt32();
            }

            if (tr.offsets_size != 0)
            {
                tr.data_offsets += current.Parent.binderVMStart.Value.ToUInt32();
            }

            if (GainingWindowFocus(current, tr))
            {
                Globals.SecurityManager.OnActiveProcessChanged(current.Parent);
            }

            for (var off_ptr = tr.data_offsets; off_ptr < tr.data_offsets + tr.offsets_size; off_ptr += 4)
            {
                var fp = new flat_binder_object();
                int off;
                if (off_ptr.Read(current, out off) != 0)
                {
                    Arch.Console.Write("Can't get offset");
                    return(-1);
                }

                var fp_ptr = tr.data_buffer + off;
                if (fp_ptr.Read(current, out fp) != 0)
                {
                    Arch.Console.Write("Read fp failed, ptr:");
                    Arch.Console.Write(fp_ptr.Value.ToInt32());
                    Arch.Console.WriteLine();
                    return(-1);
                }

                //Arch.Console.Write("off_ptr:");
                //Arch.Console.Write(tr->data_offsets.Value.ToUInt32());
                //Arch.Console.Write(" Off end:");
                //Arch.Console.Write((tr->data_offsets + tr->offsets_size).Value.ToUInt32());
                //Arch.Console.WriteLine();

                switch (fp.type)
                {
                case BinderINode.BINDER_TYPE_FD:
                {
                    var proc     = current.Parent;
                    var linux_fd = fp.binderOrHandle.Value.ToInt32();

                    GenericINode inode;
                    if (IsScreenSharingTransaction(current, ref tr))
                    {
                        inode = new ScreenBufferINode(linux_fd, proc.helperPid);
                    }
                    else
                    {
                        inode = new BinderSharedINode(linux_fd, proc.helperPid);
                    }

                    int fd = proc.GetUnusedFd();
                    proc.InstallFd(fd, new File(proc, inode, FileSystem.O_RDWR, 0));
                    // Patch the data structure
                    (fp_ptr + flat_binder_object.OFFSET_OF_HANDLE).Write(current, fd);
                }
                break;

                case BinderINode.BINDER_TYPE_HANDLE:
                    // sliently ignore it (it seems safe)
                    break;

                default:
                    Arch.Console.Write("BinderINode::PatchReadTransaction ignoring ");
                    Arch.Console.Write(fp.type);
                    Arch.Console.WriteLine();
                    break;
                }
            }

            return(0);
        }