zoukankan      html  css  js  c++  java
  • 2020网鼎杯 青龙组reverse:signal

    主函数,从内存给v4赋值,进行vm_operad操作

     vm_operad函数,会根据v4每一int大小的值进行switch选择操作,v4是传入参数,这里的接受变量是a1为int型数组

     

     v4在内存中所copy的对象是db型数据,大小为0x1c8即456

     为方便获取数据,进入内存数据16进制页面

     0x403040+0x1c8等于0x403208,所以将0x403040到0x403208的这段数据拷贝出来

    0A 00 00 00 04 00 00 00  10 00 00 00 08 00 00 00
    03 00 00 00 05 00 00 00  01 00 00 00 04 00 00 00
    20 00 00 00 08 00 00 00  05 00 00 00 03 00 00 00
    01 00 00 00 03 00 00 00  02 00 00 00 08 00 00 00
    0B 00 00 00 01 00 00 00  0C 00 00 00 08 00 00 00
    04 00 00 00 04 00 00 00  01 00 00 00 05 00 00 00
    03 00 00 00 08 00 00 00  03 00 00 00 21 00 00 00
    01 00 00 00 0B 00 00 00  08 00 00 00 0B 00 00 00
    01 00 00 00 04 00 00 00  09 00 00 00 08 00 00 00
    03 00 00 00 20 00 00 00  01 00 00 00 02 00 00 00
    51 00 00 00 08 00 00 00  04 00 00 00 24 00 00 00
    01 00 00 00 0C 00 00 00  08 00 00 00 0B 00 00 00
    01 00 00 00 05 00 00 00  02 00 00 00 08 00 00 00
    02 00 00 00 25 00 00 00  01 00 00 00 02 00 00 00
    36 00 00 00 08 00 00 00  04 00 00 00 41 00 00 00
    01 00 00 00 02 00 00 00  20 00 00 00 08 00 00 00
    05 00 00 00 01 00 00 00  01 00 00 00 05 00 00 00
    03 00 00 00 08 00 00 00  02 00 00 00 25 00 00 00
    01 00 00 00 04 00 00 00  09 00 00 00 08 00 00 00
    03 00 00 00 20 00 00 00  01 00 00 00 02 00 00 00
    41 00 00 00 08 00 00 00  0C 00 00 00 01 00 00 00
    07 00 00 00 22 00 00 00  07 00 00 00 3F 00 00 00
    07 00 00 00 34 00 00 00  07 00 00 00 32 00 00 00
    07 00 00 00 72 00 00 00  07 00 00 00 33 00 00 00
    07 00 00 00 18 00 00 00  07 00 00 00 A7 FF FF FF
    07 00 00 00 31 00 00 00  07 00 00 00 F1 FF FF FF
    07 00 00 00 28 00 00 00  07 00 00 00 84 FF FF FF
    07 00 00 00 C1 FF FF FF  07 00 00 00 1E 00 00 00
    07 00 00 00 7A 00 00 00

    4字节等于一个int,interl处理器是小端存储,刚好a1数组的值就是三个00之前那十六进制

    10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122

      vm_operad函数会根据a1数组的值进行switch操作,当值等于7时v4数组的值会与a1数组的下一位进行比较,相等继续,不等报错。7后面的数字就是正确输入进行加密后需要与之比较的值,刚好7这个值在a1数组的最后,将这串值提取出来为34,63,52,50,114,51,24,167,49,241,40,132,193,30,122,为v4数组的值

    #获得v4数组
    v4=[]
    s=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122]
    for i in range(0,len(s)):
              if s[i]==7:
                        v4.append(s[i+1])

    根据v4数组的值,逆向switch的操作的计算得到需要输入的正确flag

    v4 = [34,63,52,50,114,51,24,167,49,241,40,132,193,30,122]
    v4.reverse()
    
    a=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1]
    a.reverse()
    
    v9 = 0
    us=0
    v5=0
    flag=[]
    for i in range(0,len(a)):
              if i ==len(a)-1:
                        flag.append(us)
                        
              if a[i]==1 and a[i-1]!=1:
                        v5 = v4[v9]
                        v9+=1
                        flag.append(us)
                        
              if a[i]==2:
                        if(a[i+1]!=3 and a[i+1]!=4 and a[i+1]!=5):
                                  us = v5 - a[i-1]
                                  #print(us,v5,a[i-1])
                        
              if a[i]==3:
                        if(a[i+1]!=2 and a[i+1]!=4 and a[i+1]!=5):               
                                  us = v5 + a[i-1]  #LOBYTE是al有8位,参与运算的5、33、32是全值,所以LOBYTE可省略
                        
              if a[i]==4:
                        if(a[i+1]!=3 and a[i+1]!=2 and a[i+1]!=5):
                                  us = v5^a[i-1]
    
              if a[i]==5:
                        if(a[i+1]!=3 and a[i+1]!=4 and a[i+1]!=2):
                                  us = int(v5/a[i-1])
              if a[i]==8:
                        v5 = us
                                  
              if a[i]==11:
                        us = v5 +1
              if a[i]==12:
                        us = v5 -1
                        #print("12:",us)
    
    flag.reverse()
    out=''
    for j in flag:
              out +=chr(j)
    print("flag{"+out+"}")

    另外,LOBYTE这个函数做的时候我去百度了有说是取最右边那位,有说右边四位,这是ida的函数,但是怎么取都不对,这里我切换到汇编界面看了下LOBYTE取的是al的值,那么就是右边8位。a1数组的值没有大于8位二进制的,所以可以忽略这个函数。rax是64位寄存器,eax是32位寄存器,ax是16位寄存器,al是ax寄存器低8位,ah是ax寄存器高8位。

  • 相关阅读:
    IceFig阅读笔记
    sift算法中翻译的第11页中比值问题
    Hessian矩阵
    python使用jieba实现中文文档分词和去停用词
    Hanlp配置自定义词典遇到的问题与解决方法
    HanLP-分类模块的分词器介绍
    elasticsearch教程--中文分词器作用和使用
    HanLP-最短路径分词
    史上最全中文分词工具整理
    NLP自然语言处理中英文分词工具集锦与基本使用介绍
  • 原文地址:https://www.cnblogs.com/blackicelisa/p/12905731.html
Copyright © 2011-2022 走看看