下一步是尝试识别用于解密的密钥,问题是单个块密码加密的程序集大小约为2.5MB。但是,我观察到的是,它们都是非常相似的形式,例如片段:
在参数(
r12
)中,如下所示:针对r0
(始终为0xff
),然后执行某些操作,XOR,OR,ADD或MOV影响另一个寄存器(在示例中为0xff
)。 我目前的预感是这可能是具有展开回合的AES-128实现。隐藏钥匙?如果是这样,那么如何对其进行混淆并找到密钥呢?
附加信息。
这是到使用CBC的子例程的链接,并调用上述在主要问题中引用的子例程。
#1 楼
我认为您正确地确定了功能的目的及其参数。因此,函数sub_44d84
具有四个参数:(<decryptionFunction=0x1>, <IV>, <bytesToDecrypt>, <decryptedBytes>)
,并使用CBC为每个块调用sub_46d554
函数。sub_46d554
函数收到2个参数: /> R0
:加密的输入块R1
:加密的输出块在函数的最后部分写出到输出缓冲区。 要了解解密功能,首先要了解混淆的基本组成部分。因此,在从输入块中读取第二个字节后,我获得了一些示例代码(由于编译器的优化,该函数的开头有点混乱)。
在上图中,标有绿色的行读出了输入块的第二个字节,橙色的行初始化了
R2
寄存器。黄色和蓝色块执行类似的功能。两个块均以加法开始,将结果存储到局部变量,然后检查结果是否等于0xFF
。如果结果为0xFF
,则更改R2
的值。由于仅当加法器为R2
并且加法器始终使用0xFF
(包含输入的第二个字节)时才更改LR
,因此R2
寄存器的值只能更改一次。因为新的R2
值仅取决于LR
,所以这些块实现了一个查找表,该表是一个替换框。因此,在伪代码中,查找表是以以下方式实现的:if (input == 0xb1) out = 0x5b
if (input == 0x42) out = 0x56
...
要了解将结果存储到局部变量中的原因,让我们检查一下局部变量
var_1A8
的下一次用法。它读取局部变量,是加法的结果,并检查是否与以前的情况类似。由于仅当加法的结果在最初存储值的地方为
0xFF
时,此局部变量的值才为0xFF
,因此比较将再次检查输入字节是否等于特定值。 如果在整个函数中搜索局部变量
0xFF
,我们会反复收到很多带有特定模式(var_1A8
,STR
,LDR
,LDR
)的结果。 LDR
表示添加的存储,而STR
表示此添加的用法。因此,每个字节都要检查四次,然后再使用另一个字节。 br /> i0 = input[0x00]
d0_0 = table0[i0]
id = input[0x0d]
d0_d = table1[id]
ia = input[0x0a]
d0_a = table2[ia]
i7 = input[0x07]
d0_7 = table3[i7]
d1_0 = table4[i0]
d1_d = table5[id]
d1_a = table6[ia]
d1_7 = table7[i7]
d2_0 = table8[i0]
d2_d = table9[id]
d2_a = table10[ia]
d2_7 = table11[i7]
d3_0 = table12[i0]
d3_d = table13[id]
d3_a = table14[ia]
d3_7 = table15[i7]
因此,读出4个字节,执行替换并将结果存储在局部变量中。之后,对接下来的4个字节执行相同的操作,依此类推。在处理完整个块之后,将读取存储的结果并将以前的一些结果的异或值用作新的输入,例如:根据局部变量的用法,可以清楚地看到它使用9轮替换。
基于以上内容,我认为解密功能可以是AES-128实现。因为添加回合键,子字节和移位行步骤操作可以在一个步骤中使用查找表来实现,而混合列操作则可以在另一步骤中实现。因为只有9个回合,所以可以使用一个查找表实现AES的初始回合和第一回合。
因此,密钥(如果确实是AES实现,则为扩展密钥)被混入实现中。尽管我不是一位冷冻医生,但我想您可以通过将查找表的值与Rijndael S-Box值进行异或来检索扩展的AES密钥。但是,这似乎是一个艰巨且耗时的过程,因此,如果您只想解密一些数据,则可以考虑模拟代码。
评论
这是一个很好的答案,非常感谢@ebux。从事物的声音来看,您似乎已经在每个回合中用SubBytes步骤(找到的第一个模式)和MixColumns步骤(第二个模式,对先前的结果进行XOR)标识了中间的9轮AES。那让我想知道ShiftRows和AddRoundKey步骤。在解密过程中,最后一轮(第10轮)将仅使用按位XOR添加原始密钥,您在函数末尾看到过类似的东西吗?
–约书亚
16-2-15在12:27
AES在每个回合中都使用扩展密钥而不是原始密钥。在最后一轮结束时,查找结果存储在输出缓冲区中,这可能意味着AddRoundKey步骤或其他步骤的混合。
– ebux
16 Feb 15'在12:34
的确,除了第一轮加密(最后一轮解密)(它使用原始密钥作为扩展密钥的前16个字节时)之外,它都可以与扩展密钥一起使用,只是加密密钥本身。我明白了,我自己再看一眼。
–约书亚
16-2-15在12:46
没错,但最后的ShiftRows和SubBytes步骤可以与最后的AddRoundKey步骤结合使用。
– ebux
16 Feb 15'在12:57
我知道了-您是否对ShiftRows步骤的执行方式有任何想法?另外,可能在您的问题中错过了它,但是查找表存储在哪里(即``table0`'')?
–约书亚
16-2-15在13:04
评论
根据以上代码段,对我来说似乎不是AES-128,但是您可以共享更大的代码段还是整个功能?@ebux这是我相信正在使用CBC的过程,这是问题中提到的分组密码功能的扩展代码段(不完整,因为它是60MB的asm文件)。我认为这些调用的参数如下sub_44d84(