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位。

猜你喜欢

转载自www.cnblogs.com/blackicelisa/p/12905731.html