反转基于字符串

时间:2016-01-06 23:27:20

标签: c encryption reverse-engineering

是否可以进行此算法的逆过程?

int EDI = 0x1505;
for( int i = 0; i < lstrlen(dir); i++ )
{
  if ( dir[i] != '.' && dir[i] != '\' )
  {
     EDX = EDI * 32;
     EDX = EDX + EDI;
     EDX = EDX + dir[i];
     EDI = EDX;
  }
}

dir是一个字符串,例如,当dir是&#34; data \ etcobject \ damagecri.nif&#34;该函数的输出将是:1C9EA36C

有没有办法检索只给出输出编号的原始字符串?

3 个答案:

答案 0 :(得分:4)

你无法扭转这个功能,因为它是有损的;它的输出位数少于输入位,因此不可避免地会有多个输入返回相同的输出。例如,它会忽略./,因此输入aba/ba.b将是相同的。

即使你忽略了./,也没有办法;您正在将字符串转换为整数; waaaaaay比整数更多的字符串,所以不可避免地会有多个字符串产生相同的整数。

答案 1 :(得分:1)

  

有没有办法检索只给出输出编号的原始字符串?

一般来说:不。

请注意

EDX = EDI * 32;
EDX = EDX + EDI;
// same as 
EDX = EDI *33'

考虑长度为2的2个字符串AB

The `EDI` generated are
EDI(A) = 33*A[0] + A[1] + constant
EDI(B) = 33*B[0] + B[1] + constant

with `A[0] == 2, A[1] ==  3` we get `33*2 +  3 + constant` or `69 + constant`
with `B[0] == 1, B[1] == 36` we get `33*1 + 36 + constant` or `69 + constant`

因此,对于EDI 69 + constant,我们无法区分2个字符串原件(或许多其他候选者)。

另一种看待它的方法是我们假设只使用A-Z:然后使用7个或更多字母字符,有超过pow(26,7) or 8,031,810,176个组合和int(假设32- bit)最多只有4,294,967,296组合。所以没有办法将所有7个长字符串区分为32位int

答案 2 :(得分:0)

此:

 EDX = EDI * 32;
 EDX = EDX + EDI;
 EDX = EDX + dir[i];
 EDI = EDX;

显然与:

相同
 EDX = EDX * 33 + dir[i];

因此当dir [i]在33的范围内(例如0-32或97-129)并且EDX不溢出时,只能反转字符串。

所以,如果你可以假设字符串只有负数(ascii 97-122,那么它可能是:

  • 首先,从VAL
  • 中减去0x1505
  • 然后,计算ch = VAL % 33
  • 计算ch = ch + n*33。选择n以使ch进入97-129范围,这是下一个字符。
  • VAL中减去此字符,然后除以33:VAL = (VAL - ch) / 33
  • 从步骤2开始迭代,直到VAL为0.

如果您觉得计算出的char不正确,可以通过将ch带入ascii范围的其他范围(例如数字,大写字母)来进一步改进。但这使得算法具有启发性。

另一种方法:如果您有一个候选字符串列表(或者您可以生成一个),那么您可以使用它来提供算法并将其与数字进行比较。