Closed SciresM closed 5 years ago
Sorry to bother you, probably you already know about this approach, but just in case you need some inspiration/comparison between implementations 😉 Thx for all your work!
Hi, how a can help to translate the Text to Portuguese BR, and Italian ? You have a list of the texts for translate?. A want help.
For the running system with (K)ASLR the simple memsearch
from luma won't work sadly. So we also have to agree on a convention for wildcard pattern scanning.
Since its confusing and slow to use "unused instructions" for wildcards 0x00, 0xFF
or something along those lines I would suggest to split pattern scanning into a pattern and a mask:
{0x12, 0x23, 0x34, 0x45, 0x00, 0x00, 0x00, 0x00, ...}
"xxxx????..."
Whith x
being a character to find and ?
or any other character representing a wildcard.
With this distinction there won't be any accidental partial or full pattern matches due to overlapping wildcard characters and actual code.
Scanning will take much longer than it did on the 3DS regardless. This is the result of bigger files and the additional execution time introduced by the wildcards.
For static file scanning we could use memmem or memsearch (do i miss something? how is memsearch different from memmem?)
It is also possible to make the mask binary (uint64_t
or (typed) uint128_t
, if the pattern gets that long) to save space (1bit <> 8bit) and use fast binary operations to check for wildcards.
if(mask & 1 << loop_i)
This is a difficult question to answer, without being clear on the types of patches that require support. At a first level, I second @Valeri0p's suggestion to review yifan lu's CFW framework. For any patching that can be done at the exported API layer, this seems a good starting point.
The pattern matching concept is also likely going to be needed.
The hard part (imho) is making multiple patches that affect the same area work. Even with the above framework, which hook goes "first" is a very hard problem.
A similar problem appears to have been (attempted?) solved for file system filter driver ordering in Windows. At a high level, they define multiple types of filter drivers, with a pre-defined order that they get applied.
Perhaps something similar is appropriate for a patch framework?
So, for now we've gone with IPS. It's less flexible than pattern-matching, which is still desirable -- however, the current patch system allows for complete user control over the order in which IPS are applied, and since the patches are applied only to those kips which have matching SHA256, there shouldn't be anything doable with pattern matching not doable via IPS.
Is pattern matching still desired? (EDIT: I didn't read it well... the answer is yes) I finished coding yesterday, but didn't push or PR it as I thought I needed to include a working patching system at the same time. I will push it to my fork in a distinct branch if anyone wants to take a look.
memSearchASLR is using a mask while memSearch is not (GNU memmem()
)
As kind of a benchmark: The file is generated by reading 1GB from /dev/urandom and xxd'ing at ofset 1,000,000. The pattern is 8 bytes long and alignment is 4 bytes. It looks a little too fast, so my guess is that there is some caching going on. I can not see why memmem should be slower otherwise.
Debian (gcc) (VM)
nxdev@nxdev:~/memtest$ ./test
Malloc took 0.000009s for 1048.576000 MB
File read to memory took 1.159182s to complete
memSearchASLR took 0.414878s and location is 0x3B9ACA00
memSearch took 0.672670s and location is 0x3B9ACA00
Windows (MSVC) - memmem not available
Malloc took 0.002000s for 1048.576000 MB
File read to memory took 1.600000s to complete
memSearchASLR took 0.335000s and location is 0x3B9ACA00
memSearch took 0.000000s and location is 0x0
Decide on a standardized format, and implement in the stage 1 loader. Should be flexible enough to pattern match -- see luma-style stuff.
Is this best done via a custom "loader" system module? Needs design considerations.