需要帮助理解 XOR 密码

逆向工程 C++ 手臂
2021-07-02 10:35:15

我正在尝试修改游戏的保存文件。我认为它正在使用 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_old. v5随着循环的每次迭代递增,所以上面的表达式基本上是当前索引加上a5

然后将当前索引加上a5a4(大概是 指向的缓冲区的长度a3)相加,a3并将相应的字节与当前指向的字节进行异或运算v5

这是我对算法的看法:

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

或者换句话说,与密钥重复的异或。

这是非常标准的,所以它可能是对的,但也可能是错误的——正如我所说,反编译非常混乱。如果你想要一个确定的答案,要么通过修复变量类型来清理它,要么也发布反汇编。