easyre
__int64 sub_7FF703D296F0()
{
__int64 (__fastcall *psub_140009510)(_QWORD); // rbx
Stream *Stream; // rax
Stream *Stream_1; // rax
char Buffer[8]; // [rsp+20h] [rbp-50h] BYREF
__int64 v5; // [rsp+28h] [rbp-48h]
__int64 v6; // [rsp+30h] [rbp-40h]
__int64 v7; // [rsp+38h] [rbp-38h]
__int64 v8; // [rsp+40h] [rbp-30h]
__int64 v9; // [rsp+48h] [rbp-28h]
__int64 v10; // [rsp+50h] [rbp-20h]
__int64 v11; // [rsp+58h] [rbp-18h]
sub_7FF703D219B7();
psub_140009510 = psub_140009510;
*Buffer = 0LL;
v5 = 0LL;
v6 = 0LL;
v7 = 0LL;
v8 = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
Stream = psub_140009510(1LL);
setvbuf(Stream, 0LL, 4, 0LL);
sub_7FF703D22FD0("Input flag: ");
Stream_1 = psub_140009510(0LL);
if ( !fgets(Buffer, 64, Stream_1) )
return 1LL;
Buffer[strcspn(Buffer, "\n")] = 0;
if ( strlen(Buffer) == 32 )
{
// 信号处理函数
// Function指向处理信号的函数地址
// 11 SIGSEGV 段错误(非法内存访问)
signal(11, Function);
if ( !setjmp(Buf) )
{
MEMORY[0] = 0;
BUG();
}
sub_7FF703D21850(Buffer);
}
else
{
puts("Wrong length! Hint: 32 chars.");
}
return 0LL;
}
搜索字符串来到主函数
// 信号处理函数
// Function指向处理信号的函数地址
// 11 SIGSEGV 段错误(非法内存访问)
signal(11, Function);
if ( !setjmp(Buf) )
{
MEMORY[0] = 0;
BUG();
}
设置了一个信号处理函数,而在下面触发了一个访问非法段的异常从而进入到异常处理函数
void __fastcall __noreturn Function()
{
key = _mm_unpacklo_epi64(
_mm_unpacklo_epi32(_mm_cvtsi32_si128(key ^ 0xDEADBEEF), _mm_cvtsi32_si128(DWORD1(key) - 2023406815)),
_mm_unpacklo_epi32(
_mm_cvtsi32_si128(DWORD2(key) - 287454020),
_mm_cvtsi32_si128(HIDWORD(key) ^ 0xCCDDEEFF)));
longjmp(Buf, 1);
}
里面会对key进行一些处理,处理后会调用setjump函数回到原来的位置
int __fastcall sub_7FF703D21850(const __m128i *Buffer)
{
__m128i v1; // xmm1
char *v2; // rax
_DWORD *i; // rdx
_OWORD v5[2]; // [rsp+20h] [rbp-28h] BYREF
char v6; // [rsp+40h] [rbp-8h] BYREF
v1 = _mm_loadu_si128(Buffer + 1);
v5[0] = _mm_loadu_si128(Buffer);
v5[1] = v1;
TEA(v5, 8LL, &key);
v2 = v5;
for ( i = &cipher; *v2 == *i; ++i )
{
v2 += 4;
if ( v2 == &v6 )
return puts("Success! You got the flag.");
}
return puts("Wrong flag! Try again.");
}
最后进入到这里,可以发现是标准TEA加密,解密即可
解密脚本
#include <stdint.h>
#include <stdio.h>
#include <cstring>
// 加密函数
void encrypt(uint32_t* value, uint32_t* key) {
uint32_t v0 = value[0], v1 = value[1], sum = 0, i; /* set up */
uint32_t delta = 0x9e3779b9;
uint32_t k0 = key[0], k1 = key[1], k2 = key[2], k3 = key[3]; /* cache key */
for (i = 0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
} /* end cycle */
value[0] = v0;
value[1] = v1;
}
// 解密函数
void decrypt(uint32_t* value, uint32_t* key) {
uint32_t v0 = value[0], v1 = value[1], sum = 0xC6EF3720, i;
uint32_t delta = 0x9e3779b9;
uint32_t k0 = key[0], k1 = key[1], k2 = key[2], k3 = key[3];
for (i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
}
value[0] = v0;
value[1] = v1;
}
unsigned char cipher[] = {0x86, 0x29, 0xC2, 0xE1, 0xC5, 0xDD, 0x9E, 0xD3, 0x4D, 0x48, 0xA1, 0xDF, 0x3C, 0xE5, 0xD4, 0x10, 0xE4, 0x3B, 0x9A, 0xC4, 0x8A, 0xF4, 0xDB, 0x77, 0x29, 0xAE, 0xEB, 0xE5, 0x5C, 0xEC, 0x9F, 0xE9};
int main() {
uint32_t key[] = {0xCC99E897, 0x22222211, 0xEDBA8754, 0xBA89DCEF};
printf("\nAfter decryption:\n");
uint32_t tmp[8];
memcpy(tmp, cipher, 32);
for (int i = 0; i < 8; i += 2) {
decrypt(&tmp[i], key);
}
printf("%.32s\n", (char*)tmp);
return 0;
}
/**
* After decryption:
* flag{s1gn4l_h4ndl3r_1s_tr1cky!!}
*/