Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Missing Stack Variable #261

Open
InusualZ opened this issue Jul 8, 2023 · 2 comments
Open

[BUG] Missing Stack Variable #261

InusualZ opened this issue Jul 8, 2023 · 2 comments

Comments

@InusualZ
Copy link

InusualZ commented Jul 8, 2023

Bug

In the decompilation, you see this line:

temp_r0_2 = (sp8 << 8) | sp9;

but the variable sp9 its never declared.

Decompilation

s32 PatCryptDecrypt(s8* data, s16* size) {
    u8 sp10;
    u8 sp8;
    s16 temp_r0_2;
    s16 var_r28;
    s32 var_r29;
    s8* var_r25;
    u16 temp_r3;
    u32 temp_r0;
    u32 temp_r0_3;
    u32 temp_r0_4;
    u32 temp_r3_2;
    u32 temp_r3_3;
    u32 temp_r3_4;

    if ((data == NULL) || (size == NULL) || (temp_r3 = *size, ((temp_r3 == 0) != 0))) {
        return 0;
    }
    temp_r3_2 = temp_r3 >> 0x1F;
    temp_r0 = (temp_r3 << 0x1C) - temp_r3_2;
    if ((((temp_r0 << 4) | (temp_r0 >> 0x1C)) + temp_r3_2) != 0) {
        return 0x80000000;
    }
    memcpy(&sp10, data, 0x10);
    Camellia_DecryptBlock(0x100, &sp10, KeyTable, &sp10);
    memcpy(&sp8, &sp10, 4);
    temp_r0_2 = (sp8 << 8) | sp9;
    var_r29 = 4;
    var_r28 = 0;
    var_r25 = data;
loop_11:
    if ((var_r29 < *size) && (var_r28 < temp_r0_2)) {
        if (var_r28 < temp_r0_2) {
            temp_r3_3 = var_r29 >> 0x1F;
            temp_r0_3 = (var_r29 << 0x1C) - temp_r3_3;
            *var_r25 = (&sp10)[((temp_r0_3 << 4) | (temp_r0_3 >> 0x1C)) + temp_r3_3];
        }
        var_r29 += 1;
        var_r28 += 1;
        var_r25 += 1;
        temp_r3_4 = var_r29 >> 0x1F;
        temp_r0_4 = (var_r29 << 0x1C) - temp_r3_4;
        if ((((temp_r0_4 << 4) | (temp_r0_4 >> 0x1C)) + temp_r3_4) == 0) {
            memcpy(&sp10, &data[var_r29], 0x10);
            Camellia_DecryptBlock(0x100, &sp10, KeyTable + 0x3670, &sp10);
        }
        goto loop_11;
    }
    *size = var_r28;
    return 0;
}

Assembly:

.include "macros.s"

.section .text, "ax"

/* int PatCryptDecrypt(char* data, short* size) */
.global PatCryptDecrypt
PatCryptDecrypt:
/* 8042402C 003E760C  94 21 FF C0 */	stwu r1, -0x40(r1)
/* 80424030 003E7610  7C 08 02 A6 */	mflr r0
/* 80424034 003E7614  90 01 00 44 */	stw r0, 0x44(r1)
/* 80424038 003E7618  39 61 00 40 */	addi r11, r1, 0x40
/* 8042403C 003E761C  48 03 2D C1 */	bl _savegpr_24
/* 80424040 003E7620  7C 7A 1B 78 */	mr r26, r3
/* 80424044 003E7624  7C 9B 23 78 */	mr r27, r4
/* 80424048 003E7628  2C 03 00 00 */	cmpwi r3, 0x0
/* 8042404C 003E762C  41 82 00 18 */	beq lbl_80424064
/* 80424050 003E7630  2C 04 00 00 */	cmpwi r4, 0x0
/* 80424054 003E7634  41 82 00 10 */	beq lbl_80424064
/* 80424058 003E7638  A0 64 00 00 */	lhz r3, 0x0(r4)
/* 8042405C 003E763C  2C 03 00 00 */	cmpwi r3, 0x0
/* 80424060 003E7640  40 82 00 0C */	bne lbl_8042406C
lbl_80424064:
/* 80424064 003E7644  38 60 00 00 */	li r3, 0x0
/* 80424068 003E7648  48 00 01 18 */	b lbl_80424180
lbl_8042406C:
/* 8042406C 003E764C  54 60 E0 06 */	slwi r0, r3, 28
/* 80424070 003E7650  54 63 0F FE */	srwi r3, r3, 31
/* 80424074 003E7654  7C 03 00 50 */	subf r0, r3, r0
/* 80424078 003E7658  54 00 20 3E */	rlwinm r0, r0, 0x4, 0x0, 0x1f
/* 8042407C 003E765C  7C 00 1A 14 */	add r0, r0, r3
/* 80424080 003E7660  2C 00 00 00 */	cmpwi r0, 0x0
/* 80424084 003E7664  41 82 00 0C */	beq lbl_80424090
/* 80424088 003E7668  3C 60 80 00 */	lis r3, 0x8000
/* 8042408C 003E766C  48 00 00 F4 */	b lbl_80424180
lbl_80424090:
/* 80424090 003E7670  38 61 00 10 */	addi r3, r1, 0x10
/* 80424094 003E7674  7F 44 D3 78 */	mr r4, r26
/* 80424098 003E7678  38 A0 00 10 */	li r5, 0x10
/* 8042409C 003E767C  4B BD FF 65 */	bl memcpy
/* 804240A0 003E7680  38 60 01 00 */	li r3, 0x100
/* 804240A4 003E7684  38 81 00 10 */	addi r4, r1, 0x10
/* 804240A8 003E7688  3F C0 80 6D */	lis r30, KeyTable@ha
/* 804240AC 003E768C  38 BE 36 70 */	addi r5, r30, KeyTable@l
/* 804240B0 003E7690  7C 86 23 78 */	mr r6, r4
/* 804240B4 003E7694  4B FF FB D1 */	bl Camellia_DecryptBlock
/* 804240B8 003E7698  38 61 00 08 */	addi r3, r1, 0x8
/* 804240BC 003E769C  38 81 00 10 */	addi r4, r1, 0x10
/* 804240C0 003E76A0  38 A0 00 04 */	li r5, 0x4
/* 804240C4 003E76A4  4B BD FF 3D */	bl memcpy
/* 804240C8 003E76A8  88 01 00 08 */	lbz r0, 0x8(r1)
/* 804240CC 003E76AC  54 03 40 2E */	slwi r3, r0, 8
/* 804240D0 003E76B0  88 01 00 09 */	lbz r0, 0x9(r1)
/* 804240D4 003E76B4  7C 60 03 78 */	or r0, r3, r0
/* 804240D8 003E76B8  54 1F 04 3E */	clrlwi r31, r0, 16
/* 804240DC 003E76BC  3B A0 00 04 */	li r29, 0x4
/* 804240E0 003E76C0  3B 80 00 00 */	li r28, 0x0
/* 804240E4 003E76C4  3B 01 00 10 */	addi r24, r1, 0x10
/* 804240E8 003E76C8  7F 59 D3 78 */	mr r25, r26
/* 804240EC 003E76CC  48 00 00 74 */	b lbl_80424160
lbl_804240F0:
/* 804240F0 003E76D0  7C 1C F8 00 */	cmpw r28, r31
/* 804240F4 003E76D4  40 80 00 20 */	bge lbl_80424114
/* 804240F8 003E76D8  57 A0 E0 06 */	slwi r0, r29, 28
/* 804240FC 003E76DC  57 A3 0F FE */	srwi r3, r29, 31
/* 80424100 003E76E0  7C 03 00 50 */	subf r0, r3, r0
/* 80424104 003E76E4  54 00 20 3E */	rlwinm r0, r0, 0x4, 0x0, 0x1f
/* 80424108 003E76E8  7C 00 1A 14 */	add r0, r0, r3
/* 8042410C 003E76EC  7C 18 00 AE */	lbzx r0, r24, r0
/* 80424110 003E76F0  98 19 00 00 */	stb r0, 0x0(r25)
lbl_80424114:
/* 80424114 003E76F4  3B BD 00 01 */	addi r29, r29, 0x1
/* 80424118 003E76F8  3B 9C 00 01 */	addi r28, r28, 0x1
/* 8042411C 003E76FC  3B 39 00 01 */	addi r25, r25, 0x1
/* 80424120 003E7700  57 A0 E0 06 */	slwi r0, r29, 28
/* 80424124 003E7704  57 A3 0F FE */	srwi r3, r29, 31
/* 80424128 003E7708  7C 03 00 50 */	subf r0, r3, r0
/* 8042412C 003E770C  54 00 20 3E */	rlwinm r0, r0, 0x4, 0x0, 0x1f
/* 80424130 003E7710  7C 00 1A 14 */	add r0, r0, r3
/* 80424134 003E7714  2C 00 00 00 */	cmpwi r0, 0x0
/* 80424138 003E7718  40 82 00 28 */	bne lbl_80424160
/* 8042413C 003E771C  38 61 00 10 */	addi r3, r1, 0x10
/* 80424140 003E7720  7C 9A EA 14 */	add r4, r26, r29
/* 80424144 003E7724  38 A0 00 10 */	li r5, 0x10
/* 80424148 003E7728  4B BD FE B9 */	bl memcpy
/* 8042414C 003E772C  38 60 01 00 */	li r3, 0x100
/* 80424150 003E7730  38 81 00 10 */	addi r4, r1, 0x10
/* 80424154 003E7734  38 BE 36 70 */	addi r5, r30, 0x3670
/* 80424158 003E7738  7C 86 23 78 */	mr r6, r4
/* 8042415C 003E773C  4B FF FB 29 */	bl Camellia_DecryptBlock
lbl_80424160:
/* 80424160 003E7740  A0 1B 00 00 */	lhz r0, 0x0(r27)
/* 80424164 003E7744  7C 1D 00 00 */	cmpw r29, r0
/* 80424168 003E7748  40 80 00 0C */	bge lbl_80424174
/* 8042416C 003E774C  7C 1C F8 00 */	cmpw r28, r31
/* 80424170 003E7750  41 80 FF 80 */	blt lbl_804240F0
lbl_80424174:
/* 80424174 003E7754  57 80 04 3E */	clrlwi r0, r28, 16
/* 80424178 003E7758  B0 1B 00 00 */	sth r0, 0x0(r27)
/* 8042417C 003E775C  38 60 00 00 */	li r3, 0x0
lbl_80424180:
/* 80424180 003E7760  39 61 00 40 */	addi r11, r1, 0x40
/* 80424184 003E7764  48 03 2C C5 */	bl _restgpr_24
/* 80424188 003E7768  80 01 00 44 */	lwz r0, 0x44(r1)
/* 8042418C 003E776C  7C 08 03 A6 */	mtlr r0
/* 80424190 003E7770  38 21 00 40 */	addi r1, r1, 0x40
/* 80424194 003E7774  4E 80 00 20 */	blr

Context

typedef unsigned long size_t;

void* memset(void* dest, int val, size_t count);
void* memcpy(void* dest, const void* src, size_t n);

int PatCryptEncrypt(char* data, short* size);
int PatCryptDecrypt(char* data, short* size);

typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];


KEY_TABLE_TYPE KeyTable;

void Camellia_Ekeygen(const int keyBitLength,
		      const unsigned char *rawKey, 
		      KEY_TABLE_TYPE keyTable);

void Camellia_EncryptBlock(const int keyBitLength,
			   const unsigned char *plaintext, 
			   const KEY_TABLE_TYPE keyTable, 
			   unsigned char *cipherText);

void Camellia_DecryptBlock(const int keyBitLength, 
			   const unsigned char *cipherText, 
			   const KEY_TABLE_TYPE keyTable, 
			   unsigned char *plaintext);

void _savegpr_14(); // @80456dd4
void _savegpr_15(); // @80456dd8
void _savegpr_16(); // @80456ddc
void _savegpr_17(); // @80456de0
void _savegpr_18(); // @80456de4
void _savegpr_19(); // @80456de8
void _savegpr_20(); // @80456dec
void _savegpr_21(); // @80456df0
void _savegpr_22(); // @80456df4
void _savegpr_23(); // @80456df8
void _savegpr_24(); // @80456dfc
void _savegpr_25(); // @80456e00
void _savegpr_26(); // @80456e04
void _savegpr_27(); // @80456e08

void _restgpr_14(); // @80456e20
void _restgpr_15(); // @80456e24
void _restgpr_16(); // @80456e28
void _restgpr_17(); // @80456e2c
void _restgpr_18(); // @80456e30
void _restgpr_19(); // @80456e34
void _restgpr_20(); // @80456e38
void _restgpr_21(); // @80456e3c
void _restgpr_22(); // @80456e40
void _restgpr_23(); // @80456e44
void _restgpr_24(); // @80456e48
void _restgpr_25(); // @80456e4c
void _restgpr_26(); // @80456e50
void _restgpr_27(); // @80456e54
@mkst
Copy link

mkst commented Dec 30, 2023

sp9 is implicit. Looking at the code you can see that sp10 is at least 0x10 big, and sp8 is at least 0x4 big:

memcpy(&sp10, data, 0x10); // copy 16 bytes from data into sp10 -> sp10 must be at least 16 bytes big, e.g. u8 sp10[16];

memcpy(&sp8, &sp10, 4);  // copy 4 bytes from sp10 into sp8 -> sp8 must be at least 4 bytes big, e.g. u8 sp8[4];

This means that

temp_r0_2 = (sp8 << 8) | sp9;

would be

temp_r0_2 = (sp8[0] << 8) | sp8[1];

Are you expecting m2c to create a variable for sp9 (which isn't a real variable) or to know that sp8 is at least size 4, therefore should be a byte array of 4?

@simonlindholm
Copy link
Collaborator

#235 fixes this by adding a variable declaration for sp9, but I never landed it because on review I started feeling like m2c should do something smarter when it detects stack variables that never get written to/addresses taken.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants