Homebrew Homebrew app sys-patch - sysmod that patches on boot

dogtygr

Active Member
Newcomer
Joined
May 30, 2023
Messages
36
Trophies
0
XP
91
Country
United States
I thought it was the same pattern, MrDude's repo is hidden, no way to be sure but ask him directly
Also generated sigpatches from IpsPatchCreator might be also bugged, depends on his code and error handling but again, sources are hidden for now

An OK status from a soft does not mean everything works
My guess is pattern must be adjusted for both IpsPatchCreator and sys-patch

Is anyone have sourcecode from IpsPatchCreator 1.5.7 ?
Only way to be sure is to run a test suite like i mentioned before with generated sigpatches, or read and compare the sourcecode

I have the source code of both (sys_patch and ipspatchcreator)

The patterns are completely different, with MrDude you can have a wildcard patern with 4 bits. With sys_patch you can only have a patter of bytes. the way the sys_patch works is that it looks for a known instruction nearby the place where you have to put the patch and it uses two kind of offsets to determine the real position. With MrDude you look for a 4bit min wildcard and use an offset
 
  • Love
Reactions: R3m0ved

R3m0ved

Active Member
Newcomer
Joined
Aug 22, 2023
Messages
27
Trophies
0
XP
96
Country
Pakistan
I have the source code of both (sys_patch and ipspatchcreator)

The patterns are completely different, with MrDude you can have a wildcard patern with 4 bits. With sys_patch you can only have a patter of bytes. the way the sys_patch works is that it looks for a known instruction nearby the place where you have to put the patch and it uses two kind of offsets to determine the real position. With MrDude you look for a 4bit min wildcard and use an offset

Nicely done
So yeah, sharing the same patterns among both solutions might be a good practice
 

impeeza

¡Kabito!
Member
Joined
Apr 5, 2011
Messages
6,563
Trophies
3
Age
46
Location
At my chair.
XP
19,553
Country
Colombia
yes it can

Edit: I havent tested MrDude patches did you guys test it with them? Does it work?
yes they did work fine, even if sys-patch says «unpatched»
Post automatically merged:

So I checked the changes made in the atmosphere code. They made some tiny changes on the validation of the Acid signature that's why the usual way the patches look for the right place doesnt wprk. The thing is it is pretty easy to change the atmosphere code to not check for the acidsignature all you have to do is change two lines on the code. Below is a patch of what needs to be modified. It seems to work on my hand but I haven't fully tested it. With that it is easy to know what to change to make a sigpatch. I'll look into it maybe tomorrow or next week

@FRbaron it is a combination of reading the code and documenting yourself by reading articles on https://switchbrew.org/.
I just build the latest commit of Atmosphère applying that patch, Using MrDude's IPS Patch Creator created the Patches:

1717893915101.png


and boot my console using it (and patches)

Sys-Patch shows:
1717893983870.png


Homebrew forwarders works fine
invalid signature XCI and NSP also loads fine.
 
Last edited by impeeza,

dogtygr

Active Member
Newcomer
Joined
May 30, 2023
Messages
36
Trophies
0
XP
91
Country
United States
yes they did work fine, even if sys-patch says «unpatched»
Post automatically merged:


I just build the latest commit of Atmosphère applying that patch, Using MrDude's IPS Patch Creator created the Patches:

View attachment 441385

and boot my console using it (and patches)

Sys-Patch shows:
View attachment 441386

Homebrew forwarders works fine
invalid signature XCI and NSP also loads fine.

I indeed checked MrDude patch. It happens that we're just lucky because the MrDude's pattern appears twice now it just happens that the pattern that we need is the first one it finds. The pattern in sys_patch doesnt exist anymore in the new loader. I managed to modify the sys-patch to fit the pattern of MrDude it works fine but it's a little bit hacky and the fact that now the pattern isn't unique is a concern.
Post automatically merged:

I've been able to find a simpler way to update syspatch and it gives a unique pattern. The pattern also works with the old versions.
There's a patch below of the modifications I've made on the code (it's really nothing)
 

Attachments

  • 0001-New-pattern-for-loader.txt
    1.4 KB · Views: 1
Last edited by dogtygr,

impeeza

¡Kabito!
Member
Joined
Apr 5, 2011
Messages
6,563
Trophies
3
Age
46
Location
At my chair.
XP
19,553
Country
Colombia
I indeed checked MrDude patch. It happens that we're just lucky because the MrDude's pattern appears twice now it just happens that the pattern that we need is the first one it finds. The pattern in sys_patch doesnt exist anymore in the new loader. I managed to modify the sys-patch to fit the pattern of MrDude it works fine but it's a little bit hacky and the fact that now the pattern isn't unique is a concern.
Humm a few of luck, cool!
Post automatically merged:

I've been able to find a simpler way to update syspatch and it gives a unique pattern. The pattern also works with the old versions.
There's a patch below of the modifications I've made on the code (it's really nothing)
nice! I just now are learning how the regular expressions works on C++ I used them on text editing but is no the same
Post automatically merged:

I indeed checked MrDude patch. It happens that we're just lucky because the MrDude's pattern appears twice now it just happens that the pattern that we need is the first one it finds. The pattern in sys_patch doesnt exist anymore in the new loader. I managed to modify the sys-patch to fit the pattern of MrDude it works fine but it's a little bit hacky and the fact that now the pattern isn't unique is a concern.
Post automatically merged:

I've been able to find a simpler way to update syspatch and it gives a unique pattern. The pattern also works with the old versions.
There's a patch below of the modifications I've made on the code (it's really nothing)
Super, I build a new Atmosphère with latest commits, and also build SYS-Patch Sysmodule applying your patch, update files on my console and remove LDR patches, then restarted the console and now everything is shown like this:

1717903605550.png


And then copied the Sigpatches created using IPS Patch Creator to the SD and restarted:

1717903965674.png
 
Last edited by impeeza,

dogtygr

Active Member
Newcomer
Joined
May 30, 2023
Messages
36
Trophies
0
XP
91
Country
United States
Glad it worked!
nice! I just now are learning how the regular expressions works on C++ I used them on text editing but is no the same
Learning regex is always handy at the end of the day! Sys-patch doesn't use regex by the way. It starts by looking for a pattern (it can be a full set of bytes or a set of multiple bytes (for example 0x0945.6787 will look for places where 09456787 - a random byte following by 6787 is set). Once you have found the pattern (at this point it can be in different places) it gives you an offset where you have to go based on the place the pattern was found and you have to retrieve the next 4 bytes.

For example if you found the value 09 45 54 67 87 in address 0x0000 and what comes after that is 01 24 35 67 89 0A if the code tells you that for this pattern you then have to check the value at offset 6 you have to pick the number 24 35 67 89. After that it checks the value bit by bit with AND mask to only check the relevant bits (I'll go in detail exactly what it is below). When all checks out, there is another offset that gives you the position of where you have to modify your code relative to the number you checked. Then it checks if the old value to replace is the expected one and then replace it.
With MrDude pattern it only checks a known pattern.

I think it is interesting to know exactly the purpose of all this and what exactly the patch is doing. Since atmosphere is open source it is relatively easy to trace everything.

The goal

The end goal of all of this is to bypass the ACID signature check. The ACID signature is something in the NCA meta data (called NPDM) where it verifies if the NCA that you're about to load was signed by nintendo (to prevent from launching hombrew nsp forwarders for example).

These checks were not done in HOS versions prior to 10.0.0. If you look at the atmosphere code you'll see the function that checks the signature here:

1717936904499.png


You can see that it checks the version of the current hos and if it is above or equal to version 10.0.0 you proceed with the signature check. The goal of the whole patch is to pretend that the condition (hos::GetVersion() >= hos::Version_10_0_0) is false so we don't need to do the check.

In order to do that we have to disassemble the loader. We find that the code above is the following assembly code :
1717933790009.png


sub_710001A050 is the address of the function GetVersion(). Basically what this code does is you call the function sub_710001A050. the function updates the register w0 with the version of the hos, you load W1 with the value 0x9FFFFF you compare the result in the registers w0 and w1 and if the result is equal or lower than 0x9FFFFF you jump to the offset 0x5f04 (you skip the if). The version of the HOS is coded in hexa with the major version number on the MSB the minor one next to it and so on. For example 10.0.0 will be coded as 0x0A000000. so if you're version is 10.0.0 <=> 0x0A000000 > 0x9FFFFF and so you don't jump.

To bypass this check all you have to do is modify the register you compare to (W1) with W0. The register compares its value to itself and the result is always true.

The hexa value of the operation CMP W0, W1 is 0x6B01001F. In my example this code is in the offset 0x5FBC (in the hexa file the numbers are in little endian)

1717934263925.png


To change CMP W0, W1 to CMP W0, W0 all you have to do is change one byte 0x6B00001F which is in the offset 0x5FBE. This is exactly what the patch does.

So now we know exactly what we are looking for and we know what we need to change. We now have to be able to find the pattern.


The MrDude algorithm

MrDude algorithm is pretty simple. it looks for the two instructions (the mov one next to the cmp one). The MOV operation is 0x12BEC001 (so 01C0BE12 in the file). MrDude looks for the pattern 01C0BE1206B00001F. Since it is unlikely that this code will appear more than once (since we rarely compare the value 0x9FFFF other than here and that the signature check is one of the first step you do in the loader) this pattern works pretty well.


The Sys-patch algorithm

Sys-patch does it differently. What it initially does is that it looks for the pattern 0xFD7BC6A8C0035FD6 which is an instruction to basically come back to a function when you're done with the current one (basically it's a return). Apparently it was well know by sys-patch that a return function was exactly 16 bytes away from our cmp function.

Once you found this pattern you have to jump 16 bytes (offset 16) to get to our cmp function
1717936577933.png

(you can see that if you start from FD and you count to 16 you'll get to 1F00016B). Note that in this example the value is FD7BC8A8 and not FD7BC6A8. This is because Im using the new compiled version of atmopshere. Before this version the value was FD7BC6A8. This was the reason why sys-patch didn't work.

You might think that we're done but sys-patch goes a little bit further than that.

This part is a little bit tech-heavy. If you just want a summary of this part is that it checks before applying the patch that the pattern 1F00016B is a cmp instruction.

If you check the ARM documentation https://developer.arm.com/documentation/ddi0487/latest/ you can see exactly what is the cmp instruction:

1717938187023.png


In our case sf = 0 Rm is equal to Wm and Rn Wn. Note that CMP is a special case of SUBS that's why subs is mentioned in the sys-patch code. Our instruction is 0x6B01001F. Our op code (which is the part where you know what type of instruction you have to check) is 01101011000 the Rn value is 00000 imm6 00000 Rm 00001 and the rest is full of ones. It bascally means that you compare Register W0 to W1 and you don't make any kind of shift before you compare the value.

What sys-patch does is that it makes a right bit shift so it only gives you the last 12 bits (from 31 to 21). you end up with a 16 bit value of 0000 0011 0101 1000=> 0x0358. Sys-patch checks each bits from the new number from the first bit to the 11th one (the remaining zeros were added because of the shift so it is not needed to check). We don't need to check the shift bits (the 2nd and 3rd bits in our new number) because it can change depending on what the compiler decides to do. what we really want to check is the instruction type. This leaves us with an AND mask of 0x7F9. If the instruction is a CMP one the result of the mask needs to be 0x358. Note that if the value was for example 0000 0011 0101 1110 the result will stil be valid and will still be 0x358, as we said earlier we don't pay attention to the values of the 3rd and 2nd bits.

Sys-patch then checks the value of the register we are comparing from (w1) and verifies if it is indeed register number 1. To do this it makes a 16 bit right shift to the initial value so we can have the Rm bit in the lowest bits. In our example the new value will become 0000 1101 0110 000 0001. Since Rm takes 5 bits you need to make a AND mask of 0x1f to get the value. We end up with 1 which is exactly what we were looking.

There you have it you finally found that the instruction that you have is the correct one! Now you need to mention where to replace the old value with the new one.It is 2 bytes from our instruction (0x1F 00 01 6B (remember in memory it is in little endian but the value that you read is indeed 6b01001f).

Now you can finally apply this goddamn patch. You first check if the value has been already modified, you apply the patch and then you do all the stuff mentioned above to check if the instruction is still a cmp but this time Rm is 0 and voila! you're done!
 

Attachments

  • 1717937824246.png
    1717937824246.png
    54.7 KB · Views: 1
Last edited by dogtygr,

impeeza

¡Kabito!
Member
Joined
Apr 5, 2011
Messages
6,563
Trophies
3
Age
46
Location
At my chair.
XP
19,553
Country
Colombia
Learning regex is always handy at the end of the day! Sys-patch doesn't use regex by the way. It starts by looking for a pattern (it can be a full set of bytes or a set of multiple byte
ha ha ha ha ha, THAT'S why has bee so hard to learn! they are not regex! you can not get to goal if you are going the wrong way :P
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    K3Nv2 @ K3Nv2: https://youtu.be/h7XaTWz8zSU?si=J_9Ia9ZigxNht2Z1