我是一位具有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
。然后,将当前索引加上a5
模a4
(以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