Example #1
0
        public PeRunner(PeRunnerOptions opt)
        {
            _nextStart = opt.StartAddress;
            Initialize(_nextStart);
            using (this.EnterExit())
            {
                // load any predefined exports
                _psx = new Psx(this);
                _exports.Add("libpsxscl.so", BizExvoker.GetExvoker(_psx, CallingConventionAdapters.Waterbox));
                _emu = new Emu(this);
                _exports.Add("libemuhost.so", BizExvoker.GetExvoker(_emu, CallingConventionAdapters.Waterbox));
                _syscalls = new Syscalls(this);
                _exports.Add("__syscalls", BizExvoker.GetExvoker(_syscalls, CallingConventionAdapters.Waterbox));

                // load and connect all modules, starting with the executable
                var todoModules = new Queue <string>();
                todoModules.Enqueue(opt.Filename);

                while (todoModules.Count > 0)
                {
                    var moduleName = todoModules.Dequeue();
                    if (!_exports.ContainsKey(moduleName))
                    {
                        var    path   = Path.Combine(opt.Path, moduleName);
                        var    gzpath = path + ".gz";
                        byte[] data;
                        if (File.Exists(gzpath))
                        {
                            using (var fs = new FileStream(gzpath, FileMode.Open, FileAccess.Read))
                            {
                                data = Util.DecompressGzipFile(fs);
                            }
                        }
                        else
                        {
                            data = File.ReadAllBytes(path);
                        }

                        var module = new PeWrapper(moduleName, data, _nextStart);
                        ComputeNextStart(module.Size);
                        AddMemoryBlock(module.Memory, moduleName);
                        _savestateComponents.Add(module);
                        _disposeList.Add(module);

                        _exports.Add(moduleName, module);
                        _modules.Add(module);
                        foreach (var name in module.ImportsByModule.Keys)
                        {
                            todoModules.Enqueue(name);
                        }
                    }
                }

                _libcpatch          = new LibcPatch(this);
                _exports["libc.so"] = new PatchImportResolver(_exports["libc.so"], BizExvoker.GetExvoker(_libcpatch, CallingConventionAdapters.Waterbox));

                ConnectAllImports();

                // load all heaps
                _heap          = CreateHeapHelper(opt.SbrkHeapSizeKB, "brk-heap", true);
                _sealedheap    = CreateHeapHelper(opt.SealedHeapSizeKB, "sealed-heap", true);
                _invisibleheap = CreateHeapHelper(opt.InvisibleHeapSizeKB, "invisible-heap", false);
                _plainheap     = CreateHeapHelper(opt.PlainHeapSizeKB, "plain-heap", true);

                if (opt.MmapHeapSizeKB != 0)
                {
                    _mmapheap = new MapHeap(_nextStart, opt.MmapHeapSizeKB * 1024, "mmap-heap");
                    _mmapheap.Memory.Activate();
                    ComputeNextStart(opt.MmapHeapSizeKB * 1024);
                    AddMemoryBlock(_mmapheap.Memory, "mmap-heap");
                    _savestateComponents.Add(_mmapheap);
                    _disposeList.Add(_mmapheap);
                }

                _syscalls.Init();

                Console.WriteLine("About to enter unmanaged code");
                if (!OSTailoredCode.IsUnixHost && !System.Diagnostics.Debugger.IsAttached && Win32Imports.IsDebuggerPresent())
                {
                    // this means that GDB or another unconventional debugger is attached.
                    // if that's the case, and it's observing this core, it probably wants a break
                    System.Diagnostics.Debugger.Break();
                }

                // run unmanaged init code
                var libcEnter = _exports["libc.so"].GetProcAddrOrThrow("__libc_entry_routine");
                var psxInit   = _exports["libpsxscl.so"].GetProcAddrOrThrow("__psx_init");

                var del = (LibcEntryRoutineD)CallingConventionAdapters.Waterbox.GetDelegateForFunctionPointer(libcEnter, typeof(LibcEntryRoutineD));
                // the current mmglue code doesn't use the main pointer at all, and this just returns
                del(IntPtr.Zero, psxInit, 0);

                foreach (var m in _modules)
                {
                    m.RunGlobalCtors();
                }

                /*try
                 * {
                 *      _modules[0].RunExeEntry();
                 *      //throw new InvalidOperationException("main() returned!");
                 * }
                 * catch //(EndOfMainException)
                 * {
                 * }
                 * _modules[0].RunGlobalCtors();
                 * foreach (var m in _modules.Skip(1))
                 * {
                 *      if (!m.RunDllEntry())
                 *              throw new InvalidOperationException("DllMain() returned false");
                 *      m.RunGlobalCtors();
                 * }*/
            }
        }
Example #2
0
        public WaterboxHost(WaterboxOptions opt)
        {
            _nextStart = opt.StartAddress;
            Initialize(_nextStart);
            using (this.EnterExit())
            {
                _emu      = new EmuLibc(this);
                _syscalls = new Syscalls(this);

                _imports = new PatchImportResolver(
                    NotImplementedSyscalls.Instance,
                    BizExvoker.GetExvoker(_emu, CallingConventionAdapters.Waterbox),
                    BizExvoker.GetExvoker(_syscalls, CallingConventionAdapters.Waterbox)
                    );

                if (true)
                {
                    var moduleName = opt.Filename;

                    var    path   = Path.Combine(opt.Path, moduleName);
                    var    gzpath = path + ".gz";
                    byte[] data;
                    if (File.Exists(gzpath))
                    {
                        using var fs = new FileStream(gzpath, FileMode.Open, FileAccess.Read);
                        data         = Util.DecompressGzipFile(fs);
                    }
                    else
                    {
                        data = File.ReadAllBytes(path);
                    }

                    _module = new ElfLoader(moduleName, data, _nextStart, opt.SkipCoreConsistencyCheck, opt.SkipMemoryConsistencyCheck);

                    ComputeNextStart(_module.Memory.Size);
                    AddMemoryBlock(_module.Memory, moduleName);
                    _savestateComponents.Add(_module);
                    _disposeList.Add(_module);
                }

                ConnectAllImports();

                // load all heaps
                _heap          = CreateHeapHelper(opt.SbrkHeapSizeKB, "brk-heap", true);
                _sealedheap    = CreateHeapHelper(opt.SealedHeapSizeKB, "sealed-heap", true);
                _invisibleheap = CreateHeapHelper(opt.InvisibleHeapSizeKB, "invisible-heap", false);
                _plainheap     = CreateHeapHelper(opt.PlainHeapSizeKB, "plain-heap", true);

                if (opt.MmapHeapSizeKB != 0)
                {
                    _mmapheap = new MapHeap(_nextStart, opt.MmapHeapSizeKB * 1024, "mmap-heap");
                    _mmapheap.Memory.Activate();
                    ComputeNextStart(opt.MmapHeapSizeKB * 1024);
                    AddMemoryBlock(_mmapheap.Memory, "mmap-heap");
                    _savestateComponents.Add(_mmapheap);
                    _disposeList.Add(_mmapheap);
                }

                System.Diagnostics.Debug.WriteLine($"About to enter unmanaged code for {opt.Filename}");
                if (!OSTailoredCode.IsUnixHost && !System.Diagnostics.Debugger.IsAttached && Win32Imports.IsDebuggerPresent())
                {
                    // this means that GDB or another unconventional debugger is attached.
                    // if that's the case, and it's observing this core, it probably wants a break
                    System.Diagnostics.Debugger.Break();
                }

                _module.RunNativeInit();
            }
        }