当前位置:网站首页>[buuctf.reverse] 144_ [xman2018 qualifying]easyvm
[buuctf.reverse] 144_ [xman2018 qualifying]easyvm
2022-07-01 11:12:00 【Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi】
There are few problems with virtual machines , It's almost the same , But this really feels a little troublesome .
The symbol table is not deleted, which makes it a lot easier to deal with . Except for loop and end commands, the code is 3 byte ,1 Byte command 2 Bytes of data .
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 Save calculation results
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:
The loop has no start and end flags , It's just one of two choices, the first time in and the second time out , So there is no nesting
case 0x28:
if ( inloop ) // Single byte instruction loop
{
if ( v9 )
ptr = loopstart;
else
inloop = 0;
}
else
{
inloop = 1;
loopstart = ptr;
}
break;The operation commands are 20 individual , Include assignments , Add , displacement , Logical operations , Stack operation, etc . First print out the operation commands according to these functions ( Not very accurate , Just for convenience )
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)
Then nibble on the output results a little . Roughly divided into 4 paragraph ,
The first paragraph is for input flag Transpose
'''
lea_ch R[1] R[11] #R1 = flag
xor R[3] R[3]
xor R[0] R[0]
xor R[4] R[4]
'''
# The first 1 Segment change position
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
'''
The second paragraph is to divide each character into the first 3 after 5 Then use the latter one 5 And the front of the previous 3 Spell new bytes
# The first 1 Before the character 3 position
'''
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]
'''
# The first 2 paragraph , front 5 after 3 Combine
[((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
'''
# the last one
'''
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]
'''The first 3 Duan is first key And the i%4 Bit and i Add and then XOR with the original
# The first 3 paragraph And key loop + Serial number Exclusive or
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
'''The first 4 Duan read it for a long time and didn't understand , Probably means no , Because first pop Immediately behind push 了 , Nothing seems to have been changed
# It doesn't seem to work , No change in data
'''
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 Directly after 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
'''Write this in reverse 3 Sentence to decrypt
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}边栏推荐
- Oneconnect plans to be listed in Hong Kong on July 4: a loss of nearly 3 billion in two years, with a market capitalization evaporation of more than 90%
- LeetCode. 515. Find the maximum value in each tree row___ BFS + DFS + BFS by layer
- ES6 Promise用法小结
- 田溯宁投的天润云上市:市值22亿港元 年利润下降75%
- Mingchuang plans to be listed on July 13: the highest issue price is HK $22.1, and the net profit in a single quarter decreases by 19%
- 达梦数据冲刺科创板:拟募资24亿 冯裕才曾为华科教授
- BAIC bluevale: performance under pressure, extremely difficult period
- 商城小程序源码开源版-可二开
- Goldfish rhca memoirs: do447 uses ansible to communicate with API -- using ansible tower API to start jobs
- Handling distributed transactions with powerful dbpack (PHP tutorial)
猜你喜欢

Exposure:A White-Box Photo Post-Processing Framework阅读札记

“目标检测”+“视觉理解”实现对输入图像的理解及翻译(附源代码)

京东与腾讯续签合作:向腾讯发行A类股 价值最高达2.2亿美元

NeurIPS 2022 | 细胞图像分割竞赛正式启动!

How does MySQL copy table data from one database to another (two databases are not linked to the same database)

英特尔实验室公布集成光子学研究新进展

Intel Labs announces new progress in integrated photonics research

达梦数据冲刺科创板:拟募资24亿 冯裕才曾为华科教授

Several cases of index failure

Combination of Oracle and JSON
随机推荐
TEMPEST HDMI泄漏接收 5
The first anniversary of the data security law, which four major changes are coming?
金鱼哥RHCA回忆录:DO447使用Ansible与API通信--使用Ansible Tower API启动作业
Tempest HDMI leak receive 5
Mutual conversion of pictures in fluent uint8list format and pictures in file format
银行卡借给别人是否构成犯罪
Unittest框架中跳过要执行的测试用例
Face detection and recognition system based on mtcnn+facenet
商汤进入解禁期:核心管理层自愿禁售 强化公司长期价值信心
Huawei Equipment configure les services de base du réseau WLAN à grande échelle
名创拟7月13日上市:最高发行价22.1港元 单季净利下降19%
Yoda unified data application -- Exploration and practice of fusion computing in ant risk scenarios
CVPR 2022 | self enhanced unpaired image defogging based on density and depth decomposition
索引失效的几种情况
Handling distributed transactions with powerful dbpack (PHP tutorial)
Combination of Oracle and JSON
软件项目管理 9.2.软件项目配置管理过程
优雅地翻转数组
Unittest 框架介绍及第一个demo
[paper reading] trajectory guided control prediction for end to end autonomous driving: a simple yet strong Ba