From 6dd2d4de4d4e39b52d57454fb5df46b35b1a0276 Mon Sep 17 00:00:00 2001 From: Al Azif <33132478+Al-Azif@users.noreply.github.com> Date: Fri, 22 Aug 2025 01:34:32 -0700 Subject: [PATCH] Added built-in work around for blackscreen for 8.00-9.60 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Still feels more like a work around vs a true fix - 7.xx soon™ --- src/kpatch/700.c | 12 ++++++++ src/kpatch/750.c | 12 ++++++++ src/kpatch/800.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ src/kpatch/850.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ src/kpatch/900.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ src/kpatch/903.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ src/kpatch/950.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 404 insertions(+) diff --git a/src/kpatch/700.c b/src/kpatch/700.c index 60cfe14..53d214a 100644 --- a/src/kpatch/700.c +++ b/src/kpatch/700.c @@ -30,6 +30,7 @@ struct kexec_args { }; static inline void restore(void *kbase, struct kexec_args *uap); +static inline void patch_aio(void *kbase); static inline void do_patch(void *kbase); __attribute__((section (".text.start"))) @@ -38,6 +39,7 @@ int kpatch(void *td, struct kexec_args *uap) { void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; do_patch(kbase); + patch_aio(kbase); restore(kbase, uap); return 0; @@ -61,6 +63,16 @@ static inline void restore(void *kbase, struct kexec_args *uap) { } } +// TODO: +__attribute__((always_inline)) +static inline void patch_aio(void *kbase) { + const u64 aio_off = 0x04a1bb1; + + disable_cr0_wp(); + + enable_cr0_wp(); +} + __attribute__((always_inline)) static inline void do_patch(void *kbase) { disable_cr0_wp(); diff --git a/src/kpatch/750.c b/src/kpatch/750.c index d09fa2f..02d2645 100644 --- a/src/kpatch/750.c +++ b/src/kpatch/750.c @@ -30,6 +30,7 @@ struct kexec_args { }; static inline void restore(void *kbase, struct kexec_args *uap); +static inline void patch_aio(void *kbase); static inline void do_patch(void *kbase); __attribute__((section (".text.start"))) @@ -38,6 +39,7 @@ int kpatch(void *td, struct kexec_args *uap) { void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; do_patch(kbase); + patch_aio(kbase); restore(kbase, uap); return 0; @@ -61,6 +63,16 @@ static inline void restore(void *kbase, struct kexec_args *uap) { } } +// TODO: +__attribute__((always_inline)) +static inline void patch_aio(void *kbase) { + const u64 aio_off = 0xb20f5; + + disable_cr0_wp(); + + enable_cr0_wp(); +} + __attribute__((always_inline)) static inline void do_patch(void *kbase) { disable_cr0_wp(); diff --git a/src/kpatch/800.c b/src/kpatch/800.c index 248dfa0..961c031 100644 --- a/src/kpatch/800.c +++ b/src/kpatch/800.c @@ -30,6 +30,7 @@ struct kexec_args { }; static inline void restore(void *kbase, struct kexec_args *uap); +static inline void patch_aio(void *kbase); static inline void do_patch(void *kbase); __attribute__((section (".text.start"))) @@ -38,6 +39,7 @@ int kpatch(void *td, struct kexec_args *uap) { void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; do_patch(kbase); + patch_aio(kbase); restore(kbase, uap); return 0; @@ -61,6 +63,80 @@ static inline void restore(void *kbase, struct kexec_args *uap) { } } +__attribute__((always_inline)) +static inline void patch_aio(void *kbase) { + const u64 aio_off = 0x9f141; + + disable_cr0_wp(); + + // offset = 0x00 + // patch = {0xeb, 0x48} + write16(kbase, aio_off + 0x00, 0x48eb); + + // offset = 0x42 + // patch = {0xeb, 0x06} + write16(kbase, aio_off + 0x42, 0x06eb); + + // offset = 0x4a + // patch = {0x41, 0x83, 0xbf, 0xa0, 0x04, 0x00, 0x00, 0x00} + write64(kbase, aio_off + 0x4a, 0x00000004a0bf8341); + + // offset = 0x58 + // patch = {0x49, 0x8b, 0x87, 0xd0, 0x04, 0x00, 0x00} + write32(kbase, aio_off + 0x58, 0xd0878b49); + write16(kbase, aio_off + 0x5c, 0x0004); + write8(kbase, aio_off + 0x5e, 0x00); + + // offset = 0x65 + // patch = {0x49, 0x8b, 0xb7, 0xb0, 0x04, 0x00, 0x00} + write32(kbase, aio_off + 0x65, 0xb0b78b49); + write16(kbase, aio_off + 0x69, 0x0004); + write8(kbase, aio_off + 0x6b, 0x00); + + // offset = 0x7d + // patch = {0x49, 0x8b, 0x87, 0x40, 0x05, 0x00, 0x00} + write32(kbase, aio_off + 0x7d, 0x40878b49); + write16(kbase, aio_off + 0x81, 0x0005); + write8(kbase, aio_off + 0x83, 0x00); + + // offset = 0x8a + // patch = {0x49, 0x8b, 0xb7, 0x20, 0x05, 0x00, 0x00} + write32(kbase, aio_off + 0x8a, 0x20b78b49); + write16(kbase, aio_off + 0x8e, 0x0005); + write8(kbase, aio_off + 0x90, 0x00); + + // offset = 0xa2 + // patch = {0x49, 0x8d, 0xbf, 0xc0, 0x00, 0x00, 0x00} + write32(kbase, aio_off + 0xa2, 0xc0bf8d49); + write16(kbase, aio_off + 0xa6, 0x0000); + write8(kbase, aio_off + 0xa8, 0x00); + + // offset = 0xae + // patch = {0x49, 0x8d, 0xbf, 0xe0, 0x00, 0x00, 0x00} + write32(kbase, aio_off + 0xae, 0xe0bf8d49); + write16(kbase, aio_off + 0xb2, 0x0000); + write8(kbase, aio_off + 0xb4, 0x00); + + // offset = 0xc1 + // patch = {0x49, 0x8d, 0xbf, 0x00, 0x01, 0x00, 0x00} + write32(kbase, aio_off + 0xc1, 0x00bf8d49); + write16(kbase, aio_off + 0xc5, 0x0001); + write8(kbase, aio_off + 0xc7, 0x00); + + // offset = 0xcd + // patch = {0x49, 0x8d, 0xbf, 0x20, 0x01, 0x00, 0x00} + write32(kbase, aio_off + 0xcd, 0x20bf8d49); + write16(kbase, aio_off + 0xd1, 0x0001); + write8(kbase, aio_off + 0xd3, 0x00); + + // offset = 0xde + // patch = {0x49, 0x8b, 0xff} + write16(kbase, aio_off + 0xde, 0x8b49); + write8(kbase, aio_off + 0xe0, 0xff); + + enable_cr0_wp(); +} + __attribute__((always_inline)) static inline void do_patch(void *kbase) { disable_cr0_wp(); diff --git a/src/kpatch/850.c b/src/kpatch/850.c index 3183349..5c3f10e 100644 --- a/src/kpatch/850.c +++ b/src/kpatch/850.c @@ -30,6 +30,7 @@ struct kexec_args { }; static inline void restore(void *kbase, struct kexec_args *uap); +static inline void patch_aio(void *kbase); static inline void do_patch(void *kbase); __attribute__((section (".text.start"))) @@ -38,6 +39,7 @@ int kpatch(void *td, struct kexec_args *uap) { void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; do_patch(kbase); + patch_aio(kbase); restore(kbase, uap); return 0; @@ -61,6 +63,80 @@ static inline void restore(void *kbase, struct kexec_args *uap) { } } +__attribute__((always_inline)) +static inline void patch_aio(void *kbase) { + const u64 aio_off = 0x30221; + + disable_cr0_wp(); + + // offset = 0x00 + // patch = {0xeb, 0x48} + write16(kbase, aio_off + 0x00, 0x48eb); + + // offset = 0x42 + // patch = {0xeb, 0x06} + write16(kbase, aio_off + 0x42, 0x06eb); + + // offset = 0x4a + // patch = {0x41, 0x83, 0xbf, 0xa0, 0x04, 0x00, 0x00, 0x00} + write64(kbase, aio_off + 0x4a, 0x00000004a0bf8341); + + // offset = 0x58 + // patch = {0x49, 0x8b, 0x87, 0xd0, 0x04, 0x00, 0x00} + write32(kbase, aio_off + 0x58, 0xd0878b49); + write16(kbase, aio_off + 0x5c, 0x0004); + write8(kbase, aio_off + 0x5e, 0x00); + + // offset = 0x65 + // patch = {0x49, 0x8b, 0xb7, 0xb0, 0x04, 0x00, 0x00} + write32(kbase, aio_off + 0x65, 0xb0b78b49); + write16(kbase, aio_off + 0x69, 0x0004); + write8(kbase, aio_off + 0x6b, 0x00); + + // offset = 0x7d + // patch = {0x49, 0x8b, 0x87, 0x40, 0x05, 0x00, 0x00} + write32(kbase, aio_off + 0x7d, 0x40878b49); + write16(kbase, aio_off + 0x81, 0x0005); + write8(kbase, aio_off + 0x83, 0x00); + + // offset = 0x8a + // patch = {0x49, 0x8b, 0xb7, 0x20, 0x05, 0x00, 0x00} + write32(kbase, aio_off + 0x8a, 0x20b78b49); + write16(kbase, aio_off + 0x8e, 0x0005); + write8(kbase, aio_off + 0x90, 0x00); + + // offset = 0xa2 + // patch = {0x49, 0x8d, 0xbf, 0xc0, 0x00, 0x00, 0x00} + write32(kbase, aio_off + 0xa2, 0xc0bf8d49); + write16(kbase, aio_off + 0xa6, 0x0000); + write8(kbase, aio_off + 0xa8, 0x00); + + // offset = 0xae + // patch = {0x49, 0x8d, 0xbf, 0xe0, 0x00, 0x00, 0x00} + write32(kbase, aio_off + 0xae, 0xe0bf8d49); + write16(kbase, aio_off + 0xb2, 0x0000); + write8(kbase, aio_off + 0xb4, 0x00); + + // offset = 0xc1 + // patch = {0x49, 0x8d, 0xbf, 0x00, 0x01, 0x00, 0x00} + write32(kbase, aio_off + 0xc1, 0x00bf8d49); + write16(kbase, aio_off + 0xc5, 0x0001); + write8(kbase, aio_off + 0xc7, 0x00); + + // offset = 0xcd + // patch = {0x49, 0x8d, 0xbf, 0x20, 0x01, 0x00, 0x00} + write32(kbase, aio_off + 0xcd, 0x20bf8d49); + write16(kbase, aio_off + 0xd1, 0x0001); + write8(kbase, aio_off + 0xd3, 0x00); + + // offset = 0xde + // patch = {0x49, 0x8b, 0xff} + write16(kbase, aio_off + 0xde, 0x8b49); + write8(kbase, aio_off + 0xe0, 0xff); + + enable_cr0_wp(); +} + __attribute__((always_inline)) static inline void do_patch(void *kbase) { disable_cr0_wp(); diff --git a/src/kpatch/900.c b/src/kpatch/900.c index 1d5600a..c8b86b8 100644 --- a/src/kpatch/900.c +++ b/src/kpatch/900.c @@ -30,6 +30,7 @@ struct kexec_args { }; static inline void restore(void *kbase, struct kexec_args *uap); +static inline void patch_aio(void *kbase); static inline void do_patch(void *kbase); __attribute__((section (".text.start"))) @@ -38,6 +39,7 @@ int kpatch(void *td, struct kexec_args *uap) { void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; do_patch(kbase); + patch_aio(kbase); restore(kbase, uap); return 0; @@ -61,6 +63,80 @@ static inline void restore(void *kbase, struct kexec_args *uap) { } } +__attribute__((always_inline)) +static inline void patch_aio(void *kbase) { + const u64 aio_off = 0x415a01; + + disable_cr0_wp(); + + // offset = 0x00 + // patch = {0xeb, 0x48} + write16(kbase, aio_off + 0x00, 0x48eb); + + // offset = 0x42 + // patch = {0xeb, 0x06} + write16(kbase, aio_off + 0x42, 0x06eb); + + // offset = 0x4a + // patch = {0x41, 0x83, 0xbf, 0xa0, 0x04, 0x00, 0x00, 0x00} + write64(kbase, aio_off + 0x4a, 0x00000004a0bf8341); + + // offset = 0x58 + // patch = {0x49, 0x8b, 0x87, 0xd0, 0x04, 0x00, 0x00} + write32(kbase, aio_off + 0x58, 0xd0878b49); + write16(kbase, aio_off + 0x5c, 0x0004); + write8(kbase, aio_off + 0x5e, 0x00); + + // offset = 0x65 + // patch = {0x49, 0x8b, 0xb7, 0xb0, 0x04, 0x00, 0x00} + write32(kbase, aio_off + 0x65, 0xb0b78b49); + write16(kbase, aio_off + 0x69, 0x0004); + write8(kbase, aio_off + 0x6b, 0x00); + + // offset = 0x7d + // patch = {0x49, 0x8b, 0x87, 0x40, 0x05, 0x00, 0x00} + write32(kbase, aio_off + 0x7d, 0x40878b49); + write16(kbase, aio_off + 0x81, 0x0005); + write8(kbase, aio_off + 0x83, 0x00); + + // offset = 0x8a + // patch = {0x49, 0x8b, 0xb7, 0x20, 0x05, 0x00, 0x00} + write32(kbase, aio_off + 0x8a, 0x20b78b49); + write16(kbase, aio_off + 0x8e, 0x0005); + write8(kbase, aio_off + 0x90, 0x00); + + // offset = 0xa2 + // patch = {0x49, 0x8d, 0xbf, 0xc0, 0x00, 0x00, 0x00} + write32(kbase, aio_off + 0xa2, 0xc0bf8d49); + write16(kbase, aio_off + 0xa6, 0x0000); + write8(kbase, aio_off + 0xa8, 0x00); + + // offset = 0xae + // patch = {0x49, 0x8d, 0xbf, 0xe0, 0x00, 0x00, 0x00} + write32(kbase, aio_off + 0xae, 0xe0bf8d49); + write16(kbase, aio_off + 0xb2, 0x0000); + write8(kbase, aio_off + 0xb4, 0x00); + + // offset = 0xc1 + // patch = {0x49, 0x8d, 0xbf, 0x00, 0x01, 0x00, 0x00} + write32(kbase, aio_off + 0xc1, 0x00bf8d49); + write16(kbase, aio_off + 0xc5, 0x0001); + write8(kbase, aio_off + 0xc7, 0x00); + + // offset = 0xcd + // patch = {0x49, 0x8d, 0xbf, 0x20, 0x01, 0x00, 0x00} + write32(kbase, aio_off + 0xcd, 0x20bf8d49); + write16(kbase, aio_off + 0xd1, 0x0001); + write8(kbase, aio_off + 0xd3, 0x00); + + // offset = 0xde + // patch = {0x49, 0x8b, 0xff} + write16(kbase, aio_off + 0xde, 0x8b49); + write8(kbase, aio_off + 0xe0, 0xff); + + enable_cr0_wp(); +} + __attribute__((always_inline)) static inline void do_patch(void *kbase) { disable_cr0_wp(); diff --git a/src/kpatch/903.c b/src/kpatch/903.c index accb9cc..e5ed9a3 100644 --- a/src/kpatch/903.c +++ b/src/kpatch/903.c @@ -30,6 +30,7 @@ struct kexec_args { }; static inline void restore(void *kbase, struct kexec_args *uap); +static inline void patch_aio(void *kbase); static inline void do_patch(void *kbase); __attribute__((section (".text.start"))) @@ -38,6 +39,7 @@ int kpatch(void *td, struct kexec_args *uap) { void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; do_patch(kbase); + patch_aio(kbase); restore(kbase, uap); return 0; @@ -61,6 +63,80 @@ static inline void restore(void *kbase, struct kexec_args *uap) { } } +__attribute__((always_inline)) +static inline void patch_aio(void *kbase) { + const u64 aio_off = 0x413971; + + disable_cr0_wp(); + + // offset = 0x00 + // patch = {0xeb, 0x48} + write16(kbase, aio_off + 0x00, 0x48eb); + + // offset = 0x42 + // patch = {0xeb, 0x06} + write16(kbase, aio_off + 0x42, 0x06eb); + + // offset = 0x4a + // patch = {0x41, 0x83, 0xbf, 0xa0, 0x04, 0x00, 0x00, 0x00} + write64(kbase, aio_off + 0x4a, 0x00000004a0bf8341); + + // offset = 0x58 + // patch = {0x49, 0x8b, 0x87, 0xd0, 0x04, 0x00, 0x00} + write32(kbase, aio_off + 0x58, 0xd0878b49); + write16(kbase, aio_off + 0x5c, 0x0004); + write8(kbase, aio_off + 0x5e, 0x00); + + // offset = 0x65 + // patch = {0x49, 0x8b, 0xb7, 0xb0, 0x04, 0x00, 0x00} + write32(kbase, aio_off + 0x65, 0xb0b78b49); + write16(kbase, aio_off + 0x69, 0x0004); + write8(kbase, aio_off + 0x6b, 0x00); + + // offset = 0x7d + // patch = {0x49, 0x8b, 0x87, 0x40, 0x05, 0x00, 0x00} + write32(kbase, aio_off + 0x7d, 0x40878b49); + write16(kbase, aio_off + 0x81, 0x0005); + write8(kbase, aio_off + 0x83, 0x00); + + // offset = 0x8a + // patch = {0x49, 0x8b, 0xb7, 0x20, 0x05, 0x00, 0x00} + write32(kbase, aio_off + 0x8a, 0x20b78b49); + write16(kbase, aio_off + 0x8e, 0x0005); + write8(kbase, aio_off + 0x90, 0x00); + + // offset = 0xa2 + // patch = {0x49, 0x8d, 0xbf, 0xc0, 0x00, 0x00, 0x00} + write32(kbase, aio_off + 0xa2, 0xc0bf8d49); + write16(kbase, aio_off + 0xa6, 0x0000); + write8(kbase, aio_off + 0xa8, 0x00); + + // offset = 0xae + // patch = {0x49, 0x8d, 0xbf, 0xe0, 0x00, 0x00, 0x00} + write32(kbase, aio_off + 0xae, 0xe0bf8d49); + write16(kbase, aio_off + 0xb2, 0x0000); + write8(kbase, aio_off + 0xb4, 0x00); + + // offset = 0xc1 + // patch = {0x49, 0x8d, 0xbf, 0x00, 0x01, 0x00, 0x00} + write32(kbase, aio_off + 0xc1, 0x00bf8d49); + write16(kbase, aio_off + 0xc5, 0x0001); + write8(kbase, aio_off + 0xc7, 0x00); + + // offset = 0xcd + // patch = {0x49, 0x8d, 0xbf, 0x20, 0x01, 0x00, 0x00} + write32(kbase, aio_off + 0xcd, 0x20bf8d49); + write16(kbase, aio_off + 0xd1, 0x0001); + write8(kbase, aio_off + 0xd3, 0x00); + + // offset = 0xde + // patch = {0x49, 0x8b, 0xff} + write16(kbase, aio_off + 0xde, 0x8b49); + write8(kbase, aio_off + 0xe0, 0xff); + + enable_cr0_wp(); +} + __attribute__((always_inline)) static inline void do_patch(void *kbase) { disable_cr0_wp(); diff --git a/src/kpatch/950.c b/src/kpatch/950.c index ff81420..8f60add 100644 --- a/src/kpatch/950.c +++ b/src/kpatch/950.c @@ -30,6 +30,7 @@ struct kexec_args { }; static inline void restore(void *kbase, struct kexec_args *uap); +static inline void patch_aio(void *kbase); static inline void do_patch(void *kbase); __attribute__((section (".text.start"))) @@ -38,6 +39,7 @@ int kpatch(void *td, struct kexec_args *uap) { void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; do_patch(kbase); + patch_aio(kbase); restore(kbase, uap); return 0; @@ -61,6 +63,80 @@ static inline void restore(void *kbase, struct kexec_args *uap) { } } +__attribute__((always_inline)) +static inline void patch_aio(void *kbase) { + const u64 aio_off = 0xd7771; + + disable_cr0_wp(); + + // offset = 0x00 + // patch = {0xeb, 0x48} + write16(kbase, aio_off + 0x00, 0x48eb); + + // offset = 0x42 + // patch = {0xeb, 0x06} + write16(kbase, aio_off + 0x42, 0x06eb); + + // offset = 0x4a + // patch = {0x41, 0x83, 0xbf, 0xa0, 0x04, 0x00, 0x00, 0x00} + write64(kbase, aio_off + 0x4a, 0x00000004a0bf8341); + + // offset = 0x58 + // patch = {0x49, 0x8b, 0x87, 0xd0, 0x04, 0x00, 0x00} + write32(kbase, aio_off + 0x58, 0xd0878b49); + write16(kbase, aio_off + 0x5c, 0x0004); + write8(kbase, aio_off + 0x5e, 0x00); + + // offset = 0x65 + // patch = {0x49, 0x8b, 0xb7, 0xb0, 0x04, 0x00, 0x00} + write32(kbase, aio_off + 0x65, 0xb0b78b49); + write16(kbase, aio_off + 0x69, 0x0004); + write8(kbase, aio_off + 0x6b, 0x00); + + // offset = 0x7d + // patch = {0x49, 0x8b, 0x87, 0x40, 0x05, 0x00, 0x00} + write32(kbase, aio_off + 0x7d, 0x40878b49); + write16(kbase, aio_off + 0x81, 0x0005); + write8(kbase, aio_off + 0x83, 0x00); + + // offset = 0x8a + // patch = {0x49, 0x8b, 0xb7, 0x20, 0x05, 0x00, 0x00} + write32(kbase, aio_off + 0x8a, 0x20b78b49); + write16(kbase, aio_off + 0x8e, 0x0005); + write8(kbase, aio_off + 0x90, 0x00); + + // offset = 0xa2 + // patch = {0x49, 0x8d, 0xbf, 0xc0, 0x00, 0x00, 0x00} + write32(kbase, aio_off + 0xa2, 0xc0bf8d49); + write16(kbase, aio_off + 0xa6, 0x0000); + write8(kbase, aio_off + 0xa8, 0x00); + + // offset = 0xae + // patch = {0x49, 0x8d, 0xbf, 0xe0, 0x00, 0x00, 0x00} + write32(kbase, aio_off + 0xae, 0xe0bf8d49); + write16(kbase, aio_off + 0xb2, 0x0000); + write8(kbase, aio_off + 0xb4, 0x00); + + // offset = 0xc1 + // patch = {0x49, 0x8d, 0xbf, 0x00, 0x01, 0x00, 0x00} + write32(kbase, aio_off + 0xc1, 0x00bf8d49); + write16(kbase, aio_off + 0xc5, 0x0001); + write8(kbase, aio_off + 0xc7, 0x00); + + // offset = 0xcd + // patch = {0x49, 0x8d, 0xbf, 0x20, 0x01, 0x00, 0x00} + write32(kbase, aio_off + 0xcd, 0x20bf8d49); + write16(kbase, aio_off + 0xd1, 0x0001); + write8(kbase, aio_off + 0xd3, 0x00); + + // offset = 0xde + // patch = {0x49, 0x8b, 0xff} + write16(kbase, aio_off + 0xde, 0x8b49); + write8(kbase, aio_off + 0xe0, 0xff); + + enable_cr0_wp(); +} + __attribute__((always_inline)) static inline void do_patch(void *kbase) { disable_cr0_wp();