More range checks and separate code and heap allocation

This commit is contained in:
Duckbill 2018-01-03 00:27:44 +03:00
parent ca4685cc42
commit d28642d2c3

View File

@ -149,14 +149,26 @@ bool Cheat_write32(u32 offset, u32 value) {
return false; return false;
} }
u8 Cheat_read8(u32 offset) { bool Cheat_read8(u32 offset, u8* retValue) {
return *((u8*) (cheat_state.offset + offset)); if (Cheat_isValidAddress(cheat_state.offset + offset)) {
*retValue = *((u8*) (cheat_state.offset + offset));
return true;
}
return false;
} }
u16 Cheat_read16(u32 offset) { bool Cheat_read16(u32 offset, u16* retValue) {
return *((u16*) (cheat_state.offset + offset)); if (Cheat_isValidAddress(cheat_state.offset + offset)) {
*retValue = *((u16*) (cheat_state.offset + offset));
return true;
}
return false;
} }
u32 Cheat_read32(u32 offset) { bool Cheat_read32(u32 offset, u32* retValue) {
return *((u32*) (cheat_state.offset + offset)); if (Cheat_isValidAddress(cheat_state.offset + offset)) {
*retValue = *((u32*) (cheat_state.offset + offset));
return true;
}
return false;
} }
u8 typeEMapping[] = { 4 << 3, 5 << 3, 6 << 3, 7 << 3, 0 << 3, 1 << 3, 2 << 3, 3 u8 typeEMapping[] = { 4 << 3, 5 << 3, 6 << 3, 7 << 3, 0 << 3, 1 << 3, 2 << 3, 3
@ -231,7 +243,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
// Example: 323D6B28 10000000 // Example: 323D6B28 10000000
{ {
u32 newSkip; u32 newSkip;
if (Cheat_read32(arg0 & 0x0FFFFFFF) < arg1) { u32 value = 0;
if (!Cheat_read32(arg0 & 0x0FFFFFFF, &value)) return 0;
if (value < arg1) {
newSkip = 0; newSkip = 0;
} else { } else {
newSkip = 1; newSkip = 1;
@ -250,7 +264,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
// Example: 423D6B28 10000000 // Example: 423D6B28 10000000
{ {
u32 newSkip; u32 newSkip;
if (Cheat_read32(arg0 & 0x0FFFFFFF) > arg1) { u32 value = 0;
if (!Cheat_read32(arg0 & 0x0FFFFFFF, &value)) return 0;
if (value > arg1) {
newSkip = 0; newSkip = 0;
} else { } else {
newSkip = 1; newSkip = 1;
@ -269,7 +285,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
// Example: 523D6B28 10000000 // Example: 523D6B28 10000000
{ {
u32 newSkip; u32 newSkip;
if (Cheat_read32(arg0 & 0x0FFFFFFF) == arg1) { u32 value = 0;
if (!Cheat_read32(arg0 & 0x0FFFFFFF, &value)) return 0;
if (value == arg1) {
newSkip = 0; newSkip = 0;
} else { } else {
newSkip = 1; newSkip = 1;
@ -288,7 +306,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
// Example: 623D6B28 10000000 // Example: 623D6B28 10000000
{ {
u32 newSkip; u32 newSkip;
if (Cheat_read32(arg0 & 0x0FFFFFFF) != arg1) { u32 value = 0;
if (!Cheat_read32(arg0 & 0x0FFFFFFF, &value)) return 0;
if (value != arg1) {
newSkip = 0; newSkip = 0;
} else { } else {
newSkip = 1; newSkip = 1;
@ -311,7 +331,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
if (mask == 0) { if (mask == 0) {
mask = 0xFFFF; mask = 0xFFFF;
} }
if ((Cheat_read16(arg0 & 0x0FFFFFFF) & mask) < (arg1 & 0xFFFF)) { u16 value = 0;
if (!Cheat_read16(arg0 & 0x0FFFFFFF, &value)) return 0;
if ((value & mask) < (arg1 & 0xFFFF)) {
newSkip = 0; newSkip = 0;
} else { } else {
newSkip = 1; newSkip = 1;
@ -334,7 +356,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
if (mask == 0) { if (mask == 0) {
mask = 0xFFFF; mask = 0xFFFF;
} }
if ((Cheat_read16(arg0 & 0x0FFFFFFF) & mask) > (arg1 & 0xFFFF)) { u16 value = 0;
if (!Cheat_read16(arg0 & 0x0FFFFFFF, &value)) return 0;
if ((value & mask) > (arg1 & 0xFFFF)) {
newSkip = 0; newSkip = 0;
} else { } else {
newSkip = 1; newSkip = 1;
@ -357,7 +381,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
if (mask == 0) { if (mask == 0) {
mask = 0xFFFF; mask = 0xFFFF;
} }
if ((Cheat_read16(arg0 & 0x0FFFFFFF) & mask) == (arg1 & 0xFFFF)) { u16 value = 0;
if (!Cheat_read16(arg0 & 0x0FFFFFFF, &value)) return 0;
if ((value & mask) == (arg1 & 0xFFFF)) {
newSkip = 0; newSkip = 0;
} else { } else {
newSkip = 1; newSkip = 1;
@ -380,7 +406,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
if (mask == 0) { if (mask == 0) {
mask = 0xFFFF; mask = 0xFFFF;
} }
if ((Cheat_read16(arg0 & 0x0FFFFFFF) & mask) != (arg1 & 0xFFFF)) { u16 value = 0;
if (!Cheat_read16(arg0 & 0x0FFFFFFF, &value)) return 0;
if ((value & mask) != (arg1 & 0xFFFF)) {
newSkip = 0; newSkip = 0;
} else { } else {
newSkip = 1; newSkip = 1;
@ -600,7 +628,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
// Note: used with the D5 and D6 types. // Note: used with the D5 and D6 types.
// Example: D9000000 023D6B28 // Example: D9000000 023D6B28
if (!skipExecution) { if (!skipExecution) {
cheat_state.data = Cheat_read32(arg1); u32 value = 0;
if (!Cheat_read32(arg1, &value)) return 0;
cheat_state.data = value;
} }
break; break;
case 0x0A: case 0x0A:
@ -611,7 +641,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
// Note: used with the D5 and D7 types. // Note: used with the D5 and D7 types.
// Example: DA000000 023D6B28 // Example: DA000000 023D6B28
if (!skipExecution) { if (!skipExecution) {
cheat_state.data = Cheat_read16(arg1); u16 value = 0;
if (!Cheat_read16(arg1, &value)) return 0;
cheat_state.data = value;
} }
break; break;
case 0x0B: case 0x0B:
@ -622,7 +654,9 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
// Note: used with the D5 and D8 types. // Note: used with the D5 and D8 types.
// Example: DB000000 023D6B28 // Example: DB000000 023D6B28
if (!skipExecution) { if (!skipExecution) {
cheat_state.data = Cheat_read8(arg1); u8 value = 0;
if (!Cheat_read8(arg1, &value)) return 0;
cheat_state.data = value;
} }
break; break;
case 0x0C: case 0x0C:
@ -640,7 +674,7 @@ u32 Cheat_applyCheat(const CheatDescription* const cheat) {
// DD Type // DD Type
{ {
u32 newSkip; u32 newSkip;
if ((HID_PAD & arg1) == arg1) { if (arg1 == 0 || (HID_PAD & arg1) == arg1) {
newSkip = 0; newSkip = 0;
} else { } else {
newSkip = 1; newSkip = 1;
@ -715,24 +749,37 @@ Result Cheat_mapMemoryAndApplyCheat(u32 pid, CheatDescription* const cheat) {
Result codeRes = svcMapProcessMemoryEx(processHandle, codeDestAddress, Result codeRes = svcMapProcessMemoryEx(processHandle, codeDestAddress,
codeStartAddress, codeTotalSize); codeStartAddress, codeTotalSize);
if (R_FAILED(codeRes)) {
codeStartAddress = codeTotalSize = 0;
}
Result heapRes = svcMapProcessMemoryEx(processHandle, heapDestAddress, Result heapRes = svcMapProcessMemoryEx(processHandle, heapDestAddress,
heapStartAddress, heapTotalSize); heapStartAddress, heapTotalSize);
if (R_FAILED(heapRes)) {
heapStartAddress = heapTotalSize = 0;
}
if (R_SUCCEEDED(codeRes | heapRes)) {
if (R_SUCCEEDED(codeRes) || R_SUCCEEDED(heapRes)) {
cheat->valid = Cheat_applyCheat(cheat); cheat->valid = Cheat_applyCheat(cheat);
if (R_SUCCEEDED(codeRes)) if (R_SUCCEEDED(codeRes)) {
svcUnmapProcessMemoryEx(processHandle, codeDestAddress, svcUnmapProcessMemoryEx(processHandle, codeDestAddress,
codeTotalSize); codeTotalSize);
if (R_SUCCEEDED(heapRes)) }
if (R_SUCCEEDED(heapRes)) {
svcUnmapProcessMemoryEx(processHandle, heapDestAddress, svcUnmapProcessMemoryEx(processHandle, heapDestAddress,
heapTotalSize); heapTotalSize);
}
svcCloseHandle(processHandle); svcCloseHandle(processHandle);
cheat->active = 1; cheat->active = 1;
} else { } else {
svcCloseHandle(processHandle); svcCloseHandle(processHandle);
sprintf(failureReason, "Can not map any memory");
return codeRes;
} }
} else {
sprintf(failureReason, "Open process failed");
} }
return res; return res;
} }
@ -1033,28 +1080,33 @@ void RosalinaMenu_Cheats(void) {
} else { } else {
s32 selected = 0, page = 0, pagePrev = 0; s32 selected = 0, page = 0, pagePrev = 0;
Result r = 0;
do { do {
Draw_Lock(); Draw_Lock();
if (page != pagePrev) { if (page != pagePrev || R_FAILED(r)) {
Draw_ClearFramebuffer(); Draw_ClearFramebuffer();
} }
Draw_DrawFormattedString(10, 10, COLOR_TITLE, "Cheat list"); if (R_SUCCEEDED(r)) {
Draw_DrawFormattedString(10, 10, COLOR_TITLE, "Cheat list");
for (s32 i = 0; for (s32 i = 0;
i < CHEATS_PER_MENU_PAGE i < CHEATS_PER_MENU_PAGE
&& page * CHEATS_PER_MENU_PAGE + i < cheatCount; && page * CHEATS_PER_MENU_PAGE + i < cheatCount;
i++) { i++) {
char buf[65] = { 0 }; char buf[65] = { 0 };
s32 j = page * CHEATS_PER_MENU_PAGE + i; s32 j = page * CHEATS_PER_MENU_PAGE + i;
const char * checkbox = (cheats[j]->active ? "(x) " : "( ) "); const char * checkbox = (cheats[j]->active ? "(x) " : "( ) ");
const char * keyAct = (cheats[j]->keyActivated ? "*" : " "); const char * keyAct = (cheats[j]->keyActivated ? "*" : " ");
sprintf(buf, "%s%s%s", checkbox, keyAct, cheats[j]->name); sprintf(buf, "%s%s%s", checkbox, keyAct, cheats[j]->name);
Draw_DrawString(30, 30 + i * SPACING_Y, cheats[j]->valid ? COLOR_WHITE : COLOR_RED, buf); Draw_DrawString(30, 30 + i * SPACING_Y, cheats[j]->valid ? COLOR_WHITE : COLOR_RED, buf);
Draw_DrawCharacter(10, 30 + i * SPACING_Y, COLOR_TITLE, Draw_DrawCharacter(10, 30 + i * SPACING_Y, COLOR_TITLE,
j == selected ? '>' : ' '); j == selected ? '>' : ' ');
}
} else {
Draw_DrawFormattedString(10, 10, COLOR_TITLE, "ERROR: %08x", r);
Draw_DrawFormattedString(10, 30, COLOR_RED, failureReason);
} }
Draw_FlushFramebuffer(); Draw_FlushFramebuffer();
Draw_Unlock(); Draw_Unlock();
@ -1070,11 +1122,11 @@ void RosalinaMenu_Cheats(void) {
if (pressed & BUTTON_B) if (pressed & BUTTON_B)
break; break;
else if (pressed & BUTTON_A) { else if ((pressed & BUTTON_A) && R_SUCCEEDED(r)) {
if (cheats[selected]->active) { if (cheats[selected]->active) {
cheats[selected]->active = 0; cheats[selected]->active = 0;
} else { } else {
Cheat_mapMemoryAndApplyCheat(pid, cheats[selected]); r = Cheat_mapMemoryAndApplyCheat(pid, cheats[selected]);
} }
hasKeyActivated = 0; hasKeyActivated = 0;
for (int i = 0; i < cheatCount; i++) { for (int i = 0; i < cheatCount; i++) {