diff --git a/README.md b/README.md
index 468d5b5..db6bf29 100644
--- a/README.md
+++ b/README.md
@@ -4,14 +4,14 @@
## Requirements
-- Your device must already run **HENkaku/h-encore** on firmwares 3.60-3.70 in order to use this software. **ATTENTION: You should NOT attempt downgrading using modoru on FW 3.71-3.73**
+- Your device must already run **HENkaku/h-encore** on firmwares 3.60-3.73 in order to use this software.
- Your device's battery has be at least at 50%.
- All your plugins must be disabled, therefore you will not be able to launch the downgrader from a SD2VITA and hence, you must have a Memory Card (or Internal Storage).
-- If you have installed IMCUnlock by SKGleba, it is recommended to uninstall it first before attempting to downgrade.
+- If you have installed IMCUnlock by SKGleba, it is recommended to uninstall it first before attempting to downgrade to a firmware lower than 2.10.
## Installation
-1. Download and install [modoru.vpk](https://github.com/TheOfficialFloW/modoru/releases/download/v1.0/modoru.vpk) using *VitaShell*.
+1. Download and install [modoru.vpk](https://github.com/TheOfficialFloW/modoru/releases/download/v2.1/modoru.vpk) using *VitaShell*.
2. Obtain the `PSP2UPDAT.PUP` file of your desired firmware (make sure that this firmware is officially hackable) and place it at `ux0:app/MODORU000/PSP2UPDAT.PUP` (don't install `modoru.vpk` afterwards, otherwise the update file will be removed).
3. Disable all your plugins. Easiest way is renaming `ux0:tai` and `ur0:tai` to some other name.
4. Reboot your device and relaunch *HENkaku/h-encore*.
@@ -52,6 +52,6 @@ Thank you!
- Thanks to Freakler for the LiveArea design.
- Thanks to liblor for the name suggestion.
- Thanks to yifanlu for prior research on downgrading.
-- Thanks to molecule for SCE decryption utilities.
+- Thanks to molecule for SCE decryption utilities and secure coprocessor write primitive.
- Thanks to SKGleba for betatesting.
diff --git a/kernel.c b/kernel.c
index b515461..b905369 100644
--- a/kernel.c
+++ b/kernel.c
@@ -23,6 +23,46 @@
#define MOD_LIST_SIZE 128
+#define NZERO_RANGE(off, end, ctx) \
+ do { \
+ int curr = 0; \
+ while (off + curr < end + 4) { \
+ nzero32((off + curr), ctx); \
+ curr = curr + 4; \
+ } \
+} while (0)
+
+typedef struct {
+ void *addr;
+ uint32_t length;
+} __attribute__((packed)) region_t;
+
+typedef struct {
+ uint32_t unused_0[2];
+ uint32_t use_lv2_mode_0; // if 1, use lv2 list
+ uint32_t use_lv2_mode_1; // if 1, use lv2 list
+ uint32_t unused_10[3];
+ uint32_t list_count; // must be < 0x1F1
+ uint32_t unused_20[4];
+ uint32_t total_count; // only used in LV1 mode
+ uint32_t unused_34[1];
+ union {
+ region_t lv1[0x1F1];
+ region_t lv2[0x1F1];
+ } list;
+} __attribute__((packed)) cmd_0x50002_t;
+
+typedef struct heap_hdr {
+ void *data;
+ uint32_t size;
+ uint32_t size_aligned;
+ uint32_t padding;
+ struct heap_hdr *prev;
+ struct heap_hdr *next;
+} __attribute__((packed)) heap_hdr_t;
+
+cmd_0x50002_t cargs;
+
int module_get_export_func(SceUID pid, const char *modname, uint32_t libnid, uint32_t funcnid, uintptr_t *func);
int ksceAppMgrLaunchAppByPath(const char *name, const char *cmd, int cmdlen, int dynamic, void *opt, void *id);
@@ -38,6 +78,8 @@ static tai_hook_ref_t ksceSblSmCommCallFuncRef;
static SceUID hooks[8];
+static int doInject = 0;
+
static int ksceKernelStartPreloadedModulesPatched(SceUID pid) {
int res = TAI_CONTINUE(int, ksceKernelStartPreloadedModulesRef, pid);
@@ -97,7 +139,28 @@ static int ksceSblSsInfraAllocatePARangeVectorPatched(void *buf, int size, SceUI
return TAI_CONTINUE(int, ksceSblSsInfraAllocatePARangeVectorRef, buf, size, blockid, list);
}
+static int nzero32(uint32_t addr, int ctx) {
+ int ret = 0, sm_ret = 0;
+ memset(&cargs, 0, sizeof(cargs));
+ cargs.use_lv2_mode_0 = cargs.use_lv2_mode_1 = 0;
+ cargs.list_count = 3;
+ cargs.total_count = 1;
+ cargs.list.lv1[0].addr = cargs.list.lv1[1].addr = 0x50000000;
+ cargs.list.lv1[0].length = cargs.list.lv1[1].length = 0x10;
+ cargs.list.lv1[2].addr = 0;
+ cargs.list.lv1[2].length = addr - offsetof(heap_hdr_t, next);
+ ret = TAI_CONTINUE(int, ksceSblSmCommCallFuncRef, ctx, 0x50002, &sm_ret, &cargs, sizeof(cargs));
+ if (sm_ret < 0) {
+ return sm_ret;
+ }
+ return ret;
+}
+
static int ksceSblSmCommCallFuncPatched(int id, int service_id, int *f00d_resp, void *data, int size) {
+
+ if (doInject == 1 && service_id == 0xb0002)
+ NZERO_RANGE(0x0080bb44, 0x0080bb98, id);
+
int res = TAI_CONTINUE(int, ksceSblSmCommCallFuncRef, id, service_id, f00d_resp, data, size);
if (f00d_resp && service_id == SCE_SBL_SM_COMM_FID_SM_AUTH_SPKG) {
@@ -310,8 +373,11 @@ int k_modoru_get_factory_firmware(void) {
unsigned int factory_fw = -1;
void *sysroot = ksceKernelGetSysrootBuffer();
- if (sysroot)
+ if (sysroot) {
factory_fw = *(unsigned int *)(sysroot + 8);
+ if (*(unsigned int *)(sysroot + 4) > 0x03700011)
+ doInject = 1;
+ }
EXIT_SYSCALL(state);
return factory_fw;
diff --git a/main.c b/main.c
index 37108f8..da12de9 100644
--- a/main.c
+++ b/main.c
@@ -264,7 +264,7 @@ int main(int argc, char *argv[]) {
psvDebugScreenInit();
sceKernelPowerLock(0);
- printf("-- modoru v1.0\n");
+ printf("-- modoru v2.1\n");
printf(" by TheFloW\n\n");
if (sceIoDevctl("ux0:", 0x3001, NULL, 0, NULL, 0) == 0x80010030)
@@ -344,6 +344,11 @@ int main(int argc, char *argv[]) {
if (target_version < factory_version)
ErrorExit(10000, "Error you cannot go lower than your factory firmware.");
+ if (!bypass) {
+ if (current_version > 0x03730011)
+ ErrorExit(10000, "Error your current system software version is not supported.");
+ }
+
if (target_version == current_version) {
printf("Do you want to reinstall firmware ");
psvDebugScreenSetTextColor(YELLOW);
diff --git a/pkg/template.xml b/pkg/template.xml
index 9d45351..ffd6a0f 100644
--- a/pkg/template.xml
+++ b/pkg/template.xml
@@ -20,7 +20,7 @@
- v1.0
+ v2.1