zoukankan      html  css  js  c++  java
  • 虎符-RE-game

    基本指令

    点击查看详细内容

    - 阅读下文代码前基本须知

      
    LOAD_CONST 加载常量               1
    STORE_NAME 将变量储存为常量值     a=1   局部变量
    STORE_GLOBAL同上功能  全局变量
    BUILD_LIST  生成list
    BUILD_MAP声明字典元素数量
    STORE_MAP生成键值对 并储存
    LOAD_NAME加载局部变量
    BINARY_ADD加法
    BINARY_SUBTRACT减法
    BINARY_MULTIPLY乘法
    BINARY_DIVIDE除法
    BINARY_MODULO取余
    BINARY_SUBSCR()
    BUILD_SLICE切片
    POP_TOP将结果从堆栈顶部弹出,以保证堆栈平衡
    SETUP_LOOP表明循环开始  (to 28)参数说明此循环知道字节码偏移28字节的指令结束(也就是28字节开始不是循环)。
    FOR_ITER调用堆栈   声明generator作用到字节码偏移位置27字节。
    PRINT_ITEM为一个print函数。
    COMPARE_OP指令对堆栈中两个常量进行比较
    POP_JUMP_IF_FALSE指令,判断栈顶值来决定程序运行顺序实现判断功能。
      

    基本查看

    打开是一个txt文档。里面的内容是,python字节码。python的字节码只能靠自己硬读,没有什么其他方法。
    python逆向或者反汇编的目的就是在没有源码的基础上,通过字节码来理解源代码的运行内容

    分析

    # Python 2.7
    # Embedded file name: game.py
    #源码行号|指令在函数中的偏移|指令符号|指令参数|实际参数值
    
       1       0  LOAD_CONST               249
               3  LOAD_CONST               91
               6  LOAD_CONST               149
               9  LOAD_CONST               113
              12  LOAD_CONST               16
              15  LOAD_CONST               91
              18  LOAD_CONST               53
              21  LOAD_CONST               41
              24  BUILD_LIST_8          8
              27  STORE_NAME            0  'arr0'
    #arr0=[249,91,149,113,16,91,53,41]
       2      30  LOAD_CONST               43
              33  LOAD_CONST               1
              36  LOAD_CONST               6
              39  LOAD_CONST               69
              42  LOAD_CONST               20
              45  LOAD_CONST               62
              48  LOAD_CONST               6
              51  LOAD_CONST               44
              54  LOAD_CONST               24
              57  LOAD_CONST               113
              60  LOAD_CONST               6
              63  LOAD_CONST               35
              66  LOAD_CONST               0
              69  LOAD_CONST               3
              72  LOAD_CONST               6
              75  LOAD_CONST               44
              78  LOAD_CONST               20
              81  LOAD_CONST               22
              84  LOAD_CONST               127
              87  LOAD_CONST               60
              90  BUILD_LIST_20        20
              93  STORE_NAME            1  'arr1'
    #arr1=[43,1,6,69,20,62,6,44,24,113,6,35,0,3,6,44,20,22,127,60]
       3      96  LOAD_CONST               90
              99  LOAD_CONST               100
             102  LOAD_CONST               87
             105  LOAD_CONST               109
             108  LOAD_CONST               86
             111  LOAD_CONST               108
             114  LOAD_CONST               86
             117  LOAD_CONST               105
             120  LOAD_CONST               90
             123  LOAD_CONST               104
             126  LOAD_CONST               88
             129  LOAD_CONST               102
             132  BUILD_LIST_12        12
             135  STORE_NAME            2  'arr2'
    #arr2=[90,100,87,109,86,108,86,105,90,104,88,102]
       5     138  LOAD_CODE                <code_object check0>
             141  MAKE_FUNCTION_0       0  None
             144  STORE_NAME            3  'check0'
    #check0()
       8     147  LOAD_CODE                <code_object check1>
             150  MAKE_FUNCTION_0       0  None
             153  STORE_NAME            4  'check1'
    #check1()
      14     156  LOAD_CODE                <code_object check2>
             159  MAKE_FUNCTION_0       0  None
             162  STORE_NAME            5  'check2'
    #check2()
      20     165  LOAD_CODE                <code_object check3>
             168  MAKE_FUNCTION_0       0  None
             171  STORE_NAME            6  'check3'
    #check3()
      37     174  LOAD_NAME             7  'raw_input'
             177  CALL_FUNCTION_0       0  None
             180  STORE_NAME            8  'flag'
    #flag=raw_input()
      38     183  LOAD_NAME             3  'check0'
             186  LOAD_NAME             8  'flag'
             189  CALL_FUNCTION_1       1  None
             192  POP_JUMP_IF_FALSE   239  'to 239'
             195  LOAD_NAME             4  'check1'
             198  LOAD_NAME             8  'flag'
             201  CALL_FUNCTION_1       1  None
             204  POP_JUMP_IF_FALSE   239  'to 239'
             207  LOAD_NAME             5  'check2'
             210  LOAD_NAME             8  'flag'
             213  CALL_FUNCTION_1       1  None
             216  POP_JUMP_IF_FALSE   239  'to 239'
             219  LOAD_NAME             6  'check3'
             222  LOAD_NAME             8  'flag'
             225  CALL_FUNCTION_1       1  None
           228_0  COME_FROM           216  '216'
           228_1  COME_FROM           204  '204'
           228_2  COME_FROM           192  '192'
             228  POP_JUMP_IF_FALSE   239  'to 239'
    #if check0(flag):
    #if check1(flag):
    #    if check2(flag):
    #        if check3(flag):
    #            print 'no' 
    #        else print'ok'   
      39     231  LOAD_CONST               'ok'
             234  PRINT_ITEM
             235  PRINT_NEWLINE_CONT
             236  JUMP_FORWARD          5  'to 244'
    
      41     239  LOAD_CONST               'no'
             242  PRINT_ITEM
             243  PRINT_NEWLINE_CONT
           244_0  COME_FROM           236  '236'    
             244  LOAD_CONST               None
             247  RETURN_VALUE
    
    # check0 line 5 of game.py
    
       6       0  LOAD_GLOBAL           0  'all'
               3  LOAD_GENEXPR             '<code_object <genexpr>>'
               6  MAKE_FUNCTION_0       0  None
               9  LOAD_FAST             0  's'
              12  GET_ITER
              13  CALL_FUNCTION_1       1  None
              16  CALL_FUNCTION_1       1  None
              19  RETURN_VALUE
    #all='<code_object <genexpr>>'
    # check1 line 8 of game.py
    
       9       0  LOAD_GLOBAL           0  'len'
               3  LOAD_FAST             0  's'
               6  CALL_FUNCTION_1       1  None
               9  LOAD_CONST               100
              12  COMPARE_OP            0  <
              15  POP_JUMP_IF_FALSE    58  'to 58'
              18  LOAD_GLOBAL           0  'len'
              21  LOAD_FAST             0  's'
              24  CALL_FUNCTION_1       1  None
              27  LOAD_GLOBAL           0  'len'
              30  LOAD_FAST             0  's'
              33  CALL_FUNCTION_1       1  None
              36  BINARY_MULTIPLY
              37  LOAD_CONST               777
              40  BINARY_MODULO
              41  LOAD_CONST               233
              44  BINARY_XOR
              45  LOAD_CONST               513
              48  COMPARE_OP            2  ==
            51_0  COME_FROM            15  '15'
              51  POP_JUMP_IF_FALSE    58  'to 58'
    #if len(s)<100:
    #    if (len(s)*len(s))%777)^233==513
    #        return True
    #    else:
    #        False
    #else:
    #    False
      10      54  LOAD_GLOBAL           1  'True'
              57  RETURN_END_IF
            58_0  COME_FROM            51  '51'
    
      12      58  LOAD_GLOBAL           2  'False'
              61  RETURN_VALUE
              62  LOAD_CONST               None
              65  RETURN_VALUE
    
    # check2 line 14 of game.py
    
      15       0  LOAD_GLOBAL           0  'ord'
               3  LOAD_FAST             0  's'
               6  LOAD_CONST               0
               9  BINARY_SUBSCR
              10  CALL_FUNCTION_1       1  None
              13  LOAD_CONST               128
              16  BINARY_MULTIPLY
              17  LOAD_GLOBAL           0  'ord'
              20  LOAD_FAST             0  's'
              23  LOAD_CONST               1
              26  BINARY_SUBSCR
              27  CALL_FUNCTION_1       1  None
              30  BINARY_ADD
              31  LOAD_CONST               128
              34  BINARY_MULTIPLY
              35  LOAD_GLOBAL           0  'ord'
              38  LOAD_FAST             0  's'
              41  LOAD_CONST               2
              44  BINARY_SUBSCR
              45  CALL_FUNCTION_1       1  None
              48  BINARY_ADD
              49  LOAD_CONST               128
              52  BINARY_MULTIPLY
              53  LOAD_GLOBAL           0  'ord'
              56  LOAD_FAST             0  's'
              59  LOAD_CONST               3
              62  BINARY_SUBSCR
              63  CALL_FUNCTION_1       1  None
              66  BINARY_ADD
              67  LOAD_CONST               128
              70  BINARY_MULTIPLY
              71  LOAD_GLOBAL           0  'ord'
              74  LOAD_FAST             0  's'
              77  LOAD_CONST               4
              80  BINARY_SUBSCR
              81  CALL_FUNCTION_1       1  None
              84  BINARY_ADD
              85  LOAD_CONST               128
              88  BINARY_MULTIPLY
              89  LOAD_GLOBAL           0  'ord'
              92  LOAD_FAST             0  's'
              95  LOAD_CONST               5
              98  BINARY_SUBSCR
              99  CALL_FUNCTION_1       1  None
             102  BINARY_ADD
             103  LOAD_CONST               3533889469877L
             106  COMPARE_OP            2  ==
             109  POP_JUMP_IF_FALSE   138  'to 138'
             112  LOAD_GLOBAL           0  'ord'
             115  LOAD_FAST             0  's'
             118  LOAD_CONST               -1
             121  BINARY_SUBSCR
             122  CALL_FUNCTION_1       1  None
             125  LOAD_CONST               125
             128  COMPARE_OP            2  ==
           131_0  COME_FROM           109  '109'
             131  POP_JUMP_IF_FALSE   138  'to 138'
    #if ((((ord(s[0])*128+ord(s[1]))*128+ord(s[2]))*128+ord(s[3]))*128+ord(s[4]))*128+ord(s[5]) == 3533889469877:
    #    if ord(s[-1])==125:
    #        return True
    #    else:
    #        return False
    #else:
    #    return False
      16     134  LOAD_GLOBAL           1  'True'
             137  RETURN_END_IF
           138_0  COME_FROM           131  '131'
    
      18     138  LOAD_GLOBAL           2  'False'
             141  RETURN_VALUE
             142  LOAD_CONST               None
             145  RETURN_VALUE
    
    # check3 line 20 of game.py
    
      21       0  LOAD_GLOBAL           0  'map'
               3  LOAD_GLOBAL           1  'ord'
               6  LOAD_FAST             0  's'
               9  CALL_FUNCTION_2       2  None
              12  STORE_FAST            1  'arr'
    #arr=map(ord,s)
      22      15  LOAD_FAST             1  'arr'
              18  LOAD_CONST               6
              21  LOAD_CONST               30
              24  LOAD_CONST               3
              27  BUILD_SLICE_3         3
              30  BINARY_SUBSCR
              31  STORE_FAST            2  'a'
    #a=arr[6:30:3]
      23      34  SETUP_LOOP           62  'to 99'
              37  LOAD_GLOBAL           2  'range'
              40  LOAD_GLOBAL           3  'len'
              43  LOAD_FAST             2  'a'
              46  CALL_FUNCTION_1       1  None
              49  CALL_FUNCTION_1       1  None
              52  GET_ITER
              53  FOR_ITER             42  'to 98'
              56  STORE_FAST            3  'i'
    #for i in range(len(a))
      24      59  LOAD_FAST             2  'a'
              62  LOAD_FAST             3  'i'
              65  BINARY_SUBSCR
              66  LOAD_CONST               17684
              69  BINARY_MULTIPLY
              70  LOAD_CONST               372511
              73  BINARY_ADD
              74  LOAD_CONST               257
              77  BINARY_MODULO
              78  LOAD_GLOBAL           4  'arr0'
              81  LOAD_FAST             3  'i'
              84  BINARY_SUBSCR
              85  COMPARE_OP            3  !=
              88  POP_JUMP_IF_FALSE    53  'to 53'
    #if (a[i]*17684+372511)%257!=arr0[i]
      25      91  LOAD_GLOBAL           5  'False'
              94  RETURN_END_IF
            95_0  COME_FROM            88  '88'
              95  JUMP_BACK            53  'to 53'
              98  POP_BLOCK
            99_0  COME_FROM            34  '34'
    #return Flase
      26      99  LOAD_FAST             1  'arr'
             102  LOAD_CONST               -2
             105  LOAD_CONST               33
             108  LOAD_CONST               -1
             111  BUILD_SLICE_3         3
             114  BINARY_SUBSCR
             115  LOAD_CONST               5
             118  BINARY_MULTIPLY
             119  STORE_FAST            4  'b'
    #b=arr[-2:33:-1]*5
      27     122  LOAD_GLOBAL           0  'map'
             125  LOAD_LAMBDA              '<code_object <lambda>>'
             128  MAKE_FUNCTION_0       0  None
             131  LOAD_GLOBAL           6  'zip'
             134  LOAD_FAST             4  'b'
             137  LOAD_FAST             1  'arr'
             140  LOAD_CONST               7
             143  LOAD_CONST               27
             146  SLICE+3
             147  CALL_FUNCTION_2       2  None
             150  CALL_FUNCTION_2       2  None
             153  STORE_FAST            5  'c'
    #c=map('<code_object <lambda>>' zip(b,arr[7,27]))
      28     156  LOAD_FAST             5  'c'
             159  LOAD_GLOBAL           7  'arr1'
             162  COMPARE_OP            3  !=
             165  POP_JUMP_IF_FALSE   172  'to 172'
    #if c!=arr1
      29     168  LOAD_GLOBAL           5  'False'
             171  RETURN_END_IF
           172_0  COME_FROM           165  '165'
    #else:return False
      30     172  LOAD_CONST               0
             175  STORE_FAST            6  'p'
    #p=0
      31     178  SETUP_LOOP          105  'to 286'
             181  LOAD_GLOBAL           2  'range'
             184  LOAD_CONST               28
             187  LOAD_CONST               34
             190  CALL_FUNCTION_2       2  None
             193  GET_ITER
             194  FOR_ITER             88  'to 285'
             197  STORE_FAST            3  'i'
    #for i in range(28,34)
      32     200  LOAD_FAST             1  'arr'
             203  LOAD_FAST             3  'i'
             206  BINARY_SUBSCR
             207  LOAD_CONST               107
             210  BINARY_ADD
             211  LOAD_CONST               16
             214  BINARY_DIVIDE
             215  LOAD_CONST               77
             218  BINARY_ADD
             219  LOAD_GLOBAL           8  'arr2'
             222  LOAD_FAST             6  'p'
             225  BINARY_SUBSCR
             226  COMPARE_OP            3  !=
             229  POP_JUMP_IF_TRUE    268  'to 268'
             232  LOAD_FAST             1  'arr'
             235  LOAD_FAST             3  'i'
             238  BINARY_SUBSCR
             239  LOAD_CONST               117
             242  BINARY_ADD
             243  LOAD_CONST               16
             246  BINARY_MODULO
             247  LOAD_CONST               99
             250  BINARY_ADD
             251  LOAD_GLOBAL           8  'arr2'
             254  LOAD_FAST             6  'p'
             257  LOAD_CONST               1
             260  BINARY_ADD
             261  BINARY_SUBSCR
             262  COMPARE_OP            3  !=
           265_0  COME_FROM           229  '229'
             265  POP_JUMP_IF_FALSE   272  'to 272'
    #if (arr[i]+107)/16+77!=arr2[p]:
    #if (arr[i]+117)/16+99!=arr2[p+1]:
      33     268  LOAD_GLOBAL           9  'false'
             271  RETURN_END_IF
           272_0  COME_FROM           265  '265'
    #else:return False
      34     272  LOAD_FAST             6  'p'
             275  LOAD_CONST               2
             278  INPLACE_ADD
             279  STORE_FAST            6  'p'
             282  JUMP_BACK           194  'to 194'
             285  POP_BLOCK
           286_0  COME_FROM           178  '178'
    #p+=2
      35     286  LOAD_GLOBAL          10  'True'
             289  RETURN_VALUE
    
    # <genexpr> line 6 of game.py
    
       6       0  LOAD_FAST             0  '.0'
               3  FOR_ITER             32  'to 38'
               6  STORE_FAST            1  'x'
               9  LOAD_GLOBAL           0  'ord'
              12  LOAD_FAST             1  'x'
              15  CALL_FUNCTION_1       1  None
              18  LOAD_GLOBAL           1  'range'
              21  LOAD_CONST               32
              24  LOAD_CONST               128
              27  CALL_FUNCTION_2       2  None
              30  COMPARE_OP            6  in
              33  YIELD_VALUE
              34  POP_TOP
              35  JUMP_BACK             3  'to 3'
              38  LOAD_CONST               None
              41  RETURN_VALUE
    #for x in range(ord(x))
    # <lambda> line 27 of game.py
    
      27       0  LOAD_FAST             0  'x'
               3  LOAD_CONST               0
               6  BINARY_SUBSCR
               7  LOAD_FAST             0  'x'
              10  LOAD_CONST               1
              13  BINARY_SUBSCR
              14  BINARY_XOR
              15  RETURN_VALUE
    #lambda x[0]^x[1]
    

    整理后

    arr0=[249,91,149,113,16,91,53,41]
    arr1=[43,1,6,69,20,62,6,44,24,113,6,35,0,3,6,44,20,22,127,60]
    arr2=[90,100,87,109,86,108,86,105,90,104,88,102]
    def check0()
    def check1()
    def check2()
    def check3()
    flag=raw_input()
    if check0(flag):
        if check1(flag):
            if check2(flag):
                if check3(flag):
                    print 'ok' 
                else:
                    print'no'  
    def check0():
    all=ord(x) for x in range(32,128)
    iter(s)
    
    def check1():
    if len(s)<100:
        if (len(s)*len(s))%777)^233==513:
            return True
        else:
            False
    else:
        False
    
    def check2():
    if ((((ord(s[0])*128+ord(s[1]))*128+ord(s[2]))*128+ord(s[3]))*128+ord(s[4]))*128+ord(s[5]) == 3533889469877:
        if ord(s[-1])==125:
            return True
        else:
            return False
    else:
        return False
    
    def check3():
    arr=map(ord,s)
    a=arr[6:30:3]
    for i in range(len(a))
        if (a[i]*17684+372511)%257!=arr0[i]:
            return Flase
    b=arr[-2:33:-1]*5
    c=map(lambda x[0]:x[0]^x[1] zip(b,arr[7,27]))
    if c!=arr1:
        p=0
        for i in range(28,34):
            if (arr[i]+107)/16+77!=arr2[p]:
                if (arr[i]+117)/16+99!=arr2[p+1]:
                    p+=2
    else:
        return False
    #<genexpr> ord(x) for x in range(32,128)
    #<lambda> x[0]^x[1]
    

    这只能看个大概...不一定完全准确...有不同意见欢迎指正留言QAQ事实上非常期望得到指教。毕竟这是我第一次读这种。

    分析代码

    结合官方的wp分析
    flag需经过check0,check1,check2,check3四个函数的检查
    check0,flag字符均在32, 128范围内
    check1,条件l < 100 and ((l*l) % 777) ^ 233 == 513获得flag长度为39
    check2,通过128进制得到flag的开头为“flag{5”以及结尾为“}”
    check3,其中对三段flag进行了计算,第一部分可以爆破运算式得到,第二部分需要通过第一部分的结果异或得到,第三部分类似16进制编码,可以直接恢复

    解题脚本

    爆破

    flag = [' ']*39
    x = 3533889469877
    t = ''
    while x != 0:
    	t += chr(x%128)
    	x/=128
    flag[:6] = t[::-1]
    flag[-1] = '}'
    arr0 = [249,91,149,113,16,91,53,41]
    for i in range(8):
    	for ch in range(32, 128):
    		if (ch * 17684 + 372511) % 257 == arr0[i]:
    			flag[6+i*3]=chr(ch)
    arr1 = [43, 1, 6, 69, 20, 62, 6, 44, 24, 113, 6, 35, 0, 3, 6, 44, 20, 22, 127, 60]
    key = [0]*4
    key[0] = arr1[8] ^ ord(flag[15])
    key[1] = arr1[5] ^ ord(flag[12])
    key[2] = arr1[2] ^ ord(flag[9])
    key[3] = arr1[11] ^ ord(flag[18])
    
    flag[-2] = chr(key[0])
    flag[-3] = chr(key[1])
    flag[-4] = chr(key[2])
    flag[-5] = chr(key[3])
    for i in range(len(arr1)):
    	flag[7+i] = chr(arr1[i] ^ key[i%4])
    arr2 = [90, 100, 87, 109, 86, 108, 86, 105, 90, 104, 88, 102]
    
    

    z3脚本解

    from z3 import *
    arr0 = [249,91,149,113,16,91,53,41]
    arr1 = [43,1,6,69,20,62,6,44,24,113,6,35,0,3,6,44,20,22,127,60] 
    arr2 = [90,100,87,109,86,108,86,105,90,104,88,102]  
    k = Solver()
    s = [BitVec('s[%d]'%i,64)for i in range(39)]
    for i in range(39):
        k.add(32<=s[i])
        k.add(s[i]<128)
    k.add(((((s[0]*128+s[1])*128+s[2])*128+s[3])*128+s[4])*128+s[5] == 3533889469877)
    k.add(s[-1]== ord('}'))
    arr =  list(s)
    a = arr[6:30:3]
    for i in range(len(a)):
        k.add((a[i]*17684+372511)%257==arr0[i])
    
    b = arr[-2:33:-1]*5
    c = list(map(lambda x:x[0]^x[1] ,zip(b,arr[7:27])))
    for i in range(len(c)):
        k.add(c[i]==arr1[i])
    
    p = 0
    for i in range(28,34):
        k.add(arr2[p] == (arr[i]+107)/16+77)
        k.add((arr[i]+117)%16+99==arr2[p+1])
        p+=2
    print(k.check())
    print(k.model())
    

    z3脚本二次转换

    s = [0]*39
    s[5]=53
    s[4]=123
    s[34]=117
    s[7]=90
    s[6]=76
    s[30]=52
    s[18]=86
    s[35]=51
    s[33]=78
    s[24]=80
    s[12]=120
    s[11]=101
    s[20]=69
    s[15]=105
    s[3]=103
    s[25]=76
    s[23]=101
    s[2]=97
    s[16]=55
    s[29]=53
    s[17]=53
    s[22]=89
    s[36]=70
    s[21]=53
    s[8]=71
    s[13]=53
    s[28]=108
    s[26]=73
    s[14]=89
    s[0]=102
    s[37]=113
    s[31]=49
    s[10]=48
    s[1]=108
    s[9]=53
    s[27]=75
    s[32]=112
    s[19]=113
    s[38]=125
    for i in range(39):
       print(chr(s[i]),end="")
    

    z3很好用。z3这部分脚本详细参考于CX-330的博文。
    第一次知道有这种东西,值得学习嗷!

  • 相关阅读:
    数字音乐均衡器
    移植x264到vs2008之二
    无线连接频繁掉线,解决方法之telnet命令突破ddwrt端口最大数连接限制分析
    最新开发的消费平台开发过程 持续更新(二)
    .net 4.0 下请求验证模式变化 应对方法
    DDWRT无线参数解读
    利用 Application_Error 捕获所有异常
    location.reload() 和 location.replace()的区别和应用
    纯CSS 实现组织架构图,学习
    Syslog架设windows日志服务器
  • 原文地址:https://www.cnblogs.com/Nickyl07/p/12748955.html
Copyright © 2011-2022 走看看