首页
社区
课程
招聘
强网杯: unicorn_like_a_pro
发表于: 2021-6-14 21:28 18718

强网杯: unicorn_like_a_pro

2021-6-14 21:28
18718

unicorn framework 是一个基于 qemu 的模拟执行框架

GitHub链接: https://github.com/unicorn-engine/unicorn

这道题目内部就调用了 unicorn 框架模拟执行一段 x64代码,最开始以为出题人魔改了 unicorn 框架,用 bindiff 分析了一段时间,发现并没有魔改 unicorn 代码

附件 原题 & 脚本 & idb:
可以去我博客文章页面下载附件:传送门

本题没有符号,逆向时比较困难,用 bindiff 可以直接还原。

在 ubuntu 上编译一份 unicorn 代码,载入 bindiff 插件即可完成大部分符号还原。

IDA 中的 bindiff 插件,载入另外一份 idb 后,按下 Ctrl + 6, 点击 如下按钮,设置好阀值后即可导入符号

2.1 创建虚拟机

2.2 复制代码到虚拟机的 0x1000 地址

2.3 设置回调

Unicorn 支持很多种回调类型,当 Unicorn 运行的代码满足特定的条件时,将触发对应的回调。

在回调中可以对虚拟机中环境上下文操作,类似调试器的调试回调。

本题借助 Unicorn 指令回调,实现指令即时解密,执行后重新加密,打乱控制流。

注意控制流有两个控制回调,第二个控制回调只在 0x10A3 地址处有效,就是特殊处理的地址。

代码解密的主要逻辑在 decrypt 函数,该函数解密当前即将执行的基本块,加密上一个执行完的基本块

基本块密钥用 miniDec 函数计算,参数为上一个基本块的入口密钥 lastKey 与当前基本块入口 rip, minidec 函数如下

size_table 是一个数组,该数组保存了基本块密钥与基本块大小的关系,元素结构如下

奇数下标数据为key,偶数为基本块字节的长度。

用 python 实现基本块解密函数

这里的部分代码还涉及控制流重建,后面会提到。

ControlFlow1 回调,执行到无效指令会被调用,用于切换程序中的控制流。

该题用 3f 0f作为基本块的结尾(无效指令)触发 ControlFlow1 回调,切换控制流。

ControlFlow1 回调函数根据结尾 rip 与 当前基本块的 key 计算另外一个 key,用于索引当前基本块的后继基本块的信息。

flowInfo 是一个数组,每一个元素有如下5个字段

根据 zf 标志位跳转

注意 v9 保存的是上一个基本块的 key,此处做的 += 运算,即上一个基本块的 key 与 下一个基本块的 key 有关联。

由此可见,基本块的 key 与控制流的路径有关!写解密脚本的时候要考虑路径问题。

另外,当虚拟机中程序运行到 0x10A3 时将调整控制流并更改 key

解密后的基本块,很多都是以读取 fs 寄存器并判断结尾

r15 的值来源于 fs:xxx ,最后再与 fs:xxx 内存的值比较,很明显最后的 zf = 1。

其实并不是,这道题对 fs 寄存器指向的那段内存做了内存读回调,回调如下

每次读取 fs 指向的内存,该内存的值都会被改写。所以 mov 与 cmp 对 fs 内存访问出的结果是不同的,自然 zf = 0,走 zf = 0 的分支。

在控制流重建的时候,需要考虑以读取 fs 内存结尾的基本块,将其看作是无条件跳转,而不是 jz/jnz。

重建思路:

以 bfs 遍历顺序,从入口基本块开始解密,解密后再查询分支信息表获取后继基本块的相对偏移与key,最后将新基本块的信息加入到队列,等待分析。遍历时注意维护路径上的 key 累计值。

所有基本块解密完成后,可以得到每个基本块的后继基本块的相对偏移。

要在基本块的结尾插入跳转指令,这将改变代码布局,使得原始相对偏移不可用,所以我采取重编译来解决这个问题,重编译之前将原始基本块的入口地址作为基本的符号名,基本块结尾用 jmp/jz 等指令连接。

code.bin 文件时 dump 出来的原始 code 数据,输出 1.bin 可以直接在 ida 中反编译。

重建控制流,输出 bin 后,代码比较清晰了。

程序入口调用 syscall,由 unicorn 回调处理获取 time(0) 的值,并根据该值计算一个数 0x1C986C3B22EA63E5

为了屏蔽 ida 的优化,方便分析,我做了一些小 patch

手动 patch ,即可解决这些问题。

有两种爆破思路:

可以用 flag 开头来爆破 time(0) 时间常数

from_t0 = time_0 / 0xE10;

由于 4字节一组,qwb{QWB{flagFLAG 都是已知的 4 个字节并且 v28 可以非常轻松的获得

通过爆破开头也可以反推 time(0)

爆破出 time(0) 后的做法就是非常简单的计算任务了

 
 
 
 
 
 
 
uc_open(4u, 8, &v14);                         // UC_ARCH_X86, UC_MODE_64
uc_open(4u, 8, &v14);                         // UC_ARCH_X86, UC_MODE_64
uc_mem_write(v14, 0x1000LL, &code, 0x1027LL);
uc_mem_write(v14, 0x1000LL, &code, 0x1027LL);
 
 
 
// 虚拟机输入接口,虚拟机代码中的 in 指令
uc_hook_add(v14, &trace, 2, input + 1, 0LL, 1LL, 0LL, 0xDAu);// 2 == UC_HOOK_INSN
// 虚拟机输出接口,虚拟机中代码中的 out 指令处理
uc_hook_add(v14, &trace, 2, output, 0LL, 1LL, 0LL, 0x1F4u);// 2 = UC_HOOK_INSN
// 虚拟机中 syscall 指令处理,设置 rax 寄存器的值为 time(0)
uc_hook_add(v14, &trace, 2, syscall_time, 0LL, 1LL, 0LL, 0x2BBu);// 2 = UC_HOOK_INSN
// 虚拟机中 fs 内存访问处理,改变 fs:0 的值,关键算法部分很重要
uc_hook_add(v14, &trace, 1024, changeKey, 0LL, 0x66660000LL, 0x66661000LL, v4);// UC_HOOK_MEM_READ
// 代码解密回调
uc_hook_add(v14, &trace, 8, decrypt, &v21, 1LL, 0LL, v5);// UC_HOOK_BLOCK
// 代码控制流控制回调1
uc_hook_add(v14, &trace, 0x4000,  ControlFlow1, &v21, 1LL, 0LL, v6);// UC_HOOK_INSN_INVALID
// 代码控制流控制回调2
uc_hook_add(v14, &trace, 4,  ControlFlow2, &v21, 0x10A3LL, 0x10A4LL, v7);// UC_HOOK_CODE
// 虚拟机输入接口,虚拟机代码中的 in 指令
uc_hook_add(v14, &trace, 2, input + 1, 0LL, 1LL, 0LL, 0xDAu);// 2 == UC_HOOK_INSN
// 虚拟机输出接口,虚拟机中代码中的 out 指令处理
uc_hook_add(v14, &trace, 2, output, 0LL, 1LL, 0LL, 0x1F4u);// 2 = UC_HOOK_INSN
// 虚拟机中 syscall 指令处理,设置 rax 寄存器的值为 time(0)
uc_hook_add(v14, &trace, 2, syscall_time, 0LL, 1LL, 0LL, 0x2BBu);// 2 = UC_HOOK_INSN
// 虚拟机中 fs 内存访问处理,改变 fs:0 的值,关键算法部分很重要
uc_hook_add(v14, &trace, 1024, changeKey, 0LL, 0x66660000LL, 0x66661000LL, v4);// UC_HOOK_MEM_READ
// 代码解密回调
uc_hook_add(v14, &trace, 8, decrypt, &v21, 1LL, 0LL, v5);// UC_HOOK_BLOCK
// 代码控制流控制回调1
uc_hook_add(v14, &trace, 0x4000,  ControlFlow1, &v21, 1LL, 0LL, v6);// UC_HOOK_INSN_INVALID
// 代码控制流控制回调2
uc_hook_add(v14, &trace, 4,  ControlFlow2, &v21, 0x10A3LL, 0x10A4LL, v7);// UC_HOOK_CODE
v9 = miniDec(lastKey, entry_rip);
for ( i = 0; i <= 85; ++i )
{
  if ( v9 == *&size_table[8 * i] )
  {
    size[0] = *&size_table[8 * i + 4];        // getlen
    v12 = malloc(size[0]);
    uc_mem_read(v5, addr, v12, size[0]);
    for ( j = 0; size[0] > j; ++j )
      ;
    dec1(v12, size[0], lastKey);
    uc_mem_write(v5, addr, v12, size[0]);
    for ( k = 0; size[0] > k; ++k )
      ;
    free(v12);
    *(*&size[1] + 4LL) = addr;
    *(*&size[1] + 12LL) = **&size[1];
    *(*&size[1] + 8LL) = size[0];
    *(*&size[1] + 16LL) = addr;
    uc_reg_write(v5, 41, &addr);              // UC_X86_REG_RIP
  }
}
v9 = miniDec(lastKey, entry_rip);
for ( i = 0; i <= 85; ++i )
{
  if ( v9 == *&size_table[8 * i] )
  {
    size[0] = *&size_table[8 * i + 4];        // getlen
    v12 = malloc(size[0]);
    uc_mem_read(v5, addr, v12, size[0]);
    for ( j = 0; size[0] > j; ++j )
      ;
    dec1(v12, size[0], lastKey);
    uc_mem_write(v5, addr, v12, size[0]);
    for ( k = 0; size[0] > k; ++k )
      ;
    free(v12);
    *(*&size[1] + 4LL) = addr;
    *(*&size[1] + 12LL) = **&size[1];
    *(*&size[1] + 8LL) = size[0];
    *(*&size[1] + 16LL) = addr;
    uc_reg_write(v5, 41, &addr);              // UC_X86_REG_RIP
  }
}
__int64 __fastcall miniDec(int a1, int a2)
{
  return a2 ^ a1 ^ (a2 * a1) ^ (a1 + a2);
}
__int64 __fastcall miniDec(int a1, int a2)
{
  return a2 ^ a1 ^ (a2 * a1) ^ (a1 + a2);
}
dd key
dd size
dd key
dd size
size_table = [0x02F73020, 0x00000015, 0x09D3473A, 0x00000051, 0x0EF87B55, 0x0000000D, 0x147CB028, 0x00000023, 0x15F833AA, 0x00000030, 0x17086780, 0x00000018, 0x1733A9D4, 0x00000014, 0x17D61EE8, 0x00000051, 0x1D52F19E, 0x00000011, 0x1F732DE0, 0x0000000D, 0x1FBECFAD, 0x0000001B, 0x245BD7C8, 0x00000055, 0x25E7ABEE, 0x00000009, 0x2882C190, 0x000000A2, 0x2A2084A0, 0x00000075, 0x326AA6AE, 0x00000036, 0x33074A36, 0x00000024, 0x3440BD69, 0x0000002C, 0x362A1FC3, 0x0000002C, 0x3C0450D0, 0x0000000D, 0x3CB575FD, 0x00000011, 0x41B3B26E, 0x0000004E, 0x46005120, 0x00000011, 0x465A72CF, 0x00000002, 0x492145A0, 0x0000000D, 0x49AA4CE0, 0x0000002D, 0x4BD63647, 0x0000004E, 0x4BF84A87, 0x0000000D, 0x4D102445, 0x00000033, 0x4D4D3C55, 0x0000001B, 0x53723232, 0x0000000A, 0x5809B5CB, 0x000000A2, 0x5B12FFCE, 0x00000015, 0x5B1F3000, 0x00000051, 0x5D9FBD20, 0x00000027, 0x6219EED9, 0x0000008A, 0x65D82D17, 0x0000004C, 0x67F5671A, 0x00000063, 0x6CE2CBC1, 0x00000033, 0x718A739C, 0x0000000B, 0x71A62DD7, 0x00000015, 0x7693A1F6, 0x00000014, 0x7A473FB0, 0x00000047, 0x7AEFEDDC, 0x00000011, 0x7AF2CF90, 0x0000004F, 0x7BE0B8B0, 0x0000001B, 0x80EB3E88, 0x0000000A, 0x8213506A, 0x0000000C, 0x82468114, 0x00000011, 0x86B872A2, 0x0000001C, 0x87FBD296, 0x00000019, 0x88719339, 0x00000016, 0x89E2630A, 0x00000024, 0x8CB6536E, 0x0000004E, 0x92316E00, 0x00000015, 0x9415A51E, 0x0000004F, 0x94D658E0, 0x0000002B, 0x97E8DFCD, 0x00000036, 0x992E3874, 0x0000002A, 0x9B06958D, 0x00000030, 0x9B36B480, 0x0000000D, 0xA03CEFAD, 0x0000005A, 0xA39F47E6, 0x0000004E, 0xA946DEC4, 0x000000B4, 0xAE6173DC, 0x00000051, 0xB044A68D, 0x0000008C, 0xB29E36A8, 0x0000000B, 0xB82781F4, 0x0000000D, 0xC14DFAF8, 0x00000011, 0xC3F42E20, 0x0000001E, 0xC5E0065E, 0x00000067, 0xCAD68B21, 0x00000039, 0xCBF29AC7, 0x00000011, 0xCE8729BC, 0x0000001B, 0xD2A85A94, 0x00000004, 0xD34FA4F3, 0x00000011, 0xD64611B0, 0x00000058, 0xD814FD56, 0x00000018, 0xDD386A80, 0x0000000A, 0xDE82DFAC, 0x00000011, 0xEC68D16F, 0x0000001B, 0xEEDE845B, 0x0000003F, 0xF235F260, 0x0000008D, 0xF9AA1F0B, 0x00000087, 0xFC200887, 0x00000011, 0xFED657A3, 0x0000000C, 0x00000000]
size_table = [0x02F73020, 0x00000015, 0x09D3473A, 0x00000051, 0x0EF87B55, 0x0000000D, 0x147CB028, 0x00000023, 0x15F833AA, 0x00000030, 0x17086780, 0x00000018, 0x1733A9D4, 0x00000014, 0x17D61EE8, 0x00000051, 0x1D52F19E, 0x00000011, 0x1F732DE0, 0x0000000D, 0x1FBECFAD, 0x0000001B, 0x245BD7C8, 0x00000055, 0x25E7ABEE, 0x00000009, 0x2882C190, 0x000000A2, 0x2A2084A0, 0x00000075, 0x326AA6AE, 0x00000036, 0x33074A36, 0x00000024, 0x3440BD69, 0x0000002C, 0x362A1FC3, 0x0000002C, 0x3C0450D0, 0x0000000D, 0x3CB575FD, 0x00000011, 0x41B3B26E, 0x0000004E, 0x46005120, 0x00000011, 0x465A72CF, 0x00000002, 0x492145A0, 0x0000000D, 0x49AA4CE0, 0x0000002D, 0x4BD63647, 0x0000004E, 0x4BF84A87, 0x0000000D, 0x4D102445, 0x00000033, 0x4D4D3C55, 0x0000001B, 0x53723232, 0x0000000A, 0x5809B5CB, 0x000000A2, 0x5B12FFCE, 0x00000015, 0x5B1F3000, 0x00000051, 0x5D9FBD20, 0x00000027, 0x6219EED9, 0x0000008A, 0x65D82D17, 0x0000004C, 0x67F5671A, 0x00000063, 0x6CE2CBC1, 0x00000033, 0x718A739C, 0x0000000B, 0x71A62DD7, 0x00000015, 0x7693A1F6, 0x00000014, 0x7A473FB0, 0x00000047, 0x7AEFEDDC, 0x00000011, 0x7AF2CF90, 0x0000004F, 0x7BE0B8B0, 0x0000001B, 0x80EB3E88, 0x0000000A, 0x8213506A, 0x0000000C, 0x82468114, 0x00000011, 0x86B872A2, 0x0000001C, 0x87FBD296, 0x00000019, 0x88719339, 0x00000016, 0x89E2630A, 0x00000024, 0x8CB6536E, 0x0000004E, 0x92316E00, 0x00000015, 0x9415A51E, 0x0000004F, 0x94D658E0, 0x0000002B, 0x97E8DFCD, 0x00000036, 0x992E3874, 0x0000002A, 0x9B06958D, 0x00000030, 0x9B36B480, 0x0000000D, 0xA03CEFAD, 0x0000005A, 0xA39F47E6, 0x0000004E, 0xA946DEC4, 0x000000B4, 0xAE6173DC, 0x00000051, 0xB044A68D, 0x0000008C, 0xB29E36A8, 0x0000000B, 0xB82781F4, 0x0000000D, 0xC14DFAF8, 0x00000011, 0xC3F42E20, 0x0000001E, 0xC5E0065E, 0x00000067, 0xCAD68B21, 0x00000039, 0xCBF29AC7, 0x00000011, 0xCE8729BC, 0x0000001B, 0xD2A85A94, 0x00000004, 0xD34FA4F3, 0x00000011, 0xD64611B0, 0x00000058, 0xD814FD56, 0x00000018, 0xDD386A80, 0x0000000A, 0xDE82DFAC, 0x00000011, 0xEC68D16F, 0x0000001B, 0xEEDE845B, 0x0000003F, 0xF235F260, 0x0000008D, 0xF9AA1F0B, 0x00000087, 0xFC200887, 0x00000011, 0xFED657A3, 0x0000000C, 0x00000000]
 
def fuck(prev_key, rip):
    return rip ^ prev_key ^ ((rip * prev_key) & 0xffffffff) ^ (prev_key + rip)
 
def deXor(data, key):
    key = p32(key)
    data = bytearray(data)
    for i in range(len(data)):
        data[i] ^=  key[i % 4]
    return data
 
 
def decrypt_block(key, rip):
    key2 = fuck(key, rip)
    blockSize = get_size(key2)
    if blockSize is None:
        print("Not found1: rip:%x key:%x" % (rip, key2))
        return None, None, None
    offset = rip - 0x1000
    code_data = code_bin[offset: offset + blockSize]
    code_data = deXor(code_data, key)
    next_rip = rip + blockSize - 2
    key2 = fuck(key, next_rip)
    jmps = get_jmps(key2)
    return code_data, jmps, next_rip
def fuck(prev_key, rip):
    return rip ^ prev_key ^ ((rip * prev_key) & 0xffffffff) ^ (prev_key + rip)
 
def deXor(data, key):
    key = p32(key)
    data = bytearray(data)
    for i in range(len(data)):
        data[i] ^=  key[i % 4]
    return data
 
 
def decrypt_block(key, rip):
    key2 = fuck(key, rip)
    blockSize = get_size(key2)
    if blockSize is None:
        print("Not found1: rip:%x key:%x" % (rip, key2))
        return None, None, None
    offset = rip - 0x1000
    code_data = code_bin[offset: offset + blockSize]
    code_data = deXor(code_data, key)
    next_rip = rip + blockSize - 2
    key2 = fuck(key, next_rip)
    jmps = get_jmps(key2)
    return code_data, jmps, next_rip
 
 
 
 
dd key
dd zf_0_jmp  当基本块结尾 zf 标志寄存器为 0 的跳转偏移,下面同理
dd zf_0_key
dd zf_1_jmp
dd zf_1_key
dd key
dd zf_0_jmp  当基本块结尾 zf 标志寄存器为 0 的跳转偏移,下面同理
dd zf_0_key
dd zf_1_jmp
dd zf_1_key
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
import ctypes
from capstone import *
from keystone import *
from pwn import *
 
context.arch = 'amd64'
 
from pwn import *
fuckTable = [0x00412F5E, 0xFFFFFA22, 0x14252652, 0xFFFFF9AC, 0x66CEF8EC, 0x0251D934, 0x0000009F, 0xC56FBF59, 0xFFFFFF61, 0xAA4D5B7C, 0x02745896, 0xFFFFFB7F, 0x34B6D31E, 0xFFFFFBB0, 0x302CC828, 0x02AC5992, 0xFFFFF524, 0x67CC4064, 0xFFFFF483, 0x8A5D9B26, 0x046254D0, 0xFFFFFC37, 0x074AB936, 0xFFFFFC7F, 0xB8EA37F7, 0x0CACD9FE, 0x0000007F, 0x6112F222, 0x00000002, 0x47A72561, 0x0F0FE6EB, 0xFFFFFBAE, 0x0A1411E7, 0xFFFFFC85, 0x3BE88B46, 0x0FC59DC2, 0xFFFFF72F, 0x7D12A5EF, 0xFFFFF691, 0xE67393D6, 0x10B1EBCA, 0x000001CF, 0x473A1295, 0x0000022E, 0x7BC15385, 0x1565D41D, 0xFFFFFDC4, 0x05D337BE, 0xFFFFFE7E, 0xE12982E4, 0x18909E40, 0x000005EB, 0xAE2337AF, 0x000005B1, 0x8E0AB2ED, 0x1AE7593A, 0xFFFFF3BC, 0x23E9058D, 0xFFFFF40B, 0xDFA6CF3E, 0x1B47DA81, 0xFFFFF8C3, 0x349CC616, 0xFFFFF7E9, 0x70C290D0, 0x1D816435, 0x00000002, 0x43F999C9, 0xFFFFFFD8, 0xAB0BCA16, 0x1DACC905, 0xFFFFFF54, 0x5C129962, 0xFFFFFD06, 0xE4515A41, 0x1E03B13C, 0xFFFFFF80, 0x7E763806, 0xFFFFF36A, 0xA25F3D93, 0x22FEFC06, 0xFFFFFCDD, 0xB94E0C2F, 0xFFFFFCB6, 0xF023033D, 0x26B1E690, 0xFFFFFDAB, 0xD0C7ED0C, 0xFFFFFE9B, 0xD49872C6, 0x2A652084, 0x000001EA, 0xDF9B65EE, 0x00000051, 0x5CC5AB90, 0x2FBEBD25, 0x0000048F, 0x60A4E9F2, 0x000009AF, 0x42FE8B0D, 0x34F12D90, 0x000004C0, 0xF6257D94, 0x00000480, 0x5227DE21, 0x35F591D0, 0xFFFFFCA1, 0xDA83E113, 0xFFFFF998, 0x805C7ECB, 0x37EB0B72, 0xFFFFF3EC, 0x7480201A, 0xFFFFF903, 0xAC977E11, 0x389A58A8, 0x00000189, 0xE4005CD7, 0xFFFFFDEC, 0xB043695F, 0x3CB24155, 0x0000084C, 0x8ACB6FF1, 0x00000899, 0xACB471A5, 0x3DCBCDE3, 0x000007A8, 0xA84E3072, 0x00000384, 0xB2624259, 0x3F5290DE, 0xFFFFFE25, 0x8AC11F92, 0xFFFFFD8A, 0x44ACCD78, 0x47FF9B7E, 0x00000A81, 0x9833BF9C, 0x00000B35, 0x9B7199CD, 0x4C7867E6, 0x0000011C, 0x68BB4F80, 0x0000002E, 0x75B675CD, 0x53ADCD80, 0x000004E8, 0x6AA4F705, 0x00000452, 0xBA7C314B, 0x566E1640, 0x00000C8E, 0x203E3737, 0x00000C38, 0xF9367ED9, 0x5EDBB130, 0x000004FF, 0xD4F71A40, 0x000002AA, 0x35DC4141, 0x6C29C83A, 0x00000013, 0xBEAD8A76, 0xFFFFFFB5, 0x7A8A43EF, 0x6E036C9C, 0x00000BD5, 0x225F81E0, 0x00000D89, 0x3C25944D, 0x6FDCCE50, 0x00000605, 0xD3126740, 0x000003D5, 0xA3DA544C, 0x7132D345, 0x0000064E, 0x00915A5A, 0x000006DD, 0x5BCB6B22, 0x720DBD5C, 0x000008C3, 0x64DCFDF6, 0x00000858, 0x190B20BB, 0x7A035AD4, 0x00000424, 0x4DD955FB, 0x000004BF, 0xF65150B5, 0x7CBAED22, 0x00000AA1, 0x62CC154B, 0xFFFFFC58, 0x8DD5CEDB, 0x7EBF8EA8, 0x00000458, 0xCE844A0E, 0xFFFFF734, 0x9079D6BA, 0x804885CD, 0x000007BB, 0x89A8DA66, 0x00000136, 0x7185B813, 0x82190F37, 0xFFFFF58C, 0x013FA7D4, 0xFFFFF4AB, 0x7518093D, 0x83F7826A, 0x00000917, 0x2F33C3DD, 0xFFFFFBF0, 0x02A289B1, 0x8481BFD5, 0xFFFFF927, 0x72EED2D1, 0xFFFFF80A, 0xF46FD351, 0x85A69D6E, 0x000000B4, 0x27A3BB0F, 0x00000181, 0x49235BC0, 0x85F73150, 0x00000259, 0xA300692F, 0x000009BD, 0x5A3E46A9, 0x86E2497A, 0xFFFFFB53, 0xE7614707, 0xFFFFFBB3, 0xFA190B2A, 0x8B261F60, 0xFFFFF323, 0x97B9CC33, 0xFFFFFAB7, 0x2CB73BF0, 0x8B42B00C, 0x00000871, 0xA57A2DE3, 0x00000797, 0xA73082D6, 0x8E4C5C94, 0x000000FE, 0xEE4B594B, 0xFFFFF999, 0xDCE3B74D, 0x913A9FDB, 0xFFFFFE1C, 0x1BFFA329, 0xFFFFFD31, 0x49B21C95, 0x922BFB96, 0xFFFFF61B, 0x4FAFD829, 0xFFFFFBBA, 0x6BD5D317, 0x9F4B8702, 0xFFFFFEC1, 0xB691AD49, 0xFFFFFEF2, 0xCE6C6FE9, 0xA2CEAAA6, 0xFFFFFD89, 0x60E52701, 0xFFFFFCB2, 0x25AD9A9D, 0xAA970D72, 0xFFFFF2BB, 0xC1F58CAC, 0xFFFFF2AB, 0x20B8FE22, 0xABC02B72, 0xFFFFF94B, 0xFF6EA5A6, 0xFFFFFA6A, 0x1CD46647, 0xAE535E9E, 0x000003EC, 0x31246F6B, 0x0000035B, 0x50E2A20A, 0xB7337941, 0xFFFFF856, 0xD1A79AD7, 0xFFFFF955, 0x14673B75, 0xBB8DB95E, 0xFFFFFEEB, 0x6A7F1E5A, 0xFFFFF3B3, 0x1EF2F3AA, 0xBC1EDA22, 0xFFFFFB90, 0xE247955F, 0xFFFFFCE6, 0xA0351A85, 0xBCD91FE8, 0x0000008C, 0x71A348B9, 0x00000030, 0x821754EF, 0xBD38E305, 0xFFFFFF59, 0xE694333F, 0xFFFFFEF9, 0x436B1A45, 0xBE1AA65A, 0xFFFFF93D, 0x8761A810, 0xFFFFFEEB, 0xB2DB19FA, 0xC052453C, 0x000009B5, 0xB05027D7, 0x000009C5, 0xBCA91679, 0xC4A2D780, 0x000008B9, 0xE42FD068, 0x000007C1, 0x9F8B2B83, 0xC6A236BA, 0xFFFFFDBB, 0x20649A12, 0xFFFFFD09, 0x5F73FD94, 0xC6BB5160, 0xFFFFFE90, 0x0ED42674, 0xFFFFFF4B, 0xA76699CC, 0xCB74E940, 0x000003E3, 0x7DA194FF, 0xFFFFFCDA, 0xB23E5B15, 0xD027B387, 0xFFFFF701, 0x880BCC4F, 0xFFFFF785, 0xFEA3D685, 0xD1127D6B, 0xFFFFFAC0, 0xDF3D499A, 0x00000362, 0x84B7777D, 0xD6F5F913, 0xFFFFFCCD, 0xA5D89DB8, 0xFFFFFCAB, 0xF69BAE29, 0xDD04F828, 0xFFFFF705, 0xE18F3BA0, 0xFFFFF64D, 0xEBC799B0, 0xDDF22CB8, 0x0000075D, 0x47F7B857, 0x000001B3, 0x5C1CDEA9, 0xDF34D0A8, 0x0000014D, 0xBFE2CAD5, 0x00000201, 0x1F0C8A89, 0xE146EA40, 0x0000046D, 0x189EB8F9, 0xFFFFF6FB, 0x4CA1090D, 0xE231C560, 0x00000710, 0x2E586529, 0xFFFFFF17, 0x0E9AA776, 0xE2FC6838, 0x00000733, 0xB73DDD7A, 0x00000753, 0x14A1BDE4, 0xE44AE35D, 0x000002C8, 0x46B1F3D1, 0xFFFFFA2D, 0xD2295816, 0xE5AF4AB1, 0x00000DB0, 0x0AFF4FF9, 0x00000D91, 0xB17A4340, 0xE7E3CF21, 0x00000656, 0x9FC50924, 0x00000658, 0x31615022, 0xE8815965, 0x00000BCB, 0x6F51A655, 0x00000C0A, 0x72F5680C, 0xEBDF0F14, 0xFFFFF2B1, 0xD36EC5D4, 0xFFFFF239, 0x3B711343, 0xEC12E59B, 0x00000270, 0x3A38D2E8, 0x0000023D, 0x68D07674, 0xF4013920, 0x00000703, 0xD83CCFAA, 0x000007BA, 0x46891EEB, 0xF6847EC1, 0xFFFFFE62, 0x6D4BAAFC, 0xFFFFFD92, 0x5E6F5A94]
 
 
size_table = [0x02F73020, 0x00000015, 0x09D3473A, 0x00000051, 0x0EF87B55, 0x0000000D, 0x147CB028, 0x00000023, 0x15F833AA, 0x00000030, 0x17086780, 0x00000018, 0x1733A9D4, 0x00000014, 0x17D61EE8, 0x00000051, 0x1D52F19E, 0x00000011, 0x1F732DE0, 0x0000000D, 0x1FBECFAD, 0x0000001B, 0x245BD7C8, 0x00000055, 0x25E7ABEE, 0x00000009, 0x2882C190, 0x000000A2, 0x2A2084A0, 0x00000075, 0x326AA6AE, 0x00000036, 0x33074A36, 0x00000024, 0x3440BD69, 0x0000002C, 0x362A1FC3, 0x0000002C, 0x3C0450D0, 0x0000000D, 0x3CB575FD, 0x00000011, 0x41B3B26E, 0x0000004E, 0x46005120, 0x00000011, 0x465A72CF, 0x00000002, 0x492145A0, 0x0000000D, 0x49AA4CE0, 0x0000002D, 0x4BD63647, 0x0000004E, 0x4BF84A87, 0x0000000D, 0x4D102445, 0x00000033, 0x4D4D3C55, 0x0000001B, 0x53723232, 0x0000000A, 0x5809B5CB, 0x000000A2, 0x5B12FFCE, 0x00000015, 0x5B1F3000, 0x00000051, 0x5D9FBD20, 0x00000027, 0x6219EED9, 0x0000008A, 0x65D82D17, 0x0000004C, 0x67F5671A, 0x00000063, 0x6CE2CBC1, 0x00000033, 0x718A739C, 0x0000000B, 0x71A62DD7, 0x00000015, 0x7693A1F6, 0x00000014, 0x7A473FB0, 0x00000047, 0x7AEFEDDC, 0x00000011, 0x7AF2CF90, 0x0000004F, 0x7BE0B8B0, 0x0000001B, 0x80EB3E88, 0x0000000A, 0x8213506A, 0x0000000C, 0x82468114, 0x00000011, 0x86B872A2, 0x0000001C, 0x87FBD296, 0x00000019, 0x88719339, 0x00000016, 0x89E2630A, 0x00000024, 0x8CB6536E, 0x0000004E, 0x92316E00, 0x00000015, 0x9415A51E, 0x0000004F, 0x94D658E0, 0x0000002B, 0x97E8DFCD, 0x00000036, 0x992E3874, 0x0000002A, 0x9B06958D, 0x00000030, 0x9B36B480, 0x0000000D, 0xA03CEFAD, 0x0000005A, 0xA39F47E6, 0x0000004E, 0xA946DEC4, 0x000000B4, 0xAE6173DC, 0x00000051, 0xB044A68D, 0x0000008C, 0xB29E36A8, 0x0000000B, 0xB82781F4, 0x0000000D, 0xC14DFAF8, 0x00000011, 0xC3F42E20, 0x0000001E, 0xC5E0065E, 0x00000067, 0xCAD68B21, 0x00000039, 0xCBF29AC7, 0x00000011, 0xCE8729BC, 0x0000001B, 0xD2A85A94, 0x00000004, 0xD34FA4F3, 0x00000011, 0xD64611B0, 0x00000058, 0xD814FD56, 0x00000018, 0xDD386A80, 0x0000000A, 0xDE82DFAC, 0x00000011, 0xEC68D16F, 0x0000001B, 0xEEDE845B, 0x0000003F, 0xF235F260, 0x0000008D, 0xF9AA1F0B, 0x00000087, 0xFC200887, 0x00000011, 0xFED657A3, 0x0000000C, 0x00000000]
zf_0_jmp = 0
zf_0_key = 1
zf_1_jmp = 2
zf_1_key = 3
 
 
code_bin = open("code.bin", "rb").read()
print("code size: ", hex(len(code_bin)))
 
def get_size(key):
    for i in range(85):
        if size_table[i * 2] == key:
            return  size_table[i * 2 + 1]
    return None
 
def get_jmps(key):
    for i in range(85):
        base = i * 5
        if fuckTable[base] == key:
            # zf_0_jmp, zf_0_key, zf_1_jmp, zf_1_key
            return fuckTable[base + 1: base + 5]
    print("not found2: ", hex(key))
    return None
 
def fuck(prev_key, rip):
    return rip ^ prev_key ^ ((rip * prev_key) & 0xffffffff) ^ (prev_key + rip)
 
def deXor(data, key):
    key = p32(key)
    data = bytearray(data)
    for i in range(len(data)):
        data[i] ^=  key[i % 4]
    return data
 
 
def decrypt_block(key, rip):
    key2 = fuck(key, rip)
    blockSize = get_size(key2)
 
    if blockSize is None:
        print("Not found1: rip:%x key:%x" % (rip, key2))
        return None, None, None
 
    offset = rip - 0x1000
    code_data = code_bin[offset: offset + blockSize]
    code_data = deXor(code_data, key)
    next_rip = rip + blockSize - 2
    key2 = fuck(key, next_rip)
 
    jmps = get_jmps(key2)
 
    return code_data, jmps, next_rip
 
class Node:
    def __init__(self, data, rip):
        self.code_data = data
        self.child1 = 0
        self.child2 = 0
        self.end_rip = None
        self.rip = rip
 
 
def disasm(data, baseaddr):
    md = Cs(CS_ARCH_X86, CS_MODE_64)
    ins = ''
    for i in md.disasm(data, baseaddr):
        asm_code = "%s\t%s" % (i.mnemonic, i.op_str)
        ins += asm_code + "\n"
    return ins
 
def buildNode(key_, rip_):
    work_queue = [(key_, rip_)]
    log_map = {}
    while len(work_queue) > 0:
        T = work_queue[0]
        work_queue.remove(T)
        key, rip = T
 
 
        if rip in log_map:
            continue
 
        if rip == 0x10A3:
            key -= 0x2B09B990
            rip = 0x1EEC
 
        code_data, jmps, next_rip = decrypt_block(key, rip)
 
        if code_data is None:
            continue
 
        node_cur = Node(code_data, rip)
 
        node_cur.end_rip = next_rip
        log_map[rip] = node_cur
 
        if jmps is None:
            continue
 
        asm_text = disasm(node_cur.code_data, rip)
 
 
        newrip = next_rip + ctypes.c_int32(jmps[zf_0_jmp]).value
        node_cur.child1 = newrip
        if newrip not in log_map:
            work_queue.append(((key + jmps[zf_0_key]) & 0xffffffff, newrip))
 
        if 'qword ptr fs:[' in asm_text.splitlines()[-1]:
            continue
 
 
        newrip = next_rip + ctypes.c_int32(jmps[zf_1_jmp]).value
        node_cur.child2 = newrip
        if newrip not in log_map:
            work_queue.append(((key + jmps[zf_1_key]) & 0xffffffff, newrip))
 
 
    jmptables = {}
    for i in sorted(log_map.keys()):
        if log_map[i].child1 is None:
            log_map[i].child1 = 0
 
        if log_map[i].child2 is None:
            log_map[i].child2 = 0
 
        jmptables[hex(log_map[i].end_rip)] = (hex(log_map[i].rip), hex(log_map[i].child1), hex(log_map[i].child2))
    print("len:", len(jmptables))
    print(jmptables)
 
    all_asm = ''
    for i in sorted(log_map.keys()):
        print(hex(i))
        node = log_map[i]
        if i == 0x1EEC:
            all_asm += "_0x10a3:\n"
 
        all_asm += "_" + hex(i) + ":\n"
        all_asm += disasm(node.code_data, i)
 
        if node.child1 != 0 and node.child2 != 0:
            jmp_code = "jz _" + hex(node.child2) + "\n"
            jmp_code += "jmp _" + hex(node.child1) + "\n"
 
        elif node.child1 == 0 and node.child2 != 0:
            jmp_code = "jmp _" + hex(node.child2) + "\n"
 
        elif node.child2 == 0 and node.child1 != 0:
            jmp_code = "jmp _" + hex(node.child1) + "\n"
        else:
            jmp_code = '\n'
 
        all_asm += jmp_code
 
    all_asm = all_asm.replace("endbr64", "nop\n" * 4)
    code_bin = asm(all_asm)
    open('1.bin', 'wb').write(code_bin)
    print(all_asm)
    print("all nodes: ", len(log_map))
 
buildNode(0x3265B1F5, 0x1000)
import ctypes
from capstone import *
from keystone import *
from pwn import *
 
context.arch = 'amd64'
 
from pwn import *
fuckTable = [0x00412F5E, 0xFFFFFA22, 0x14252652, 0xFFFFF9AC, 0x66CEF8EC, 0x0251D934, 0x0000009F, 0xC56FBF59, 0xFFFFFF61, 0xAA4D5B7C, 0x02745896, 0xFFFFFB7F, 0x34B6D31E, 0xFFFFFBB0, 0x302CC828, 0x02AC5992, 0xFFFFF524, 0x67CC4064, 0xFFFFF483, 0x8A5D9B26, 0x046254D0, 0xFFFFFC37, 0x074AB936, 0xFFFFFC7F, 0xB8EA37F7, 0x0CACD9FE, 0x0000007F, 0x6112F222, 0x00000002, 0x47A72561, 0x0F0FE6EB, 0xFFFFFBAE, 0x0A1411E7, 0xFFFFFC85, 0x3BE88B46, 0x0FC59DC2, 0xFFFFF72F, 0x7D12A5EF, 0xFFFFF691, 0xE67393D6, 0x10B1EBCA, 0x000001CF, 0x473A1295, 0x0000022E, 0x7BC15385, 0x1565D41D, 0xFFFFFDC4, 0x05D337BE, 0xFFFFFE7E, 0xE12982E4, 0x18909E40, 0x000005EB, 0xAE2337AF, 0x000005B1, 0x8E0AB2ED, 0x1AE7593A, 0xFFFFF3BC, 0x23E9058D, 0xFFFFF40B, 0xDFA6CF3E, 0x1B47DA81, 0xFFFFF8C3, 0x349CC616, 0xFFFFF7E9, 0x70C290D0, 0x1D816435, 0x00000002, 0x43F999C9, 0xFFFFFFD8, 0xAB0BCA16, 0x1DACC905, 0xFFFFFF54, 0x5C129962, 0xFFFFFD06, 0xE4515A41, 0x1E03B13C, 0xFFFFFF80, 0x7E763806, 0xFFFFF36A, 0xA25F3D93, 0x22FEFC06, 0xFFFFFCDD, 0xB94E0C2F, 0xFFFFFCB6, 0xF023033D, 0x26B1E690, 0xFFFFFDAB, 0xD0C7ED0C, 0xFFFFFE9B, 0xD49872C6, 0x2A652084, 0x000001EA, 0xDF9B65EE, 0x00000051, 0x5CC5AB90, 0x2FBEBD25, 0x0000048F, 0x60A4E9F2, 0x000009AF, 0x42FE8B0D, 0x34F12D90, 0x000004C0, 0xF6257D94, 0x00000480, 0x5227DE21, 0x35F591D0, 0xFFFFFCA1, 0xDA83E113, 0xFFFFF998, 0x805C7ECB, 0x37EB0B72, 0xFFFFF3EC, 0x7480201A, 0xFFFFF903, 0xAC977E11, 0x389A58A8, 0x00000189, 0xE4005CD7, 0xFFFFFDEC, 0xB043695F, 0x3CB24155, 0x0000084C, 0x8ACB6FF1, 0x00000899, 0xACB471A5, 0x3DCBCDE3, 0x000007A8, 0xA84E3072, 0x00000384, 0xB2624259, 0x3F5290DE, 0xFFFFFE25, 0x8AC11F92, 0xFFFFFD8A, 0x44ACCD78, 0x47FF9B7E, 0x00000A81, 0x9833BF9C, 0x00000B35, 0x9B7199CD, 0x4C7867E6, 0x0000011C, 0x68BB4F80, 0x0000002E, 0x75B675CD, 0x53ADCD80, 0x000004E8, 0x6AA4F705, 0x00000452, 0xBA7C314B, 0x566E1640, 0x00000C8E, 0x203E3737, 0x00000C38, 0xF9367ED9, 0x5EDBB130, 0x000004FF, 0xD4F71A40, 0x000002AA, 0x35DC4141, 0x6C29C83A, 0x00000013, 0xBEAD8A76, 0xFFFFFFB5, 0x7A8A43EF, 0x6E036C9C, 0x00000BD5, 0x225F81E0, 0x00000D89, 0x3C25944D, 0x6FDCCE50, 0x00000605, 0xD3126740, 0x000003D5, 0xA3DA544C, 0x7132D345, 0x0000064E, 0x00915A5A, 0x000006DD, 0x5BCB6B22, 0x720DBD5C, 0x000008C3, 0x64DCFDF6, 0x00000858, 0x190B20BB, 0x7A035AD4, 0x00000424, 0x4DD955FB, 0x000004BF, 0xF65150B5, 0x7CBAED22, 0x00000AA1, 0x62CC154B, 0xFFFFFC58, 0x8DD5CEDB, 0x7EBF8EA8, 0x00000458, 0xCE844A0E, 0xFFFFF734, 0x9079D6BA, 0x804885CD, 0x000007BB, 0x89A8DA66, 0x00000136, 0x7185B813, 0x82190F37, 0xFFFFF58C, 0x013FA7D4, 0xFFFFF4AB, 0x7518093D, 0x83F7826A, 0x00000917, 0x2F33C3DD, 0xFFFFFBF0, 0x02A289B1, 0x8481BFD5, 0xFFFFF927, 0x72EED2D1, 0xFFFFF80A, 0xF46FD351, 0x85A69D6E, 0x000000B4, 0x27A3BB0F, 0x00000181, 0x49235BC0, 0x85F73150, 0x00000259, 0xA300692F, 0x000009BD, 0x5A3E46A9, 0x86E2497A, 0xFFFFFB53, 0xE7614707, 0xFFFFFBB3, 0xFA190B2A, 0x8B261F60, 0xFFFFF323, 0x97B9CC33, 0xFFFFFAB7, 0x2CB73BF0, 0x8B42B00C, 0x00000871, 0xA57A2DE3, 0x00000797, 0xA73082D6, 0x8E4C5C94, 0x000000FE, 0xEE4B594B, 0xFFFFF999, 0xDCE3B74D, 0x913A9FDB, 0xFFFFFE1C, 0x1BFFA329, 0xFFFFFD31, 0x49B21C95, 0x922BFB96, 0xFFFFF61B, 0x4FAFD829, 0xFFFFFBBA, 0x6BD5D317, 0x9F4B8702, 0xFFFFFEC1, 0xB691AD49, 0xFFFFFEF2, 0xCE6C6FE9, 0xA2CEAAA6, 0xFFFFFD89, 0x60E52701, 0xFFFFFCB2, 0x25AD9A9D, 0xAA970D72, 0xFFFFF2BB, 0xC1F58CAC, 0xFFFFF2AB, 0x20B8FE22, 0xABC02B72, 0xFFFFF94B, 0xFF6EA5A6, 0xFFFFFA6A, 0x1CD46647, 0xAE535E9E, 0x000003EC, 0x31246F6B, 0x0000035B, 0x50E2A20A, 0xB7337941, 0xFFFFF856, 0xD1A79AD7, 0xFFFFF955, 0x14673B75, 0xBB8DB95E, 0xFFFFFEEB, 0x6A7F1E5A, 0xFFFFF3B3, 0x1EF2F3AA, 0xBC1EDA22, 0xFFFFFB90, 0xE247955F, 0xFFFFFCE6, 0xA0351A85, 0xBCD91FE8, 0x0000008C, 0x71A348B9, 0x00000030, 0x821754EF, 0xBD38E305, 0xFFFFFF59, 0xE694333F, 0xFFFFFEF9, 0x436B1A45, 0xBE1AA65A, 0xFFFFF93D, 0x8761A810, 0xFFFFFEEB, 0xB2DB19FA, 0xC052453C, 0x000009B5, 0xB05027D7, 0x000009C5, 0xBCA91679, 0xC4A2D780, 0x000008B9, 0xE42FD068, 0x000007C1, 0x9F8B2B83, 0xC6A236BA, 0xFFFFFDBB, 0x20649A12, 0xFFFFFD09, 0x5F73FD94, 0xC6BB5160, 0xFFFFFE90, 0x0ED42674, 0xFFFFFF4B, 0xA76699CC, 0xCB74E940, 0x000003E3, 0x7DA194FF, 0xFFFFFCDA, 0xB23E5B15, 0xD027B387, 0xFFFFF701, 0x880BCC4F, 0xFFFFF785, 0xFEA3D685, 0xD1127D6B, 0xFFFFFAC0, 0xDF3D499A, 0x00000362, 0x84B7777D, 0xD6F5F913, 0xFFFFFCCD, 0xA5D89DB8, 0xFFFFFCAB, 0xF69BAE29, 0xDD04F828, 0xFFFFF705, 0xE18F3BA0, 0xFFFFF64D, 0xEBC799B0, 0xDDF22CB8, 0x0000075D, 0x47F7B857, 0x000001B3, 0x5C1CDEA9, 0xDF34D0A8, 0x0000014D, 0xBFE2CAD5, 0x00000201, 0x1F0C8A89, 0xE146EA40, 0x0000046D, 0x189EB8F9, 0xFFFFF6FB, 0x4CA1090D, 0xE231C560, 0x00000710, 0x2E586529, 0xFFFFFF17, 0x0E9AA776, 0xE2FC6838, 0x00000733, 0xB73DDD7A, 0x00000753, 0x14A1BDE4, 0xE44AE35D, 0x000002C8, 0x46B1F3D1, 0xFFFFFA2D, 0xD2295816, 0xE5AF4AB1, 0x00000DB0, 0x0AFF4FF9, 0x00000D91, 0xB17A4340, 0xE7E3CF21, 0x00000656, 0x9FC50924, 0x00000658, 0x31615022, 0xE8815965, 0x00000BCB, 0x6F51A655, 0x00000C0A, 0x72F5680C, 0xEBDF0F14, 0xFFFFF2B1, 0xD36EC5D4, 0xFFFFF239, 0x3B711343, 0xEC12E59B, 0x00000270, 0x3A38D2E8, 0x0000023D, 0x68D07674, 0xF4013920, 0x00000703, 0xD83CCFAA, 0x000007BA, 0x46891EEB, 0xF6847EC1, 0xFFFFFE62, 0x6D4BAAFC, 0xFFFFFD92, 0x5E6F5A94]
 
 
size_table = [0x02F73020, 0x00000015, 0x09D3473A, 0x00000051, 0x0EF87B55, 0x0000000D, 0x147CB028, 0x00000023, 0x15F833AA, 0x00000030, 0x17086780, 0x00000018, 0x1733A9D4, 0x00000014, 0x17D61EE8, 0x00000051, 0x1D52F19E, 0x00000011, 0x1F732DE0, 0x0000000D, 0x1FBECFAD, 0x0000001B, 0x245BD7C8, 0x00000055, 0x25E7ABEE, 0x00000009, 0x2882C190, 0x000000A2, 0x2A2084A0, 0x00000075, 0x326AA6AE, 0x00000036, 0x33074A36, 0x00000024, 0x3440BD69, 0x0000002C, 0x362A1FC3, 0x0000002C, 0x3C0450D0, 0x0000000D, 0x3CB575FD, 0x00000011, 0x41B3B26E, 0x0000004E, 0x46005120, 0x00000011, 0x465A72CF, 0x00000002, 0x492145A0, 0x0000000D, 0x49AA4CE0, 0x0000002D, 0x4BD63647, 0x0000004E, 0x4BF84A87, 0x0000000D, 0x4D102445, 0x00000033, 0x4D4D3C55, 0x0000001B, 0x53723232, 0x0000000A, 0x5809B5CB, 0x000000A2, 0x5B12FFCE, 0x00000015, 0x5B1F3000, 0x00000051, 0x5D9FBD20, 0x00000027, 0x6219EED9, 0x0000008A, 0x65D82D17, 0x0000004C, 0x67F5671A, 0x00000063, 0x6CE2CBC1, 0x00000033, 0x718A739C, 0x0000000B, 0x71A62DD7, 0x00000015, 0x7693A1F6, 0x00000014, 0x7A473FB0, 0x00000047, 0x7AEFEDDC, 0x00000011, 0x7AF2CF90, 0x0000004F, 0x7BE0B8B0, 0x0000001B, 0x80EB3E88, 0x0000000A, 0x8213506A, 0x0000000C, 0x82468114, 0x00000011, 0x86B872A2, 0x0000001C, 0x87FBD296, 0x00000019, 0x88719339, 0x00000016, 0x89E2630A, 0x00000024, 0x8CB6536E, 0x0000004E, 0x92316E00, 0x00000015, 0x9415A51E, 0x0000004F, 0x94D658E0, 0x0000002B, 0x97E8DFCD, 0x00000036, 0x992E3874, 0x0000002A, 0x9B06958D, 0x00000030, 0x9B36B480, 0x0000000D, 0xA03CEFAD, 0x0000005A, 0xA39F47E6, 0x0000004E, 0xA946DEC4, 0x000000B4, 0xAE6173DC, 0x00000051, 0xB044A68D, 0x0000008C, 0xB29E36A8, 0x0000000B, 0xB82781F4, 0x0000000D, 0xC14DFAF8, 0x00000011, 0xC3F42E20, 0x0000001E, 0xC5E0065E, 0x00000067, 0xCAD68B21, 0x00000039, 0xCBF29AC7, 0x00000011, 0xCE8729BC, 0x0000001B, 0xD2A85A94, 0x00000004, 0xD34FA4F3, 0x00000011, 0xD64611B0, 0x00000058, 0xD814FD56, 0x00000018, 0xDD386A80, 0x0000000A, 0xDE82DFAC, 0x00000011, 0xEC68D16F, 0x0000001B, 0xEEDE845B, 0x0000003F, 0xF235F260, 0x0000008D, 0xF9AA1F0B, 0x00000087, 0xFC200887, 0x00000011, 0xFED657A3, 0x0000000C, 0x00000000]
zf_0_jmp = 0
zf_0_key = 1
zf_1_jmp = 2
zf_1_key = 3
 
 
code_bin = open("code.bin", "rb").read()
print("code size: ", hex(len(code_bin)))
 
def get_size(key):
    for i in range(85):
        if size_table[i * 2] == key:
            return  size_table[i * 2 + 1]
    return None
 
def get_jmps(key):
    for i in range(85):
        base = i * 5
        if fuckTable[base] == key:
            # zf_0_jmp, zf_0_key, zf_1_jmp, zf_1_key
            return fuckTable[base + 1: base + 5]
    print("not found2: ", hex(key))
    return None
 
def fuck(prev_key, rip):
    return rip ^ prev_key ^ ((rip * prev_key) & 0xffffffff) ^ (prev_key + rip)
 
def deXor(data, key):
    key = p32(key)
    data = bytearray(data)
    for i in range(len(data)):
        data[i] ^=  key[i % 4]
    return data
 
 
def decrypt_block(key, rip):
    key2 = fuck(key, rip)
    blockSize = get_size(key2)
 
    if blockSize is None:
        print("Not found1: rip:%x key:%x" % (rip, key2))
        return None, None, None
 
    offset = rip - 0x1000
    code_data = code_bin[offset: offset + blockSize]
    code_data = deXor(code_data, key)
    next_rip = rip + blockSize - 2
    key2 = fuck(key, next_rip)
 
    jmps = get_jmps(key2)
 
    return code_data, jmps, next_rip
 
class Node:
    def __init__(self, data, rip):
        self.code_data = data
        self.child1 = 0
        self.child2 = 0
        self.end_rip = None
        self.rip = rip
 
 
def disasm(data, baseaddr):
    md = Cs(CS_ARCH_X86, CS_MODE_64)
    ins = ''
    for i in md.disasm(data, baseaddr):
        asm_code = "%s\t%s" % (i.mnemonic, i.op_str)
        ins += asm_code + "\n"
    return ins
 
def buildNode(key_, rip_):
    work_queue = [(key_, rip_)]
    log_map = {}
    while len(work_queue) > 0:
        T = work_queue[0]
        work_queue.remove(T)
        key, rip = T
 
 
        if rip in log_map:
            continue
 
        if rip == 0x10A3:
            key -= 0x2B09B990
            rip = 0x1EEC
 
        code_data, jmps, next_rip = decrypt_block(key, rip)
 
        if code_data is None:
            continue
 
        node_cur = Node(code_data, rip)
 
        node_cur.end_rip = next_rip
        log_map[rip] = node_cur
 
        if jmps is None:
            continue
 
        asm_text = disasm(node_cur.code_data, rip)
 
 
        newrip = next_rip + ctypes.c_int32(jmps[zf_0_jmp]).value
        node_cur.child1 = newrip
        if newrip not in log_map:
            work_queue.append(((key + jmps[zf_0_key]) & 0xffffffff, newrip))
 
        if 'qword ptr fs:[' in asm_text.splitlines()[-1]:
            continue
 
 
        newrip = next_rip + ctypes.c_int32(jmps[zf_1_jmp]).value
        node_cur.child2 = newrip
        if newrip not in log_map:
            work_queue.append(((key + jmps[zf_1_key]) & 0xffffffff, newrip))
 
 
    jmptables = {}
    for i in sorted(log_map.keys()):
        if log_map[i].child1 is None:
            log_map[i].child1 = 0
 
        if log_map[i].child2 is None:
            log_map[i].child2 = 0
 
        jmptables[hex(log_map[i].end_rip)] = (hex(log_map[i].rip), hex(log_map[i].child1), hex(log_map[i].child2))
    print("len:", len(jmptables))
    print(jmptables)
 
    all_asm = ''
    for i in sorted(log_map.keys()):
        print(hex(i))
        node = log_map[i]
        if i == 0x1EEC:
            all_asm += "_0x10a3:\n"
 
        all_asm += "_" + hex(i) + ":\n"
        all_asm += disasm(node.code_data, i)
 
        if node.child1 != 0 and node.child2 != 0:
            jmp_code = "jz _" + hex(node.child2) + "\n"
            jmp_code += "jmp _" + hex(node.child1) + "\n"
 
        elif node.child1 == 0 and node.child2 != 0:
            jmp_code = "jmp _" + hex(node.child2) + "\n"
 
        elif node.child2 == 0 and node.child1 != 0:
            jmp_code = "jmp _" + hex(node.child1) + "\n"
        else:
            jmp_code = '\n'
 
        all_asm += jmp_code
 
    all_asm = all_asm.replace("endbr64", "nop\n" * 4)
    code_bin = asm(all_asm)
    open('1.bin', 'wb').write(code_bin)
    print(all_asm)
    print("all nodes: ", len(log_map))
 
buildNode(0x3265B1F5, 0x1000)
// rsp = 0x7777F000
void __noreturn sub_4()
{
  unsigned __int8 v0; // al
  int v1; // eax
  __int64 v2; // rax
  __int64 xorKey[4]; // [rsp+0h] [rbp-2C0h]
  __int128 v4; // [rsp+21h] [rbp-29Fh] BYREF
  char v5[14]; // [rsp+31h] [rbp-28Fh] BYREF
  char v6[17]; // [rsp+3Fh] [rbp-281h] BYREF
  __int64 compare[5]; // [rsp+50h] [rbp-270h] BYREF
  __int64 v8; // [rsp+78h] [rbp-248h]
  __int64 FlagInData[8]; // [rsp+80h] [rbp-240h] BYREF
  unsigned __int8 v10; // [rsp+C2h] [rbp-1FEh]
  unsigned __int8 v11; // [rsp+C3h] [rbp-1FDh]
  int kk; // [rsp+C4h] [rbp-1FCh]
  __int64 v13; // [rsp+C8h] [rbp-1F8h]
  __int128 *v14; // [rsp+D0h] [rbp-1F0h]
  unsigned __int8 v15; // [rsp+DAh] [rbp-1E6h]
  unsigned __int8 v16; // [rsp+DBh] [rbp-1E5h]
  int mm; // [rsp+DCh] [rbp-1E4h]
  __int64 v18; // [rsp+E0h] [rbp-1E0h]
  __int64 v19; // [rsp+E8h] [rbp-1D8h]
  unsigned __int8 v20; // [rsp+F3h] [rbp-1CDh]
  int jj; // [rsp+F4h] [rbp-1CCh]
  __int64 v22; // [rsp+F8h] [rbp-1C8h]
  __int64 *v23; // [rsp+100h] [rbp-1C0h]
  __int64 *v24; // [rsp+108h] [rbp-1B8h]
  int ii; // [rsp+110h] [rbp-1B0h]
  unsigned int v26; // [rsp+114h] [rbp-1ACh]
  int v27; // [rsp+118h] [rbp-1A8h]
  unsigned int v28; // [rsp+11Ch] [rbp-1A4h]
  unsigned int *v29; // [rsp+120h] [rbp-1A0h]
  int n; // [rsp+12Ch] [rbp-194h]
  unsigned __int64 v31; // [rsp+130h] [rbp-190h]
  unsigned __int64 v32; // [rsp+138h] [rbp-188h]
  unsigned __int64 v33; // [rsp+140h] [rbp-180h]
  unsigned __int64 data2; // [rsp+148h] [rbp-178h]
  int m; // [rsp+154h] [rbp-16Ch]
  unsigned __int64 v36; // [rsp+158h] [rbp-168h]
  unsigned __int64 data1; // [rsp+160h] [rbp-160h]
  int i_0; // [rsp+16Ch] [rbp-154h]
  __int64 v39; // [rsp+170h] [rbp-150h]
  unsigned __int64 from_t0; // [rsp+178h] [rbp-148h]
  __int64 const_32; // [rsp+180h] [rbp-140h]
  __int64 *flag_ptr; // [rsp+188h] [rbp-138h]
  unsigned __int64 v43; // [rsp+190h] [rbp-130h]
  __int64 v44; // [rsp+198h] [rbp-128h]
  __int64 *v45; // [rsp+1A0h] [rbp-120h]
  unsigned __int8 v46; // [rsp+202h] [rbp-BEh]
  unsigned __int8 v47; // [rsp+203h] [rbp-BDh]
  int nn; // [rsp+204h] [rbp-BCh]
  __int64 v49; // [rsp+208h] [rbp-B8h]
  char *v50; // [rsp+210h] [rbp-B0h]
  __int64 flagLen; // [rsp+218h] [rbp-A8h]
  __int64 *v52; // [rsp+220h] [rbp-A0h]
  unsigned __int8 v53; // [rsp+22Ah] [rbp-96h]
  unsigned __int8 v54; // [rsp+22Bh] [rbp-95h]
  int i1; // [rsp+22Ch] [rbp-94h]
  __int64 v56; // [rsp+230h] [rbp-90h]
  char *v57; // [rsp+238h] [rbp-88h]
  __int64 v58; // [rsp+240h] [rbp-80h]
  __int64 time0; // [rsp+248h] [rbp-78h]
  __int64 v60; // [rsp+250h] [rbp-70h]
  __int64 d2; // [rsp+258h] [rbp-68h]
  __int64 v62; // [rsp+260h] [rbp-60h]
  __int64 d1; // [rsp+268h] [rbp-58h]
  int i; // [rsp+274h] [rbp-4Ch]
  __int64 data0; // [rsp+278h] [rbp-48h]
  unsigned __int8 v66; // [rsp+282h] [rbp-3Eh]
  unsigned __int8 v67; // [rsp+283h] [rbp-3Dh]
  int j; // [rsp+284h] [rbp-3Ch]
  __int64 v69; // [rsp+288h] [rbp-38h]
  char *v70; // [rsp+290h] [rbp-30h]
  unsigned __int8 v71; // [rsp+29Ah] [rbp-26h]
  unsigned __int8 v72; // [rsp+29Bh] [rbp-25h]
  int k; // [rsp+29Ch] [rbp-24h]
  __int64 v74; // [rsp+2A0h] [rbp-20h]
  __int64 *flagIn; // [rsp+2A8h] [rbp-18h]
  __int64 v76; // [rsp+2B0h] [rbp-10h]
  unsigned __int64 time0_1; // [rsp+2B8h] [rbp-8h]
 
  v58 = 0x7177625F32303231i64;
  __writefsqword(0, 0x7177625F32303231ui64);
  __asm { syscall; Low latency system call }
  time0 = MEMORY[0x1337];                       // time(0)
  time0_1 = MEMORY[0x1337];
  v2 = MEMORY[0x1337] / 0xE10ui64;
  data0 = MEMORY[0x1337] / 0xE10ui64;
  for ( i = 0; i != 256; ++i )
  {
    d1 = 0i64;
    d1 = *(_QWORD *)v2;
    v62 = d1;
    d2 = 0i64;
    d2 = *(_QWORD *)(d1 + 1);
    v60 = d2;
    data0 = __ROL8__((data0 ^ d1) + d2 + 33 * data0 + 1, 13);
    if ( (i & 1) != 0 )
      data0 = v60 ^ (v62 + data0);
    if ( (i & 2) != 0 )
      data0 ^= v62 + v60;
    if ( (i & 4) != 0 )
      data0 ^= v60 ^ v62;
    v2 = i & 8;
    if ( (i & 8) != 0 )
    {
      v2 = data0 + v62 + v60;
      data0 = v2;
    }
  }
  v76 = data0;
  strcpy(v6, "input flag:\n");
  v70 = v6;
  v69 = 12i64;
  for ( j = 0; v69 != j; ++j )
  {
    v67 = v70[j];
    v66 = v67;
    __outbyte(1u, v67);                         // putchar
  }
  memset(FlagInData, 0, sizeof(FlagInData));
  flagIn = FlagInData;
  v74 = 0x40i64;
  for ( k = 0; ; ++k )
  {
    if ( v74 == k )
      goto LABEL_3;
    v0 = __inbyte(0);                           // get_char
    v72 = v0;
    v71 = v0;
    if ( v0 == '\n' )
      break;
    *((_BYTE *)flagIn + k) = v71;
  }
  *((_BYTE *)flagIn + k) = 0;
LABEL_3:
  if ( v76 == 0x1C986C3B22EA63E5i64 )
  {
    v52 = FlagInData;
    for ( flagLen = 0i64; *((_BYTE *)v52 + flagLen); ++flagLen )
      ;
    v8 = flagLen;
    if ( flagLen == 32 )
    {
      v45 = FlagInData;
      v44 = 32i64;
      v43 = time0_1 / 0xE10;
      flag_ptr = FlagInData;
      const_32 = 32i64;
      from_t0 = time0_1 / 0xE10;
      v39 = 0x5249415452455451i64;
      __writefsqword(0, 0x5249415452455451ui64);
      for ( i_0 = 0; const_32 != i_0; ++i_0 )
      {
        data1 = __readfsqword(0);               // 0x5249415452455451
        v36 = i_0;
        for ( m = 0; m != 256; ++m )
        {
          data2 = __readfsqword(0);
          v33 = data2;
          v32 = data2;
          v31 = data2;
          v36 = (v36 ^ data2) + data2 + 0x21 * v36 + 1;
          v36 = __ROL8__(v36, 13);
          if ( (m & 1) != 0 )
            v36 = v31 ^ (v33 + v36);
          if ( (m & 2) != 0 )
            v36 ^= v33 + v31;
          if ( (m & 4) != 0 )
            v36 ^= v31 ^ v33;
          if ( (m & 8) != 0 )
            v36 += v33 + v31;
        }
        *((_BYTE *)flag_ptr + i_0) ^= (_BYTE)data1 + (_BYTE)v36;
      }
      for ( n = 0; const_32 != n; n += 4 )      // 4字节一组
      {
        v29 = (unsigned int *)((char *)flag_ptr + n);
        v28 = *v29;
        v27 = 0;
        v26 = v28;
        v28 = from_t0 + _mm_crc32_u32(0, v28);
        *v29 = v28;
      }
      xorKey[0] = 0x178DEC4F232DDB6Ei64;
      xorKey[1] = 0xC2AAB7D6D2A167C3ui64;
      xorKey[2] = 0xF1AB91F72761A80Fui64;
      xorKey[3] = 0x3DCEDC28076C41Ai64;
      for ( ii = 0; v44 != ii; ++ii )
        *((_BYTE *)v45 + ii) ^= *((_BYTE *)xorKey + ii);
      compare[0] = 0x3EC81D9432CEF584i64;
      compare[1] = 0xB649A4DCD6BD24FEui64;
      compare[2] = 0xC5927F0B767A787Dui64;
      compare[3] = 0x1F245B7F751BB52Ei64;
      v24 = FlagInData;
      v23 = compare;
      v22 = v8;
      for ( jj = 0; ; ++jj )
      {
        if ( v22 == jj )
        {
          v1 = 0;
          goto LABEL_47;
        }
        v20 = *((_BYTE *)v24 + jj) - *((_BYTE *)v23 + jj);
        if ( v20 )
          break;
      }
      v1 = v20;
LABEL_47:
      if ( v1 )
      {
        strcpy((char *)&v4, "wrong\n");
        v14 = &v4;
        v13 = 6i64;
        for ( kk = 0; v13 != kk; ++kk )
        {
          v11 = *((_BYTE *)v14 + kk);
          v10 = v11;
          __outbyte(1u, v11);
        }
      }
      else
      {
        strcpy((char *)&v4 + 7, "correct\n");
        v19 = (__int64)&v4 + 7;
        v18 = 8i64;
        for ( mm = 0; v18 != mm; ++mm )
        {
          v16 = *(_BYTE *)(mm + v19);
          v15 = v16;
          __outbyte(1u, v16);
        }
      }
    }
    else
    {
      strcpy(v5, "wrong\n");
      v50 = v5;
      v49 = 6i64;
      for ( nn = 0; v49 != nn; ++nn )
      {
        v47 = v50[nn];
        v46 = v47;
        __outbyte(1u, v47);
      }
    }
  }
  else
  {
    *(_DWORD *)&v5[7] = 'norw';
    *(_WORD *)&v5[11] = '\ng';
    v5[13] = 0;
    v57 = &v5[7];
    v56 = 6i64;
    for ( i1 = 0; v56 != i1; ++i1 )
    {
      v54 = v57[i1];
      v53 = v54;
      __outbyte(1u, v54);
    }
  }
  __halt();
}
// rsp = 0x7777F000
void __noreturn sub_4()
{
  unsigned __int8 v0; // al
  int v1; // eax
  __int64 v2; // rax
  __int64 xorKey[4]; // [rsp+0h] [rbp-2C0h]
  __int128 v4; // [rsp+21h] [rbp-29Fh] BYREF
  char v5[14]; // [rsp+31h] [rbp-28Fh] BYREF
  char v6[17]; // [rsp+3Fh] [rbp-281h] BYREF
  __int64 compare[5]; // [rsp+50h] [rbp-270h] BYREF
  __int64 v8; // [rsp+78h] [rbp-248h]
  __int64 FlagInData[8]; // [rsp+80h] [rbp-240h] BYREF
  unsigned __int8 v10; // [rsp+C2h] [rbp-1FEh]
  unsigned __int8 v11; // [rsp+C3h] [rbp-1FDh]
  int kk; // [rsp+C4h] [rbp-1FCh]
  __int64 v13; // [rsp+C8h] [rbp-1F8h]
  __int128 *v14; // [rsp+D0h] [rbp-1F0h]
  unsigned __int8 v15; // [rsp+DAh] [rbp-1E6h]
  unsigned __int8 v16; // [rsp+DBh] [rbp-1E5h]
  int mm; // [rsp+DCh] [rbp-1E4h]
  __int64 v18; // [rsp+E0h] [rbp-1E0h]
  __int64 v19; // [rsp+E8h] [rbp-1D8h]
  unsigned __int8 v20; // [rsp+F3h] [rbp-1CDh]
  int jj; // [rsp+F4h] [rbp-1CCh]
  __int64 v22; // [rsp+F8h] [rbp-1C8h]
  __int64 *v23; // [rsp+100h] [rbp-1C0h]
  __int64 *v24; // [rsp+108h] [rbp-1B8h]
  int ii; // [rsp+110h] [rbp-1B0h]
  unsigned int v26; // [rsp+114h] [rbp-1ACh]
  int v27; // [rsp+118h] [rbp-1A8h]
  unsigned int v28; // [rsp+11Ch] [rbp-1A4h]
  unsigned int *v29; // [rsp+120h] [rbp-1A0h]
  int n; // [rsp+12Ch] [rbp-194h]
  unsigned __int64 v31; // [rsp+130h] [rbp-190h]
  unsigned __int64 v32; // [rsp+138h] [rbp-188h]
  unsigned __int64 v33; // [rsp+140h] [rbp-180h]
  unsigned __int64 data2; // [rsp+148h] [rbp-178h]
  int m; // [rsp+154h] [rbp-16Ch]
  unsigned __int64 v36; // [rsp+158h] [rbp-168h]
  unsigned __int64 data1; // [rsp+160h] [rbp-160h]

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 12
支持
分享
最新回复 (16)
雪    币: 26245
活跃值: (63297)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
感谢分享~
2021-6-14 21:32
0
雪    币: 15
活跃值: (1913)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
无名侠爷爷tql!!!所以除了unicorn还有其它re的wp吗,比如Longtimeago
2021-6-14 22:02
0
雪    币: 2677
活跃值: (5340)
能力值: ( LV10,RANK:177 )
在线值:
发帖
回帖
粉丝
4
666,tql
2021-6-14 22:07
0
雪    币: 4168
活跃值: (15932)
能力值: ( LV9,RANK:710 )
在线值:
发帖
回帖
粉丝
5
太强了
2021-6-14 22:12
0
雪    币: 59
活跃值: (1501)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
厉害啊!
2021-6-14 22:23
0
雪    币: 1368
活跃值: (1461)
能力值: ( LV5,RANK:63 )
在线值:
发帖
回帖
粉丝
7

无名爷爷!

最后于 2021-6-14 22:46 被Minhal编辑 ,原因:
2021-6-14 22:45
0
雪    币: 916
活跃值: (3434)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
8
无名哥哥我爱你 [打call][打call][打call]
2021-6-14 23:09
0
雪    币: 1054
活跃值: (1772)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
无名哥哥我爱你 [打call][打call][打call] 
2021-6-15 00:15
0
雪    币: 3116
活跃值: (1269)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
10
倒是学了个符号还原技能
2021-6-15 11:44
0
雪    币: 2134
活跃值: (3911)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
11
太强了
2021-6-15 14:47
0
雪    币: 8447
活跃值: (5041)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
12
牛逼
2021-6-15 23:29
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
想请教下楼主是怎么控制编译方式和参数的,我编译出来的和题目匹配不上
2021-6-16 15:52
0
雪    币: 14303
活跃值: (10776)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
14
爷爷!
2021-6-16 15:54
0
雪    币: 12
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
想问下最后的头文件"ida.h"是包含在crypto++包中的还是idasdk的呢?用g++ 带头文件指定路径-I ./ida.h_path都保存编译不通过诶
2021-6-21 22:31
0
雪    币: 6911
活跃值: (9069)
能力值: ( LV17,RANK:797 )
在线值:
发帖
回帖
粉丝
16
CHOLASLEE 想请教下楼主是怎么控制编译方式和参数的,我编译出来的和题目匹配不上[em_67]
不能完全识别,ubuntu 20 编译,similarity 最低 0.5
2021-6-22 23:46
0
雪    币: 6911
活跃值: (9069)
能力值: ( LV17,RANK:797 )
在线值:
发帖
回帖
粉丝
17
大史 4.0 想问下最后的头文件"ida.h"是包含在crypto++包中的还是idasdk的呢?用g++ 带头文件指定路径-I ./ida.h_path都保存编译不通过诶
ida.h 就是 idasdk 里的文件,可以直接编译。
2021-6-22 23:47
0
游客
登录 | 注册 方可回帖
返回
//