zoukankan      html  css  js  c++  java
  • re | [安洵杯 2019]game

    这是一道x64的elf逆向题。

    先进入主函数,定位到输入输出和一个叫sudoku的全局变量数组:

    sudoku的意思是数独,所以定位到sudoku数组的位置,将其提出来:

    这里我犯了一个错误,这些数据在内存中存储的时候是小端序的int,我提出来以后为了简洁只写了两位,导致我后面分析的时候一直把它当成了char,最后才反应过来问题所在【真的憨憨】

    不管那么多了,再通过主函数依次跟进分析一下那些函数的作用:

    trace和check就跳过了,功能很明显能猜测出来。

    进入check1:

    这里用了一个叫做ollvm的操作来混淆代码,以前也遇到过很多次,不过今天才知道原来叫这个名字。

    反正一步一步跟就完事儿了,推出来3个加密过程:

    1先交换前后顺序【0】---【20】,【1】---【21】。。。。

    2两个一组两两交换

    3最后做位运算:a1[v12] = (a1[v12] & 0xF3 | ~a1[v12] & 0xC) - 20

    *注:以上是程序对我们输入的字符串进行的反向操作。

    再跟进check3:

    关键点在于check2函数来判断是否正确,所以再跟进check2【又是混淆加密过得,所以这里只放关键点了】:

    2的作用是将v16(已经将我们字符串插入的数组)放入dog3数组;

    1的作用是将dog3与sudoku对比。

    真正的关键点在下面:

    这里v16是int数组,用yourinput - 48的目的是转化为数字,【呼应前文】我一开始把最终的对比以为成char型的对比('1','2'..这样),所以困住了好一会儿。

    反正全部分析完了,思路就很明确了:

    1.填数独:

    这里我上网找了个工具帮我算,然后把填的空弄了出来:

    4693641762894685722843556137219876255986

    2.数字+48转字符

    3.重复一次位运算【这里原因不清楚的话自己推一下就知道了】

    4.两两交换

    5.前后倒置

    上代码:

     1 void main(){
     2     char a[] = "4693641762894685722843556137219876255986";
     3     int len = strlen(a);
     4     char tmp;
     5     for (int i = 0; i < len; i ++){
     6         //这一步我一开始没注意数据类型的转化。。。
     7         a[i] = (a[i]-'0') + 48;
     8         //正向-》a[i] = (a[i] & 0xF3 | ~a[i] & 0xC) - 20;
     9         //反向操作
    10         tmp = a[i] + 20;
    11         tmp = ((tmp & 0xF3) | (~tmp & 0xC)) ;  //再次取反倒回去
    12         a[i] = tmp;
    13     }
    14     for (i = 0; i < len; i += 2){
    15         tmp = a[i];
    16         a[i] = a[i+1];
    17         a[i+1] = tmp;
    18     }
    19     printf("%s 
    ", a);
    20     return;
    21 }

    得出的字符串前后手动倒置一下,就可以了。

    感觉这题还是挺有意思的,混淆挺恶心的。

  • 相关阅读:
    读图,特征提取——形状
    5.2 SW1控制LED1亮灭(中断功能)
    3、寄存器
    5.1、按键SW1控制LED1亮灭
    4.2、LED1、LED2交替闪烁
    2、编程工具IAR、烧写工具SmartRF的使用
    4.1、实现4个LED灯同时闪烁
    1、CC2530单片机介绍
    装windows系统教程
    连接夜神模拟器
  • 原文地址:https://www.cnblogs.com/Mz1-rc/p/13690400.html
Copyright © 2011-2022 走看看