当前位置:网站首页>[buuctf.reverse] 144_[XMAN2018排位赛]easyvm
[buuctf.reverse] 144_[XMAN2018排位赛]easyvm
2022-07-01 11:07:00 【石氏是时试】
虚拟机的题很少,感觉都差不多,不过这个确实感觉麻烦了点。
没有删除符号表这让处理起来方便了不少。代码除循环和结束命令外都是3字节,1字节命令2字节数据。
printf("Please input your flag:");
flag = malloc(0x20u);
scanf("%32s", flag);
v3[1] = (int)&flag;
memcpy(cipher, &unk_3E75, sizeof(cipher));
v3[0] = (int)cipher;
v2[1] = (int)v3;
v2[0] = 0xEFBEADDE;
R[0] = (char **)&v17;
R[1] = (char **)&v11;
R[2] = (char **)&v10;
R[3] = (char **)&v16;
R[4] = (char **)&v15; // R4,V15存计算结果
R[5] = &v7;
R[6] = (char **)&v9;
R[7] = (char **)&v8;
R[8] = (char **)&v14;
R[9] = (char **)&v13;
R[10] = (char **)&v12;
R[11] = (char **)&flag;
R[12] = (char **)v3; // cipher
R[13] = (char **)v2;
while ( 1 )
{
v22 = read_code(code, &ptr); // pop
v21 = v22 & 0xFE;
v20 = v22 & 1;
switch ( v22 & 0xFE )
{
case 0:
v6 = read_code(code, &ptr); // op a b : mov R[a],(char)R[b] mov R[b],(char)b
v5 = read_code(code, &ptr);
if ( v20 )
{
if ( v20 == 1 )
mov((int *)R[v6], (char)*R[v5]);
}
else
{
mov((int *)R[v6], v5);
}
break;
case 2:
v6 = read_code(code, &ptr); // op a b : mov R[a],(int)R[b] mov R[b],(int)b
v5 = read_code(code, &ptr);
if ( v20 )
{
if ( v20 == 1 )
mov32((int *)R[v6], (int)*R[v5]);
}
else
{
mov32((int *)R[v6], v5);
}
break;
case 4:
循环没有开始结束标志,只是个二选一第一次进第二次出,所以没有嵌套
case 0x28:
if ( inloop ) // 单字节指令 循环
{
if ( v9 )
ptr = loopstart;
else
inloop = 0;
}
else
{
inloop = 1;
loopstart = ptr;
}
break;操作命令一共20个,包含赋值,加,移位,逻辑运算,栈运算等。先把操作命令按这些功能打印出来(不大准确,只为方便观看)
def printcode(code):
i = 0
while i<246:
op = code[i]; i+=1
v1 = op&0xfe
v2 = op&1
if v1 < 0x28:
a = code[i]; i+=1
b = code[i]; i+=1
if v1 == 0 and v2 == 1:
print(f'mov R[{a}] R[{b}]')
if v1 == 0 and v2 == 0:
print(f'mov R[{a}] {b}')
if v1 == 2 and v2 == 1:
print(f'mov32 R[{a}] R[{b}]')
if v1 == 2 and v2 == 0:
print(f'mov32 R[{a}] {b}')
if v1 == 4 and v2 == 1:
print(f'lea_ch R[{a}] R[{b}]')
if v1 == 6 and v2 == 1:
print(f'lea_int R[{a}] R[{b}]')
if v1 == 8 and v2 == 1:
print(f'ldr_int R[{a}] R[{b}]')
if v1 == 10 and v2 == 1:
print(f'ldr_ch R[{a}] R[{b}]')
if v1 == 12 and v2 == 1:
print(f'add R[{a}] R[{b}]')
if v1 == 12 and v2 == 0:
print(f'add R[{a}] {b}')
if v1 == 14 and v2 == 1:
print(f'add_pint R[{a}] R[{b}]')
if v1 == 14 and v2 == 0:
print(f'add_pint R[{a}] {b}')
if v1 == 16 and v2 == 1:
print(f'add_pch R[{a}] R[{b}]')
if v1 == 16 and v2 == 0:
print(f'add_pcj R[{a}] {b}')
if v1 == 18 and v2 == 1:
print(f'xor R[{a}] R[{b}]')
if v1 == 18 and v2 == 0:
print(f'xor R[{a}] {b}')
if v1 == 20 and v2 == 0:
print(f'mod R[{a}] {b}')
if v1 == 22 and v2 == 1:
print(f'or R[{a}] R[{b}]')
if v1 == 22 and v2 == 0:
print(f'or R[{a}] {b}')
if v1 == 24 and v2 == 1:
print(f'and R[{a}] R[{b}]')
if v1 == 24 and v2 == 0:
print(f'and R[{a}] {b}')
if v1 == 26 and v2 == 1:
print(f'push R[{a}] R[{b}]')
if v1 == 26 and v2 == 0:
print(f'push R[{a}] {b}')
if v1 == 28 and v2 == 1:
print(f'pop R[{a}] R[{b}]')
if v1 == 30 and v2 == 1:
print(f'shr R[{a}] R[{b}]')
if v1 == 30 and v2 == 0:
print(f'shr R[{a}] {b}')
if v1 == 32 and v2 == 1:
print(f'shl R[{a}] R[{b}]')
if v1 == 32 and v2 == 0:
print(f'shl R[{a}] {b}')
if v1 == 34 and v2 == 1:
print(f'ror R[{a}] R[{b}]')
if v1 == 34 and v2 == 0:
print(f'ror R[{a}] {b}')
if v1 == 36 and v2 == 1:
print(f'cmp_l R[{a}] R[{b}]')
if v1 == 36 and v2 == 0:
print(f'cmp_l R[{a}] {b}')
if v1 == 38 and v2 == 1:
print(f'cmp_eq R[{a}] R[{b}]')
if v1 == 38 and v2 == 0:
print(f'cmp_eq R[{a}] {b}')
if v1 == 40:
print('loop')
if v1 == 42:
print('end')
return
code = open('easyvm', 'rb').read()[0x2e95: 0x2e95+246]
print(list(code))
printcode(code)
然后对输出的结果一点点啃。大概分成4段,
第一段是对输入的flag进行换位
'''
lea_ch R[1] R[11] #R1 = flag
xor R[3] R[3]
xor R[0] R[0]
xor R[4] R[4]
'''
#第1段换位置
j=0
for i in range(32):
j = (j + 51)%32
stack[i] = flag[j]
'''
loop
add R[0] 51
mod R[0] 32
lea_ch R[9] R[1]
add_pch R[9] R[0]
ldr_ch R[10] R[9]
mov R[4] R[10]
push R[5] R[4]
add R[3] 1
cmp_l R[3] 32
loop
'''
第二段是将每个字符分成前3后5然后用后一个的后5和前一个的前3拼成新的字节
#第1字符的前3位
'''
xor R[0] R[0]
lea_int R[8] R[5]
add_pint R[8] 224
lea_int R[2] R[8]
ldr_int R[10] R[2]
mov R[0] R[10]
and R[0] 224
shr R[0] 5
mov R[4] R[0]
xor R[3] R[3]
'''
#第2段,前5后3组合
[((flag[i]<<3)|(flag[(i-1) %32]>>5))&0xff for i in range(32)]
'''
loop
ldr_int R[10] R[2]
mov R[0] R[10]
and R[0] 31
shl R[0] 3 # a&0x1f;a<<=3
push R[5] R[0]
lea_int R[8] R[5]
add_pint R[8] 224
lea_int R[2] R[8]
ldr_int R[10] R[2]
mov R[0] R[10]
and R[0] 224 # a&0xe0;a>>5
shr R[0] 5
pop R[5] R[10]
add R[10] R[0]
push R[5] R[10]
add R[3] 1
cmp_l R[3] 31
loop
'''
#最后一个
'''
ldr_int R[10] R[2]
mov R[0] R[10]
and R[0] 31
shl R[0] 3
add R[0] R[4]
push R[5] R[0]
'''第3段是先把key和第i%4位与i相加后再与原文作异或
#第3段 与key循环+序号 异或
def ror8(a):
return (a>>i)|((a&0xff)<<24)
r3=0
r4=0xEFBEADDE
for i in range(32):
stack[i] = flag[i]^(r4+i)
r4 = ror8(r4)
'''
xor R[3] R[3]
mov32 R[4] R[13] #0xEFBEADDE
loop
lea_int R[8] R[5]
add_pint R[8] 224
lea_int R[2] R[8]
ldr_int R[10] R[2]
mov R[0] R[10]
push R[5] R[0]
mov R[0] R[4]
add R[0] R[3]
pop R[5] R[10]
xor R[10] R[0]
push R[5] R[10]
ror R[4] 8
add R[3] 1
cmp_l R[3] 32
loop
'''第4段看了半天没看懂,大概意思是没有,因为先是pop后边马上就push了,似乎没有作什么改动
#似乎没用,并没有改变数据
'''
xor R[3] R[3]
xor R[4] R[4]
lea_ch R[1] R[12]
loop
lea_ch R[9] R[1]
add_pch R[9] R[3]
ldr_ch R[10] R[9]
mov R[0] R[10]
push R[5] R[0]
lea_int R[8] R[5]
add_pint R[8] 223
ldr_int R[10] R[8]
pop R[5] R[0] #pop后直接push
push R[5] R[0]
cmp_eq R[0] R[10] #v8 = (r0 != r10)? 1: 0; r7=v8
or R[4] R[7]
add R[3] 1
cmp_l R[3] 32
loop
end
'''根据这个反过来写出3句来解密
cipher = open('easyvm', 'rb').read()[0x2e75: 0x2e75+32]
#print(cipher)
key = [0xDE, 0xAD, 0xBE, 0xEF]
m = [cipher[i]^(key[i%4] + i) for i in range(32)] #3
v = [( (m[(i-1)%32]<<5) | (m[i]>>3) )&0xff for i in range(32)] #2
flag = [0]*32 #1
p = 0
for i in range(32):
p = (p+51)%32
flag[p] = v[i]
print(bytes(flag))
#xman{ae791f19bdf77357ff10bb6b0e}
#flag{ae791f19bdf77357ff10bb6b0e}边栏推荐
- LeetCode.515. 在每个树行中找最大值___逐一BFS+DFS+按层BFS
- Sqlachemy common operations
- LeetCode. 515. Find the maximum value in each tree row___ BFS + DFS + BFS by layer
- Graduation season · advanced technology er
- Mall applet source code open source version - two open
- Mutual conversion of pictures in fluent uint8list format and pictures in file format
- MySQL IN 和 NOT IN () 空列表报错
- CVPR 2022 | self enhanced unpaired image defogging based on density and depth decomposition
- . Net 5.0+ does not need to rely on third-party native implementation of scheduled tasks
- [.net6] use ml.net+onnx pre training model to liven the classic "Huaqiang buys melons" in station B
猜你喜欢

Matplotlib data visualization Foundation

NC | intestinal cells and lactic acid bacteria work together to prevent Candida infection

谷歌新论文-Minerva:用语言模型解决定量推理问题

金融壹账通拟7月4日香港上市:2年亏近30亿 市值蒸发超90%

2022年6月编程语言排行,第一名居然是它?!

Neurips 2022 | cell image segmentation competition officially launched!
![[AI information monthly] 350 + resources! All the information and trends that can't be missed in June are here! < Download attached >](/img/62/562e93e66addc8e86c0a19bc514389.png)
[AI information monthly] 350 + resources! All the information and trends that can't be missed in June are here! < Download attached >

The exclusive collection of China lunar exploration project is limited to sale!

"Target detection" + "visual understanding" to realize the understanding and translation of the input image (with source code)

编译调试Net6源码
随机推荐
12款大家都在用的产品管理平台
Personal mall two open Xiaoyao B2C mall system source code - Commercial Version / group shopping discount seckill source code
想请教一下,我在广州,到哪里开户比较好?现在网上开户安全么?
escape sequence
PHP有哪些优势和劣势
Mysql的四个隔离级别是如何实现的 (简要)
Rising stars in Plant Sciences (rsps2022) final Science Lecture (6.30 pm)
CVPR 2022 | 基于密度与深度分解的自增强非成对图像去雾
JS foundation -- data type
[AI information monthly] 350 + resources! All the information and trends that can't be missed in June are here! < Download attached >
Addition, deletion, modification and query of database
Ask everyone in the group about the fact that the logminer scheme of flick Oracle CDC has been used to run stably in production
Rising Stars in Plant Sciences (RSPS2022) Finalist科学演讲会(6.30晚9点)
Infinite innovation in cloud "vision" | the 2022 Alibaba cloud live summit was officially launched
个人商城二开逍遥B2C商城系统源码-可商用版/拼团拼购优惠折扣秒杀源码
技术分享 | Linkis参数介绍
Face detection and recognition system based on mtcnn+facenet
Yoda unified data application -- Exploration and practice of fusion computing in ant risk scenarios
[.net6] use ml.net+onnx pre training model to liven the classic "Huaqiang buys melons" in station B
商汤进入解禁期:核心管理层自愿禁售 强化公司长期价值信心