/* * Load the credential for an application. * * Currently ExpressOS does not deal with key management, etc. * It uses a static key for all application. */ internal static Credential GetCredential(ASCIIString name, Process process) { Contract.Ensures(Contract.Result <Credential>().GhostOwner == process); var key = new byte[] { 0xc8, 0x43, 0xae, 0x85, 0x9b, 0x63, 0x4b, 0x72, 0x1b, 0x14, 0xcf, 0x6d, 0xa8, 0xf9, 0x6f, 0x1d }; // 1003 == AID_GRAPHICS return(new Credential(process, 1003, key)); }
/* * Load the credential for an application. * * Currently ExpressOS does not deal with key management, etc. * It uses a static key for all application. */ internal static Credential GetCredential(ASCIIString name, Process process) { Contract.Ensures(Contract.Result<Credential>().GhostOwner == process); var key = new byte[] { 0xc8, 0x43, 0xae, 0x85, 0x9b, 0x63, 0x4b, 0x72, 0x1b, 0x14, 0xcf, 0x6d, 0xa8, 0xf9, 0x6f, 0x1d }; // 1003 == AID_GRAPHICS return new Credential(process, 1003, key); }
public static int Parse(int helperPid, File file, Process proc, ref UserPtr stackTop) { Contract.Requires(file.GhostOwner == proc); Contract.Requires(proc.Space.GhostOwner == proc); var buf = new byte[Size]; uint pos = 0; if (file.Read(buf, ref pos) != buf.Length) return -ErrorCode.EINVAL; var eh = Read(buf); if (eh.type != ELF32Header.ELF_TYPE_EXECUTABLE || eh.ProgramHeaderOffest == 0) return -ErrorCode.ENOEXEC; proc.EntryPoint = eh.EntryPoint; ELF32ProgramHeader ph = new ELF32ProgramHeader(); var ret = FindInterpreter(file, eh, ref ph); if (ret == -ErrorCode.EINVAL) { Arch.Console.WriteLine("Malformed ELF file"); return ret; } else if (ret == 0) { var interpreterBuf = new byte[ph.FileSize]; pos = ph.offset; if (file.Read(interpreterBuf, ref pos) != interpreterBuf.Length) return -ErrorCode.EINVAL; var interpreterName = new ASCIIString(interpreterBuf); ErrorCode ec; var interpreter_inode = Arch.ArchFS.Open(helperPid, interpreterName, 0, 0, out ec); if (interpreter_inode == null) return -ErrorCode.ENOENT; var interpreter = new File(proc, interpreter_inode, FileFlags.ReadOnly, 0); /* * Parse the information of linker. * * This function will also override the entry point. */ if (Parse(helperPid, interpreter, proc, ref stackTop) != 0) return -ErrorCode.EINVAL; // So now let's copy the program header to the top of the stack, and push auxlirary vectors PushProgramHeaderAndAuxliraryVectors(proc, file, eh, ref stackTop); } return MapInSegments(file, proc, eh); }
internal Process(ASCIIString name, AndroidApplicationInfo appInfo) { Contract.Ensures(Credential.GhostOwner == this); Contract.Ensures(Space.GhostOwner == this); Contract.Ensures(Files.GhostOwner == this); this.AppInfo = appInfo; SFSFilePrefix = Util.StringToByteArray(appInfo.DataDir, false); this.Files = new FileDescriptorTable(this); const uint UTCB_BOTTOM = 0xc0000000; var utcb = new Pointer(UTCB_BOTTOM); // TODO: expose interface to change the name of the process var archAddressSpace = Arch.ArchAddressSpace.Create(name, utcb, Arch.ArchDefinition.UTCBSizeShift + Arch.ArchDefinition.MaxThreadPerTaskLog2); this.Space = new AddressSpace(this, archAddressSpace); this.Credential = SecurityManager.GetCredential(name, this); }
private static ASCIIString[] CreateEnvpArrayWithWorkspace(ASCIIString[] envp, Process proc, int workspace_fd, uint workspace_size) { var res = new ASCIIString[envp.Length + 1]; for (int i = 0; i < envp.Length; ++i) { res[i] = envp[i]; } var inode = new Arch.ArchINode(workspace_fd, workspace_size, proc.helperPid); var file = new File(proc, inode, FileFlags.ReadOnly, 0); var fd = proc.GetUnusedFd(); proc.InstallFd(fd, file); var s = "ANDROID_PROPERTY_WORKSPACE=" + fd.ToString() + "," + workspace_size.ToString(); res[envp.Length] = new ASCIIString(s); return(res); }
public static int Parse(int helperPid, File file, Process proc, ref UserPtr stackTop) { Contract.Requires(file.GhostOwner == proc); Contract.Requires(proc.Space.GhostOwner == proc); var buf = new byte[Size]; uint pos = 0; if (file.Read(buf, ref pos) != buf.Length) { return(-ErrorCode.EINVAL); } var eh = Read(buf); if (eh.type != ELF32Header.ELF_TYPE_EXECUTABLE || eh.ProgramHeaderOffest == 0) { return(-ErrorCode.ENOEXEC); } proc.EntryPoint = eh.EntryPoint; ELF32ProgramHeader ph = new ELF32ProgramHeader(); var ret = FindInterpreter(file, eh, ref ph); if (ret == -ErrorCode.EINVAL) { Arch.Console.WriteLine("Malformed ELF file"); return(ret); } else if (ret == 0) { var interpreterBuf = new byte[ph.FileSize]; pos = ph.offset; if (file.Read(interpreterBuf, ref pos) != interpreterBuf.Length) { return(-ErrorCode.EINVAL); } var interpreterName = new ASCIIString(interpreterBuf); ErrorCode ec; var interpreter_inode = Arch.ArchFS.Open(helperPid, interpreterName, 0, 0, out ec); if (interpreter_inode == null) { return(-ErrorCode.ENOENT); } var interpreter = new File(proc, interpreter_inode, FileFlags.ReadOnly, 0); /* * Parse the information of linker. * * This function will also override the entry point. */ if (Parse(helperPid, interpreter, proc, ref stackTop) != 0) { return(-ErrorCode.EINVAL); } // So now let's copy the program header to the top of the stack, and push auxlirary vectors PushProgramHeaderAndAuxliraryVectors(proc, file, eh, ref stackTop); } return(MapInSegments(file, proc, eh)); }
// // We do sync read for this one, since it's simpler.. // public static Process CreateProcess(ASCIIString path, ASCIIString[] argv, ASCIIString[] envp, AndroidApplicationInfo appInfo) { var proc = new Process(path, appInfo); Utils.Assert(!proc.Space.impl._value.isInvalid); uint addr; int workspace_fd; uint workspace_size; proc.helperPid = Arch.IPCStubs.linux_sys_take_helper(out addr, out workspace_fd, out workspace_size); if (proc.helperPid < 0) { Arch.Console.WriteLine("CreateProcess: cannot get helper"); return null; } proc.ShadowBinderVMStart = addr; ErrorCode ec; var inode = Arch.ArchFS.Open(proc.helperPid, path, 0, 0, out ec); if (inode == null) { Arch.Console.WriteLine("CreateProcess: cannot open file"); return null; } var stack_top = new UserPtr(INITIAL_STACK_LOCATION); // 4M Initial stack var stack_size = 4096 * Arch.ArchDefinition.PageSize; proc.Space.AddStackMapping(stack_top, stack_size); stack_top += stack_size; var augmented_envp = CreateEnvpArrayWithWorkspace(envp, proc, workspace_fd, workspace_size); var envp_ptr = PushCharArray(proc, augmented_envp, ref stack_top); if (envp_ptr == null) { Arch.Console.WriteLine("CreateProcess: Push envp failed"); return null; } var argv_ptr = PushCharArray(proc, argv, ref stack_top); if (argv_ptr == null) { Arch.Console.WriteLine("CreateProcess: Push argv failed"); return null; } stack_top = UserPtr.RoundDown(stack_top); // Parse the ELF file, which might push additional info on to the stack // (i.e., aux vectors when the ELF is dynamically linked) var file = new File(proc, inode, FileFlags.ReadWrite, 0); int ret = ELF32Header.Parse(proc.helperPid, file, proc, ref stack_top); if (ret != 0) { Arch.Console.WriteLine("CreateProcess: Parse ELF file failed"); return null; } //%esp The stack contains the arguments and environment: // 0(%esp) argc // 4(%esp) argv[0] // ... // (4*argc)(%esp) NULL // (4*(argc+1))(%esp) envp[0] // ... // NULL if (PushArgumentPointers(proc, envp_ptr, ref stack_top) != 0) return null; if (PushArgumentPointers(proc, argv_ptr, ref stack_top) != 0) return null; if (PushInt(proc, argv_ptr.Length, ref stack_top) != 0) return null; // Stdio var file_stdout = File.CreateStdout(proc); Contract.Assume(proc.Files.IsAvailableFd(Process.STDOUT_FD)); proc.InstallFd(Process.STDOUT_FD, file_stdout); var file_stderr = File.CreateStdout(proc); Contract.Assume(proc.Files.IsAvailableFd(Process.STDERR_FD)); proc.InstallFd(Process.STDERR_FD, file_stderr); var mainThread = Thread.Create(proc); if (appInfo != null) { var p = appInfo.ToParcel(); Globals.LinuxIPCBuffer.CopyFrom(0, p); Arch.IPCStubs.WriteAppInfo(proc.helperPid, p.Length); } // Start the main thread mainThread.Start(new Pointer(proc.EntryPoint), stack_top.Value); return proc; }
private static UserPtr[] PushCharArray(Process proc, ASCIIString[] arr, ref UserPtr stack_top) { var res = new UserPtr[arr.Length]; for (int i = 0; i < arr.Length; ++i) { // Include the terminator stack_top -= arr[i].Length + 1; res[i] = stack_top; if (stack_top.Write(proc, arr[i].GetByteString()) != 0) return null; } return res; }
private static ASCIIString[] CreateEnvpArrayWithWorkspace(ASCIIString[] envp, Process proc, int workspace_fd, uint workspace_size) { var res = new ASCIIString[envp.Length + 1]; for (int i = 0; i < envp.Length; ++i) res[i] = envp[i]; var inode = new Arch.ArchINode(workspace_fd, workspace_size, proc.helperPid); var file = new File(proc, inode, FileFlags.ReadOnly, 0); var fd = proc.GetUnusedFd(); proc.InstallFd(fd, file); var s = "ANDROID_PROPERTY_WORKSPACE=" + fd.ToString() + "," + workspace_size.ToString(); res[envp.Length] = new ASCIIString(s); return res; }
public const uint CLONE_IO = 0x80000000; /* Clone io context */ // // We do sync read for this one, since it's simpler.. // public static Process CreateProcess(ASCIIString path, ASCIIString[] argv, ASCIIString[] envp, AndroidApplicationInfo appInfo) { var proc = new Process(path, appInfo); Utils.Assert(!proc.Space.impl._value.isInvalid); uint addr; int workspace_fd; uint workspace_size; proc.helperPid = Arch.IPCStubs.linux_sys_take_helper(out addr, out workspace_fd, out workspace_size); if (proc.helperPid < 0) { Arch.Console.WriteLine("CreateProcess: cannot get helper"); return(null); } proc.ShadowBinderVMStart = addr; ErrorCode ec; var inode = Arch.ArchFS.Open(proc.helperPid, path, 0, 0, out ec); if (inode == null) { Arch.Console.WriteLine("CreateProcess: cannot open file"); return(null); } var stack_top = new UserPtr(INITIAL_STACK_LOCATION); // 4M Initial stack var stack_size = 4096 * Arch.ArchDefinition.PageSize; proc.Space.AddStackMapping(stack_top, stack_size); stack_top += stack_size; var augmented_envp = CreateEnvpArrayWithWorkspace(envp, proc, workspace_fd, workspace_size); var envp_ptr = PushCharArray(proc, augmented_envp, ref stack_top); if (envp_ptr == null) { Arch.Console.WriteLine("CreateProcess: Push envp failed"); return(null); } var argv_ptr = PushCharArray(proc, argv, ref stack_top); if (argv_ptr == null) { Arch.Console.WriteLine("CreateProcess: Push argv failed"); return(null); } stack_top = UserPtr.RoundDown(stack_top); // Parse the ELF file, which might push additional info on to the stack // (i.e., aux vectors when the ELF is dynamically linked) var file = new File(proc, inode, FileFlags.ReadWrite, 0); int ret = ELF32Header.Parse(proc.helperPid, file, proc, ref stack_top); if (ret != 0) { Arch.Console.WriteLine("CreateProcess: Parse ELF file failed"); return(null); } //%esp The stack contains the arguments and environment: // 0(%esp) argc // 4(%esp) argv[0] // ... // (4*argc)(%esp) NULL // (4*(argc+1))(%esp) envp[0] // ... // NULL if (PushArgumentPointers(proc, envp_ptr, ref stack_top) != 0) { return(null); } if (PushArgumentPointers(proc, argv_ptr, ref stack_top) != 0) { return(null); } if (PushInt(proc, argv_ptr.Length, ref stack_top) != 0) { return(null); } // Stdio var file_stdout = File.CreateStdout(proc); Contract.Assume(proc.Files.IsAvailableFd(Process.STDOUT_FD)); proc.InstallFd(Process.STDOUT_FD, file_stdout); var file_stderr = File.CreateStdout(proc); Contract.Assume(proc.Files.IsAvailableFd(Process.STDERR_FD)); proc.InstallFd(Process.STDERR_FD, file_stderr); var mainThread = Thread.Create(proc); if (appInfo != null) { var p = appInfo.ToParcel(); Globals.LinuxIPCBuffer.CopyFrom(0, p); Arch.IPCStubs.WriteAppInfo(proc.helperPid, p.Length); } // Start the main thread mainThread.Start(new Pointer(proc.EntryPoint), stack_top.Value); return(proc); }
public static void Initialize() { IPCFilename = new ASCIIString("/dev/binder"); AshmemFileName = new ASCIIString("/dev/ashmem"); CWDStr = new ASCIIString("/"); }
public static void Start(ref BootParam param) { Console.WriteLine("Hello from ExpressOS-Managed"); ArchGlobals.Initialize(ref param); Globals.Initialize(ref param); SyscallProfiler.Initialize(); Misc.Initialize(); FileSystem.Initialize(); AESManaged.Initialize(); SHA1Managed.Initialize(); AndroidApplicationInfo appInfo = new AndroidApplicationInfo(); var appName = "me.haohui.expressos.browserbench"; appInfo.PackageName = appName; appInfo.uid = 1002; appInfo.flags = 0x8be45; appInfo.SourceDir = "/system/app/BrowserBench.apk"; appInfo.DataDir = "/data/data/" + appName; appInfo.Enabled = true; appInfo.TargetSdkVersion = 10; appInfo.Intent = appName + "/" + appName + ".BrowserActivity"; #if false var argv = new ASCIIString[] { new ASCIIString("/system/bin/simple-hello"), }; var envp = new ASCIIString[] { //new ASCIIString("LD_PRELOAD=/system/lib/libr2.so"), //new ASCIIString("HH_DEBUG=1"), }; #elif false var argv = new ASCIIString[] { new ASCIIString("/system/bin/bench-sqlite"), new ASCIIString("/data/data/com.valkyrie/1.db"), }; var envp = new ASCIIString[] { }; #elif false var argv = new ASCIIString[] { new ASCIIString("/system/bin/bench-bootanim"), }; var envp = new ASCIIString[] { new ASCIIString("CLASSPATH=/system/framework/am.jar"), new ASCIIString("PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin"), new ASCIIString("LD_LIBRARY_PATH=/vendor/lib:/system/lib"), new ASCIIString("ANDROID_BOOTLOGO=1"), new ASCIIString("ANDROID_ROOT=/system"), new ASCIIString("ANDROID_ASSETS=/system/app"), new ASCIIString("ANDROID_DATA=/data"), new ASCIIString("EXTERNAL_STORAGE=/mnt/sdcard"), new ASCIIString("ASEC_MOUNTPOINT=/mnt/asec"), new ASCIIString("LOOP_MOUNTPOINT=/mnt/obb"), new ASCIIString("BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar"), // new ASCIIString("LD_PRELOAD=/system/lib/libr2.so"), }; #elif false var argv = new ASCIIString[] { new ASCIIString("/data/presenter"), }; var envp = new ASCIIString[] { new ASCIIString("CLASSPATH=/system/framework/am.jar"), new ASCIIString("PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin"), new ASCIIString("LD_LIBRARY_PATH=/vendor/lib:/system/lib"), new ASCIIString("ANDROID_BOOTLOGO=1"), new ASCIIString("ANDROID_ROOT=/system"), new ASCIIString("ANDROID_ASSETS=/system/app"), new ASCIIString("ANDROID_DATA=/data"), new ASCIIString("EXTERNAL_STORAGE=/mnt/sdcard"), new ASCIIString("ASEC_MOUNTPOINT=/mnt/asec"), new ASCIIString("LOOP_MOUNTPOINT=/mnt/obb"), new ASCIIString("BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar"), new ASCIIString("SLIDES=/data/slides.zip"), }; #elif false var argv = new ASCIIString[] { new ASCIIString("/system/bin/bench-vbinder"), }; var envp = new ASCIIString[] { }; #elif false var argv = new ASCIIString[] { new ASCIIString("/system/xbin/wget"), new ASCIIString("http://128.174.236.238"), }; var envp = new ASCIIString[] { }; #elif false var argv = new ASCIIString[] { new ASCIIString("/system/bin/app_process"), new ASCIIString("/system/bin"), new ASCIIString("com.android.commands.am.Am"), new ASCIIString("start"), new ASCIIString("-a"), new ASCIIString("android.intent.action.MAIN"), new ASCIIString("-n"), new ASCIIString("com.valkyrie/com.valkyrie.HelloAndroidActivity"), }; var envp = new ASCIIString[] { new ASCIIString("CLASSPATH=/system/framework/am.jar"), new ASCIIString("PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin"), new ASCIIString("LD_LIBRARY_PATH=/vendor/lib:/system/lib"), new ASCIIString("ANDROID_BOOTLOGO=1"), new ASCIIString("ANDROID_ROOT=/system"), new ASCIIString("ANDROID_ASSETS=/system/app"), new ASCIIString("ANDROID_DATA=/data"), new ASCIIString("EXTERNAL_STORAGE=/mnt/sdcard"), new ASCIIString("ASEC_MOUNTPOINT=/mnt/asec"), new ASCIIString("LOOP_MOUNTPOINT=/mnt/obb"), new ASCIIString("BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar"), /*new ASCIIString("HH_DEBUG=1"), */ }; #elif true var argv = new ASCIIString[] { new ASCIIString("/system/bin/app_process"), new ASCIIString("/system/bin"), new ASCIIString("android.app.ActivityThread"), }; var envp = new ASCIIString[] { new ASCIIString("CLASSPATH=/system/framework/am.jar"), new ASCIIString("PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin"), new ASCIIString("LD_LIBRARY_PATH=/vendor/lib:/system/lib"), new ASCIIString("ANDROID_BOOTLOGO=1"), new ASCIIString("ANDROID_ROOT=/system"), new ASCIIString("ANDROID_ASSETS=/system/app"), new ASCIIString("ANDROID_DATA=/data"), new ASCIIString("EXTERNAL_STORAGE=/mnt/sdcard"), new ASCIIString("ASEC_MOUNTPOINT=/mnt/asec"), new ASCIIString("LOOP_MOUNTPOINT=/mnt/obb"), new ASCIIString("BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar"), new ASCIIString("HH_DEBUG=1"), /* new ASCIIString("LD_PRELOAD=/libr2.so"), */ }; #else var argv = new ASCIIString[] { new ASCIIString("/system/bin/app_process"), new ASCIIString("-Xgc:preverify"), new ASCIIString("-Xgc:postverify"), new ASCIIString("-Xgc:verifycardtable"), new ASCIIString("/system/bin"), new ASCIIString("android.os.GcTests"), }; var envp = new ASCIIString[] { new ASCIIString("CLASSPATH=/system/framework/frameworkcoretests.jar"), new ASCIIString("PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin"), new ASCIIString("LD_LIBRARY_PATH=/vendor/lib:/system/lib"), new ASCIIString("ANDROID_BOOTLOGO=1"), new ASCIIString("ANDROID_ROOT=/system"), new ASCIIString("ANDROID_ASSETS=/system/app"), new ASCIIString("ANDROID_DATA=/data"), new ASCIIString("EXTERNAL_STORAGE=/mnt/sdcard"), new ASCIIString("ASEC_MOUNTPOINT=/mnt/asec"), new ASCIIString("LOOP_MOUNTPOINT=/mnt/obb"), new ASCIIString("BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar"), new ASCIIString("HH_DEBUG=1"), //new ASCIIString("LD_PRELOAD=/libr2.so"), }; #endif var proc = ExpressOS.Kernel.Exec.CreateProcess(argv[0], argv, envp, appInfo); if (proc == null) Console.WriteLine("Cannot start init"); Globals.SecurityManager.OnActiveProcessChanged(proc); Console.WriteLine("ExpressOS initialized"); Looper.ServerLoop(); }