mirror of
https://github.com/zeldaret/st
synced 2026-08-24 23:36:03 -04:00
521100caed
* `Actor::mType` field * Remove fake symbol `data_027e0254` * `dsd format` * eur: Enable dsprot decomp * jp: Enable dsprot decomp * dsprot OK * `dsd format` * Use new `weak` attribute * Add relocations for exception table link-time constants * Add exception table symbols * Bump dsd to v0.12.0 * `#define FALSE 1` ??? Why did I make it 1? * Truncate `data_ov001_020c27a8` That data belongs to dsprot
153 lines
4.6 KiB
C
153 lines
4.6 KiB
C
/* No dedicated header */
|
|
|
|
#include "dsprot.h"
|
|
#include "dsprot/encoding_constants.h"
|
|
#include "dsprot/encryptor.h"
|
|
#include "dsprot/integrity.h"
|
|
#include "dsprot/mac_owner.h"
|
|
#include "dsprot/rom_test.h"
|
|
|
|
// Functions to be encrypted (cannot be called directly)
|
|
u32 DetectFlashcart(void *callback);
|
|
u32 DetectNotFlashcart(void *callback);
|
|
u32 DetectEmulator(void *callback);
|
|
u32 DetectNotEmulator(void *callback);
|
|
u32 DetectDummy(void *callback);
|
|
u32 DetectNotDummy(void *callback);
|
|
|
|
#define DSP_OBFS_OFFSET (0x320)
|
|
|
|
#define FUNC_QUEUE_END (0)
|
|
|
|
typedef u32 (*TaskFunc)(void);
|
|
typedef void (*CallbackFunc)(void);
|
|
|
|
enum {
|
|
EXPECT_FALSE,
|
|
EXPECT_TRUE
|
|
};
|
|
|
|
// This was likely not originally an inline, but an inline is able to match here nicely
|
|
static inline u32 dsprotMain(u32 *func_queue, int expected_result, void *callback) {
|
|
BOOL ret;
|
|
BOOL func_result;
|
|
s32 compare_sum;
|
|
u32 i;
|
|
s32 func_result_sum;
|
|
|
|
// These two bit arrays must be signed to match
|
|
compare_sum = 0;
|
|
func_result_sum = 0;
|
|
|
|
for (i = 0; func_queue[i] != FUNC_QUEUE_END; i++) {
|
|
func_result = ((TaskFunc) (func_queue[i] - ENC_VAL_1 - DSP_OBFS_OFFSET))() != 0;
|
|
|
|
func_result_sum += func_result;
|
|
func_result_sum <<= 1;
|
|
|
|
compare_sum += TRUE;
|
|
compare_sum <<= 1;
|
|
}
|
|
|
|
if (expected_result == EXPECT_TRUE) {
|
|
ret = (func_result_sum >> 1) == (compare_sum >> 1);
|
|
} else {
|
|
ret = ((func_result_sum & compare_sum) >> 1) != 0;
|
|
}
|
|
|
|
if (callback != NULL && ret) {
|
|
((CallbackFunc) callback)();
|
|
}
|
|
|
|
return (u32) ret;
|
|
}
|
|
|
|
u32 DetectFlashcart(void *callback) {
|
|
u32 func_queue[32];
|
|
|
|
func_queue[2] = FUNC_QUEUE_END;
|
|
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_ROMTest_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
|
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_ROMTest_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
|
|
|
return dsprotMain(&func_queue[0], EXPECT_FALSE, callback);
|
|
}
|
|
|
|
u32 DetectNotFlashcart(void *callback) {
|
|
u32 func_queue[32];
|
|
|
|
func_queue[2] = FUNC_QUEUE_END;
|
|
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_ROMTest_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
|
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_ROMTest_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
|
|
|
return dsprotMain(&func_queue[0], EXPECT_TRUE, callback);
|
|
}
|
|
|
|
u32 DetectEmulator(void *callback) {
|
|
u32 func_queue[32];
|
|
|
|
func_queue[2] = FUNC_QUEUE_END;
|
|
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_MACOwner_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
|
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_MACOwner_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
|
|
|
return dsprotMain(&func_queue[0], EXPECT_FALSE, callback);
|
|
}
|
|
|
|
u32 DetectNotEmulator(void *callback) {
|
|
u32 func_queue[32];
|
|
|
|
func_queue[2] = FUNC_QUEUE_END;
|
|
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_MACOwner_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
|
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_MACOwner_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
|
|
|
return dsprotMain(&func_queue[0], EXPECT_TRUE, callback);
|
|
}
|
|
|
|
u32 DetectDummy(void *callback) {
|
|
u32 func_queue[32];
|
|
|
|
// Prevent optimization of the function queue processing
|
|
*(u32 *) &func_queue[0] = FUNC_QUEUE_END;
|
|
|
|
return dsprotMain(&func_queue[0], EXPECT_FALSE, callback);
|
|
}
|
|
|
|
u32 DetectNotDummy(void *callback) {
|
|
u32 func_queue[32];
|
|
|
|
// Prevent optimization of the function queue processing
|
|
*(u32 *) &func_queue[0] = FUNC_QUEUE_END;
|
|
|
|
return dsprotMain(&func_queue[0], EXPECT_TRUE, callback);
|
|
}
|
|
|
|
// DECRYPTION_WRAPPER(DetectFlashcart, 0xac, 0x2e8b, DSProt_)
|
|
// DECRYPTION_WRAPPER(DetectNotFlashcart, 0xac, 0x2e8b, DSProt_)
|
|
// DECRYPTION_WRAPPER(DetectEmulator, 0xac, 0x2e8b, DSProt_)
|
|
// DECRYPTION_WRAPPER(DetectNotEmulator, 0xac, 0x2e8b, DSProt_)
|
|
// DECRYPTION_WRAPPER(DetectDummy, 0x94, 0x2e8b, DSProt_)
|
|
// DECRYPTION_WRAPPER(DetectNotDummy, 0x94, 0x2e8b, DSProt_)
|
|
|
|
// // clang-format off
|
|
// asm void NitroStaticInit() {
|
|
// stmdb sp!, {lr};
|
|
// add r0, pc, #0x4;
|
|
// bl Encryptor_DecodeFunctionTable;
|
|
// ldmia sp!, {pc};
|
|
// dcd DSProt_DetectFlashcart + ENC_VAL_1
|
|
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
|
|
// dcd DSProt_DetectNotFlashcart + ENC_VAL_1
|
|
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
|
|
// dcd DSProt_DetectEmulator + ENC_VAL_1
|
|
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
|
|
// dcd DSProt_DetectNotEmulator + ENC_VAL_1
|
|
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
|
|
// dcd DSProt_DetectDummy + ENC_VAL_1
|
|
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
|
|
// dcd DSProt_DetectNotDummy + ENC_VAL_1
|
|
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
|
|
// dcd 0
|
|
// dcd 0
|
|
// dcd DSProt_Garbage + 0x1400
|
|
// }
|
|
// // clang-format on
|