美文网首页
用C语言来解密 ---解密问题

用C语言来解密 ---解密问题

作者: LeeAutumn | 来源:发表于2017-01-11 15:33 被阅读0次

首先看secret.cpp的代码结合“From:”来进行切入。

由于前面进行的都是声明变量,变量赋值的工作,所以从第103行开始分析。

process_key12(int * key1,int * key2)函数中*((int *) (key1 + *key1)) = *key2;表示了将*key1(实际变量存储地址)的所在位置向高地址增加 *key1 的偏移量处的值赋为key2的值。当然这和偏移量有关,所以现在还不知道那个值被修改了。

继续向下看源码,发现start = 0, stride =1。

然后是process_key34(),查看代码后发现实类似的操作,先放着。

然后开始extract_message1(start, stride)密文的decode操作。将start = 0,stride = 1带代入,发现是一个死循环,所以此时start和stride的值并不对,那么如何修改呢,发现是process_key12()的影响,于是研究此函数:

  • 局部变量的生成顺序是dummy,start,stride,key1,key2,由于栈是从高地址向低地址进行分配的,所以*key是一个正数并且process函数只能修改一个数的值而start和stride都由dummy来初始决定,所以显而易见修改了dummy的值,所以key1的值为3(因为有dummy,start,stride三个4字节int值),接下来需要确定key2的值。
  • start = (int)(*(((char *) &dummy)));
    stride = (int)(*(((char *) &dummy) + 1));
    这两段是start的赋值,可以看到先转成char指针,在转成int值,而char占用1字节,int占用4字节,所以(_ _ _ _,表示dummy的四个字节,而程序里以字节为单位来逆序排列dummy的四个字节,如dummy=340,内存内dummy的字节序列是(低地址到高地址)15 04 00 00,由此可以看出,不仅栈是从高地址向低地址来分配的,而且变量的字节是由高地址向低地址00000415读取的)。
  • 现在根据From:的ascii码值来找,发现为46 72 6F 6D 3A,然后在data中查找,注意data在内存中以4字节唯一单位,四字节内部顺序是高地址向低地址读取,所以并不是纯粹的data中的那些顺序,而且data中的4字节是从最后一个开始压进栈中的。所以加法操作后到高地址,正好可以到达data后面的字节中。
  • 现在来看for循环,i变量只是提供message[i]中i的作用,内部变量循环stride-1次,出来后又+1,现在来观察几个字节出现的顺序,后面的数值是距离*data的距离,即+j。
46:  9 *10* 20
72:  *11* 12 21
6F:  *13* 15
6D:  *14* 19
3A:  *16*

可以看到内部循环为两次,所以stride=3,start = 10 -1 =9,所以key2=0x00000309=777.

之后得到结果

From: Friend
To: You
Good! Now try choosing keys3,4 to force a call to extract2 and
avoid the call to extract1

发现还有第二段密文,然我们用key3和key4来绕过extract1,所以需要更改process_key34之后的返回地址。

process_key34的函数过程为*(((int *)&key3) + *key3) += *key4;*key3为偏移量,此处&key3指的是形参中的key3,所以就和函数栈有关。我们知道形参是从右往左入栈的,而在形参入栈后,会把函数返回地址加上,所以函数返回地址是在key3的下面(低地址处),所以*key3的值为-1,所以函数的返回地址增加多少才能绕过exetract_message1呢,此时我们反汇编源程序,查看exetract_message1和exetract_message2的函数地址。

0x100000ead <+253>: callq  0x100000c10               ; process_keys34 at main.c:57
    0x100000eb2 <+258>: movl   -0x18(%rbp), %edi
    0x100000eb5 <+261>: movl   -0x1c(%rbp), %esi
    0x100000eb8 <+264>: callq  0x100000c40               ; extract_message1 at main.c:62
    0x100000ebd <+269>: movq   %rax, -0x38(%rbp)
    0x100000ec1 <+273>: movq   -0x38(%rbp), %rax
    0x100000ec5 <+277>: movsbl (%rax), %esi
    0x100000ec8 <+280>: cmpl   $0x0, %esi
    0x100000ece <+286>: jne    0x100000f0a               ; <+346> at main.c:128
    0x100000ed4 <+292>: leaq   -0x28(%rbp), %rdi
    0x100000ed8 <+296>: leaq   -0x2c(%rbp), %rsi
    0x100000edc <+300>: callq  0x100000c10               ; process_keys34 at main.c:57
    0x100000ee1 <+305>: movl   -0x18(%rbp), %edi
    0x100000ee4 <+308>: movl   -0x1c(%rbp), %esi
    0x100000ee7 <+311>: callq  0x100000d30               ; extract_message2 at main.c:82

所以key4= 311 - 264 = 47。

虽然key3和key4带进去都没有得到正确的值,但是我尽力了。~~

综上,key1 = 3,key2 = 777,key = -1,key4 = 47。

相关文章

网友评论

      本文标题:用C语言来解密 ---解密问题

      本文链接:https://www.haomeiwen.com/subject/oydrbttx.html