Range checks added

This commit is contained in:
Duckbill 2018-01-02 14:23:45 +03:00
parent fd80294bf2
commit ca4685cc42

View File

@ -45,6 +45,7 @@ typedef struct CheatProcessInfo {
typedef struct CheatDescription {
u32 active;
u32 valid;
u32 keyActivated;
u32 keyCombo;
char name[40];
@ -52,6 +53,10 @@ typedef struct CheatDescription {
u64 codes[0];
} CheatDescription;
u32 codeStartAddress, heapStartAddress;
u32 codeTotalSize, heapTotalSize;
CheatDescription* cheats[1024] = { 0 };
u8 cheatFileBuffer[16384] = { 0 };
u32 cheatFilePos = 0;
@ -112,14 +117,36 @@ u64 cheatTitleInfo = -1ULL;
char failureReason[64];
void Cheat_write8(u32 offset, u8 value) {
*((u8*) (cheat_state.offset + offset)) = value;
bool Cheat_isValidAddress(u32 address) {
if (codeStartAddress <= address && address <= codeStartAddress + codeTotalSize) {
return true;
}
if (heapStartAddress <= address && address <= heapStartAddress + heapTotalSize) {
return true;
}
return false;
}
void Cheat_write16(u32 offset, u16 value) {
*((u16*) (cheat_state.offset + offset)) = value;
bool Cheat_write8(u32 offset, u8 value) {
if (Cheat_isValidAddress(cheat_state.offset + offset)) {
*((u8*) (cheat_state.offset + offset)) = value;
return true;
}
return false;
}
void Cheat_write32(u32 offset, u32 value) {
*((u32*) (cheat_state.offset + offset)) = value;
bool Cheat_write16(u32 offset, u16 value) {
if (Cheat_isValidAddress(cheat_state.offset + offset)) {
*((u16*) (cheat_state.offset + offset)) = value;
return true;
}
return false;
}
bool Cheat_write32(u32 offset, u32 value) {
if (Cheat_isValidAddress(cheat_state.offset + offset)) {
*((u32*) (cheat_state.offset + offset)) = value;
return true;
}
return false;
}
u8 Cheat_read8(u32 offset) {
@ -147,7 +174,7 @@ u8 Cheat_getNextTypeE(const CheatDescription* cheat) {
>> (typeEMapping[cheat_state.typeEIdx])) & 0xFF);
}
void Cheat_applyCheat(const CheatDescription* const cheat) {
u32 Cheat_applyCheat(const CheatDescription* const cheat) {
cheat_state.index = 0;
cheat_state.offset = 0;
cheat_state.data = 0;
@ -166,7 +193,7 @@ void Cheat_applyCheat(const CheatDescription* const cheat) {
u32 arg1 = (u32) ((cheat->codes[cheat_state.index])
& 0x00000000FFFFFFFFULL);
if (arg0 == 0 && arg1 == 0) {
goto end_main_loop;
return 0;
}
u32 code = ((arg0 >> 28) & 0x0F);
u32 subcode = ((arg0 >> 24) & 0x0F);
@ -177,7 +204,7 @@ void Cheat_applyCheat(const CheatDescription* const cheat) {
// Format: 0XXXXXXX YYYYYYYY
// Description: 32bit write of YYYYYYYY to 0XXXXXXX.
if (!skipExecution) {
Cheat_write32((arg0 & 0x0FFFFFFF), arg1);
if (!Cheat_write32((arg0 & 0x0FFFFFFF), arg1)) return 0;
}
break;
case 0x1:
@ -185,7 +212,7 @@ void Cheat_applyCheat(const CheatDescription* const cheat) {
// Format: 1XXXXXXX 0000YYYY
// Description: 16bit write of YYYY to 0XXXXXXX.
if (!skipExecution) {
Cheat_write16((arg0 & 0x0FFFFFFF), (u16) (arg1 & 0xFFFF));
if (!Cheat_write16((arg0 & 0x0FFFFFFF), (u16) (arg1 & 0xFFFF))) return 0;
}
break;
case 0x2:
@ -193,7 +220,7 @@ void Cheat_applyCheat(const CheatDescription* const cheat) {
// Format: 2XXXXXXX 000000YY
// Description: 8bit write of YY to 0XXXXXXX.
if (!skipExecution) {
Cheat_write8((arg0 & 0x0FFFFFFF), (u8) (arg1 & 0xFF));
if (!Cheat_write8((arg0 & 0x0FFFFFFF), (u8) (arg1 & 0xFF))) return 0;
}
break;
case 0x3:
@ -537,7 +564,7 @@ void Cheat_applyCheat(const CheatDescription* const cheat) {
// Note: used with the C, D3, and D9 types.
// Example: D3000000 023D6B28
if (!skipExecution) {
Cheat_write32(arg1, cheat_state.data);
if (!Cheat_write32(arg1, cheat_state.data)) return 0;
cheat_state.offset += 4;
}
break;
@ -549,7 +576,7 @@ void Cheat_applyCheat(const CheatDescription* const cheat) {
// Note: used with the C, D3, and DA types.
// Example: D7000000 023D6B28
if (!skipExecution) {
Cheat_write16(arg1, (u16) (cheat_state.data & 0xFFFF));
if (!Cheat_write16(arg1, (u16) (cheat_state.data & 0xFFFF))) return 0;
cheat_state.offset += 2;
}
break;
@ -561,7 +588,7 @@ void Cheat_applyCheat(const CheatDescription* const cheat) {
// Note: used with the C, D3, and DB types.
// Example: D8000000 023D6B28
if (!skipExecution) {
Cheat_write8(arg1, (u8) (cheat_state.data & 0xFF));
if (!Cheat_write8(arg1, (u8) (cheat_state.data & 0xFF))) return 0;
cheat_state.offset += 1;
}
break;
@ -625,7 +652,7 @@ void Cheat_applyCheat(const CheatDescription* const cheat) {
}
break;
default:
goto end_main_loop;
return 0;
}
break;
case 0xE:
@ -644,18 +671,18 @@ void Cheat_applyCheat(const CheatDescription* const cheat) {
for (u32 i = 0; i < count; i++) {
u8 byte = Cheat_getNextTypeE(cheat);
if (!skipExecution) {
Cheat_write8(beginOffset + i, byte);
if (!Cheat_write8(beginOffset + i, byte)) return 0;
}
}
cheat_state.index = cheat_state.typeELine;
}
break;
default:
goto end_main_loop;
return 0;
}
cheat_state.index++;
}
end_main_loop: ;
return 1;
}
Result Cheat_mapMemoryAndApplyCheat(u32 pid, CheatDescription* const cheat) {
@ -664,9 +691,7 @@ Result Cheat_mapMemoryAndApplyCheat(u32 pid, CheatDescription* const cheat) {
res = svcOpenProcess(&processHandle, pid);
if (R_SUCCEEDED(res)) {
u32 codeStartAddress, heapStartAddress;
u32 codeDestAddress, heapDestAddress;
u32 codeTotalSize, heapTotalSize;
s64 textStartAddress, textTotalRoundedSize, rodataTotalRoundedSize,
dataTotalRoundedSize;
@ -694,7 +719,7 @@ Result Cheat_mapMemoryAndApplyCheat(u32 pid, CheatDescription* const cheat) {
heapStartAddress, heapTotalSize);
if (R_SUCCEEDED(codeRes | heapRes)) {
Cheat_applyCheat(cheat);
cheat->valid = Cheat_applyCheat(cheat);
if (R_SUCCEEDED(codeRes))
svcUnmapProcessMemoryEx(processHandle, codeDestAddress,
@ -742,6 +767,7 @@ CheatDescription* Cheat_allocCheat() {
+ sizeof(u64) * (prev->codesCount));
}
cheat->active = 0;
cheat->valid = 1;
cheat->codesCount = 0;
cheat->keyActivated = 0;
cheat->keyCombo = 0;
@ -919,53 +945,6 @@ void Cheat_loadCheatsIntoMemory(u64 titleId) {
}
}
void loadCheatsIntoMemoryBin(u64 titleId) {
cheatCount = 0;
cheatTitleInfo = titleId;
hasKeyActivated = 0;
char path[] = "/luma/titles/0000000000000000/cheats.bin";
Cheat_progIdToStr(path + 28, titleId);
IFile file;
if (!Cheat_openLumaFile(&file, path))
return;
u8 buffer[8];
u64 total;
IFile_Read(&file, &total, buffer, 1);
u8 cc = buffer[0];
for (u8 i = 0; i < cc; i++) {
CheatDescription* cheat = Cheat_allocCheat();
cheat->active = 0;
IFile_Read(&file, &total, buffer, 1);
u8 nameLen = buffer[0];
IFile_Read(&file, &total, cheat->name, nameLen);
cheat->name[nameLen] = '\0';
IFile_Read(&file, &total, buffer, 1);
u8 codeCount = buffer[0];
cheat->codesCount = 0;
cheat->keyActivated = 0;
cheat->keyCombo = 0;
for (u8 j = 0; j < codeCount; j++) {
IFile_Read(&file, &total, buffer, 8);
u64 tmp = buffer[0];
for (u8 k = 1; k < 8; k++) {
tmp = (tmp << 8) + buffer[k];
}
Cheat_addCode(cheat, tmp);
if (((tmp >> 32) & 0xFFFFFFFF) == 0xDD000000) {
cheat->keyCombo |= (tmp & 0xFFF);
cheat->keyActivated = 1;
}
}
}
IFile_Close(&file);
}
u32 Cheat_GetCurrentPID(u64* titleId) {
s32 processAmount = Cheats_FetchProcessInfo();
@ -1071,7 +1050,7 @@ void RosalinaMenu_Cheats(void) {
const char * keyAct = (cheats[j]->keyActivated ? "*" : " ");
sprintf(buf, "%s%s%s", checkbox, keyAct, cheats[j]->name);
Draw_DrawString(30, 30 + i * SPACING_Y, COLOR_WHITE, 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,
j == selected ? '>' : ' ');
}