[HGAME 2022 week4]hardasm

参考
s0uthwood

长见识了 AVX2指令集
IDA打开 main里面全是这种:
image

注意到前面我们的输入是ymm0
image

最后有个check
image

汇编
image

这里mov后进行cmp 然后check比较位 要全为1才正确
找到enc数组image

整体逻辑就是我们输入的作为ymm0
ymm0经过一系列变换后与enc比较
这些变换的参数就是ymm1~ymm7
已知ymm:256位 转为32个byte 刚好

几个函数
xor add sub没什么好说的 注意&0xff即可
重点是vpermd 和 vpshufb

vpermd:

网上找官方文档也看不怎么明白...
image

采取动态调试的方法
这里获取ymmx寄存器的值可以ida_python:

get_reg_value("ymmx")

经过比较发现

def vpermd(a,b):
    s = b[:4] + b[16:24] + b[4:16] + b[24:]
    for i in range(len(s)):
        b[i] = s[i]
"""
origin:
ymm4 ymm7
b"3_bh\rd\xa8\xff\x8f\x99\xa7\x94\x9e\x9a)4'6\xd6\x82\xc2m\xe8\xaa\x96Je\xc0\x0c7\x19\xc9"
b'\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00'

after vpermd:
ymm4 ymm7
b"3_bh'6\xd6\x82\xc2m\xe8\xaa\rd\xa8\xff\x8f\x99\xa7\x94\x9e\x9a)4\x96Je\xc0\x0c7\x19\xc9"
b'\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00'

b"3_bh \rd\xa8\xff\x8f\x99\xa7\x94\x9e\x9a)4 '6\xd6\x82\xc2m\xe8\xaa \x96Je\xc0\x0c7\x19\xc9"
b"3_bh '6\xd6\x82\xc2m\xe8\xaa \rd\xa8\xff\x8f\x99\xa7\x94\x9e\x9a)4 \x96Je\xc0\x0c7\x19\xc9"
就是中间部分交换了下
"""

vpermd的第一个数组不会变 第二个数组进行了换序 对着样例写就行

vpshufb同理 只是更复杂一点

def vpshufb(a,b):
    s = []
    s = a[:2] + a[8:11] + a[2:6] + \
        a[12:15] + a[6:8] + a[11:12]+ \
        a[15:17] + a[22:27] + a[18:22] + a[29:31]+\
        a[27:29] + a[17:18] + a[31:32]
    for i in range(len(s)):
        a[i] = s[i]
    

"""
origin:
ymm4 ymm6
b'\xbc~\xca_\xda\x8a\xfc\xab\x82M\x90\xaad?\xd1\xb1d\xea\xa4\xe0\xac\x10\xe3\x19\xaf*x\x06\x9d\xbd/B'
b'\x00\x01\x08\t\n\x02\x03\x04\x05\x0c\r\x0e\x06\x07\x0b\x0f\x00\x06\x07\x08\t\n\x02\x03\x04\x05\r\x0e\x0b\x0c\x01\x0f'

after vpshufb:
ymm4 ymm6
b'\xbc~\x82M\x90\xca_\xda\x8ad?\xd1\xfc\xab\xaa\xb1d\xe3\x19\xaf*x\xa4\xe0\xac\x10\xbd/\x06\x9d\xeaB'
b'\x00\x01\x08\t\n\x02\x03\x04\x05\x0c\r\x0e\x06\x07\x0b\x0f\x00\x06\x07\x08\t\n\x02\x03\x04\x05\r\x0e\x0b\x0c\x01\x0f'


from
b'\xbc~\xca_\xda\x8a\xfc\xab\x82M\x90 \xaad?    \xd1\xb1d\xea\xa4\xe0\xac\x10\xe3\x19\xaf * x \x06\x9d\xbd  / B   '
   0  1  2 3  4   5   6   7   8 9  10 11 12 13  14   15 16 17 18 19  20  21  22  23  24  25 26 27 28  29  30 31 
to
b'\xbc~\x82M\x90\xca_\xda\x8ad?\xd1\xfc\xab\xaa\xb1d\xe3\x19\xaf*x\xa4\xe0\xac\x10\xbd/\x06\x9d\xeaB'

"""

这样我们就还原了指令集对应的函数
完全可以正向用z3约束求解
将6666条汇编提取出来 写成函数形式跑一遍最后加个约束即可

from z3 import *
ymm1 = [0xF0, 0xFF, 0x64, 0x26, 0xF2, 0x8F, 0x40, 0xEE, 0xEE, 0x27, 0x07, 0xEF, 0x88, 0x0A, 0x21, 0x14, 0xC3, 0xFC, 0x70, 0xE5, 0xA8, 0xF3, 0xF5, 0x1A, 0xD4, 0x3C, 0xB1, 0x0C, 0xE5, 0xBC, 0xB9, 0x1B]
ymm2 = [0x0D, 0xC0, 0x84, 0xC5, 0x0E, 0x80, 0x50, 0xFF, 0x28, 0x1A, 0x80, 0x48, 0x1D, 0xC1, 0xE3, 0x1D, 0x34, 0x51, 0x9B, 0x35, 0xBC, 0xD5, 0xF4, 0xC3, 0xC4, 0x40, 0x90, 0x07, 0x2A, 0xC0, 0x2D, 0x90]
ymm3 = [0x89, 0xA1, 0x3E, 0xC0, 0xE5, 0x14, 0x5F, 0xC5, 0x5F, 0x14, 0xB0, 0xD0, 0x25, 0x1F, 0xE8, 0xF5, 0xB0, 0x34, 0x36, 0xC2, 0xC7, 0xA0, 0xB2, 0x3C, 0x5E, 0x7E, 0x9C, 0xA4, 0x98, 0xE8, 0x54, 0x0B]
ymm4 = [0x33, 0x5F, 0x62, 0x68, 0x0D, 0x64, 0xA8, 0xFF, 0x8F, 0x99, 0xA7, 0x94, 0x9E, 0x9A, 0x29, 0x34, 0x27, 0x36, 0xD6, 0x82, 0xC2, 0x6D, 0xE8, 0xAA, 0x96, 0x4A, 0x65, 0xC0, 0x0C, 0x37, 0x19, 0xC9]
ymm5 = [0x8F, 0x21, 0xA8, 0x37, 0x43, 0x09, 0x07, 0x33, 0xA6, 0x87, 0x4C, 0x4A, 0xA1, 0x74, 0x4B, 0xE6, 0x55, 0x13, 0x5B, 0x3F, 0x1C, 0xD7, 0xB9, 0x9E, 0x39, 0x60, 0x1D, 0xC6, 0x91, 0x8A, 0x36, 0x8B]
ymm6 = [0x00, 0x01, 0x08, 0x09, 0x0A, 0x02, 0x03, 0x04, 0x05, 0x0C, 0x0D, 0x0E, 0x06, 0x07, 0x0B, 0x0F, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x02, 0x03, 0x04, 0x05, 0x0D, 0x0E, 0x0B, 0x0C, 0x01, 0x0F]
ymm7 = [0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00]

enc = [0x93, 0xCB, 0xE7, 0x93, 0xA9, 0x81, 0x0D, 0xB6, 0xD8, 0xDD, 0x9C, 0x7F, 0xC0, 0x4D, 0xCD, 0xF0, 0x00, 0xA0, 0x9F, 0x22, 0x89, 0xEF, 0x54, 0x5D, 0xEF, 0x00, 0x8D, 0xFE, 0x5E, 0x4C, 0xD0, 0xEC]

s = Solver()
ymm0 = [BitVec("flag[%d]"%i,8) for i in range(32)]

def vpxor(a,b):
    for i in range(len(a)):
        a[i] ^= b[i]
        a[i] &= 0xff

def vpsubb(a,b):
    for i in range(len(a)):
        a[i] -= b[i]
        a[i] &= 0xff

def vpaddb(a,b):
    for i in range(len(a)):
        a[i] += b[i]
        a[i] &= 0xff

def vpermd(a,b):
    s = b[:4] + b[16:24] + b[4:16] + b[24:]
    for i in range(len(s)):
        b[i] = s[i]
"""
origin:
ymm4 ymm7
b"3_bh\rd\xa8\xff\x8f\x99\xa7\x94\x9e\x9a)4'6\xd6\x82\xc2m\xe8\xaa\x96Je\xc0\x0c7\x19\xc9"
b'\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00'

after vpermd:
ymm4 ymm7
b"3_bh'6\xd6\x82\xc2m\xe8\xaa\rd\xa8\xff\x8f\x99\xa7\x94\x9e\x9a)4\x96Je\xc0\x0c7\x19\xc9"
b'\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00'

b"3_bh \rd\xa8\xff\x8f\x99\xa7\x94\x9e\x9a)4 '6\xd6\x82\xc2m\xe8\xaa \x96Je\xc0\x0c7\x19\xc9"
b"3_bh '6\xd6\x82\xc2m\xe8\xaa \rd\xa8\xff\x8f\x99\xa7\x94\x9e\x9a)4 \x96Je\xc0\x0c7\x19\xc9"
就是中间部分交换了下
"""
from libnum import *
def vpshufb(a,b):
    s = []
    s = a[:2] + a[8:11] + a[2:6] + \
        a[12:15] + a[6:8] + a[11:12]+ \
        a[15:17] + a[22:27] + a[18:22] + a[29:31]+\
        a[27:29] + a[17:18] + a[31:32]
    for i in range(len(s)):
        a[i] = s[i]
    

"""
origin:
ymm4 ymm6
b'\xbc~\xca_\xda\x8a\xfc\xab\x82M\x90\xaad?\xd1\xb1d\xea\xa4\xe0\xac\x10\xe3\x19\xaf*x\x06\x9d\xbd/B'
b'\x00\x01\x08\t\n\x02\x03\x04\x05\x0c\r\x0e\x06\x07\x0b\x0f\x00\x06\x07\x08\t\n\x02\x03\x04\x05\r\x0e\x0b\x0c\x01\x0f'

after vpshufb:
ymm4 ymm6
b'\xbc~\x82M\x90\xca_\xda\x8ad?\xd1\xfc\xab\xaa\xb1d\xe3\x19\xaf*x\xa4\xe0\xac\x10\xbd/\x06\x9d\xeaB'
b'\x00\x01\x08\t\n\x02\x03\x04\x05\x0c\r\x0e\x06\x07\x0b\x0f\x00\x06\x07\x08\t\n\x02\x03\x04\x05\r\x0e\x0b\x0c\x01\x0f'


from
b'\xbc~\xca_\xda\x8a\xfc\xab\x82M\x90 \xaad?    \xd1\xb1d\xea\xa4\xe0\xac\x10\xe3\x19\xaf * x \x06\x9d\xbd  / B   '
   0  1  2 3  4   5   6   7   8 9  10 11 12 13  14   15 16 17 18 19  20  21  22  23  24  25 26 27 28  29  30 31 
to
b'\xbc~\x82M\x90\xca_\xda\x8ad?\xd1\xfc\xab\xaa\xb1d\xe3\x19\xaf*x\xa4\xe0\xac\x10\xbd/\x06\x9d\xeaB'


"""


vpermd(ymm7,ymm4)
...
vpermd(ymm7,ymm1)

for i in range(32):
    s.add(ymm0[i]==enc[i])
print(s.check())
ans = s.model()
print(ans)
ymm0 = [BitVec("flag[%d]"%i,8) for i in range(32)]
for i in ymm0:
    print(chr(ans[i].as_long()),end='')

跑一遍就出了
hgame{right_your_asm_is_good!!}

posted @ 2024-02-03 17:46  N0zoM1z0  阅读(18)  评论(0编辑  收藏  举报