public int sceKernelLoadModuleWithStream(Func<Stream> GetStreamAction, string Path, uint Flags, SceKernelLMOption* SceKernelLMOption) { var Module = new HleModuleGuest(PspEmulatorContext); try { Path = Path.ToLowerInvariant(); if (Path.StartsWith(@"disc0:/PSP_GAME/USRDIR/kmodule")) { throw (new Exception("Ignore kmodule!")); } if ( Path.EndsWith(@"/libatrac3plus.prx") || Path.EndsWith(@"/videocodec.prx") || Path.EndsWith(@"/audiocodec.prx") || Path.EndsWith(@"/mpeg.prx") || Path.EndsWith(@"/mpegbase.prx") || Path.EndsWith(@"/libfont.prx") || false) { Logger.Warning("Ignore {0}!", Path); throw (new Exception("Ignore " + Path + "!")); //var ModuleId = Modules.Create(new HleModule()); //Module.ID = ModuleId; //return ModuleId; } var ModuleStream = GetStreamAction(); var HleModuleGuest = Loader.LoadModule( ModuleStream, new PspMemoryStream(PspMemory), MemoryManager.GetPartition(HleMemoryManager.Partitions.User), ModuleManager, "", ModuleName: Path, IsMainModule: false ); var SceModulePartition = MemoryManager.GetPartition(HleMemoryManager.Partitions.Kernel0).Allocate(sizeof(SceModule)); var SceModulePtr = (SceModule*)PspMemory.PspAddressToPointerSafe(SceModulePartition.Low, Marshal.SizeOf(typeof(SceModule))); SceModulePtr->Attributes = HleModuleGuest.ModuleInfo.ModuleAtributes; SceModulePtr->Version = HleModuleGuest.ModuleInfo.ModuleVersion; SceModulePtr->ModuleName = HleModuleGuest.ModuleInfo.Name; SceModulePtr->GP = HleModuleGuest.ModuleInfo.GP; SceModulePtr->ent_top = HleModuleGuest.ModuleInfo.ExportsStart; SceModulePtr->ent_size = HleModuleGuest.ModuleInfo.ExportsEnd - HleModuleGuest.ModuleInfo.ExportsStart; SceModulePtr->stub_top = HleModuleGuest.ModuleInfo.ImportsStart; SceModulePtr->stub_size = HleModuleGuest.ModuleInfo.ImportsEnd - HleModuleGuest.ModuleInfo.ImportsStart; Module.ModuleInfo = HleModuleGuest.ModuleInfo; Module.InitInfo = HleModuleGuest.InitInfo; Module.Loaded = true; Module.SceModuleStructPartition = SceModulePartition; //Loader.InitInfo.GP } catch (Exception Exception) { Console.WriteLine(Exception); Module.Loaded = false; } var ModuleId = Modules.Create(Module); Module.ID = ModuleId; return ModuleId; }
public void _LoadFile(string fileName) { //GC.Collect(); SetVirtualFolder(Path.GetDirectoryName(fileName)); var memoryStream = new PspMemoryStream(PspMemory); var arguments = new[] { "ms0:/PSP/GAME/virtual/EBOOT.PBP", }; Stream loadStream = File.OpenRead(fileName); //using () { var elfLoadStreamTry = new List <Stream>(); //Stream ElfLoadStream = null; var format = new FormatDetector().DetectSubType(loadStream); string title = null; switch (format) { case FormatDetector.SubType.Pbp: { var pbp = new Pbp().Load(loadStream); elfLoadStreamTry.Add(pbp[Pbp.Types.PspData]); Logger.TryCatch(() => { var paramSfo = new Psf().Load(pbp[Pbp.Types.ParamSfo]); if (paramSfo.EntryDictionary.ContainsKey("TITLE")) { title = (string)paramSfo.EntryDictionary["TITLE"]; } if (paramSfo.EntryDictionary.ContainsKey("PSP_SYSTEM_VER")) { HleConfig.FirmwareVersion = paramSfo.EntryDictionary["PSP_SYSTEM_VER"].ToString(); } }); } break; case FormatDetector.SubType.Elf: elfLoadStreamTry.Add(loadStream); break; case FormatDetector.SubType.Dax: case FormatDetector.SubType.Cso: case FormatDetector.SubType.Iso: { arguments[0] = "disc0:/PSP/GAME/SYSDIR/EBOOT.BIN"; var iso = SetIso(fileName); Logger.TryCatch(() => { var paramSfo = new Psf().Load(iso.Root.Locate("/PSP_GAME/PARAM.SFO").Open()); title = (string)paramSfo.EntryDictionary["TITLE"]; }); var filesToTry = new[] { "/PSP_GAME/SYSDIR/BOOT.BIN", "/PSP_GAME/SYSDIR/EBOOT.BIN", "/PSP_GAME/SYSDIR/EBOOT.OLD", }; foreach (var fileToTry in filesToTry) { try { elfLoadStreamTry.Add(iso.Root.Locate(fileToTry).Open()); } catch (Exception e) { Console.WriteLine(e); } //if (ElfLoadStream.Length != 0) break; } /* * if (ElfLoadStream.Length == 0) * { * throw (new Exception(String.Format("{0} files are empty", String.Join(", ", FilesToTry)))); * } */ } break; default: throw (new NotImplementedException("Can't load format '" + format + "'")); } Exception loadException = null; HleModuleGuest hleModuleGuest = null; foreach (var elfLoadStream in elfLoadStreamTry) { try { loadException = null; if (elfLoadStream.Length < 256) { throw(new InvalidProgramException("File too short")); } hleModuleGuest = Loader.LoadModule( elfLoadStream, memoryStream, MemoryManager.GetPartition(MemoryPartitions.User), ModuleManager, title, moduleName: fileName, isMainModule: true ); loadException = null; break; } catch (InvalidProgramException e) { loadException = e; } } if (loadException != null) { throw loadException; } RegisterSyscalls(); const uint startArgumentAddress = 0x08000100; var endArgumentAddress = startArgumentAddress; var argumentsChunk = arguments .Select(argument => Encoding.UTF8.GetBytes(argument + "\0")) .Aggregate(new byte[] { }, (accumulate, chunk) => accumulate.Concat(chunk)) ; var reservedSyscallsPartition = MemoryManager.GetPartition(MemoryPartitions.Kernel0).Allocate( 0x100, Name: "ReservedSyscallsPartition" ); var argumentsPartition = MemoryManager.GetPartition(MemoryPartitions.Kernel0).Allocate( argumentsChunk.Length, Name: "ArgumentsPartition" ); PspMemory.WriteBytes(argumentsPartition.Low, argumentsChunk); Debug.Assert(ThreadManForUser != null); // @TODO: Use Module Manager //var MainThread = ThreadManager.Create(); //var CpuThreadState = MainThread.CpuThreadState; var currentCpuThreadState = new CpuThreadState(CpuProcessor); { if (hleModuleGuest == null) { //throw new InvalidOperationException("hleModuleGuest == null"); } //CpuThreadState.PC = Loader.InitInfo.PC; currentCpuThreadState.Gp = hleModuleGuest.InitInfo.Gp; currentCpuThreadState.CallerModule = hleModuleGuest; var threadId = (int)ThreadManForUser.sceKernelCreateThread(currentCpuThreadState, "<EntryPoint>", hleModuleGuest.InitInfo.Pc, 10, 0x1000, PspThreadAttributes.ClearStack, null); //var Thread = HleThreadManager.GetThreadById(ThreadId); ThreadManForUser._sceKernelStartThread(currentCpuThreadState, threadId, argumentsPartition.Size, argumentsPartition.Low); //Console.WriteLine("RA: 0x{0:X}", CurrentCpuThreadState.RA); } currentCpuThreadState.DumpRegisters(); MemoryManager.GetPartition(MemoryPartitions.User).Dump(); //ModuleManager.LoadedGuestModules.Add(HleModuleGuest); //MainThread.CurrentStatus = HleThread.Status.Ready; } }
public HleModuleGuest LoadModule(Stream FileStream, Stream MemoryStream, MemoryPartition MemoryPartition, HleModuleManager ModuleManager, String GameTitle, string ModuleName, bool IsMainModule) { this.HleModuleGuest = new HleModuleGuest(PspEmulatorContext); this.ElfLoader = new ElfLoader(); this.ModuleManager = ModuleManager; var Magic = FileStream.SliceWithLength(0, 4).ReadString(4); Logger.Info("Magic: '{0}'", Magic); if (Magic == "~PSP") { try { var DecryptedData = new EncryptedPrx().Decrypt(FileStream.ReadAll(), true); File.WriteAllBytes("last_decoded_prx.bin", DecryptedData); FileStream = new MemoryStream(DecryptedData); } catch (Exception Exception) { Logger.Error(Exception); throw (Exception); } } this.ElfLoader.Load(FileStream, ModuleName); PspEmulatorContext.PspConfig.InfoExeHasRelocation = this.ElfLoader.NeedsRelocation; if (this.ElfLoader.NeedsRelocation) { var DummyPartition = MemoryPartition.Allocate( 0x4000, Name: "Dummy" ); BaseAddress = MemoryPartition.ChildPartitions.OrderByDescending(Partition => Partition.Size).First().Low; Logger.Info("BASE ADDRESS (Try ): 0x{0:X}", BaseAddress); BaseAddress = MathUtils.NextAligned(BaseAddress, 0x1000); Logger.Info("BASE ADDRESS (Aligned): 0x{0:X}", BaseAddress); } else { BaseAddress = 0; } PspEmulatorContext.PspConfig.RelocatedBaseAddress = BaseAddress; PspEmulatorContext.PspConfig.GameTitle = GameTitle; this.ElfLoader.AllocateAndWrite(MemoryStream, MemoryPartition, BaseAddress); if (this.ElfLoader.NeedsRelocation) { RelocateFromHeaders(); } if (!ElfLoader.SectionHeadersByName.ContainsKey(".rodata.sceModuleInfo")) { throw(new Exception("Can't find segment '.rodata.sceModuleInfo'")); } HleModuleGuest.ModuleInfo = ElfLoader.SectionHeaderFileStream(ElfLoader.SectionHeadersByName[".rodata.sceModuleInfo"]).ReadStruct<ElfPsp.ModuleInfo>(); ; //Console.WriteLine(this.ModuleInfo.ToStringDefault()); HleModuleGuest.InitInfo = new InitInfoStruct() { PC = ElfLoader.Header.EntryPoint + BaseAddress, GP = HleModuleGuest.ModuleInfo.GP + BaseAddress, }; UpdateModuleImports(); UpdateModuleExports(); ModuleManager.LoadedGuestModules.Add(HleModuleGuest); return HleModuleGuest; }
public HleModuleGuest LoadModule(Stream fileStream, Stream memoryStream, MemoryPartition memoryPartition, HleModuleManager moduleManager, string gameTitle, string moduleName, bool isMainModule) { HleModuleGuest = InjectContext.NewInstance <HleModuleGuest>(); ElfLoader = new ElfLoader(); ModuleManager = moduleManager; var magic = fileStream.SliceWithLength(0, 4).ReadString(4); _logger.Info("Magic: '{0}'", magic); if (magic == "~PSP") { try { var decryptedData = new EncryptedPrx().Decrypt(fileStream.ReadAll(), true); File.WriteAllBytes("last_decoded_prx.bin", decryptedData); fileStream = new MemoryStream(decryptedData); } catch (Exception exception) { _logger.Error(exception); throw; } } ElfLoader.Load(fileStream, moduleName); ElfConfig.InfoExeHasRelocation = ElfLoader.NeedsRelocation; if (ElfLoader.NeedsRelocation) { var dummyPartition = memoryPartition.Allocate(0x4000, Name: "Dummy"); BaseAddress = memoryPartition.ChildPartitions.OrderByDescending(partition => partition.Size).First() .Low; _logger.Info("BASE ADDRESS (Try ): 0x{0:X}", BaseAddress); BaseAddress = MathUtils.NextAligned(BaseAddress, 0x1000); _logger.Info("BASE ADDRESS (Aligned): 0x{0:X}", BaseAddress); } else { BaseAddress = 0; } ElfConfig.RelocatedBaseAddress = BaseAddress; ElfConfig.GameTitle = gameTitle; ElfLoader.AllocateAndWrite(memoryStream, memoryPartition, BaseAddress); LoadModuleInfo(); if (ElfLoader.NeedsRelocation) { RelocateFromHeaders(); } LoadModuleInfo(); //Console.WriteLine(this.ModuleInfo.ToStringDefault()); HleModuleGuest.InitInfo = new InitInfoStruct() { Pc = ElfLoader.Header.EntryPoint + BaseAddress, Gp = HleModuleGuest.ModuleInfo.Gp, }; UpdateModuleImports(); UpdateModuleExports(); moduleManager.LoadedGuestModules.Add(HleModuleGuest); return(HleModuleGuest); }