Loader services: Difference between revisions

mNo edit summary
 
(10 intermediate revisions by 4 users not shown)
Line 1: Line 1:
= ldr:dmnt =
= ldr:shel =
This is "nn::ldr::detail::IDebugMonitorInterface".
This is "nn::ldr::detail::IShellInterface".
 
This service has IPC max_sessions 3.


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 6: Line 8:
! Cmd || Name
! Cmd || Name
|-
|-
| 0 || [[Loader_services#AddProcessToDebugLaunchQueue|AddProcessToDebugLaunchQueue]]
| 0 || [[#SetProgramArgument]]
|-
|-
| 1 || [[Loader_services#ClearDebugLaunchQueue|ClearDebugLaunchQueue]]
| 1 || [[#FlushArguments]]
|-
| 2 || [[Loader_services#GetNsoInfos|GetNsoInfos]]
|}
|}


== AddProcessToDebugLaunchQueue ==
== SetProgramArgument ==
Same as [[Loader_services#AddProcessToLaunchQueue|AddProcessToLaunchQueue]] but for processes marked as debug.
Takes a type-0x9 input buffer with launch arguments (as string), an u32 (size of arguments string), and an input [[NCM_services#ProgramId|ProgramId]]. No output.


== ClearDebugLaunchQueue ==
[11.0.0+] Now takes a type-0x5 buffer instead of type-0x9. Now takes a total of 8-bytes of input, instead of 0x10-bytes total.
Same as [[Loader_services#ClearLaunchQueue|ClearLaunchQueue]].


== GetNsoInfos ==
Loads a process for the specified title-id and passes along the supplied arguments.
Takes in a u64 ProcessID, and a C descriptor. Returns the number of NsoInfos copied to output.
Loaded processes are kept in a queue waiting for PM to launch them. The maximum number of waiting processes in this list is 10.


NsoInfo has the following layout:
== FlushArguments ==
No input/output.
 
Clears the loaded processes waiting queue.
 
= ldr:dmnt =
This is "nn::ldr::detail::IDebugMonitorInterface".
 
This service has IPC max_sessions 2.


{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! Offset
! Cmd || Name
! Size
! Description
|-
|-
| 0x0
| 0 || [[#SetProgramArgument2]]
| 0x20
| "Build ID", from NSO header+0x40.
|-
|-
| 0x20
| 1 || [[#FlushArguments2]]
| 0x8
| Mapped address for this NSO
|-
| 0x28
| 0x8
| Mapped size for this NSO
|-
|-
| 2 || [[#GetProcessModuleInfo]]
|}
|}


== SetProgramArgument2 ==
Same as [[#SetProgramArgument]].
== FlushArguments2 ==
Same as [[#FlushArguments]].
== GetProcessModuleInfo ==
Takes a type-0xA output buffer of [[#ModuleInfo]] and an input u64 ProcessId. Returns an output s32.


= ldr:pm =
= ldr:pm =
This is "nn::ldr::detail::IProcessManagerInterface".
This is "nn::ldr::detail::IProcessManagerInterface".
This service has IPC max_sessions 1.


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 52: Line 60:
! Cmd || Name
! Cmd || Name
|-
|-
| 0 || CreateProcess
| 0 || [[#CreateProcess]]
|-
|-
| 1 || [[#GetProgramInfo]]
| 1 || [[#GetProgramInfo]]
|-
|-
| 2 || [[#RegisterTitle]]
| 2 || [[#PinProgram]]
|-
| 3 || [[#UnpinProgram]]
|-
|-
| 3 || [[#UnregisterTitle]]
| 4 || [10.0.0+] [[#SetEnabledProgramVerification]]
|}
|}
== CreateProcess ==
Takes an input [[#PinId]], an input [[#CreateProcessFlag]] and an input ResourceLimit handle. Returns an output Process handle.


== GetProgramInfo ==
== GetProgramInfo ==
Takes a TitleId + StorageId, parses the NPDM, and writes output to a C descriptor buffer as follows:
Takes a type-0x1A output buffer containing a [[#ProgramInfo]] and a [[NCM_services#ProgramLocation|ProgramLocation]]. No output.
 
[20.0.0+] Now takes an additional input u16.
 
== PinProgram ==
Takes a [[NCM_services#ProgramLocation|ProgramLocation]]. Returns an output [[#PinId]].
 
== UnpinProgram ==
Takes an input [[#PinId]]. No output.


== SetEnabledProgramVerification ==
Takes an input bool. No output.
When the flag is zero, it will set ret=0 instead of ret={error} when verifying the fixed-key [[NPDM]] ACID signature fails. This also skips verifying the [[NCA#Header|NCA Header]] signature using the ACID key. Note that if verifying the fixed-key ACID signature is successful, and verifying the ACID-key NCA header signature fails, it will throw an error and abort.
= CreateProcessFlag =
{| class="wikitable" border="1"
|-
!  Value
!  Description
|-
| 0 || EnableDebug
|-
| 1 || DisableAslr
|}
= PinId =
This is an u64.
= ModuleInfo =
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x20
| ModuleId
|-
| 0x20
| 0x8
| Address
|-
| 0x28
| 0x8
| Size
|}
= ProgramInfo =
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 72: Line 133:
| 0x0
| 0x0
| 0x1
| 0x1
| MainThreadPrio. Arg1 to svcStartProcess
| MainThreadPriority
|-
|-
| 0x1
| 0x1
| 0x1
| 0x1
| DefaultCpuId. Arg2 to svcStartProcess
| DefaultCpuId
|-
|-
| 0x2
| 0x2
| 0x1
| 0x2
| ApplicationType, see [[Process Manager services|here]].
| Flags
|-
| 0x3
| 0x1
| Padding
|-
|-
| 0x4
| 0x4
| 0x4
| 0x4
| MainThreadStackSize. Arg3 to svcStartProcess
| MainThreadStackSize
|-
|-
| 0x8
| 0x8
| 0x8
| 0x8
| TitleIdRange_Min
| [[NCM_services#ProgramId|ProgramId]]
|-
|-
| 0x10
| 0x10
| 0x4
| 0x4
| ACID [[NPDM#Service Access Control|Service Access Control]] list size
| AcidSacSize
|-
|-
| 0x14
| 0x14
| 0x4
| 0x4
| ACI0 [[NPDM#Service Access Control|Service Access Control]] list size
| AciSacSize
|-
|-
| 0x18
| 0x18
| 0x4
| 0x4
| ACID [[NPDM#FS Access Control|FS Access Control]] buffer size
| AcidFacSize
|-
|-
| 0x1C
| 0x1C
| 0x4
| 0x4
| ACI0 [[NPDM#FS Access Control|FS Access Control]] buffer size
| AciFacSize
|-
|-
| 0x20
| 0x20
| <Varies>
| 0x10
| ACID [[NPDM#Service Access Control|Service Access Control]] list
| [19.0.0+] Reserved
|-
| <Varies>
| <Varies>
| ACI0 [[NPDM#Service Access Control|Service Access Control]] list
|-
| <Varies>
| <Varies>
| ACID [[NPDM#FS Access Control|FS Access Control]] buffer
|-
| <Varies>
| <Varies>
| ACI0 [[NPDM#FS Access Control|FS Access Control]]
|}
 
== RegisterTitle ==
Takes a TitleId + StorageId, returns an index.
 
== UnregisterTitle ==
Takes the index from [[#RegisterTitle]].
 
= ldr:shel =
This is "nn::ldr::detail::IShellInterface".
 
{| class="wikitable" border="1"
|-
! Cmd || Name
|-
| 0 || [[#AddProcessToLaunchQueue]]
|-
| 1 || [[#ClearLaunchQueue]]
|}
 
== AddProcessToLaunchQueue ==
Takes a type-0x19 input buffer with launch arguments (as string), an u32 (size of arguments string), and an input title-id.
 
Loads a process for the specified title-id and passes along the supplied arguments.
Loaded processes are kept in a queue waiting for PM to launch them. The maximum number of waiting processes in this list is 10.
 
== ClearLaunchQueue ==
Clears the loaded processes waiting queue.
 
= ldr:ro, ro:1 =
[1.0.0-2.3.0] This is "nn::ldr::detail::IRoInterface"
 
[3.0.0+] This is "nn::ro::detail::IRoInterface".
 
[7.0.0+] ro:1 was added, and also creates nn::ro::detail::IRoInterface objects.
 
{| class="wikitable" border="1"
|-
! Cmd || Name
|-
|-
| 0 || [[#LoadNro]]
| [19.0.0+] 0x30 ([1.0.0-18.1.0] 0x20)
| Variable
| AcidSac
|-
|-
| 1 || UnloadNro
| Variable
| Variable
| AciSac
|-
|-
| 2 || [[#LoadNrr]]
| Variable
| Variable
| AcidFac
|-
|-
| 3 || UnloadNrr
| Variable
|-
| Variable
| 4 || [[#Initialize]]
| AciFac
|-
| 10 || [7.0.0+] [[#LoadNrrEx]]
|}
|}
== LoadNro ==
{| class="wikitable" border="1"
|-
! Word || Value
|-
| 0 || 0x00000004
|-
| 1 || 0x80000012
|-
| 2 || 0x00000001
|- style="border-top: double"
| 0-1 || Pid
|- style="border-top: double"
| 0 || "SCFI"
|-
| 1 || 0x00000000
|-
| 2 || Always 0.
|-
| 3 || Nro heap address
|-
| 4 || Nro size
|-
| 5 || Bss backing heap address
|-
| 6 || Bss size
|}
== LoadNrr ==
[7.0.0+] A new 8-bit field at NRR + 0x33C (previously padding) must be 0 for this function to succeed.
{| class="wikitable" border="1"
|-
! Word || Value
|-
| 0 || 0x00000004
|-
| 1 || 0x8000000E
|-
| 2 || 0x00000001
|-
|- style="border-top: double"
| 0-1 || Pid
|- style="border-top: double"
| 0 || "SFCI"
|-
| 1 || 0x00000002
|-
| 2 || Always 0.
|-
| 3 || Nrr address
|-
| 4 || Nrr size
|}
== Initialize ==
{| class="wikitable" border="1"
|-
! Word || Value
|-
| 0 || 0x00000004
|-
| 1 || 0x8000000A
|-
| 2 || 0x00000003
|- style="border-top: double"
| 0-1 || Pid
|-
| 2 || Process handle (0xFFFF8001)
|- style="border-top: double"
| 0 || "SFCI"
|-
| 1 || 0x00000004
|-
| 2 || Always 0.
|}
== LoadNrrEx ==
Takes in a u64 nrr_address, a u64 nrr_size, a pid descriptor, and a process handle.
First, this validates that the pid descriptor matches the pid for the process handle sent to this->Initialize() earlier.
Then, this calls the same function as LoadNrr, except using the passed process handle instead of the one sent to Initialize.
When called from an ro:1 session, the field at NRR header + 0x33C must be 0x1. When called from ldr:ro session, the field at NRR header + 0x33C must be 0x0.


[[Category:Services]]
[[Category:Services]]