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; }
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); }