I am trying to modify a save file for a game. I think it is using an XOR cipher to encrypt it. Looking though the disassembly I think I found the function that decrypts it. I ran the assembly through a decompiler to get a better grip on what is going on.
I am a C# programmer with some knowledge of C/C++. I generally understand what is accomplished by this code, but there are some details I don't understand.
int __fastcall DecryptBuffer(unsigned __int8 *a1, int a2, int a3, unsigned int a4, int a5)
{
unsigned __int8 *v5;
unsigned __int8 *v6;
int result;
int v8;
v5 = a1;
v6 = &a1[a2];
result = a5;
v8 = a5 - (_DWORD)v5;
while ( v5 != v6 )
{
result = *v5 ^ *(unsigned __int8 *)(a3 + (unsigned int)&v5[v8] % a4);
*v5++ = result;
}
return result;
}
It accepts as parameters:
a1
- a byte arraya2
- the length of the arraya3
-0xB19D425B
a4
-0x107
a5
-0x00
First, I can't figure out the value of v8
. I don't know what (_DWORD)v5
means, or why it is subtracted from zero.
Second, I don't know what (unsigned int)&v5[v8]
is actually doing. I take it to mean it is looking up a byte somewhere in the array, but is it retrieving a single byte and casting to an uint, or four bytes?
Here is the disassembly:
sub_301E44
PUSH.W {R4-R8,LR}
MOV R4, R0
ADDS R6, R0, R1
LDR R0, [SP,#0x18+arg_0]
MOV R7, R2
MOV R8, R3
SUBS R5, R0, R4
loc_301E54
CMP R4, R6
BEQ locret_301E6C
ADDS R0, R5, R4
MOV R1, R8
BL.W __aeabi_uidivmod
LDRB R0, [R4]
LDRB R3, [R7,R1]
EORS R0, R3
STRB.W R0, [R4],#1
B loc_301E54
locret_301E6C
POP.W {R4-R8,PC}
This is the function that calls the above:
PUSH {R0-R2,LR}
MOVS R3, #0
LDR R2, =(dword_8749EF - 0x301E80)
STR R3, [SP,#0x10+var_10]
MOVW R3, #0x107
ADD R2, PC ; dword_8749EF
BL sub_301E44
ADD SP, SP, #0xC