hgame 2023 week4 re

发布于 2024-03-15  113 次阅读


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进行分析,这个程序逆向工程就会十分繁琐

img

现在来看一下题:

首先用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

The world's full of lonely people afraid to make the first move.