这是我做过的最难的逆向题,题目给了1000个二进制程序,单个难度不大,但是把1000个统一起来自动化那真是太难了,根据这题是考自动化。
一
题目背景
# This file was *autogenerated* from the file derive_key.sage
from sage.all_cmdline import * # import sage library
_sage_const_202750432774689774479024096223623722409 = Integer(202750432774689774479024096223623722409); _sage_const_2 = Integer(2); _sage_const_950 = Integer(950); _sage_const_0 = Integer(0); _sage_const_16 = Integer(16)
p = _sage_const_202750432774689774479024096223623722409
F = Zmod(p)
G = F['x']; (x,) = G._first_ngens(1)
# just the accepted input values from the challenges
solutions = []
points = [*{int.from_bytes(s[:_sage_const_2 ], 'big'): int.from_bytes(s[_sage_const_2 :], 'big') for s in solutions}.items()]
if len(points) >= _sage_const_950 :
key = G.lagrange_polynomial(points)[_sage_const_0 ]
print(f"key: {key.lift().to_bytes(_sage_const_16 , 'big').hex()}")
二
ida 初探
__int64 __fastcall VM(__int64 *a1)
{
__int64 result; // rax
unsigned int *v3; // rdx
unsigned int v4; // edi
__int64 v5; // r14
__int64 v6; // rdi
unsigned int v7; // r8d
__int64 v8; // rsi
__int64 v9; // rcx
__int64 v10; // rdx
unsigned int v11; // edi
__int64 v12; // rcx
__int64 *v13; // rax
__int64 v14; // rdi
__int64 (__fastcall *v15)(_QWORD, __int64, __int64, __int64, __int64, __int64, __int64); // r10
__int64 v16; // rax
char v17; // cl
__int64 v18; // rdx
unsigned int v19; // edx
unsigned int v20; // ecx
unsigned __int64 *v21; // rax
unsigned __int64 v22; // rcx
__int64 v23; // [rsp-8h] [rbp-18h]
v23 = result;
v3 = (unsigned int *)a1[31];
v4 = *v3;
v5 = (__int64)(v3 + 1);
a1[31] = (__int64)(v3 + 1);
v6 = _byteswap_ulong(v4);
v7 = (unsigned int)v6 >> 29;
if ( (unsigned int)v6 < 0x20000000 || v7 == 1 && (result = v6 & 0x10000000, (v6 & 0x10000000) == 0) )
{
v8 = ((unsigned int)v6 >> 19) & 0x1F;
if ( (BYTE3(v6) & 1 & (v7 == 1)) != 0 || (v6 & 0xE1000000) == 0 )
{
if ( v7 == 1 || (unsigned int)v6 >> 25 == 9 || (unsigned int)v6 >> 25 == 7 )// imm
v9 = v6 << 50 >> 50; // low 14 bits signed
else
v9 = v6 & 0x3FFF; // low 14 bits unsigned
}
else
{
v9 = a1[((unsigned int)v6 >> 9) & 0x1F];
}
v10 = a1[((unsigned int)v6 >> 14) & 0x1F];
v11 = (unsigned int)v6 >> 25;
if ( v7 == 1 )
{
switch ( v11 & 7 )
{
case 0u:
result = v10 == v9;
a1[v8] = result;
break;
case 1u:
result = v10 != v9;
a1[v8] = result;
break;
case 2u:
result = v10 <= v9;
a1[v8] = result;
break;
case 3u:
result = v10 < v9;
a1[v8] = result;
break;
case 4u:
result = v10 <= (unsigned __int64)v9;
a1[v8] = result;
break;
case 5u:
result = v10 < (unsigned __int64)v9;
a1[v8] = result;
break;
default:
LABEL_20:
result = 0LL;
a1[v8] = 0LL;
break;
}
}
else
{
switch ( v11 & 0xF )
{
case 0u:
v12 = v10 | v9;
goto LABEL_38;
case 1u:
v12 = v10 ^ v9;
goto LABEL_38;
case 2u:
v12 = v10 & v9;
goto LABEL_38;
case 3u:
v12 = v10 + v9;
goto LABEL_38;
case 4u:
v18 = v10 - v9;
goto LABEL_48;
case 5u:
v12 = v10 * v9;
LABEL_38:
result = v12;
a1[v8] = v12;
return result;
case 6u:
result = v10 / (unsigned __int64)v9;
a1[v8] = v10 / (unsigned __int64)v9;
return result;
case 7u:
result = v10 / v9;
a1[v8] = v10 / v9;
return result;
case 8u:
v18 = v10 % (unsigned __int64)v9;
goto LABEL_48;
case 9u:
v18 = v10 % v9;
goto LABEL_48;
case 0xAu:
v18 = v10 << v9;
goto LABEL_48;
case 0xBu:
v18 = v10 >> v9;
goto LABEL_48;
case 0xCu:
v18 = (unsigned __int64)v10 >> v9;
goto LABEL_48;
case 0xDu:
v18 = __ROL8__(v10, v9);
goto LABEL_48;
case 0xEu:
v18 = __ROR8__(v10, v9);
LABEL_48:
result = v18;
a1[v8] = v18;
break;
default:
goto LABEL_20;
}
}
return result;
}
if ( v7 == 1 )
{
v7 = ((unsigned int)v6 >> 26) & 3;
if ( v7 == 2 )
{
v14 = ((unsigned int)v6 >> 20) & 0x1F;
v15 = (__int64 (__fastcall *)(_QWORD, __int64, __int64, __int64, __int64, __int64, __int64))a1[v14];
if ( (unsigned __int64)v15 < a1[32] || (unsigned __int64)v15 >= a1[33] )
{
result = v15(*a1, a1[1], a1[2], a1[3], a1[4], a1[5], v23);
*a1 = result;
a1[31] = v5;
}
else
{
v16 = a1[30]; // PUSH
*(_QWORD *)(v16 - 8) = v5; // call
result = v16 - 8;
a1[31] = a1[v14];
a1[30] = result;
}
return result;
}
if ( !v7 )
{
v13 = (__int64 *)a1[30]; // pop
a1[31] = *v13; // ret
result = (__int64)(v13 + 1);
a1[30] = result;
return result;
}
if ( (v6 & 0x2000000) != 0 ) // check 26 bit
{
result = 37LL;
v17 = 39;
}
else
{
result = ((unsigned int)v6 >> 20) & 0x1F; // 21-25
if ( !a1[result] )
goto LABEL_52;
result = 42LL;
v17 = 44;
}
a1[31] = (__int64)v3 + ((__int64)((unsigned __int64)(unsigned int)v6 << v17) >> result);
LABEL_52:
if ( (v6 & 0x2000000) == 0 )
return result;
}
if ( v7 == 2 )
{
if ( (((unsigned int)v6 >> 27) & 3) != 0 ) // 2829
{
v19 = ((unsigned int)v6 >> 21) & 0x1F; // 22-26
v20 = WORD1(v6) & 0x1F;
result = (unsigned __int16)v6 - 0x8000LL;
if ( (v6 & 0x8000u) == 0LL )
result = (unsigned __int16)v6;
if ( (((unsigned int)v6 >> 27) & 3) == 1 )
{
result = *(_QWORD *)(a1[v20] + result);
a1[v19] = result; // load
}
else
{
switch ( ((unsigned int)v6 >> 26) & 3 ) // store
{
case 0u:
*(_BYTE *)(a1[v20] + result) = a1[v19];
break;
case 1u:
*(_WORD *)(a1[v20] + result) = a1[v19];
break;
case 2u:
*(_DWORD *)(a1[v20] + result) = a1[v19];
break;
case 3u:
*(_QWORD *)(a1[v20] + result) = a1[v19];
break;
}
}
}
else
{
v21 = (unsigned __int64 *)a1[31];
v22 = _byteswap_uint64(*v21);
result = (__int64)(v21 + 1);
a1[31] = result;
a1[WORD1(v6) & 0x1F] = v22;
}
}
return result;
}
源代码模拟
#include<stdio.h>
#include<stdint.h>
#include"defs.h"
#include <intrin.h>
#include<iostream>
#include <cstdarg>
using namespace std;
int lut[256] = {};
__int64 __fastcall VM_0(__int64 *a1) //big edian no lfsr
{
__int64 result; // rax
unsigned int *v3; // rdx
unsigned int v4; // edi
__int64 v5; // r14
__int64 v6; // rdi
unsigned int v7; // r8d
__int64 v8; // rsi
__int64 v9; // rcx
__int64 v10; // rdx
unsigned int v11; // edi
__int64 v12; // rcx
__int64 *v13; // rax
__int64 v14; // rdi
__int64 (__fastcall *v15)(_QWORD, __int64, __int64, __int64, __int64, __int64, __int64); // r10
__int64 v16; // rax
char v17; // cl
__int64 v18; // rdx
unsigned int v19; // edx
unsigned int v20; // ecx
unsigned __int64 *v21; // rax
unsigned __int64 v22; // rcx
__int64 v23; // [rsp-8h] [rbp-18h]
v23 = result;
v3 = (unsigned int *)a1[31];
v4 = *v3;
v5 = (__int64)(v3 + 1);
a1[31] = (__int64)(v3 + 1);
v6 = _byteswap_ulong(v4);
v7 = (unsigned int)v6 >> 29;
if ( (unsigned int)v6 < 0x20000000 || v7 == 1 && (result = v6 & 0x10000000, (v6 & 0x10000000) == 0) )
{
v8 = ((unsigned int)v6 >> 19) & 0x1F;
if ( (BYTE3(v6) & 1 & (v7 == 1)) != 0 || (v6 & 0xE1000000) == 0 )
{
if ( v7 == 1 || (unsigned int)v6 >> 25 == 9 || (unsigned int)v6 >> 25 == 7 )// imm
v9 = v6 << 50 >> 50; // low 14 bits signed
else
v9 = v6 & 0x3FFF; // low 14 bits unsigned
}
else
{
v9 = a1[((unsigned int)v6 >> 9) & 0x1F];
}
v10 = a1[((unsigned int)v6 >> 14) & 0x1F];
v11 = (unsigned int)v6 >> 25;
if ( v7 == 1 )
{
switch ( v11 & 7 )
{
case 0u:
result = v10 == v9;
cout << "SETEQ " << std::hex << v10 << " " << std::hex << v9 <<endl;
a1[v8] = result;
break;
case 1u:
result = v10 != v9;
cout << "SETNOTEQ " << std::hex << v10 << " " << std::hex << v9 <<endl;
a1[v8] = result;
break;
case 2u:
result = v10 <= v9;
cout << "SETLE " << std::hex << v10 << " " << std::hex << v9 <<endl;
a1[v8] = result;
break;
case 3u:
result = v10 < v9;
cout << "SETL " << std::hex << v10 << " " << std::hex << v9 <<endl;
a1[v8] = result;
break;
case 4u:
result = v10 <= (unsigned __int64)v9;
cout << "SETBE " << std::hex << v10 << " " << std::hex << v9 <<endl;
a1[v8] = result;
break;
case 5u:
result = v10 < (unsigned __int64)v9;
cout << "SETB " << std::hex << v10 << " " << std::hex << v9 <<endl;
a1[v8] = result;
break;
default:
LABEL_20:
result = 0LL;
a1[v8] = 0LL;
break;
}
}
else
{
printf("r%d ",v8);
switch ( v11 & 0xF )
{
case 0u:
v12 = v10 | v9;
cout << "OR " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_38;
case 1u:
v12 = v10 ^ v9;
cout << "XOR " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_38;
case 2u:
v12 = v10 & v9;
cout << "AND " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_38;
case 3u:
v12 = v10 + v9;
cout << "ADD " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_38;
case 4u:
v18 = v10 - v9;
cout << "SUB " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_48;
case 5u:
v12 = v10 * v9;
cout << "MUL " << std::hex << v10 << " " << std::hex << v9 << endl;
LABEL_38:
result = v12;
a1[v8] = v12;
return result;
case 6u:
result = v10 / (unsigned __int64)v9;
a1[v8] = v10 / (unsigned __int64)v9;
cout << "DIV " << std::hex << v10 << " " << std::hex << v9 << endl;
return result;
case 7u:
result = v10 / v9;
a1[v8] = v10 / v9;
cout << "IDIV " << std::hex << v10 << " " << std::hex << v9 << endl;
return result;
case 8u:
v18 = v10 % (unsigned __int64)v9;
cout << "MOD " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_48;
case 9u:
v18 = v10 % v9;
cout << "IMOD " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_48;
case 0xAu:
v18 = v10 << v9;
cout << "letfRotate " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_48;
case 0xBu:
v18 = v10 >> v9;
cout << "irightRotate " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_48;
case 0xCu:
v18 = (unsigned __int64)v10 >> v9;
cout << "rightRotate " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_48;
case 0xDu:
v18 = __ROL8__(v10, v9);
cout << "ROL8 " << std::hex << v10 << " " << std::hex << v9 << endl;
goto LABEL_48;
case 0xEu:
v18 = __ROR8__(v10, v9);
cout << "ROR8 " << std::hex << v10 << " " << std::hex << v9 << endl;
LABEL_48:
result = v18;
a1[v8] = v18;
break;
default:
goto LABEL_20;
}
}
return result;
}
if ( v7 == 1 )
{
v7 = ((unsigned int)v6 >> 26) & 3;
if ( v7 == 2 )
{
v14 = ((unsigned int)v6 >> 20) & 0x1F;
v15 = (__int64 (__fastcall *)(_QWORD, __int64, __int64, __int64, __int64, __int64, __int64))a1[v14];
if ( (unsigned __int64)v15 < a1[32] || (unsigned __int64)v15 >= a1[33] )
{
result = v15(*a1, a1[1], a1[2], a1[3], a1[4], a1[5], v23);
cout << "call_out" << endl;
*a1 = result;
a1[31] = v5;
}
else
{
cout << "call in" << endl;
v16 = a1[30]; // PUSH
*(_QWORD *)(v16 - 8) = v5; // call
result = v16 - 8;
a1[31] = a1[v14];
a1[30] = result;
}
return result;
}
if ( !v7 )
{
cout << "ret" << endl;
v13 = (__int64 *)a1[30]; // pop
a1[31] = *v13; // ret
result = (__int64)(v13 + 1);
a1[30] = result;
return result;
}
if ( (v6 & 0x2000000) != 0 ) // check 26 bit
{
cout << "jump" << endl;
result = 37LL;
v17 = 39;
}
else
{
cout << "jcc" << endl;
result = ((unsigned int)v6 >> 20) & 0x1F; // 21-25
if ( !a1[result] )
goto LABEL_52;
result = 42LL;
v17 = 44;
}
a1[31] = (__int64)v3 + ((__int64)((unsigned __int64)(unsigned int)v6 << v17) >> result);
LABEL_52:
if ( (v6 & 0x2000000) == 0 )
return result;
}
if ( v7 == 2 )
{
if ( (((unsigned int)v6 >> 27) & 3) != 0 ) // 2829
{
v19 = ((unsigned int)v6 >> 21) & 0x1F; // 22-26
v20 = WORD1(v6) & 0x1F;
result = (unsigned __int16)v6 - 0x8000LL;
if ( (v6 & 0x8000u) == 0LL )
result = (unsigned __int16)v6;
if ( (((unsigned int)v6 >> 27) & 3) == 1 )
{
printf("load r%d [r%d+0x%x]n",v19, v20, result);
result = *(_QWORD *)(a1[v20] + result);
a1[v19] = result; // load
}
else
{
switch ( ((unsigned int)v6 >> 26) & 3 ) // store
{
case 0u:
printf("stb [r%d + 0x%d] r%dn",v20,result,v19);
*(_BYTE *)(a1[v20] + result) = a1[v19];
break;
case 1u:
printf("stw [r%d + 0x%d] r%dn",v20,result,v19);
*(_WORD *)(a1[v20] + result) = a1[v19];
break;
case 2u:
printf("stdw [r%d + 0x%d] r%dn",v20,result,v19);
*(_DWORD *)(a1[v20] + result) = a1[v19];
break;
case 3u:
printf("stqw [r%d + 0x%d] r%dn",v20,result,v19);
*(_QWORD *)(a1[v20] + result) = a1[v19];
break;
}
}
}
else
{
v21 = (unsigned __int64 *)a1[31];
v22 = _byteswap_uint64(*v21);
result = (__int64)(v21 + 1);
a1[31] = result;
a1[WORD1(v6) & 0x1F] = v22;
printf("speical_load r%d 0x%xn",WORD1(v6) & 0x1f,v22);
}
}
return result;
}
__int64 __fastcall VM_1(__int64 *a1) // little lfsr
{
unsigned int *v2; // rcx
__int64 result; // rax
_DWORD *v4; // r14
int v5; // edx
unsigned int v6; // edx
unsigned int v7; // ebp
unsigned int v8; // edi
__int64 v9; // rsi
__int64 v10; // rcx
__int64 v11; // rdx
unsigned int v12; // eax
__int64 v13; // rcx
__int64 v14; // rax
__int64 v15; // rax
__int64 (__fastcall *v16)(__int64, __int64, __int64, __int64, __int64, __int64); // r10
__int64 v17; // rcx
unsigned int v18; // r8d
int v19; // edx
__int64 v20; // rsi
__int64 v21; // rdx
unsigned int v22; // esi
unsigned int v23; // edx
__int64 v24; // rcx
_QWORD *v25; // rcx
__int64 v26; // rsi
int v27; // edi
unsigned int v28; // edx
unsigned __int64 v29; // rdi
v2 = (unsigned int *)a1[31];
result = *v2;
v4 = v2 + 1;
a1[31] = (__int64)(v2 + 1);
v5 = *((_DWORD *)a1 + 68);
if ( !v5 )
{
*((_DWORD *)a1 + 68) = result;
return result;
}
v6 = v5 ^ (v5 << 13) ^ ((v5 ^ (unsigned int)(v5 << 13)) >> 17);
v7 = v6 ^ (32 * v6);
*((_DWORD *)a1 + 68) = v7;
result = v7 ^ (unsigned int)result;
v8 = (unsigned int)result >> 29;
if ( (unsigned int)result < 0x20000000 || v8 == 1 && (result & 0x10000000) == 0 )
{
v9 = ((unsigned int)result >> 19) & 0x1F;
if ( (result & 0xE1000000) == 0 || (BYTE3(result) & 1 & (v8 == 1)) != 0 )
{
if ( v8 == 1 || (unsigned int)result >> 25 == 9 || (unsigned int)result >> 25 == 7 )
v10 = result << 50 >> 50;
else
v10 = result & 0x3FFF;
}
else
{
v10 = a1[((unsigned int)result >> 9) & 0x1F];
}
v11 = a1[((unsigned int)result >> 14) & 0x1F];
v12 = (unsigned int)result >> 25;
if ( v8 == 1 )
{
switch ( v12 & 7 )
{
case 0u:
result = v11 == v10;
a1[v9] = result;
break;
case 1u:
result = v11 != v10;
cout << "SETNOTEQ " << std::hex << v11 << " " << std::hex << v10 <<endl;
a1[v9] = result;
break;
case 2u:
result = v11 <= v10;
a1[v9] = result;
break;
case 3u:
result = v11 < v10;
a1[v9] = result;
break;
case 4u:
result = v11 <= (unsigned __int64)v10;
a1[v9] = result;
break;
case 5u:
result = v11 < (unsigned __int64)v10;
a1[v9] = result;
break;
default:
goto LABEL_22;
}
}
else
{
switch ( v12 & 0xF )
{
case 0u:
v13 = v11 | v10;
goto LABEL_40;
case 1u:
v13 = v11 ^ v10;
cout << "XOR " << std::hex << v11 << " " << std::hex << v10 << endl;
goto LABEL_40;
case 2u:
v13 = v11 & v10;
goto LABEL_40;
case 3u:
v13 = v11 + v10;
goto LABEL_40;
case 4u:
v21 = v11 - v10;
goto LABEL_50;
case 5u:
v13 = v11 * v10;
LABEL_40:
result = v13;
a1[v9] = v13;
return result;
case 6u:
result = v11 / (unsigned __int64)v10;
a1[v9] = v11 / (unsigned __int64)v10;
return result;
case 7u:
result = v11 / v10;
a1[v9] = v11 / v10;
return result;
case 8u:
v21 = v11 % (unsigned __int64)v10;
goto LABEL_50;
case 9u:
v21 = v11 % v10;
goto LABEL_50;
case 0xAu:
v21 = v11 << v10;
goto LABEL_50;
case 0xBu:
v21 = v11 >> v10;
goto LABEL_50;
case 0xCu:
v21 = (unsigned __int64)v11 >> v10;
goto LABEL_50;
case 0xDu:
v21 = __ROL8__(v11, v10);
goto LABEL_50;
case 0xEu:
v21 = __ROR8__(v11, v10);
LABEL_50:
result = v21;
a1[v9] = v21;
break;
default:
LABEL_22:
result = 0LL;
a1[v9] = 0LL;
break;
}
}
return result;
}
if ( v8 == 1 )
{
v8 = ((unsigned int)result >> 26) & 3;
if ( v8 == 2 )
{
v15 = ((unsigned int)result >> 20) & 0x1F;
v16 = (__int64 (__fastcall *)(__int64, __int64, __int64, __int64, __int64, __int64))a1[v15];
if ( (unsigned __int64)v16 < a1[32] || (unsigned __int64)v16 >= a1[33] )
{
result = v16(*a1, a1[1], a1[2], a1[3], a1[4], a1[5]);
*a1 = result;
*((_DWORD *)a1 + 68) = v7;
a1[31] = (__int64)v4;
}
else
{
v17 = a1[30];
*(_QWORD *)(v17 - 8) = v7;
*((_DWORD *)a1 + 68) = 0;
*(_QWORD *)(v17 - 16) = a1[31];
result = a1[v15];
a1[31] = result;
a1[30] = v17 - 16;
}
return result;
}
if ( !v8 )
{
v14 = a1[30];
a1[31] = *(_QWORD *)v14;
*((_DWORD *)a1 + 68) = *(_DWORD *)(v14 + 8);
result = v14 + 16;
a1[30] = result;
return result;
}
v18 = v7 ^ (v7 << 13) ^ ((v7 ^ (v7 << 13)) >> 17) ^ (32 * (v7 ^ (v7 << 13) ^ ((v7 ^ (v7 << 13)) >> 17)));
v19 = v18 ^ *v4;
*((_DWORD *)a1 + 68) = v18;
if ( (result & 0x2000000) != 0 )
{
v20 = result << 39 >> 37;
}
else
{
if ( !a1[((unsigned int)result >> 20) & 0x1F] )
{
a1[31] = (__int64)(v2 + 2);
if ( (result & 0x2000000) == 0 )
return result;
goto LABEL_54;
}
v20 = result << 44 >> 42;
}
a1[31] = (__int64)v2 + v20;
*((_DWORD *)a1 + 68) = v19;
if ( (result & 0x2000000) == 0 )
return result;
}
LABEL_54:
if ( v8 == 2 )
{
if ( (((unsigned int)result >> 27) & 3) != 0 )
{
v22 = ((unsigned int)result >> 21) & 0x1F;
v23 = WORD1(result) & 0x1F;
v24 = (unsigned __int16)result - 0x8000LL;
if ( (result & 0x8000u) == 0LL )
v24 = (unsigned __int16)result;
if ( (((unsigned int)result >> 27) & 3) == 1 )
{
result = *(_QWORD *)(a1[v23] + v24);
a1[v22] = result;
}
else
{
switch ( ((unsigned int)result >> 26) & 3 )
{
case 0u:
result = LOBYTE(a1[v22]);
*(_BYTE *)(a1[v23] + v24) = result;
break;
case 1u:
result = LOWORD(a1[v22]);
*(_WORD *)(a1[v23] + v24) = result;
break;
case 2u:
result = LODWORD(a1[v22]);
*(_DWORD *)(a1[v23] + v24) = result;
break;
case 3u:
result = a1[v22];
*(_QWORD *)(a1[v23] + v24) = result;
break;
}
}
}
else
{
result = WORD1(result) & 0x1F;
v25 = (_QWORD *)a1[31];
v26 = *((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13) ^ ((unsigned int)(*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13)) >> 17) ^ (32 * (*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13) ^ ((unsigned int)(*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13)) >> 17)));
v27 = v26 ^ ((*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13) ^ ((unsigned int)(*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13)) >> 17) ^ (32 * (*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13) ^ ((unsigned int)(*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13)) >> 17)))) << 13) ^ (((unsigned int)v26 ^ ((*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13) ^ ((unsigned int)(*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13)) >> 17) ^ (32 * (*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13) ^ ((unsigned int)(*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13)) >> 17)))) << 13)) >> 17);
v28 = v27 ^ (32 * v27);
v29 = *v25 ^ (v26 | ((unsigned __int64)v28 << 32));
*((_DWORD *)a1 + 68) = v28;
a1[31] = (__int64)(v25 + 1);
a1[result] = v29;
printf("speical_load r%d 0x%xn",result,v29);
}
}
return result;
}
__int64 __fastcall VM_2(__int64 *a1) // little no lfsr
{
__int64 result; // rax
unsigned int *v3; // rdx
__int64 v4; // rdi
__int64 v5; // r14
unsigned int v6; // r8d
__int64 v7; // rsi
__int64 v8; // rcx
__int64 v9; // rdx
unsigned int v10; // edi
__int64 v11; // rcx
__int64 *v12; // rax
__int64 v13; // rdi
__int64 (__fastcall *v14)(_QWORD, __int64, __int64, __int64, __int64, __int64, __int64); // r10
__int64 v15; // rax
char v16; // cl
__int64 v17; // rdx
unsigned int v18; // edx
unsigned int v19; // ecx
__int64 *v20; // rax
__int64 v21; // rcx
__int64 v22; // [rsp-8h] [rbp-18h]
v22 = result;
v3 = (unsigned int *)a1[31];
v4 = *v3;
v5 = (__int64)(v3 + 1);
a1[31] = (__int64)(v3 + 1);
v6 = (unsigned int)v4 >> 29;
if ( (unsigned int)v4 < 0x20000000 || v6 == 1 && (result = v4 & 0x10000000, (v4 & 0x10000000) == 0) )
{
v7 = ((unsigned int)v4 >> 19) & 0x1F;
if ( (v4 & 0xE1000000) == 0 || (BYTE3(v4) & 1 & (v6 == 1)) != 0 )
{
if ( v6 == 1 || (unsigned int)v4 >> 25 == 9 || (unsigned int)v4 >> 25 == 7 )
v8 = v4 << 50 >> 50;
else
v8 = v4 & 0x3FFF;
}
else
{
v8 = a1[((unsigned int)v4 >> 9) & 0x1F];
}
printf("r%d=",((unsigned int)v4 >> 19) & 0x1F);
v9 = a1[((unsigned int)v4 >> 14) & 0x1F];
v10 = (unsigned int)v4 >> 25;
if ( v6 == 1 )
{
switch ( v10 & 7 )
{
case 0u:
result = v9 == v8;
printf("SETEQ r%d(%llx) r%d(%llx)n",((unsigned int)v4 >> 14) & 0x1F,a1[0],((unsigned int)v4 >> 9) & 0x1F,a1[1]);
a1[v7] = result;
break;
case 1u:
result = v9 != v8;
cout << "SETNOTEQ " << std::hex << v9 << " " << std::hex << v8 <<endl;
a1[v7] = result;
break;
case 2u:
result = v9 <= v8;
cout << "SETLE " << std::hex << v9 << " " << std::hex << v8 <<endl;
a1[v7] = result;
break;
case 3u:
result = v9 < v8;
cout << "SETL " << std::hex << v9 << " " << std::hex << v8 <<endl;
a1[v7] = result;
break;
case 4u:
result = v9 <= (unsigned __int64)v8;
cout << "SETBE " << std::hex << v9 << " " << std::hex << v8 <<endl;
a1[v7] = result;
break;
case 5u:
result = v9 < (unsigned __int64)v8;
cout << "SETB " << std::hex << v9 << " " << std::hex << v8 <<endl;
a1[v7] = result;
break;
default:
goto LABEL_20;
}
}
else
{
switch ( v10 & 0xF )
{
case 0u:
v11 = v9 | v8;
cout << "OR " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_38;
case 1u:
v11 = v9 ^ v8;
cout << "XOR " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_38;
case 2u:
v11 = v9 & v8;
cout << "AND " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_38;
case 3u:
v11 = v9 + v8;
cout << "ADD " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_38;
case 4u:
v17 = v9 - v8;
cout << "SUB " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_48;
case 5u:
v11 = v9 * v8;
cout << "MUL " << std::hex << v9 << " " << std::hex << v8 << endl;
LABEL_38:
result = v11;
a1[v7] = v11;
return result;
case 6u:
result = v9 / (unsigned __int64)v8;
a1[v7] = v9 / (unsigned __int64)v8;
cout << "DIV " << std::hex << v9 << " " << std::hex << v8 << endl;
return result;
case 7u:
result = v9 / v8;
a1[v7] = v9 / v8;
cout << "iDIV " << std::hex << v9 << " " << std::hex << v8 << endl;
return result;
case 8u:
v17 = v9 % (unsigned __int64)v8;
cout << "MOD " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_48;
case 9u:
v17 = v9 % v8;
cout << "IMOD " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_48;
case 0xAu:
v17 = v9 << v8;
cout << "<< " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_48;
case 0xBu:
v17 = v9 >> v8;
cout << "i>> " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_48;
case 0xCu:
v17 = (unsigned __int64)v9 >> v8;
cout << ">> " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_48;
case 0xDu:
v17 = __ROL8__(v9, v8);
cout << "ROL8 " << std::hex << v9 << " " << std::hex << v8 << endl;
goto LABEL_48;
case 0xEu:
v17 = __ROR8__(v9, v8);
cout << "ROR8 " << std::hex << v9 << " " << std::hex << v8 << endl;
LABEL_48:
result = v17;
a1[v7] = v17;
break;
default:
LABEL_20:
result = 0LL;
a1[v7] = 0LL;
break;
}
}
return result;
}
if ( v6 == 1 )
{
v6 = ((unsigned int)v4 >> 26) & 3;
if ( v6 == 2 )
{
v13 = ((unsigned int)v4 >> 20) & 0x1F;
v14 = (__int64 (__fastcall *)(_QWORD, __int64, __int64, __int64, __int64, __int64, __int64))a1[v13];
if ( (unsigned __int64)v14 < a1[32] || (unsigned __int64)v14 >= a1[33] )
{
result = v14(*a1, a1[1], a1[2], a1[3], a1[4], a1[5], v22);
*a1 = result;
cout << "call_out ";
if((unsigned __int64)v14 == (unsigned __int64)&malloc){
cout << "malloc ";
}
else{
cout << "sub_880 ";
}
cout << "load r0 0x" << std::hex << result << endl;
a1[31] = v5;
}
else
{
cout << "call in" << endl;
v15 = a1[30];
*(_QWORD *)(v15 - 8) = v5;
result = v15 - 8;
a1[31] = a1[v13];
a1[30] = result;
}
return result;
}
if ( !v6 )
{
cout << "ret" << endl;
v12 = (__int64 *)a1[30];
a1[31] = *v12;
result = (__int64)(v12 + 1);
a1[30] = result;
return result;
}
if ( (v4 & 0x2000000) != 0 )
{
cout << "jump" << endl;
result = 37LL;
v16 = 39;
}
else
{
cout << "jcc" << endl;
result = ((unsigned int)v4 >> 20) & 0x1F;
if ( !a1[result] )
goto LABEL_52;
result = 42LL;
v16 = 44;
}
a1[31] = (__int64)v3 + ((__int64)((unsigned __int64)(unsigned int)v4 << v16) >> result);
LABEL_52:
if ( (v4 & 0x2000000) == 0 )
return result;
}
if ( v6 == 2 )
{
if ( (((unsigned int)v4 >> 27) & 3) != 0 )
{
v18 = ((unsigned int)v4 >> 21) & 0x1F;
v19 = WORD1(v4) & 0x1F;
result = (unsigned __int16)v4 - 0x8000LL;
if ( (v4 & 0x8000u) == 0LL )
result = (unsigned __int16)v4;
if ( (((unsigned int)v4 >> 27) & 3) == 1 )
{
printf("load r%d [r%d+0x%x](%llx)n",v18, v19, result,*(_QWORD *)(a1[v19] + result));
result = *(_QWORD *)(a1[v19] + result);
a1[v18] = result;
}
else
{
switch ( ((unsigned int)v4 >> 26) & 3 )
{
case 0u:
printf("stb [r%d(0x%llx) + 0x%x] r%d(0x%x)n",v19,a1[v19],result,v18,a1[v18]);
*(_BYTE *)(a1[v19] + result) = a1[v18];
break;
case 1u:
printf("stw [r%d(0x%llx) + 0x%x] r%d(0x%x)n",v19,a1[v19],result,v18,a1[v18]);
*(_WORD *)(a1[v19] + result) = a1[v18];
break;
case 2u:
printf("stdw [r%d(0x%llx) + 0x%x] r%d(0x%x)n",v19,a1[v19],result,v18,a1[v18]);
*(_DWORD *)(a1[v19] + result) = a1[v18];
break;
case 3u:
printf("stqw [r%d(0x%llx) + 0x%x] r%d(0x%llx)n",v19,a1[v19],result,v18,a1[v18]);
*(_QWORD *)(a1[v19] + result) = a1[v18];
break;
}
}
}
else
{
v20 = (__int64 *)a1[31];
v21 = *v20;
result = (__int64)(v20 + 1);
a1[31] = result;
a1[WORD1(v4) & 0x1F] = v21;
printf("speical_load r%d 0x%llxn",WORD1(v4) & 0x1F,v21);
}
}
return result;
}
__int64 __fastcall VM_3(__int64 *a1) //big lfsr
{
unsigned int *v2; // rcx
unsigned int v3; // eax
unsigned int *v4; // r14
int result; // rax
int v6; // edx
unsigned int v7; // edx
unsigned int v8; // ebp
unsigned int v9; // edi
__int64 v10; // rsi
__int64 v11; // rcx
__int64 v12; // rdx
unsigned int v13; // eax
__int64 v14; // rcx
__int64 v15; // rax
__int64 v16; // rax
__int64 (__fastcall *v17)(__int64, __int64, __int64, __int64, __int64, __int64); // r10
__int64 v18; // rcx
unsigned __int32 v19; // esi
unsigned int v20; // edx
int v21; // edx
__int64 v22; // rsi
__int64 v23; // rdx
unsigned int v24; // esi
unsigned int v25; // edx
__int64 v26; // rcx
unsigned __int64 *v27; // rcx
unsigned __int64 v28; // rdx
__int64 v29; // rdi
unsigned int v30; // esi
__int64 v31; // rsi
v2 = (unsigned int *)a1[31];
v3 = *v2;
v4 = v2 + 1;
a1[31] = (__int64)(v2 + 1);
result = _byteswap_ulong(v3);
v6 = *((_DWORD *)a1 + 68);
if ( !v6 )
{
*((_DWORD *)a1 + 68) = result;
return result;
}
v7 = v6 ^ (v6 << 13) ^ ((v6 ^ (unsigned int)(v6 << 13)) >> 17);
v8 = v7 ^ (32 * v7);
*((_DWORD *)a1 + 68) = v8;
result = v8 ^ (unsigned int)result;
int op = result;
v9 = (unsigned int)result >> 29;
if ( (unsigned int)result < 0x20000000 || v9 == 1 && (result & 0x10000000) == 0 )
{
v10 = ((unsigned int)result >> 19) & 0x1F;
if ( (BYTE3(result) & 1 & (v9 == 1)) != 0 || (result & 0xE1000000) == 0 )
{
if ( v9 == 1 || (unsigned int)result >> 25 == 9 || (unsigned int)result >> 25 == 7 )
v11 = result << 50 >> 50;
else
v11 = result & 0x3FFF;
}
else
{
v11 = a1[((unsigned int)result >> 9) & 0x1F];
}
v12 = a1[((unsigned int)result >> 14) & 0x1F];
v13 = (unsigned int)result >> 25;
if ( v9 == 1 )
{
switch ( v13 & 7 )
{
case 0u:
result = v12 == v11;
a1[v10] = result;
break;
case 1u:
result = v12 != v11;
a1[v10] = result;
break;
case 2u:
result = v12 <= v11;
a1[v10] = result;
break;
case 3u:
result = v12 < v11;
a1[v10] = result;
break;
case 4u:
result = v12 <= (unsigned __int64)v11;
a1[v10] = result;
break;
case 5u:
result = v12 < (unsigned __int64)v11;
a1[v10] = result;
break;
default:
LABEL_22:
result = 0LL;
a1[v10] = 0LL;
break;
}
}
else
{
switch ( v13 & 0xF )
{
case 0u:
v14 = v12 | v11;
cout << "OR " << std::hex << v12 << " " << std::hex << v11 << endl;
goto LABEL_40;
case 1u:
v14 = v12 ^ v11;
cout << "XOR " << std::hex << v12 << " " << std::hex << v11 << endl;
goto LABEL_40;
case 2u:
v14 = v12 & v11;
goto LABEL_40;
case 3u:
v14 = v12 + v11;
goto LABEL_40;
case 4u:
v23 = v12 - v11;
goto LABEL_50;
case 5u:
v14 = v12 * v11;
LABEL_40:
result = v14;
a1[v10] = v14;
return result;
case 6u:
result = v12 / (unsigned __int64)v11;
a1[v10] = v12 / (unsigned __int64)v11;
return result;
case 7u:
result = v12 / v11;
a1[v10] = v12 / v11;
return result;
case 8u:
v23 = v12 % (unsigned __int64)v11;
goto LABEL_50;
case 9u:
v23 = v12 % v11;
goto LABEL_50;
case 0xAu:
v23 = v12 << v11;
goto LABEL_50;
case 0xBu:
v23 = v12 >> v11;
goto LABEL_50;
case 0xCu:
v23 = (unsigned __int64)v12 >> v11;
goto LABEL_50;
case 0xDu:
v23 = __ROL8__(v12, v11);
goto LABEL_50;
case 0xEu:
v23 = __ROR8__(v12, v11);
LABEL_50:
result = v23;
a1[v10] = v23;
break;
default:
goto LABEL_22;
}
}
return result;
}
if ( v9 == 1 )
{
v9 = ((unsigned int)result >> 26) & 3;
if ( v9 == 2 )
{
v16 = ((unsigned int)result >> 20) & 0x1F;
v17 = (__int64 (__fastcall *)(__int64, __int64, __int64, __int64, __int64, __int64))a1[v16];
if ( (unsigned __int64)v17 < a1[32] || (unsigned __int64)v17 >= a1[33] )
{
result = v17(*a1, a1[1], a1[2], a1[3], a1[4], a1[5]);
*a1 = result;
*((_DWORD *)a1 + 68) = v8;
a1[31] = (__int64)v4;
}
else
{
v18 = a1[30];
*(_QWORD *)(v18 - 8) = v8;
*((_DWORD *)a1 + 68) = 0;
*(_QWORD *)(v18 - 16) = a1[31];
result = a1[v16];
a1[31] = result;
a1[30] = v18 - 16;
}
return result;
}
if ( !v9 )
{
v15 = a1[30];
a1[31] = *(_QWORD *)v15;
*((_DWORD *)a1 + 68) = *(_DWORD *)(v15 + 8);
result = v15 + 16;
a1[30] = result;
return result;
}
v19 = _byteswap_ulong(*v4);
v20 = v8 ^ (v8 << 13) ^ ((v8 ^ (v8 << 13)) >> 17) ^ (32 * (v8 ^ (v8 << 13) ^ ((v8 ^ (v8 << 13)) >> 17)));
*((_DWORD *)a1 + 68) = v20;
v21 = v19 ^ v20;
if ( (result & 0x2000000) != 0 )
{
v22 = result << 39 >> 37;
}
else
{
if ( !a1[((unsigned int)result >> 20) & 0x1F] )
{
a1[31] = (__int64)(v2 + 2);
if ( (result & 0x2000000) == 0 )
return result;
goto LABEL_54;
}
v22 = result << 44 >> 42;
}
a1[31] = (__int64)v2 + v22;
*((_DWORD *)a1 + 68) = v21;
if ( (result & 0x2000000) == 0 )
return result;
}
LABEL_54:
if ( v9 == 2 )
{
if ( (((unsigned int)result >> 27) & 3) != 0 )
{
v24 = ((unsigned int)result >> 21) & 0x1F;
v25 = WORD1(result) & 0x1F;
v26 = (unsigned __int16)result - 0x8000LL;
if ( (result & 0x8000u) == 0LL )
v26 = (unsigned __int16)result;
if ( (((unsigned int)result >> 27) & 3) == 1 )
{
result = *(_QWORD *)(a1[v25] + v26);
a1[v24] = result;
}
else
{
switch ( ((unsigned int)result >> 26) & 3 )
{
case 0u:
result = LOBYTE(a1[v24]);
// printf("stb [r%d(0x%llx) + 0x%x] %dn",v25,a1[v25],v26,result);
*(_BYTE *)(a1[v25] + v26) = result;
lut[v26] = result;
break;
case 1u:
result = LOWORD(a1[v24]);
*(_WORD *)(a1[v25] + v26) = result;
break;
case 2u:
result = LODWORD(a1[v24]);
// printf("stb [r%d(0x%llx) + 0x%x] %dn",v25,a1[v25],v26,result);
*(_DWORD *)(a1[v25] + v26) = result;
break;
case 3u:
result = a1[v24];
*(_QWORD *)(a1[v25] + v26) = result;
break;
}
}
}
else
{
v27 = (unsigned __int64 *)a1[31];
v28 = _byteswap_uint64(*v27);
result = WORD1(result) & 0x1F;
v29 = *((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13) ^ ((unsigned int)(*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13)) >> 17) ^ (32 * (*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13) ^ ((unsigned int)(*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13)) >> 17)));
v30 = v29 ^ ((*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13) ^ ((unsigned int)(*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13)) >> 17) ^ (32 * (*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13) ^ ((unsigned int)(*((_DWORD *)a1 + 68) ^ (*((_DWORD *)a1 + 68) << 13)) >> 17)))) << 13);
v31 = v30 ^ (v30 >> 17) ^ (32 * (v30 ^ (v30 >> 17)));
*((_DWORD *)a1 + 68) = v31;
a1[31] = (__int64)(v27 + 1);
a1[result] = v28 ^ ((v29 << 32) | v31);
}
}
return result;
}
uint64_t *VM_context[35] = {};
// uint32_t vm_op[] ={1976427875, 1351343259, 1612664318, 2433205737, 3046975632, 626481909, 3975013335, 1283834271, 383842469, 2798764607, 3696776187, 4170144409, 3927840730, 140005937, 296365805, 3006110615, 114327633, 907844063, 3022702211, 2094777016, 380884373, 2122175971, 4071574588, 3938022081, 1291573375, 2485753974, 1637416006, 4225852075, 2071585308, 2944719709, 1829101233, 1110572158, 1226074819, 3195242372, 3700808210, 2358660209, 773180593, 1613267327, 3521386025, 3193100902, 3286298012, 125790494, 3739056418, 868714240, 449803732, 1162871038, 3284082516, 1132005886, 219434964, 3270653390, 2439627356, 2288841484, 2833712748, 3361731726, 24685703, 212809789, 1942064915, 1678065084, 2333851310, 3395827190, 2523335453, 2394389613, 4165418664, 2903638873, 2164667506, 1851059343, 3730292360, 2165542698, 751933430, 3570644408, 3807533179, 3001106151, 2765902712, 15013466, 3163343218, 1901037579, 2067435631, 2686188370, 102989091, 449875783, 3845053741, 3789950633, 1049668332, 3217047880, 3254166107, 2081737864, 1762950497, 3288320157, 2445723366, 3485236189, 2829750486, 1316492443, 1828739766, 1216936220, 102664883, 860567771, 666288825, 2690740270, 3401968968, 3296031195, 2576567149, 1404238554, 2460817723, 1316752377, 1142163556, 634933654, 4139592741, 3944930753, 4201007861, 2565907881, 3515769792, 509629095, 1914959267, 3413268951, 3866941944, 2570884892, 130754488, 3476344395, 2941373444, 954938226, 3115950279, 1910313443, 3539974380, 1152694459, 161957162, 2027389803, 3256243228, 2202601580, 350258403, 420305581, 4158379088, 4147748253, 3782528332, 415810441, 3851463627, 1900178605, 1706351520, 12261950, 710745188, 1618400571, 3758136596, 3588723718, 4019777524, 5730523, 2711857345, 1593930573, 1238076068, 1565171299, 1746162131, 3076237801, 3529845435, 614467621, 4127683123, 2985137187, 712499802, 2258687668, 4011166297, 2007954013, 2461237807, 4051514471, 3788240089, 3981309296, 2155578576, 4274358913, 1044119006, 1797312874, 471180725, 2668645079, 2959703070, 1449104858, 1351292286, 1380416001, 1017187931, 2488176202, 1607611593, 2568349725, 269334228, 1322262420, 640788365, 854822713, 3479197977, 336484541, 301774093, 3685430230, 3430961642, 3294824626, 572559954, 3106371047, 3554052626, 2863905378, 1451040142, 2715236917, 1748692918, 815704389, 1245897369, 3529752260, 679872560, 1370670363, 3128954428, 194210382, 4215132095, 726643573, 2759775927, 1682022233, 1696861348, 1056704786, 623808445, 1817613680, 1538512307, 304297361, 1635128254, 3900760555, 1476473223, 1018071399, 3189200443, 1836668397, 1960361774, 2710665026, 2884304536, 2635971280, 1561188051, 799781246, 92290065, 955077766, 3321361990, 3940059321, 1156565456, 4114932330, 1786488397, 3365007865, 1100625809, 936833548, 2979980210, 4229890500, 533880377, 925117089, 1826796659, 2547436593, 2610515177, 754195478, 2428611002, 108115699, 3195984300, 4279480768, 1152860825, 1863578395, 146548328, 1840985960, 370213461, 3867179729, 2930101134, 1122732950, 1385093301, 588295429, 1261484657, 1455895265, 1353137825, 1067233262, 1297469336, 1443126045, 1939277798, 633014186, 3830243538, 775906197, 3793847937, 2900344786, 1930660129, 3339283805, 1461562198, 3800375221, 1034336979, 2989177160, 2045478884, 1530852102, 551868518, 833271568, 1348848761, 667249786, 2936189850, 285406341, 1116977808, 3978840504, 3068398612, 718431417, 2728910183, 921714326, 3769690485, 1535139857, 3798540057, 1855735377, 3013788154, 4197447741, 707913497, 3179598374, 2522184863, 3887899534, 1106283519, 3830502288, 3445392769, 730899274, 390027277, 1329558143, 275693576, 3916701319, 1213562715, 1448912296, 4146302020, 615974141, 2100384564, 1655463229, 3594536881, 2283379794, 2546644164, 3034885571, 277358008, 3980187918, 2103533347, 3054831619, 3402918421, 2752064401, 3307441361, 2350121419, 3535283195, 254933546, 203278039, 4077109433, 4211117231, 1874972668, 62911161, 599812366, 1510336986, 2602272400, 855339023, 2378668339, 931522116, 2691745340, 1420807049, 2708482394, 2332824275, 3707675361, 2761457235, 651371181, 429313852, 1471549740, 3542725217, 3599514006, 2385987184, 2979421507, 3056159203, 2380437801, 1349115791, 4165110556, 2329890254, 3592472800, 945181790, 3006540133, 1383837718, 1867099648, 2322736858, 3921766584, 3532443784, 2518731666, 1166480143, 2792859296, 3602109062, 4002587877, 1254091688, 3571947805, 1441661741, 1582185579, 670679198, 891293598, 947512857, 2600189485, 3444708488, 2623533162, 1763844706, 3636180936, 3464387303, 1056783259, 2125213268, 2455875221, 1332525393, 1319767510, 2411771964, 1868983187, 1621258024, 2646446968, 685295305, 3778207848, 1809969305, 3080879647, 3548738700, 962705829, 421938331, 2085543119, 523486628, 1215521652, 2034761339, 3461503728, 2471650520, 1192339508, 3818188999, 333418330, 3085733036, 1150209842, 3197148033, 2995955619, 3877787727, 1123794442, 1727832910, 4211330100, 208769819, 3649236463, 3104632734, 1657641648, 2775384300, 2690320885, 3231005233, 2166903089, 2140359358, 1043298635, 3914777503, 1640666740, 2636542005, 2417480486, 1380143074, 1173041005, 3097732539, 623693782, 2978779769, 443041291, 2946671661, 2844290215, 4220230618, 1503471348, 665683958, 3134492485, 2009290111, 3426629379, 534377307, 518299929, 2198340002, 1834404033, 1065468552, 4092711909, 764324806, 2901802363, 2452610125, 2712933359, 694886536, 1271040013, 1862142351, 3299906953, 1975076334, 1001504596, 2484425936, 2679339055, 2401030456, 1611021906, 1085535213, 4147039947, 3584583917, 383184342, 3249397962, 507169557, 35340291, 1450476838, 3840114600, 1602399221, 1089751835, 2145786364, 4041202427, 4109495431, 2527477250, 1560142377, 1837578652, 1808661526, 1299374663, 986565150, 3329195914, 1234758580, 2347279129, 3226408400, 2283658599, 3054740073, 1395572083, 3333841720, 1249219001, 656682067, 266554370, 2568096635, 485770513, 1349780853, 3078283914, 3799628881, 4280716332, 1633676419, 1830263082, 3381782820, 754256877, 2155187655, 1873190764, 2284714928, 3170428765, 3709621214, 122043686, 1494935408, 1568900548, 4113005769, 517960156, 2779759669, 3997109150, 1983003883, 2389480438, 2535771608, 672561366, 2033616224, 2042009132, 3037516435, 3225373369, 2209908234, 226424653, 3288949959, 1603318959, 1724629419, 2951514084, 912198427, 1471589204, 2507804994, 38149107, 3992306371, 2279069712, 213979244, 3277221841, 4090877293, 2201702145, 132699456, 427025349, 3966146747, 585410742, 1336227915, 2310964976, 413787785, 3256452950, 1968866743, 4000753537, 1444861975, 2705673868, 3516843675, 1131836880, 3514215189, 2807317813, 631444731, 1758503386, 645321110, 1389336314, 284431831, 3618102503, 719646775, 2545039835, 304479513, 4213119349, 2305190346, 154682538, 2812761913, 1482546777, 631844162, 4054050127, 1164531181, 3989276939, 3263324551, 1370503188, 2693784221, 352106250, 786440075, 2429447376, 2022937001, 1607349664, 4148609264, 1153818047, 3970449212, 1218584233, 4097117707, 418894655, 2081597627, 2767007972, 3605553748, 3099373403, 3291767689, 393889897, 952465676, 1206685658, 2883904375, 3642302740, 3119229219, 3726804543, 1548873331, 2523391537, 2557398516, 1473029336, 1019096754, 2432653575, 3509505769, 1728861234, 2471189853, 2431092479, 1526585802, 3346184365, 536927635, 3168541128, 2604483109, 2085935216, 1082083765, 4155611789, 95955942, 3667132573, 1086915312, 3736694213, 4111004249, 3398619340, 2553566595, 928751317, 2339079072, 460666010, 80584458, 491019742, 2456251340, 369776954, 3540814068, 3887147804, 3434058825, 3001551096, 2292526794, 607773318, 2276948120, 247335351, 2697667605, 3708134991, 2482947853, 898780984, 1988741127, 1938251904, 337591520, 401067696, 3240706405, 3831635463, 1161394882, 121646438, 2585624199, 1788675476, 3729774771, 1149066903, 2899232714, 3870573595, 3928339543, 3829877435, 1396804105, 1892179772, 2024212238, 1112390287, 245347464, 1959506234, 1531925529, 1245788559, 724758985, 2244370256, 574368177, 1977157958, 123223131, 845450955, 758150329, 895304849, 3304635462, 3591885291, 678196720};
uint32_t vm_op[] = {1976427875, 1351343259, 1612664318, 2433205737, 3046975632, 626481909, 3975013335, 1283834271, 383842469, 2798764607, 3696776187, 4170144409, 3927840730, 140005937, 296365805, 3006110615, 114327633, 907844063, 3022702211, 2094777016, 380884373, 2122175971, 4071574588, 3938022081, 1291573375, 2485753974, 1637416006, 4225852075, 2071585308, 2944719709, 1829101233, 1110572158, 1226074819, 3195242372, 3700808210, 2358660209, 773180593, 1613267327, 3521386025, 3193100902, 3286298012, 125790494, 3739056418, 868714240, 449803732, 1162871038, 3284082516, 1132005886, 219434964, 3270653390, 2439627356, 2288841484, 2833712748, 3361731726, 24685703, 212809789, 1942064915, 1678065084, 2333851310, 3395827190, 2523335453, 2394389613, 4165418664, 2903638873, 2164667506, 1851059343, 3730292360, 2165542698, 751933430, 3570644408, 3807533179, 3001106151, 2765902712, 15013466, 3163343218, 1901037579, 2067435631, 2686188370, 102989091, 449875783, 3845053741, 3789950633, 1049668332, 3217047880, 3254166107, 2081737864, 1762950497, 3288320157, 2445723366, 3485236189, 2829750486, 1316492443, 1828739766, 1216936220, 102664883, 860567771, 666288825, 2690740270, 3401968968, 3296031195, 2576567149, 1404238554, 2460817723, 1316752377, 1142163556, 634933654, 4139592741, 3944930753, 4201007861, 2565907881, 3515769792, 509629095, 1914959267, 3413268951, 3866941944, 2570884892, 130754488, 3476344395, 2941373444, 954938226, 3115950279, 1910313443, 3539974380, 1152694459, 161957162, 2027389803, 3256243228, 2202601580, 350258403, 420305581, 4158379088, 4147748253, 3782528332, 415810441, 3851463627, 1900178605, 1706351520, 12261950, 710745188, 1618400571, 3758136596, 3588723718, 4019777524, 5730523, 2711857345, 1593930573, 1238076068, 1565171299, 1746162131, 3076237801, 3529845435, 614467621, 4127683123, 2985137187, 712499802, 2258687668, 4011166297, 2007954013, 2461237807, 4051514471, 3788240089, 3981309296, 2155578576, 4274358913, 1044119006, 1797312874, 471180725, 2668645079, 2959703070, 1449104858, 1351292286, 1380416001, 1017187931, 2488176202, 1607611593, 2568349725, 269334228, 1322262420, 640788365, 854822713, 3479197977, 336484541, 301774093, 3685430230, 3430961642, 3294824626, 572559954, 3106371047, 3554052626, 2863905378, 1451040142, 2715236917, 1748692918, 815704389, 1245897369, 3529752260, 679872560, 1370670363, 3128954428, 194210382, 4215132095, 726643573, 2759775927, 1682022233, 1696861348, 1056704786, 623808445, 1817613680, 1538512307, 304297361, 1635128254, 3900760555, 1476473223, 1018071399, 3189200443, 1836668397, 1960361774, 2710665026, 2884304536, 2635971280, 1561188051, 799781246, 92290065, 955077766, 3321361990, 3940059321, 1156565456, 4114932330, 1786488397, 3365007865, 1100625809, 936833548, 2979980210, 4229890500, 533880377, 925117089, 1826796659, 2547436593, 2610515177, 754195478, 2428611002, 108115699, 3195984300, 4279480768, 1152860825, 1863578395, 146548328, 1840985960, 370213461, 3867179729, 2930101134, 1122732950, 1385093301, 588295429, 1261484657, 1455895265, 1353137825, 1067233262, 1297469336, 1443126045, 1939277798, 633014186, 3830243538, 775906197, 3793847937, 2900344786, 1930660129, 3339283805, 1461562198, 3800375221, 1034336979, 2989177160, 2045478884, 1530852102, 551868518, 833271568, 1348848761, 667249786, 2936189850, 285406341, 1116977808, 3978840504, 3068398612, 718431417, 2728910183, 921714326, 3769690485, 1535139857, 3798540057, 1855735377, 3013788154, 4197447741, 707913497, 3179598374, 2522184863, 3887899534, 1106283519, 3830502288, 3445392769, 730899274, 390027277, 1329558143, 275693576, 3916701319, 1213562715, 1448912296, 4146302020, 615974141, 2100384564, 1655463229, 3594536881, 2283379794, 2546644164, 3034885571, 277358008, 3980187918, 2103533347, 3054831619, 3402918421, 2752064401, 3307441361, 2350121419, 3535283195, 254933546, 203278039, 4077109433, 4211117231, 1874972668, 62911161, 599812366, 1510336986, 2602272400, 855339023, 2378668339, 931522116, 2691745340, 1420807049, 2708482394, 2332824275, 3707675361, 2761457235, 651371181, 429313852, 1471549740, 3542725217, 3599514006, 2385987184, 2979421507, 3056159203, 2380437801, 1349115791, 4165110556, 2329890254, 3592472800, 945181790, 3006540133, 1383837718, 1867099648, 2322736858, 3921766584, 3532443784, 2518731666, 1166480143, 2792859296, 3602109062, 4002587877, 1254091688, 3571947805, 1441661741, 1582185579, 670679198, 891293598, 947512857, 2600189485, 3444708488, 2623533162, 1763844706, 3636180936, 3464387303, 1056783259, 2125213268, 2455875221, 1332525393, 1319767510, 2411771964, 1868983187, 1621258024, 2646446968, 685295305, 3778207848, 1809969305, 3080879647, 3548738700, 962705829, 421938331, 2085543119, 523486628, 1215521652, 2034761339, 3461503728, 2471650520, 1192339508, 3818188999, 333418330, 3085733036, 1150209842, 3197148033, 2995955619, 3877787727, 1123794442, 1727832910, 4211330100, 208769819, 3649236463, 3104632734, 1657641648, 2775384300, 2690320885, 3231005233, 2166903089, 2140359358, 1043298635, 3914777503, 1640666740, 2636542005, 2417480486, 1380143074, 1173041005, 3097732539, 623693782, 2978779769, 443041291, 2946671661, 2844290215, 4220230618, 1503471348, 665683958, 3134492485, 2009290111, 3426629379, 534377307, 518299929, 2198340002, 1834404033, 1065468552, 4092711909, 764324806, 2901802363, 2452610125, 2712933359, 694886536, 1271040013, 1862142351, 3299906953, 1975076334, 1001504596, 2484425936, 2679339055, 2401030456, 1611021906, 1085535213, 4147039947, 3584583917, 383184342, 3249397962, 507169557, 35340291, 1450476838, 3840114600, 1602399221, 1089751835, 2145786364, 4041202427, 4109495431, 2527477250, 1560142377, 1837578652, 1808661526, 1299374663, 986565150, 3329195914, 1234758580, 2347279129, 3226408400, 2283658599, 3054740073, 1395572083, 3333841720, 1249219001, 656682067, 266554370, 2568096635, 485770513, 1349780853, 3078283914, 3799628881, 4280716332, 1633676419, 1830263082, 3381782820, 754256877, 2155187655, 1873190764, 2284714928, 3170428765, 3709621214, 122043686, 1494935408, 1568900548, 4113005769, 517960156, 2779759669, 3997109150, 1983003883, 2389480438, 2535771608, 672561366, 2033616224, 2042009132, 3037516435, 3225373369, 2209908234, 226424653, 3288949959, 1603318959, 1724629419, 2951514084, 912198427, 1471589204, 2507804994, 38149107, 3992306371, 2279069712, 213979244, 3277221841, 4090877293, 2201702145, 132699456, 427025349, 3966146747, 585410742, 1336227915, 2310964976, 413787785, 3256452950, 1968866743, 4000753537, 1444861975, 2705673868, 3516843675, 1131836880, 3514215189, 2807317813, 631444731, 1758503386, 645321110, 1389336314, 284431831, 3618102503, 719646775, 2545039835, 304479513, 4213119349, 2305190346, 154682538, 2812761913, 1482546777, 631844162, 4054050127, 1164531181, 3989276939, 3263324551, 1370503188, 2693784221, 352106250, 786440075, 2429447376, 2022937001, 1607349664, 4148609264, 1153818047, 3970449212, 1218584233, 4097117707, 418894655, 2081597627, 2767007972, 3605553748, 3099373403, 3291767689, 393889897, 952465676, 1206685658, 2883904375, 3642302740, 3119229219, 3726804543, 1548873331, 2523391537, 2557398516, 1473029336, 1019096754, 2432653575, 3509505769, 1728861234, 2471189853, 2431092479, 1526585802, 3346184365, 536927635, 3168541128, 2604483109, 2085935216, 1082083765, 4155611789, 95955942, 3667132573, 1086915312, 3736694213, 4111004249, 3398619340, 2553566595, 928751317, 2339079072, 460666010, 80584458, 491019742, 2456251340, 369776954, 3540814068, 3887147804, 3434058825, 3001551096, 2292526794, 607773318, 2276948120, 247335351, 2697667605, 3708134991, 2482947853, 898780984, 1988741127, 1938251904, 337591520, 401067696, 3240706405, 3831635463, 1161394882, 121646438, 2585624199, 1788675476, 3729774771, 1149066903, 2899232714, 3870573595, 3928339543, 3829877435, 1396804105, 1892179772, 2024212238, 1112390287, 245347464, 1959506234, 1531925529, 1245788559, 724758985, 2244370256, 574368177, 1977157958, 123223131, 845450955, 758150329, 895304849, 3304635462, 3591885291, 678196720};
uint8_t input[0x12] = { 0x11, //0
0x42, //1
0x43, //2
0x44, //3
0x45, //4
0x46, //5
0x47, //6
0x48, //7
0x49, //8
0x4a, //9
0x4b, //0xa
0x4c, //0xb
0x4d, //0xc
0x4e, //0xd
0x4f, //0xe
0x50, //0xf
0x51, //0x10
0x52 //0x11
};
uint64_t do_vm2(int start, uint64_t count, ...);
uint64_t __fastcall sub_555555555880(__int64 *a1)
{
__int64 v2; // rdi
__int64 v4; // rbx
__int64 v5; // rax
int v6; // ecx
__int64 v7; // rdi
if ( *(_DWORD *)a1 == 4 )
{
v2 = 76LL;
cout << "call 4" << endl;
return do_vm2(v2, 1uLL, a1);
}
if ( *(_DWORD *)a1 == 3 )
{
v2 = 60LL;
cout << "call 3" << endl;
return do_vm2(v2, 1uLL, a1);
}
v4 = sub_555555555880((__int64 *)a1[1]);
v5 = sub_555555555880((__int64 *)a1[2]);
v6 = *(_DWORD *)a1;
if ( *(_DWORD *)a1 == 2 )
{
v7 = 16LL;
cout << "call 2" << endl;
return do_vm2(v7, 2uLL, v4, v5);
}
if ( v6 == 1 ){
cout << "call 1" << endl;
return do_vm2(0LL, 2uLL, v4, v5);
}
if ( !v6 )
{
v7 = 40LL;
cout << "call 0" << endl;
return do_vm2(v7, 2uLL, v4, v5);
}
return 0LL;
}
int once = 1;
uint64_t do_vm2(int start, uint64_t count, ...){
uint64_t **arr = VM_context;
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; ++i) {
arr[i] = (uint64_t *)va_arg(args, uint64_t);
}
va_end(args);
if(once){
arr[30] = (uint64_t *)operator new[](0x2000uLL) + 0x2000LL;
arr[32] = (uint64_t *)vm_op;
arr[33] = (uint64_t *)vm_op+sizeof(vm_op);
arr[0] = (uint64_t *)input;
arr[1] = (uint64_t *)0x12;
_QWORD * v6 = (_QWORD *)arr[32];
*(_QWORD *)((char *)v6 + 84) ^= (unsigned __int64)(v6 + 292);
v6[16] ^= (unsigned __int64)(v6 + 293);
*(_QWORD *)((char *)v6 + 244) ^= (unsigned __int64)(v6 + 293);
*(_QWORD *)((char *)v6 + 260) ^= (unsigned __int64)(v6 + 292);
*(_QWORD *)((char *)v6 + 324) ^= (unsigned __int64)&malloc;
v6[281] ^= (unsigned __int64)sub_555555555880;
once = 0;
}
uint64_t * old_rsp = arr[30];
uint64_t * rsp = old_rsp;
*(rsp-1) = 0x13371337;
arr[30]--;
arr[31] = (uint64_t *)&vm_op[start/4];
while(arr[31] != (uint64_t *)0x13371337){
VM_2((int64_t *)arr);
}
arr[30] = old_rsp;
return (uint64_t)arr[0];
}
int main(){
uint64_t **arr = VM_context;
arr[30] = (uint64_t *)operator new[](0x2000uLL) + 0x2000LL;
arr[32] = (uint64_t *)vm_op;
arr[33] = (uint64_t *)vm_op+sizeof(vm_op);
arr[0] = (uint64_t *)input;
arr[1] = (uint64_t *)0x12;
uint64_t * old_rsp = arr[30];
uint64_t * rsp = old_rsp;
*(rsp-1) = 0x13371337;
arr[30]--;
arr[31] = (uint64_t *)&vm_op[0];
arr[34] = 0;
while(arr[31] != (uint64_t *)0x13371337){
VM_3((int64_t *)arr);
}
arr[30] = old_rsp;
return (uint64_t)arr[0];
}
三
pyda 侧信道
from pyda import *
from pwnlib.elf.elf import ELF
from pwnlib.util.packing import u64, u32
import string
import sys
import subprocess
from collections import defaultdict
p = process()
e = ELF(p.exe_path)
e.address = p.maps[p.exe_path].base
plt_map = { e.plt[x]: x for x in e.plt }
def get_cmp(proc):
p = subprocess.run(f"objdump -M intel -d {proc.exe_path} | grep cmp", shell=True, capture_output=True)
output = p.stdout.decode()
cmp_locs = {}
for l in output.split("n"):
if len(l) <= 1:
continue
# TODO: memory cmp
if "QWORD PTR" in l:
continue
if ":t" not in l:
continue
cmp_locs[int(l.split(":")[0].strip(), 16)] = l.split()[-1]
return cmp_locs
def get_xor(proc):
p = subprocess.run(f"objdump -M intel -d {proc.exe_path} | grep xor", shell=True, capture_output=True)
output = p.stdout.decode()
xor_locs = {}
for l in output.split("n"):
if len(l) <= 1:
continue
# TODO: memory cmp
if "QWORD PTR" in l:
continue
if ":t" not in l:
continue
xor_locs[int(l.split(":")[0].strip(), 16)] = l.split()[-1]
return xor_locs
cmp_locs_unfiltered = get_cmp(p)
xor_locs_unfiltered = get_xor(p)
cmp_locs = {}
for (a, v) in cmp_locs_unfiltered.items():
info = v.split(",")
if len(info) != 2:
continue
if "[" in info[0] or "[" in info[1]:
continue
if "0x" in info[0] or "0x" in info[1]:
continue
cmp_locs[a] = info
print(f"cmp_locs: {len(cmp_locs)}")
xor_locs = {}
for (a, v) in xor_locs_unfiltered.items():
info = v.split(",")
if len(info) != 2:
continue
if "[" in info[0] or "[" in info[1]:
continue
if "0x" in info[0] or "0x" in info[1]:
continue
xor_locs[a] = info
print(f"xor_locs: {len(xor_locs)}")
eq_count = 0
neq_count = 0
reg_map = {
"eax": "rax",
"ebx": "rbx",
"ecx": "rcx",
"edx": "rdx",
"esi": "rsi",
"edi": "rdi",
"ebp": "rbp",
"esp": "rsp",
"r8d": "r8",
}
counts_by_pc = defaultdict(int)
good_cmps = defaultdict(int)
good_xors = defaultdict(int)
def cmp_hook(p):
global eq_count, neq_count
info = cmp_locs[p.regs.pc - e.address]
counts_by_pc[p.regs.pc - e.address] += 1
reg1 = reg_map.get(info[0], info[0])
reg2 = reg_map.get(info[1], info[1])
r1 = p.regs[reg1]
r2 = p.regs[reg2]
eq = r1 == r2
if eq:
eq_count += 1
else:
neq_count += 1
print(f"cmp @ {hex(p.regs.rip - e.address)} {reg1}={hex(r1)} {reg2}={hex(r2)} {eq}")
for x in cmp_locs:
p.hook(e.address + x, cmp_hook)
def xor_hook(p):
info = xor_locs[p.regs.pc - e.address]
counts_by_pc[p.regs.pc - e.address] += 1
reg1 = reg_map.get(info[0], info[0])
reg2 = reg_map.get(info[1], info[1])
r1 = p.regs[reg1]
r2 = p.regs[reg2]
print(f"xor @ {hex(p.regs.rip - e.address)} {reg1}={hex(r1)} {reg2}={hex(r2)} ")
for x in xor_locs:
p.hook(e.address + x, xor_hook)
p.run()
import subprocess
import copy
solutions = []
solved_chk = []
def extract_byte(n, byte_index):
return (n >> (byte_index * 8)) & 0xFF
def solve(chunk_index):
try:
flag = [i+0x41 for i in range(0x12)]
i = 0
pre_last_cmp_false = ''
while i < 0x12:
no_xor = False
check_flag = 0
input = ''
for num in flag:
input += str(hex(num)[2:]).rjust(2,'0')
cmd = [
"pyda",
"examples/xor_cmplog.py",
"--",
f"chall/chk{chunk_index}.bin",
f'{input}'
]
with open("trace.txt",'w') as f:
p = subprocess.run(cmd,stdout=f,timeout=5)
with open('trace.txt','r') as f:
read_lines = f.readlines()
p = subprocess.run([ f"chall/chk{chunk_index}.bin",
f'{input}'])
if p.returncode == 0:
break
maybe_flag = [i+0x41 for i in range(0x12)]
last_cmp_false = 0
for index,line in enumerate(read_lines):
# print(line)
if line.startswith("cmp @") :
if line.endswith("Falsen"):
last_cmp_false = index
val = int(read_lines[last_cmp_false].split(" ")[3].split("=")[1],16)
if val >= 0x41 and val <= 0x52:
tar = int(read_lines[last_cmp_false].split(" ")[4].split("=")[1],16)
maybe_flag[val - 0x41] = tar
# if chunk_index == 9:
print("index:",i)
last_cmp_false_left_val = int(read_lines[last_cmp_false].split(" ")[3].split("=")[1],16)
right_cmp_false_right_val = int(read_lines[last_cmp_false].split(" ")[4].split("=")[1],16)
if last_cmp_false_left_val <= 0x12 and right_cmp_false_right_val == 0x12: # tree call
# print(flag)
res = ''
for num in maybe_flag:
res += str(hex(num)[2:]).rjust(2,'0')
p = subprocess.run([ f"chall/chk{chunk_index}.bin",
f'{res}'])
if p.returncode == 0:
print(f"{chunk_index} solved")
solved_chk.append(chunk_index)
solutions.append(flag)
print(res)
return
else:
print(f'{chunk_index} unsolved')
exit()
else:
if check_flag == 0:
op1 = read_lines[last_cmp_false-1].split(" ")[0]
op2 = read_lines[last_cmp_false-2].split(" ")[0]
op3 = read_lines[last_cmp_false-3].split(" ")[0]
op4 = read_lines[last_cmp_false-4].split(" ")[0]
op5 = read_lines[last_cmp_false-5].split(" ")[0]
op6 = read_lines[last_cmp_false-6].split(" ")[0]
if op1 == 'xor' and op2 == 'cmp':
check_flag = 3
elif op1 == 'xor' and op2 == 'xor' and op3 == 'cmp':
check_flag = 1
elif op1 == "xor" and op2 == 'xor' and op3 == 'xor' and op4 == 'xor' and op4 == 'xor'and op5 == 'xor' and op6 == 'xor':
check_flag = 2
if check_flag == 1:
print("case 1")
print(read_lines[last_cmp_false-2].split(" "))
print(read_lines[last_cmp_false].split(" "))
left = int(read_lines[last_cmp_false].split(" ")[3].split("=")[1],16)
right = int(read_lines[last_cmp_false].split(" ")[4].split("=")[1],16)
replace_index = int(read_lines[last_cmp_false-2].split(" ")[4].split("=")[1],16)
xor_val = int(read_lines[last_cmp_false-2].split(" ")[3].split("=")[1],16)
xord_flag_val = left if replace_index ^ xor_val == right else right
while replace_index!=0:
val = xord_flag_val & 0xff
index = (replace_index & 0xff) - 0x41
xval = xor_val & 0xff
print(hex(index),hex(val),hex(xval),hex(val ^ xval))
flag[index] = val ^ xval
i = i + 1
replace_index = replace_index >> 8
xord_flag_val = xord_flag_val >> 8
xor_val = xor_val >> 8
elif check_flag == 2:
print("case 2")
print(read_lines[last_cmp_false-6].split(" "))
print(read_lines[last_cmp_false].split(" "))
left = int(read_lines[last_cmp_false].split(" ")[3].split("=")[1],16)
length = (left.bit_length() - 1) // 8 if left != 0 else 0
xor_val = int(read_lines[last_cmp_false-6].split(" ")[3].split("=")[1],16)
xlength = (xor_val.bit_length() - 1) // 8 if xor_val!=0 else 0
if xlength != length: # no xor
no_xor = True
else:
right = int(read_lines[last_cmp_false].split(" ")[4].split("=")[1],16)
replace_index = int(read_lines[last_cmp_false-6].split(" ")[4].split("=")[1],16)
xord_flag_val = left if replace_index ^ xor_val == right else right
while replace_index!=0:
val = xord_flag_val & 0xff
index = (replace_index & 0xff) - 0x41
xval = xor_val & 0xff
print(hex(index),hex(val),hex(xval),hex(val ^ xval))
flag[index] = val ^ xval
i = i + 1
replace_index = replace_index >> 8
xord_flag_val = xord_flag_val >> 8
xor_val = xor_val >> 8
if check_flag == 3 or no_xor :
print("case 3")
cur_last_cmp_false = read_lines[last_cmp_false]
print(cur_last_cmp_false)
print(pre_last_cmp_false)
if pre_last_cmp_false != cur_last_cmp_false:
error = False
else:
print("error")
error = True
flag = pre_flag
i = i - 1
left = int(read_lines[last_cmp_false].split(" ")[3].split("=")[1],16)
right = int(read_lines[last_cmp_false].split(" ")[4].split("=")[1],16)
if right >= 0x41 and right <=0x52 and flag[right - 0x41] == right:
print("index in right")
index,flag_val = right, left
else:
print("index in left")
index,flag_val = left, right
if error:
print("swap before", hex(index),hex(flag_val))
index, flag_val = flag_val, index
print("swap", hex(index),hex(flag_val))
print(hex(index),hex(flag_val))
pre_flag = copy.deepcopy(flag)
flag[index - 0x41] = flag_val
i = i + 1
pre_last_cmp_false = cur_last_cmp_false
print(flag)
# print(flag)
res = ''
for num in flag:
res += str(hex(num)[2:]).rjust(2,'0')
p = subprocess.run([ f"chall/chk{chunk_index}.bin",
f'{res}'])
if p.returncode == 0:
print(f"{chunk_index} solved")
solved_chk.append(chunk_index)
solutions.append(flag)
print(res)
return
else:
print(f'{chunk_index} unsolved')
exit()
except Exception as e:
print(e)
print(f"{chunk_index} unsolved")
pass
for chunk_index in range(38,1000):
solve(chunk_index)
print(solved_chk)
print(len(solved_chk))
with open("solution.py",'w') as f:
f.write(str(solutions))
四
解释器
from elftools.elf.elffile import ELFFile
from numpy import uint64 as u64
import z3
import itertools
from disassamble import *
import leg
def lcg(ini, mul, add):
ini = u64(ini)
mul = u64(mul)
add = u64(add)
while True:
yield ini
ini = (ini * mul + add) & u64(0xffffffff)
def solve_perm(d, dis):
ctx = ConcreteContext()
ctx.mem.map(0x1000, len(d) - 0x10, d[0x10:])
ctx.mem.map(0x7fff0000, 0x10000, None)
ctx.regs[31] = u64(0x1000)
ctx.regs[30] = u64(0x7fff0f00)
inp = bytes(range(0x12))
ctx.mem.write(0x7fff0f00, inp)
ctx.regs[0] = u64(0x7fff0f00)
ctx.regs[1] = u64(0x12)
_, tb = sorted(dis.functions[0x1000].blocks.items())[-3]
while True:
b = dis.functions[0x1000].blocks[ctx.regs[31]]
if b == tb:
break
for ins in b.insns:
ctx.emulate(ins)
data = ctx.mem.read(ctx.regs[30], 0x100)
assert(data == bytes(range(0x100)))
for ins in tb.insns:
ctx.emulate(ins)
data = ctx.mem.read(ctx.regs[30], 0x100)
for i in range(0x10):
print(" ".join(f"{j:02x}" for j in data[i * 0x10: (i + 1) * 0x10]))
_, checker = sorted(dis.functions[0x1000].blocks.items())[-2]
lds = []
xors = []
ld = None
xor = None
first = True
for ins in checker.insns:
if ins.mnemonic == "XORI":
assert(xor is None)
xor = ins.arg2
print(f"xor: {xor:#x}")
elif ins.mnemonic == "LD" and ctx.regs[ins.base] + ins.disp >= ctx.regs[30] and ctx.regs[ins.base] + ins.disp < ctx.regs[30] + 0x100:
if ld is not None and first:
if xor is None:
xor = u64(0)
lds = [ld]
xors = [xor]
xor = None
first = False
else:
assert(ld is None)
ld = ctx.regs[ins.base] + ins.disp - ctx.regs[30]
print(f"ld: {ld:#x}")
elif ins.mnemonic == "OR":
assert(ld is not None)
lds.append(ld)
if xor is None:
xor = u64(0)
xors.append(xor)
xor = None
ld = None
ctx.emulate(ins)
print(f"lds({len(lds)}: {lds}")
print(f"xors({len(xors)}: {xors}")
vals = [data[x] for _, x in sorted(zip(lds, xors))]
print(bytes(vals).hex())
return bytes(vals)
def solve_tree(d, dis):
# highly sophisitcated detection
_, fun = sorted(dis.functions.items())[-1]
_, block = sorted(fun.blocks.items())[-1]
last_ins = block.insns[-1]
past_addr = last_ins.address + last_ins.size
while past_addr + 0x20 < len(d) + 0x1000:
dis.disassemble_function(past_addr)
dis.recursive_decode()
_, fun = sorted(dis.functions.items())[-1]
_, block = sorted(fun.blocks.items())[-1]
last_ins = block.insns[-1]
past_addr = last_ins.address + last_ins.size
fun = None
tb = None
for faddr, f in sorted(dis.functions.items()):
for addr, b in sorted(f.blocks.items()):
for ins in b.insns:
if ins.mnemonic == "CALL":
fun = f
tb = b
ctx = ConcreteContext()
ctx.mem.map(0x1000, len(d) - 0x10, d[0x10:])
ctx.mem.map(0x7fff0000, 0x10000, None)
ctx.regs[31] = u64(faddr)
ctx.regs[30] = u64(0x7fff0f00)
inp = bytes(range(0x12))
ctx.mem.write(0x7fff0f00, inp)
ctx.regs[0] = u64(0x7fff0f00)
ctx.regs[1] = u64(0x12)
heap = 0x13370000
ctx.mem.map(heap, 0x10000, None)
while True:
b = fun.blocks[ctx.regs[31]]
if b == tb:
break
for ins in b.insns:
if ins.mnemonic[:2] == "ST" and ctx.regs[ins.base] == 0:
continue
ctx.emulate(ins)
for ins in tb.insns:
if ins.mnemonic == "CALL" and ctx.regs[0] > 0x13370000:
tree = ctx.regs[0]
break
elif ins.mnemonic == "CALL":
size = ctx.regs[0]
ctx.regs[0] = heap
heap = heap + size
continue
ctx.emulate(ins)
print(f"heap: {heap:#x}")
print(f"tree: {tree:#x}")
flag = z3.BitVec("flag", 8 * 0x12)
solver = z3.Solver()
def build_exp(addr):
kind = int.from_bytes(ctx.mem.read(addr, 4), 'little')
match kind:
case 0:
print("(", end="")
left = build_exp(int.from_bytes(ctx.mem.read(addr + 8, 8), 'little'))
print(" == ", end="")
right = build_exp(int.from_bytes(ctx.mem.read(addr + 16, 8), 'little'))
print(")", end="")
return z3.If(left == right, 1, 0)
case 1:
print("(", end="")
left = build_exp(int.from_bytes(ctx.mem.read(addr + 8, 8), 'little'))
print(" + ", end="")
right = build_exp(int.from_bytes(ctx.mem.read(addr + 16, 8), 'little'))
print(")", end="")
return left + right
case 3:
val = int.from_bytes(ctx.mem.read(addr + 8, 8), 'little')
print(f"{val:#x}", end="")
return val
case 4:
off = int.from_bytes(ctx.mem.read(addr + 8, 8), 'little')
print(f"inp[{off}]", end="")
return z3.Extract(8 * (0x11 - off) + 7, 8 * (0x11 - off), flag)
solver.add(build_exp(tree) != 0)
print("")
if solver.check() == z3.sat:
m = solver.model()
print(m)
flag = m[flag].as_long().to_bytes(18, 'big')
print(flag.hex())
return flag
else:
print("unsat")
def solve_symblic(d, dis):
simctx = SymbolicContext()
simctx.mem.map(0x1000, len(d) - 0x10, d[0x10:])
simctx.mem.map(0x7fff0000, 0x10000, None)
simctx.regs[31] = u64(0x1000)
simctx.regs[30] = u64(0x7fff0f00)
flag = z3.BitVec("flag", 8 * 0x12)
inp = z3.Concat(z3.BitVecVal(0, 8 * 7), flag)
for i in range(0x12):
simctx.mem.write(0x7fff0f00 + i, z3.Extract(8 * (i + 7) + 7, 8 * i, inp))
simctx.regs[0] = u64(0x7fff0f00)
simctx.regs[1] = u64(0x12)
fin = False
while not fin:
for ins in dis.functions[0x1000].blocks[simctx.regs[31]].insns:
simctx.emulate(ins)
if ins.mnemonic == "RET":
print(fin)
fin = True
break
if simctx.solver.check() == z3.sat:
m = simctx.solver.model()
print(m)
flag = m[flag].as_long().to_bytes(18, 'little')
print(flag.hex())
return flag
else:
print("unsat")
def analyze(file):
e = ELFFile(file)
data = e.get_section_by_name(".data")
print(data.header)
d = data.data()
dis = None
for end, enc in itertools.product(["little", "big"][::-1], [True, False]):
try:
dis = Disassembler(0x1000, d[0x10:], leg.Context(end, enc))
dis.disassemble_function(0x1000)
dis.recursive_decode()
break
except:
pass
for _, f in sorted(dis.functions.items()):
for addr, b in sorted(f.blocks.items()):
print(f"loc_{addr:04x}:")
for ins in b.insns:
print(f"t[{ins.address:#06x}]: {ins}")
# highly sophisitcated detection
_, fun = sorted(dis.functions.items())[-1]
_, block = sorted(fun.blocks.items())[-1]
last_ins = block.insns[-1]
past_addr = last_ins.address + last_ins.size
print(f"last address: {past_addr:#x}, {len(d) + 0x1000:#x}")
if past_addr + 0x20 < len(d) + 0x1000:
return solve_tree(d, dis)
hasbackbr = False
for block in fun.blocks.values():
last_ins = block.insns[-1]
if InstructionGroup.JMP not in last_ins.grps:
continue
print(f"{last_ins}")
if last_ins.jmp_targets[0] < last_ins.address:
hasbackbr = True
break
else:
return solve_symblic(d, dis)
return solve_perm(d, dis)
# emuctx = leg.EmuContext()
# emuctx.mem.map(0x1000, len(d) - 0x10, d[0x10:])
# emuctx.mem.map(0x7fff0000, 0x10000, None)
# emuctx.regs[31] = 0x1000
# emuctx.regs[30] = 0x7fff0f00
# inp = bytes.fromhex("00010001bb03ba2f50ead84c4d13abe73c3c")
# emuctx.mem.write(0x7fff0f00, len(inp), inp)
# emuctx.regs[0] = u64(0x7fff0f00)
# emuctx.regs[1] = u64(0x12)
# for i in range(100):
# emuctx.step()
# print(emuctx.regs)
# print(emuctx.mem.read(0x7fff0f00, len(inp)).hex())
class SymboilcMemory:
def __init__(self):
self.mappings = []
self.symbolic = {}
def map(self, addr, size, data=None):
for (mb, ms, _) in self.mappings:
if (addr + size) <= mb:
continue
if (mb + ms) <= addr:
continue
raise RuntimeError("overlapping mappings")
if data is not None:
data = data[:size].ljust(size, b"x00")
else:
data = bytes([0] * size)
self.mappings.append((addr, size, bytearray(data)))
def read(self, addr, size):
if addr in self.symbolic:
res = self.symbolic[addr]
#assert(size * 8 == res.size())
#print(f"read symbolic value {res}")
return res
for (mb, ms, data) in self.mappings:
if mb <= addr and addr + size <= mb + ms:
return data[addr - mb:addr - mb + size]
def toregval(self, data):
issym = False
for d in data:
if type(d) != int:
issym = True
break
if len(data) < 8:
data = data.rjust(8, b"x00")
if not issym:
return int.from_bytes(data, 'little')
return z3.Concat([z3.BitVecVal(b, 8) if type(b) == int else b for b in data[::-1]])
def writeb(self, address, b):
if type(d) == int:
self.symbolic.pop(address, None)
def write(self, address, data):
print(f"write to {address:#x}")
self.symbolic[address] = data
class ConcreteContext:
def __init__(self):
self.mem = leg.VirtualMemory()
self.regs = [u64(0) for _ in range(32)]
def emulate(self, ins):
print(f"{ins.address:#06x}: {ins}")
self.regs[31] = ins.address + ins.size
if isinstance(ins,leg.BinOp) or isinstance(ins,leg.SetCC):
arg1 = self.regs[ins.arg1]
arg2 = None
mnemonic = None
if not ins.imm:
arg2 = self.regs[ins.arg2]
mnemonic = ins.mnemonic
else:
arg2 = u64(ins.arg2)
mnemonic = ins.mnemonic[:-1]
res = None
match mnemonic:
case "OR":
res = arg1 | arg2
case "XOR":
res = arg1 ^ arg2
case "AND":
res = arg1 & arg2
case "ADD":
res = arg1 + arg2
case "SUB":
res = arg1 - arg2
case "MUL":
res = arg1 * arg2
case "DIV":
res = arg1 // arg2
case "SDIV":
res = u64(i64(arg1) // i64(arg2))
case "REM":
res = arg1 % arg2
case "SREM":
res = u64(i64(arg1) % i64(arg2))
case "SLL":
res = arg1 << (arg2 & u64(0x3f))
case "SAR":
res = u64(i64(arg1) >> i64(arg2 & u64(0x3f)))
case "SLR":
res = arg1 >> arg2
case "SETEQ":
res = u64(1) if arg1 == arg2 else u64(0)
case "SETNE":
res = u64(1) if arg1 != arg2 else u64(0)
case "SETLE":
res = u64(1) if i64(arg1) <= i64(arg2) else u64(0)
case "SETLT":
res = u64(1) if i64(arg1) < i64(arg2) else u64(0)
case "SETULE":
res = u64(1) if arg1 <= arg2 else u64(0)
case "SETULT":
res = u64(1) if arg1 < arg2 else u64(0)
case _:
raise RuntimeError(f"{mnemonic} not implemented")
self.regs[ins.rr] = res
elif isinstance(ins, leg.LoadStoreOp):
if ins.mnemonic == "LDI":
self.regs[ins.rr] = u64(ins.imm)
elif ins.mnemonic[:2] == "ST":
addr = self.regs[ins.base] + ins.disp
val = int(self.regs[ins.reg])
match ins.width:
case 0:
self.mem.write(addr, bytes([val & 0xff]))
case 1:
self.mem.write(addr, (val & 0xffff).to_bytes(2, 'little'))
case 2:
self.mem.write(addr, (val & 0xffffffff).to_bytes(4, 'little'))
case 3:
self.mem.write(addr, val.to_bytes(8, 'little'))
elif ins.mnemonic == "LD":
val = self.mem.read(self.regs[ins.base] + ins.disp, 8)
self.regs[ins.reg] = u64(int.from_bytes(val, 'little'))
else:
raise RuntimeError(f"{ins.mnemonic} not implemented")
elif isinstance(ins, leg.Branch):
if ins.mnemonic == "BRCC":
if self.regs[ins.creg] != u64(0):
self.regs[31] = u64(ins.imm)
elif ins.mnemonic == "BR":
self.regs[31] = u64(ins.imm)
elif ins.mnemonic == "RET":
print(f"return value: {self.regs[0]}")
else:
raise RuntimeError(f"{ins.mnemonic} not implemented")
elif ins.mnemonic == "ENTRY":
return
else:
raise RuntimeError(f"{ins.mnemonic} not implemented")
class SymbolicContext:
def __init__(self):
self.mem = SymboilcMemory()
self.regs = [u64(0) for _ in range(32)]
self.solver = z3.Solver()
def emulate(self, ins):
print(f"{ins.address:#06x}: {ins}")
self.regs[31] = ins.address + ins.size
if isinstance(ins,leg.BinOp) or isinstance(ins,leg.SetCC):
arg1 = self.regs[ins.arg1]
arg2 = None
mnemonic = None
if not ins.imm:
arg2 = self.regs[ins.arg2]
mnemonic = ins.mnemonic
else:
arg2 = u64(ins.arg2)
mnemonic = ins.mnemonic[:-1]
res = None
match mnemonic:
case "OR":
res = arg1 | arg2
case "XOR":
res = arg1 ^ arg2
case "AND":
res = arg1 & arg2
case "ADD":
res = arg1 + arg2
case "SUB":
res = arg1 - arg2
case "MUL":
res = arg1 * arg2
case "DIV":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = z3.UDiv(arg1, arg2)
else:
res = arg1 // arg2
case "SDIV":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = arg1 // arg2
else:
res = u64(i64(arg1) // i64(arg2))
case "REM":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = z3.URem(arg1, arg2)
else:
res = arg1 % arg2
case "SREM":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = arg1 % arg2
else:
res = u64(i64(arg1) % i64(arg2))
case "SLL":
res = arg1 << (arg2 & u64(0x3f))
case "SAR":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = arg1 >> (arg2 & u64(0x3f))
else:
res = u64(i64(arg1) >> i64(arg2 & u64(0x3f)))
case "SLR":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = z3.LShr(arg1, arg2 & u64(0x3f))
else:
res = arg1 >> arg2
case "SETEQ":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = z3.If(arg1 == arg2, z3.BitVecVal(1, 64), z3.BitVecVal(0, 64))
else:
res = u64(1) if arg1 == arg2 else u64(0)
case "SETNE":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = z3.If(arg1 != arg2, z3.BitVecVal(1, 64), z3.BitVecVal(0, 64))
else:
res = u64(1) if arg1 != arg2 else u64(0)
case "SETLE":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = z3.If(arg1 <= arg2, z3.BitVecVal(1, 64), z3.BitVecVal(0, 64))
else:
res = u64(1) if i64(arg1) <= i64(arg2) else u64(0)
case "SETLT":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = z3.If(arg1 < arg2, z3.BitVecVal(1, 64), z3.BitVecVal(0, 64))
else:
res = u64(1) if i64(arg1) < i64(arg2) else u64(0)
case "SETULE":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = z3.If(z3.ULE(arg1, arg2), z3.BitVecVal(1, 64), z3.BitVecVal(0, 64))
else:
res = u64(1) if arg1 <= arg2 else u64(0)
case "SETULT":
if not isinstance(arg1,u64) or not isinstance(arg2,u64):
res = z3.If(z3.ULT(arg1, arg2), z3.BitVecVal(1, 64), z3.BitVecVal(0, 64))
else:
res = u64(1) if arg1 < arg2 else u64(0)
case _:
raise RuntimeError(f"{mnemonic} not implemented")
self.regs[ins.rr] = res
elif isinstance(ins, leg.LoadStoreOp):
if ins.mnemonic == "LDI":
self.regs[ins.rr] = u64(ins.imm)
elif ins.mnemonic[:2] == "ST":
self.mem.write(self.regs[ins.base] + ins.disp, self.regs[ins.reg])
elif ins.mnemonic == "LD":
val = self.mem.read(self.regs[ins.base] + ins.disp, 8)
self.regs[ins.reg] = val
else:
raise RuntimeError(f"{ins.mnemonic} not implemented")
elif isinstance(ins, leg.SetCC):
raise RuntimeError(f"{ins.mnemonic} not implemented")
elif isinstance(ins, leg.Branch):
if ins.mnemonic == "BRCC":
if isinstance(self.regs[ins.creg], u64):
if self.regs[ins.creg] != u64(0):
self.regs[31] = u64(ins.imm)
else:
var = self.regs[ins.creg] == u64(0)
#print(f"adding:n{var}n")
self.solver.add(var)
elif ins.mnemonic == "BR":
self.regs[31] = u64(ins.imm)
elif ins.mnemonic == "RET":
if isinstance(self.regs[0], u64):
print(f"return value: {self.regs[0]}")
else:
var = self.regs[0] == u64(1)
#print(f"adding:n{var}n")
self.solver.add(var)
else:
raise RuntimeError(f"{ins.mnemonic} not implemented")
elif ins.mnemonic == "ENTRY":
return
else:
raise RuntimeError(f"{ins.mnemonic} not implemented")
if __name__ == "__main__":
import sys
if len(sys.argv) != 2:
sys.exit(1)
with open(sys.argv[1], "rb") as f:
analyze(f)
五
模拟执行
import angr
import sys
class NewOperator(angr.SimProcedure):
def run(self, size):
addr = self.state.heap.allocate(size)
return addr
program = sys.argv[1]
proj = angr.Project(program, main_opts={'base_addr': 0}, load_options={'auto_load_libs': False})
proj.hook_symbol('_Znwm', NewOperator())
proj.hook_symbol('_Znam', NewOperator())
state = proj.factory.entry_state(add_options=angr.options.unicorn, args=[b'', b''])
AMAIN = 0x1180
assert state.memory.load(0x1180, 7).concrete_value == 0x41574156415453
# 1st
simgr = proj.factory.simulation_manager(state)
simgr.explore(find=0x1180)
assert len(simgr.found) == 1
state1 = simgr.found[0]
off = state1.regs.rdi
assert off.concrete
assert state1.regs.rsi.concrete_value == 2
# 2nd
N = 256
flags = [state.solver.BVS('flag_%d' % i, 8) for i in range(N)]
store = state.heap.allocate(N)
for i in range(N):
state.memory.store(store + i, flags[i])
N = 18
state = proj.factory.call_state(AMAIN, off, 2, store, N, base_state=state)
simgr = proj.factory.simulation_manager(state)
simgr.run()
for state in simgr.deadended:
state.add_constraints(state.regs.rax != 0)
if state.satisfiable():
ans = bytearray()
for i in range(N):
ans.append(state.solver.eval_one(flags[i]))
print(ans.hex(), end='')
break
else:
raise Exception('No solution found')
看雪ID:SleepAlone
https://bbs.kanxue.com/user-home-950548.htm
#
原文始发于微信公众号(看雪学苑):HXP38C3 Mbins Wp 解释器:侧信道攻击与模拟执行技术深度解析
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论