1.shellcode:
放入die里面查看是一个64位用GO写的程序,用ida打开看看:
使用ida插件findcrypt可以看到有一个base64:
根据题目的名字可以得知,这是一个关于shellcode的题目,当程序运行的时候会解密一段机器码来运行
os_ReadFile()的作用是从指定的文件里面读取数据,并将读取的内容放在缓冲区里面
syscall_Syscall()函数的作用是执行系统的调用。系统的调用是应用程序与操作系统之间的接口,他可以执行以下的操作:
- 文件操作:通过系统调用可以打开,关闭,读取,写入,创建的操作
- 进程管理:可以创建,终止,等待进程,获取和修改进程
- 内存管理:可以申请,释放内存
- 网络通信:可以简历啊网络连接,发送接收数据
这里就是我们的需要解开的base64码,
因为这下面两个字符串没有交叉引用,所以大概率是和我们要解开的是一起的,按A合在一起,然后就提取出来base64解密并保存为文件放在ida里面反汇编,
import base64
with open('out', 'wb') as f:
f.write(base64.b64decode('VUiD7FBIjWwkIEiJTUBIi0VAiwCJRQC4BAAAAEgDRUCLAIlFBMdFC AAAAADHRQwj782rx0UQFgAAAMdFFCEAAADHRRgsAAAAx0UcNwAAAMdFIAAAAACLRSCD+CBzWotFDANFC IlFCItFBMHgBANFEItVCANVBDPCi1UEweoFA1UUM8IDRQCJRQCLRQDB4AQDRRiLVQgDVQAzwotVAMHqB QNVHDPCA0UEiUUEuAEAAAADRSCJRSDrnkiLRUCLVQCJELgEAAAASANFQItVBIkQSI1lMF3D'))
反编译出来是个tea加密
from ctypes import *
from libnum import *
def encrypt(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x9e3779b9
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(0)
for i in range(32):
total.value += delta
v0.value += ((v1.value << 4) + k0) ^ (v1.value + total.value) ^ ((v1.value >> 5) + k1)
v1.value += ((v0.value << 4) + k2) ^ (v0.value + total.value) ^ ((v0.value >> 5) + k3)
return v0.value, v1.value
def decrypt(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0xABCDEF23
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(delta * 32)
for i in range(32):
v1.value -= ((v0.value << 4) + k2) ^ (v0.value + total.value) ^ ((v0.value >> 5) + k3)
v0.value -= ((v1.value << 4) + k0) ^ (v1.value + total.value) ^ ((v1.value >> 5) + k1)
total.value -= delta
return v0.value, v1.value
# test
if __name__ == "__main__":
# 需要注意的是这里数据读取的顺序
va = [0xE4B36920, 0x936924D0,
0xA816D144, 0xAA82D5F5,
0x3679F0DA, 0x7F32FD06,
0x3460C0D3, 0xB7214939,
0xE57269A2, 0x836A51FA]
# 四个key,每个是32bit,即密钥长度为128bit
key = [22, 33, 44, 55]
flag=''
#res = encrypt(value, key)
#print("Encrypted data is : ", hex(res[0]), hex(res[1]))
for i in range(0,len(va),2):
res = decrypt([va[i],va[i+1]], key)
flag+=str((n2s(res[0])[::-1] + n2s(res[1])[::-1]))[2:10]
print(flag)
2.VM:
VM逆向:这里的虚拟机不是商业的vmp之内的保护软件,而是出题嗯实现的小型虚拟机,题目本身一般没有实现某些复杂功能
基本原理:这里的VM指的是一种解释执行系统或者模拟器(Emulator)
逆向中的虚拟保护是一种基于虚拟机的代码保护技术。基于x86汇编系统中的可执行代码转化为字节码指令系统的代码,来达到不被轻易逆向和篡改的目的(也就是把程序代码转化为 自定义的操作码),
vm_start:虚拟机的入口函数,对虚拟机环境进行初始化
vm_dispatcher:调度器,解释操作码,并选择对应的handle函数执行,当handle执行完后会跳回到这里,形成一个循环
opcode:程序可执行代码转化成的操作码
所以在这种情况下,要想逆向程序,就要对整个Emulator结构进行逆向,理解程序的功能,还需要结合opcode进行分析,这个程序逆向工程就会十分繁琐
现在来看一下题:
首先用die打开看一下是个64位的,用64位ida打开
有题目名字可以知道是一个vm的题,我们先来看一下主函数:
虚拟机的题主要是要分析出来虚拟机的数据结构
main函数的第八行是初始化了vmn的结构体
我们可以看到函数sub_1400010b0里面是vm的主要代码:
我么可以看到里面有一个while循环,这一个循环在全局数组中按a1[24]下标的数据只要不是255就继续执行所以这个数组是code,也就是这个虚拟机的字节码数组,a1大概率是ip的寄存器
然后来看看sub_140001940函数
我们可以发现这里就是vm的主分发器(如cpu里面的译码器)
随便点进去一个看看:
可以看到这里是读取数据的,那么就可以当成 mov
其中 sub_1400014D0这一个函数英爱就是主加密函数:
__int64 __fastcall sub_1400014D0(__int64 a1)
{
__int64 result; // rax
switch ( byte_140005360[*(_DWORD *)(a1 + 24) + 1] )
{
case 0u:
*(_DWORD *)(a1 + 4i64 * byte_140005360[*(_DWORD *)(a1 + 24) + 2]) += *(_DWORD *)(a1
+ 4i64
* byte_140005360[*(_DWORD *)(a1 + 24) + 3]);
break;
case 1u:
*(_DWORD *)(a1 + 4i64 * byte_140005360[*(_DWORD *)(a1 + 24) + 2]) -= *(_DWORD *)(a1
+ 4i64
* byte_140005360[*(_DWORD *)(a1 + 24) + 3]);
break;
case 2u:
*(_DWORD *)(a1 + 4i64 * byte_140005360[*(_DWORD *)(a1 + 24) + 2]) *= *(_DWORD *)(a1
+ 4i64
* byte_140005360[*(_DWORD *)(a1 + 24) + 3]);
break;
case 3u:
*(_DWORD *)(a1 + 4i64 * byte_140005360[*(_DWORD *)(a1 + 24) + 2]) ^= *(_DWORD *)(a1
+ 4i64
* byte_140005360[*(_DWORD *)(a1 + 24) + 3]);
break;
case 4u:
*(_DWORD *)(a1 + 4i64 * byte_140005360[*(_DWORD *)(a1 + 24) + 2]) <<= *(_DWORD *)(a1
+ 4i64
* byte_140005360[*(_DWORD *)(a1 + 24) + 3]);
*(_DWORD *)(a1 + 4i64 * byte_140005360[*(_DWORD *)(a1 + 24) + 2]) &= 0xFF00u;
break;
case 5u:
*(_DWORD *)(a1 + 4i64 * byte_140005360[*(_DWORD *)(a1 + 24) + 2]) >>= *(_DWORD *)(a1
+ 4i64
* byte_140005360[*(_DWORD *)(a1 + 24) + 3]);
break;
default:
break;
}
result = (unsigned int)(*(_DWORD *)(a1 + 24) + 4);
*(_DWORD *)(a1 + 24) = result;
return result;
}
然后就能还原一下:
然后就能写反汇编器:
opcode=[ 0x00, 0x03, 0x02, 0x00, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x03, 0x02, 0x32,
0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
0x01, 0x00, 0x00, 0x03, 0x02, 0x64, 0x03, 0x00, 0x02, 0x03,
0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x01, 0x00, 0x00, 0x03,
0x00, 0x08, 0x00, 0x02, 0x02, 0x01, 0x03, 0x04, 0x01, 0x00,
0x03, 0x05, 0x02, 0x00, 0x03, 0x00, 0x01, 0x02, 0x00, 0x02,
0x00, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00, 0x01, 0x03, 0x00,
0x03, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x01, 0x28,
0x04, 0x06, 0x5F, 0x05, 0x00, 0x00, 0x03, 0x03, 0x00, 0x02,
0x01, 0x00, 0x03, 0x02, 0x96, 0x03, 0x00, 0x02, 0x03, 0x00,
0x00, 0x00, 0x00, 0x04, 0x07, 0x88, 0x00, 0x03, 0x00, 0x01,
0x03, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03,
0x01, 0x28, 0x04, 0x07, 0x63, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
ip=0
def func1():
global ip
if opcode[ip+1]:
match opcode[ip+1]:
case 1:
print(f"mov input[reg{[2]}] reg[0]")
case 2:
print(f"mov reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")
case 3:
print(f"mov reg[{opcode[ip+2]}] {opcode[ip+3]}")
else: print(f"mov reg[0] input[reg{[2]}]")
ip+=4
def func2():
global ip
v2= opcode[ip+1]
if v2:
match v2:
case 1 :
print(f"push reg[0]")
case 2 :
print(f"push reg[2]")
case 3 :
print(f"push reg[3]")
else: print(f"push reg[0]")
ip +=2
def func3():
global ip
v2= opcode[ip+1]
if v2:
match v2:
case 1 :
print(f"pop reg[1]")
case 2 :
print(f"pop reg[2]")
case 3 :
print(f"pop reg[3]")
else: print(f"pop reg[0]")
ip +=2
def func4():
global ip
v2= opcode[ip+1]
match v2:
case 0:
print(f"add reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")
case 1:
print(f"sub reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")
case 2:
print(f"mul reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")
case 3:
print(f"xor reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")
case 4:
print(f"shl reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")
case 5:
print(f"shr reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")
ip+=4
def func5():
global ip
print(f"cmp reg[0] reg[1]")
ip+=1
def func6():
global ip
print(f"jmp {opcode[ip+1]}")
ip +=2
def func7():
global ip
print(f"je {opcode[ip+1]}")
ip +=2
def func8():
global ip
print(f"jne {opcode[ip + 1]}")
ip += 2
while opcode[ip]!=255:
match opcode[ip]:
case 0:
print("%d"%(ip),end=' ')
func1()
case 1:
print("%d"%(ip),end=' ')
func2()
case 2:
print("%d"%(ip),end=' ')
func3()
case 3:
print("%d"%(ip),end=' ')
func4()
case 4:
print("%d"%(ip),end=' ')
func5()
case 5:
print("%d"%(ip),end=' ')
func6()
case 6:
print("%d"%(ip),end=' ')
func7()
case 7:
print("%d"%(ip),end=' ')
func8()
c=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 168, 2, 188, 172, 156, 206, 250, 2, 185, 255, 58, 116, 72, 25, 105, 232, 3, 203, 201, 255, 252, 128, 214, 141, 215, 114, 0, 167, 29, 61, 153, 136, 153, 191, 232, 150, 46, 93, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 169, 189, 139, 23, 194, 110, 248, 245, 110, 99, 99, 213, 70, 93, 22, 152, 56, 48, 115, 56, 193, 94, 237, 176, 41, 90, 24, 64, 167, 253, 10, 30, 120, 139, 98, 219, 15, 143, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18432, 61696, 16384, 8448, 13569, 25600, 30721, 63744, 6145, 20992, 9472, 23809, 18176, 64768, 26881, 23552, 44801, 45568, 60417, 20993, 20225, 6657, 20480, 34049, 52480, 8960, 63488, 3072, 52992, 15617, 17665, 33280, 53761, 10497, 54529, 1537, 41473, 56832, 42497, 51713, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# for i in range(0,len(c),50):
# for j in range(i,i+50):
# print(c[j],end=' ')
# print()
data=c
for i in range(40):
num = data[150 + 39 - i]
print(num, end=' ')
tmp1 = (((num << 8) & 0xff00) + ((num >> 8) & (0xff))) & 0xffff
ans = (tmp1 ^ data[100 + i]) - data[i + 50]
# print(chr(ans), end='')
print()
a,b,o,d=c[:50],c[50:100],c[100:150],c[-50:-10][::-1]
for x,y,z in zip(b,o,d):
try:
# print(z,end=' ')
t=(((z<<8)&0xff00)+((z>>8)&0xff))&0xffff
f=((t^y)-x)
print(chr(f),end='')
except:pass
Comments | NOTHING