我正在尝试修改游戏的保存文件。我认为它正在使用XOR密码对其进行加密。通过反汇编,我想我找到了将其解密的函数。我通过反编译器运行了程序集,以更好地掌握发生的情况。

我是一位具有C / C ++知识的C#程序员。我通常了解此代码可以完成什么,但有一些我不了解的细节。

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;
}


它接受为参数:



a1-字节数组

a2-数组的长度

a3-0xB19D425B


a4-0x107


a5-0x00


首先,我不知道v8的值。我不知道(_DWORD)v5是什么意思,也不知道为什么要从零中减去它。

其次,我也不知道(unsigned int)&v5[v8]到底在做什么。我的意思是说它正在数组中的某个位置查找一个字节,但是它是在获取单个字节并转换为uint还是四个字节?

这里是反汇编:

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}


这是调用上述函数的函数:

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


#1 楼

(_DWORD)v5只是将__int8*指针转换为_DWORD。如果不修复变量类型,反编译通常会很混乱,所以让我们暂时忽略类型。

要了解v8的值,请将其替换为下面的表达式:
&v5[a5 - v5_old]。我们也可以将其理解为v5 + a5 - v5_oldv5随着循环的每次迭代而递增,因此上述表达式基本上是当前索引加上a5。然后,将当前索引加上a5a4(以a3指向的缓冲区的长度)为模,然后将其加到a3,并将相应的字节与v5当前指向的字节进行XOR运算。

这是我对算法的看法:

void DecryptBuffer ( char *buffer, int buffer_len, char *key, int key_len, int key_start )
{ 
    int i;
    for ( i = 0; i < buffer_len; i++ )
        buffer [ i ] ^= key [ ( key_start + i ) % key_len ];
}


换句话说,对XOR进行重复操作。

这是很标准的,所以可能是正确的,但是可能是错误的-正如我说的,反编译非常混乱。如果您想要确定的答案,请通过固定变量类型来清理它,或者也要进行反汇编。

评论


非常感谢,那行得通。我永远不会意识到key是指向数组的指针(而不仅仅是整数),而v8被用来确定我们到缓冲区的距离。我附上了拆卸件,以确保完整性。

–切特
18-10-4在0:06