南邮CTF逆向题第四道WxyVM解题思路

首先看下题目

 

南邮CTF逆向题第四道WxyVM解题思路

南邮CTF逆向题第四道WxyVM解题思路

ELF文件

直接载入64位IDA

进入main函数

F5查看C代码

南邮CTF逆向题第四道WxyVM解题思路

分析main函数代码:

 

南邮CTF逆向题第四道WxyVM解题思路

 

__int64 __fastcall main(__int64 a1,char**a2,char**a3)//main函数有三个参数

{

char v4;// [rsp+Bh] [rbp-5h] //定义一个char型变量v4

signedint i;// [rsp+Ch] [rbp-4h] //int i;

 

puts("[WxyVM 0.0.1]");//输出字符串"[WxyVM 0.0.1]"

puts("input your flag:");//输出字符串"input your flag:"

scanf("%s",&byte_604B80);//获取用户输入一个字符串保存在地址604B80的位置

v4 =1;//v4 = 1;

sub_4005B6();//调用sub_4005B6这个函数

if( strlen(&byte_604B80)!=24)//如果获取的字符串长度不等于24

v4 =0;//v4 = 0;

for( i =0; i <=23;++i )//开始for循环i>23时跳出

{

if(*(&byte_604B80 + i)!= dword_601060[i])//比较404B80加上i的地址处保存的值与601060处的值

v4 =0;//即地址604B80601060 两个数组相比较若相等v4 = 0;

}

if( v4 )//如果v4等于0 输出字符串"correct"

puts("correct");

else//否则输出字符串"wrong"

puts("wrong");

return0LL;

}

 

接着我们看看函数sub_4005B6:

分析一波

南邮CTF逆向题第四道WxyVM解题思路

南邮CTF逆向题第四道WxyVM解题思路

思路一:

该函数对我们在main中输入的字符串进行修改,根据v0的值来确定进入哪个case,6010c0处的数组应该是每三个为一组,分别为v0,v1,v2,每组中的第一个数字决定跳到哪个操作进行运算,第二个数字决定对用户字符串的第几个字符进行操作,第三个数字决定我们要操作的操作数。

 

所以我们只要对上面运算进行逆运算即可得到flag

 

将6010c0处的数组保存下来,查看后发现v0的值只有1,2,3,那么我们就不管后三种情况,字符串长度只有24位,我们选择直接**,脚本如下所示:

b =''

 

c =[]

 

d =[]

 

e =[]

 

s =['0xc4','0x34','0x22','0xb1','0xd3','0x11','0x97','0x7','0xdb','0x37','0xc4','0x6','0x1d','0xfc','0x5b','0xed','0x98','0xdf','0x94','0xd8','0xb3','0x84','0xcc','0x8']

 

with open('test.txt','r')as f:

 

whileTrue:

 

a = f.readline()# 整行读取数据

 

ifnot a:

 

break

 

b += a[:24]+a[25:]

 

for i in range(0,len(b),9):

 

c.append(int(b[i:i+2]))

 

d.append(int(b[i+3:i+5],16))

 

e.append(int(b[i+6:i+8],16))

 

defrplus(s,x,y):

 

s[x]=(s[x]+y)%2**8

 

defrsub(s,x,y):

 

s[x]=(s[x]- y)%2**8

 

defrxor(s,x,y):

 

s[x]=(s[x]^y)%2**8

 

defcase(s,i,x,y):

 

if i ==1:

 

rplus(s,x, y)

 

elif i ==2:

 

rsub(s,x, y)

 

elif i ==3:

 

rxor(s,x, y)

 

count =0

 

flag =[0for i in range(24)]

 

result =''

 

for k in range(24):

 

for j in range(33,128):

 

flag[k]= j

 

for i in range(len(c)):

 

case(flag,c[i], d[i], e[i])

 

if hex(flag[k])==s[k]:

 

result += chr(j)

 

print chr(j)

 

break

 

print result

 

得到nctf{Embr4ce_Vm_j0in_R3}

思路二:

直接对全部进行逆运算

 

 

可以参考

http://blog.****.net/m0_37812124/article/details/76269151

http://blog.****.net/whklhhhh/article/details/74793530?locationNum=1&fps=1

ELF文件格式详解

http://blog.****.net/tenfyguo/article/details/5631561