보안 공부 시작하고 처음으로 코드게이트 CTF에 참가해봤습니다. 어렵긴 어렵지만 문제들이 재밌더라구요. 대회 끝난 이후에도 못 푼 문제들에 대해서 한 번 더 풀어볼 계획입니다.
리버싱 한 문제를 겨우 풀었는데, 나머지 문제들이 Rust랑 Basic으로 작성된 프로그램이어서 처음 분석하느라 애를 먹었네요. Rust 공부를 따로 하고 있는데, 조금 익숙해진 뒤에 다시 도전해보도록 하겠습니다.
Everlasting_Message

바이너리와 flag_enc 파일이 하나 주어집니다. flag_enc 파일의 크기가 약 200MB 정도 되네요.
__int64 __fastcall main(int a1, char **a2, char **a3)
{
_QWORD *v3; // rdx
unsigned __int8 v5; // [rsp+1Fh] [rbp-F61h]
int i; // [rsp+20h] [rbp-F60h]
int j; // [rsp+24h] [rbp-F5Ch]
int k; // [rsp+28h] [rbp-F58h]
int m; // [rsp+2Ch] [rbp-F54h]
int fd; // [rsp+30h] [rbp-F50h]
int fd_2; // [rsp+34h] [rbp-F4Ch]
unsigned __int64 index; // [rsp+38h] [rbp-F48h]
size_t n; // [rsp+40h] [rbp-F40h]
unsigned __int64 len; // [rsp+48h] [rbp-F38h]
struct msgbuf msgp; // [rsp+50h] [rbp-F30h] BYREF
char buf[1280]; // [rsp+70h] [rbp-F10h] BYREF
char v17[2568]; // [rsp+570h] [rbp-A10h] BYREF
unsigned __int64 v18; // [rsp+F78h] [rbp-8h]
v18 = __readfsqword(0x28u);
if ( a1 <= 2 )
exit(-1);
fd = open(a2[1], 0, a3);
if ( fd < 0 )
exit(-1);
fd_2 = open(a2[2], 66, 0644LL);
if ( fd_2 < 0 )
exit(-1);
msqid = msgget(0, 01666);
if ( msqid < 0 )
exit(-1);
msqid_2 = msgget(0, 01666);
if ( msqid_2 < 0 )
exit(-1);
for ( i = 0; i <= 3; ++i )
pthread_create(&qword_90C0[i], 0LL, (void *(*)(void *))start_routine, &qword_9020[3 * i]);
do
{
len = read(fd, buf, 0x500uLL);
if ( len % 0xA ) // 10의 배수로 패딩 작업
{
v5 = 10 - len % 0xA;
for ( j = 0; j < v5; ++j )
buf[len + j] = v5;
len += v5;
}
index = 0LL;
n = 0LL;
while ( index < len ) // len은 10의 배수
{
for ( k = 1; k <= 4; ++k )
{
msgp.mtype = k;
v3 = *(_QWORD **)&buf[index + 8];
msgp.mtext[0] = *(_QWORD **)&buf[index];
msgp.mtext[1] = v3;
if ( msgsnd(msqid, &msgp, 0x10uLL, 0) )
perror("msgsnd-m");
}
for ( m = 1; m <= 4; ++m )
{
if ( msgrcv(msqid_2, &msgp, 0x10uLL, m, 0) < 0 )
perror("msgrcv-m");
memcpy(&v17[5 * m - 5 + n], msgp.mtext, 5uLL);
}
index += 10LL;
n += 20LL;
}
write(fd_2, v17, n);
}
while ( len > 0x4FF );
if ( msgctl(msqid, 0, 0LL) == -1 )
exit(1);
if ( msgctl(msqid_2, 0, 0LL) == -1 )
exit(1);
close(fd);
close(fd_2);
return 0LL;
}
바이너리의 main 함수입니다.
스레드와 메세지 큐를 사용하는 것을 확인할 수 있습니다. flag 파일을 열어서 크기가 10의 배수가 아니면 패딩을 시켜줍니다.
msqid를 통해서 메세지 타입이랑 16바이트 크기의 데이터를 메세지 큐에 전송하고, msqid_2를 통해서 메세지 큐를 통해서 데이터를 전달받고 전달받은 데이터를 통해서 fd_2로 파일에 쓰기를 진행합니다.
int __fastcall start_routine(__int64 (__fastcall **a1)(_QWORD))
{
ssize_t v1; // rax
__int64 v2; // rbx
_QWORD *v4; // [rsp+10h] [rbp-70h]
__int64 v5; // [rsp+20h] [rbp-60h]
__int64 v6; // [rsp+28h] [rbp-58h]
struct msgbuf msgp; // [rsp+30h] [rbp-50h] BYREF
unsigned __int64 v8; // [rsp+68h] [rbp-18h]
v8 = __readfsqword(0x28u);
do
{
v1 = msgrcv(msqid, &msgp, 0x10uLL, *(int *)a1, 0);
if ( v1 < 0 )
break;
v5 = ((__int64 (__fastcall **)(_QWORD **))a1)[1](msgp.mtext);
v6 = a1[2](v5);
v2 = v6 ^ (1LL << (rand() & 0x3F));
v4 = (_QWORD *)(v2 ^ (1LL << (rand() & 0x3F)));
msgp.mtype = *(int *)a1;
msgp.mtext[0] = v4;
LODWORD(v1) = msgsnd(msqid_2, &msgp, 0x10uLL, 0);
}
while ( !(_DWORD)v1 );
return v1;
}
전송한 메세지큐의 데이터들은 4개의 스레드에서 각각 처리 후 msqid_2를 통해서 데이터를 main 스레드로 전송합니다.
매개변수에는 8바이트 크기의 메세지 타입, 8바이트 크기의 포인터변수 2개가 존재합니다.
*a1을 통해서 메세지 타입을 지정할 수 있고, a1[1]과 a1[2]를 통해서 함수를 호출합니다.
스레드마다 전달되는 매개변수가 다른데, 전체적인 흐름은 다음과 같습니다.
struct node{ // 매개변수의 타입을 정의
long mtype;
void *func_1;
void *func_2;
};
1. a1[1] 함수는 전달받은 데이터 16바이트를 20bit씩 총 80bit(10바이트)의 데이터를 잘라(마스킹)줍니다.
2. a1[2] 함수는 마스킹한 데이터를 통해서 shift, xor 연산을 진행 후 값을 반환합니다.
3. 반환된 값에 rand() & 0x3F를 xor시켜서 bit를 오염시킵니다.
4. 이후 값을 msqid_2를 통해서 메세지큐에 데이터를 전달합니다.
전달한 데이터는 메인 스레드에서 결과 파일에 저장하게 되는데, 이 때 5바이트만 저장하게 됩니다.
하지만 rand() & 0x3F는 5바이트 이상에도 데이터를 오염시킬 수 있기 때문에 이를 생각해보면 메인 스레드에서 파일에 저장하는 5바이트의 데이터는 오염된 비트의 갯수가 최소 0개, 최대 2개일 수 있습니다.
처음에는 shift, xor 연산을 진행하는 함수에서 바로 복호화 하는 방법을 떠올리지 못해서 plain data를 브루트포싱하는 방법을 택하였습니다. plain data 2.5바이트당 0xfffff씩 브루트포싱하면 되기 때문에 plain data를 쉽게 구할 수 있지만, 이는 시간이 오래 걸리고, 더욱이 200메가나 되는 flag_enc 파일을 전부 복호화하는데 c언어로 구현해도 몇백시간이나 걸리는 것을 확인하고 포기하였습니다.(func_2 함수로 생성될 수 있는 데이터 테이블을 적용시켜도 오래 걸렸습니다.)
그래서 떠오른 방법이 flag_enc 5바이트로 plain data 2.5바이트를 구할 수 있는데, 오염된 bit 수가 최대 2개이기 때문에 flag_enc 5바이트가 테이블의 키값으로 존재하면 plain data를 바로 구할 수 있도록 구현하는 것이었습니다.
40bit 중 오염된 비트가 최대 2개인 경우의 수는 최대 821개이기 때문에 5바이트의 데이터가 키값으로 존재하지 않으면 다른 오염된 경우의 수를 찾고 다시 키값이 존재하는 지 검사하는 식으로 시도하였습니다.
이렇게 하면 plain data를 0xFFFFF만큼 브루트포싱하는 것을 821번 브루트포싱 하면 되기 때문에 시간단축에 상당히 도움됩니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned long table[4][0xfffff];
unsigned char BYTE1(int a){
return a >> 8;
};
unsigned char BYTE2(int a){
return a >> 16;
};
unsigned short WORD1(int a){
return a >> 16;
};
unsigned long sub_12E9(unsigned long a1);
unsigned long sub_264D(unsigned long a1);
unsigned long sub_3977(unsigned long a1);
unsigned long sub_4C0E(unsigned long a1);
int hasExactlyTwoOnes(unsigned long a);
void createTable();
int main(){
FILE *file, *plain;
unsigned long buffer=0, i, j;
unsigned long data, result;
unsigned long text[2] = { 0 };
unsigned long long totalBytesRead = 0;
unsigned long long fileSize = -1; // 파일 크기 (바이트), 초기값 -1로 설정
size_t bytesRead;
createTable();
printf("Table create Done!\n");
}
unsigned long sub_12E9(unsigned long a1)
{
long v1; // rax
unsigned long v2; // rcx
long v3; // rax
unsigned long v4; // rcx
unsigned long v5; // rdx
long v6; // rax
unsigned long v7; // rcx
unsigned long v8; // rcx
long v9; // rax
unsigned long v10; // rdx
long v11; // rax
unsigned long v12; // rcx
long v13; // rax
long v14; // rcx
v1 = (8
* ((unsigned char)((a1 >> 18) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ BYTE1(a1) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 19))) & 8;
v2 = (16
* ((unsigned char)((a1 >> 18) ^ (a1 >> 13) ^ (a1 >> 10) ^ BYTE1(a1) ^ (a1 >> 6) ^ (a1 >> 5) ^ a1 ^ (a1 >> 4)) ^ (unsigned char)(a1 >> 19))) & 0x10 | v1 | (4 * ((unsigned char)((a1 >> 10) ^ BYTE1(a1) ^ (a1 >> 7) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 14))) & 4 | (2 * ((unsigned char)(BYTE2(a1) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ BYTE1(a1) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 4) ^ a1 ^ (a1 >> 2)) ^ (unsigned char)(a1 >> 17))) & 2 | (unsigned long)(((unsigned char)((a1 >> 18) ^ (a1 >> 17) ^ BYTE2(a1) ^ (a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ BYTE1(a1) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 2)) ^ (unsigned char)(a1 >> 19)) & 1);
v3 = (((unsigned short)((a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 10) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 5) ^ (a1 >> 2) ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 17)) << 8) & 0x100;
v4 = v3 | (unsigned char)(((unsigned char)((a1 >> 18) ^ (a1 >> 17) ^ BYTE2(a1) ^ (a1 >> 15) ^ (a1 >> 12) ^ (a1 >> 10) ^ (a1 >> 9) ^ BYTE1(a1) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 19)) << 7) | (((unsigned char)((a1 >> 17) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 11) ^ (a1 >> 9) ^ BYTE1(a1) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 18)) << 6) & 0x40 | (32 * ((unsigned char)((a1 >> 17) ^ BYTE2(a1) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ BYTE1(a1) ^ (a1 >> 6) ^ (a1 >> 3) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 18))) & 0x20 | v2;
v5 = (((unsigned short)(WORD1(a1) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 9) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 19)) << 11) & 0x800 | (((unsigned short)((a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 11) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 17)) << 10) & 0x400 | (((unsigned short)((a1 >> 18) ^ (a1 >> 17) ^ (a1 >> 14) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 19)) << 9) & 0x200 | v4;
v6 = (unsigned short)(((unsigned short)((a1 >> 17) ^ WORD1(a1) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2) ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 18)) << 15);
v7 = v6 | (((unsigned short)((a1 >> 15) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 2) ^ (a1 >> 1)) ^ WORD1(a1)) << 14) & 0x4000 | (((unsigned short)((a1 >> 18) ^ WORD1(a1) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2) ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 19)) << 13) & 0x2000 | (((unsigned short)((a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 9) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 2)) ^ (unsigned short)(a1 >> 17)) << 12) & 0x1000 | v5;
v8 = (((unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 19)) << 19) & 0x80000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 19)) << 18) & 0x40000 | (((unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 16)) << 17) & 0x20000 | (((unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 15)) << 16) & 0x10000 | v7;
v9 = (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 18)) << 23) & 0x800000;
v10 = (((unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 14)) << 24) & 0x1000000 | v9 | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 22) & 0x400000 | (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 21) & 0x200000 | (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 20) & 0x100000 | v8;
v11 = (((unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 10)) << 29) & 0x20000000;
v12 = v11 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 19)) << 28) & 0x10000000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 27) & 0x8000000 | (((unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 16)) << 26) & 0x4000000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 25) & 0x2000000 | v10;
v13 = (((a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 4) ^ (a1 >> 2) ^ (a1 >> 18)) << 35) & 0x800000000;
v14 = v13 | (((a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 10) ^ (a1 >> 8) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 1) ^ (a1 >> 16)) << 34) & 0x400000000 | (((a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1) ^ (a1 >> 18)) << 33) & 0x200000000 | (((a1 >> 17) ^ (a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 12) ^ (a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 3) ^ a1 ^ (a1 >> 1) ^ (a1 >> 18)) << 32) & 0x100000000 | (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 18)) << 31) | (((unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 18)) << 30) & 0x40000000 | v12;
return (((a1 >> 17) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 1) ^ (a1 >> 19)) << 38) & 0x4000000000 | (((a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 2) ^ (a1 >> 17)) << 37) & 0x2000000000 | (((a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 10) ^ (a1 >> 3) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1) ^ (a1 >> 17)) << 36) & 0x1000000000 | v14 | (((a1 >> 18) ^ (a1 >> 15) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 19)) << 39) & 0x8000000000;
};
unsigned long sub_264D(unsigned long a1)
{
long v1; // rax
unsigned long v2; // rdx
unsigned long v3; // rcx
long v4; // rax
unsigned long v5; // rdx
long v6; // rax
unsigned long v7; // rdx
unsigned long v8; // rcx
unsigned long v9; // rdx
unsigned long v10; // rcx
unsigned long v11; // rdx
long v12; // rdx
v1 = (16
* ((unsigned char)((a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 9) ^ BYTE1(a1) ^ (a1 >> 5) ^ (a1 >> 4) ^ a1 ^ (a1 >> 3)) ^ (unsigned char)(a1 >> 17))) & 0x10;
v2 = v1 | (8
* ((unsigned char)(BYTE2(a1) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 18))) & 8 | (4 * ((unsigned char)(BYTE2(a1) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 19))) & 4 | (2 * ((unsigned char)(BYTE2(a1) ^ (a1 >> 15) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ BYTE1(a1) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4)) ^ (unsigned char)(a1 >> 18))) & 2 | (unsigned long)(((unsigned char)((a1 >> 18) ^ BYTE2(a1) ^ (a1 >> 13) ^ (a1 >> 12) ^ BYTE1(a1) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 19)) & 1);
v3 = (unsigned char)(((unsigned char)((a1 >> 18) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ BYTE1(a1) ^ (a1 >> 5) ^ a1 ^ (a1 >> 2)) ^ (unsigned char)(a1 >> 19)) << 7) | (((unsigned char)((a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 10) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2)) ^ (unsigned char)(a1 >> 19)) << 6) & 0x40 | (32 * ((unsigned char)((a1 >> 17) ^ (a1 >> 12) ^ (a1 >> 10) ^ (a1 >> 9) ^ BYTE1(a1) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 19))) & 0x20 | v2;
v4 = (((unsigned short)((a1 >> 17) ^ WORD1(a1) ^ (a1 >> 13) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 6) ^ (a1 >> 5) ^ a1 ^ (a1 >> 4)) ^ (unsigned short)(a1 >> 18)) << 12) & 0x1000;
v5 = v4 | (((unsigned short)((a1 >> 18) ^ (a1 >> 17) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 7) ^ (a1 >> 5)) ^ (unsigned short)(a1 >> 19)) << 11) & 0x800 | (((unsigned short)((a1 >> 17) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 19)) << 10) & 0x400 | (((unsigned short)((a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 5) ^ (a1 >> 4) ^ a1 ^ (a1 >> 3)) ^ (unsigned short)(a1 >> 19)) << 9) & 0x200 | (((unsigned short)((a1 >> 17) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 10) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 5) ^ (a1 >> 4) ^ a1 ^ (a1 >> 2)) ^ (unsigned short)(a1 >> 18)) << 8) & 0x100 | v3;
v6 = (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 19)) << 17) & 0x20000;
v7 = v6 | (((unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 18)) << 16) & 0x10000 | (unsigned short)(((unsigned short)((a1 >> 13) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 5) ^ (a1 >> 2) ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 17)) << 15) | (((unsigned short)((a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 9) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 2) ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 19)) << 14) & 0x4000 | (((unsigned short)(WORD1(a1) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 6) ^ (a1 >> 4)) ^ (unsigned short)(a1 >> 18)) << 13) & 0x2000 | v5;
v8 = (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 19)) << 20) & 0x100000 | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 19) & 0x80000 | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 19)) << 18) & 0x40000 | v7;
v9 = (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 24) & 0x1000000 | (((unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 23) & 0x800000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 22) & 0x400000 | (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 21) & 0x200000 | v8;
v10 = (((unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 13)) << 28) & 0x10000000 | (((unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 16)) << 27) & 0x8000000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 26) & 0x4000000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 18)) << 25) & 0x2000000 | v9;
v11 = (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 31) | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 30) & 0x40000000 | (((unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 16)) << 29) & 0x20000000 | v10;
v12 = (((a1 >> 17) ^ (a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 11) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 1) ^ (a1 >> 19)) << 36) & 0x1000000000 | (((a1 >> 15) ^ (a1 >> 12) ^ (a1 >> 9) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 1) ^ (a1 >> 18)) << 35) & 0x800000000 | (((a1 >> 18) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 11) ^ (a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ a1 ^ (a1 >> 1) ^ (a1 >> 19)) << 34) & 0x400000000 | (((a1 >> 18) ^ (a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 2) ^ (a1 >> 19)) << 33) & 0x200000000 | (((a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 10) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 2) ^ (a1 >> 16)) << 32) & 0x100000000 | v11;
return (((a1 >> 16) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 1) ^ (a1 >> 17)) << 38) & 0x4000000000 | (((a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 9) ^ (a1 >> 8) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 1) ^ (a1 >> 19)) << 37) & 0x2000000000 | v12 | (((a1 >> 17) ^ (a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 11) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1) ^ (a1 >> 19)) << 39) & 0x8000000000;
}
unsigned long sub_3977(unsigned long a1)
{
unsigned long v1; // rcx
unsigned long v2; // rcx
unsigned long v3; // rcx
unsigned long v4; // rdx
unsigned long v5; // rcx
unsigned long v6; // rcx
unsigned long v7; // rdx
unsigned long v8; // rdx
long v9; // rdx
v1 = (16
* ((unsigned char)((a1 >> 17) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 10) ^ BYTE1(a1) ^ (a1 >> 6) ^ a1 ^ (a1 >> 3)) ^ (unsigned char)(a1 >> 18))) & 0x10 | (8 * ((unsigned char)((a1 >> 13) ^ (a1 >> 11) ^ (a1 >> 4)) ^ BYTE2(a1))) & 8 | (4 * ((unsigned char)((a1 >> 18) ^ BYTE2(a1) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 3) ^ a1 ^ (a1 >> 2)) ^ (unsigned char)(a1 >> 19))) & 4 | (2 * ((unsigned char)((a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 9) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2)) ^ (unsigned char)(a1 >> 19))) & 2 | (unsigned long)(((unsigned char)((a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 5) ^ (a1 >> 3) ^ a1 ^ (a1 >> 2)) ^ BYTE2(a1)) & 1);
v2 = (((unsigned short)(WORD1(a1) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 3) ^ a1 ^ (a1 >> 2)) ^ (unsigned short)(a1 >> 17)) << 8) & 0x100 | (unsigned char)(((unsigned char)((a1 >> 14) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 4)) ^ (unsigned char)(a1 >> 17)) << 7) | (((unsigned char)((a1 >> 17) ^ BYTE2(a1) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 6) ^ (a1 >> 2)) ^ (unsigned char)(a1 >> 18)) << 6) & 0x40 | (32 * ((unsigned char)((a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2) ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 19))) & 0x20 | v1;
v3 = (((unsigned short)((a1 >> 18) ^ WORD1(a1) ^ (a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 3)) ^ (unsigned short)(a1 >> 19)) << 12) & 0x1000 | (((unsigned short)((a1 >> 17) ^ (a1 >> 13) ^ (a1 >> 9) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 3)) ^ (unsigned short)(a1 >> 19)) << 11) & 0x800 | (((unsigned short)((a1 >> 17) ^ WORD1(a1) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ a1 ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 18)) << 10) & 0x400 | (((unsigned short)((a1 >> 11) ^ (a1 >> 10) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 6) ^ a1 ^ (a1 >> 5)) ^ (unsigned short)(a1 >> 15)) << 9) & 0x200 | v2;
v4 = (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 17) & 0x20000 | (((unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 14)) << 16) & 0x10000 | (unsigned short)(((unsigned short)((a1 >> 17) ^ WORD1(a1) ^ (a1 >> 15) ^ (a1 >> 11) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 4) ^ (a1 >> 2)) ^ (unsigned short)(a1 >> 19)) << 15) | (((unsigned short)((a1 >> 18) ^ (a1 >> 13) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2)) ^ (unsigned short)(a1 >> 19)) << 14) & 0x4000 | (((unsigned short)((a1 >> 12) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 6) ^ (a1 >> 4) ^ a1 ^ (a1 >> 2)) ^ (unsigned short)(a1 >> 18)) << 13) & 0x2000 | v3;
v5 = (((unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 17)) << 21) & 0x200000 | (((unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 16)) << 20) & 0x100000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 19) & 0x80000 | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 19)) << 18) & 0x40000 | v4;
v6 = (((unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 16)) << 24) & 0x1000000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 23) & 0x800000 | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 22) & 0x400000 | v5;
v7 = (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 17)) << 28) & 0x10000000 | (((unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 17)) << 27) & 0x8000000 | (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 26) & 0x4000000 | (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 18)) << 25) & 0x2000000 | v6;
v8 = (((unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 31) | (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 30) & 0x40000000 | (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 29) & 0x20000000 | v7;
v9 = (((a1 >> 13) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 2) ^ (a1 >> 19)) << 36) & 0x1000000000LL | (((a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 9) ^ (a1 >> 8) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 19)) << 35) & 0x800000000LL | (((a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ a1 ^ (a1 >> 2) ^ (a1 >> 19)) << 34) & 0x400000000LL | (((a1 >> 18) ^ (a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 4) ^ a1 ^ (a1 >> 1) ^ (a1 >> 19)) << 33) & 0x200000000LL | (((a1 >> 18) ^ (a1 >> 17) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 8) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2) ^ (a1 >> 19)) << 32) & 0x100000000LL | v8;
return (((a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 7) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 2) ^ (a1 >> 18)) << 38) & 0x4000000000LL | (((a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 2) ^ (a1 >> 1) ^ (a1 >> 18)) << 37) & 0x2000000000LL | v9 | (((a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2) ^ (a1 >> 1) ^ (a1 >> 16)) << 39) & 0x8000000000LL;
}
unsigned long sub_4C0E(unsigned long a1)
{
unsigned long v1; // rcx
unsigned long v2; // rcx
unsigned long v3; // rcx
unsigned long v4; // rcx
long v5; // rax
unsigned long v6; // rcx
unsigned long v7; // rcx
unsigned long v8; // rdx
unsigned long v9; // rdx
long v10; // rcx
long v11; // rcx
v1 = (8
* ((unsigned char)((a1 >> 13) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 18))) & 8 | (4 * ((unsigned char)((a1 >> 11) ^ BYTE1(a1) ^ (a1 >> 5) ^ a1 ^ (a1 >> 3)) ^ (unsigned char)(a1 >> 18))) & 4 | (2 * ((unsigned char)(BYTE2(a1) ^ (a1 >> 15) ^ (a1 >> 12) ^ (a1 >> 10) ^ (a1 >> 9) ^ BYTE1(a1) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 3) ^ a1 ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 19))) & 2 | (unsigned long)(((unsigned char)((a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ BYTE1(a1) ^ (a1 >> 7)) ^ BYTE2(a1)) & 1);
v2 = (unsigned char)(((unsigned char)((a1 >> 18) ^ BYTE2(a1) ^ (a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 10) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 3) ^ a1 ^ (a1 >> 2)) ^ (unsigned char)(a1 >> 19)) << 7) | (((unsigned char)((a1 >> 12) ^ BYTE1(a1) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 2) ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 14)) << 6) & 0x40 | (32 * ((unsigned char)((a1 >> 15) ^ (a1 >> 12) ^ (a1 >> 10) ^ (a1 >> 9) ^ BYTE1(a1) ^ (a1 >> 5) ^ (a1 >> 4)) ^ (unsigned char)(a1 >> 18))) & 0x20 | (16 * ((unsigned char)(BYTE2(a1) ^ (a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1)) ^ (unsigned char)(a1 >> 19))) & 0x10 | v1;
v3 = (((unsigned short)(WORD1(a1) ^ (a1 >> 15) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 6) ^ (a1 >> 5) ^ a1 ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 18)) << 11) & 0x800 | (((unsigned short)(WORD1(a1) ^ (a1 >> 14) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 2) ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 19)) << 10) & 0x400 | (((unsigned short)((a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 7) ^ a1 ^ (a1 >> 6)) ^ (unsigned short)(a1 >> 13)) << 9) & 0x200 | (((unsigned short)((a1 >> 18) ^ (a1 >> 17) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 9) ^ (a1 >> 5) ^ (a1 >> 3) ^ a1 ^ (a1 >> 2)) ^ (unsigned short)(a1 >> 19)) << 8) & 0x100 | v2;
v4 = (unsigned short)(((unsigned short)((a1 >> 14) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1)) ^ WORD1(a1)) << 15) | (((unsigned short)((a1 >> 18) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 5) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 2) ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 19)) << 14) & 0x4000 | (((unsigned short)((a1 >> 13) ^ (a1 >> 11) ^ (a1 >> 10) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1)) ^ (unsigned short)(a1 >> 17)) << 13) & 0x2000 | (((unsigned short)((a1 >> 11) ^ (a1 >> 10) ^ ((unsigned int)a1 >> 8) ^ (a1 >> 4) ^ a1 ^ (a1 >> 2)) ^ WORD1(a1)) << 12) & 0x1000 | v3;
v5 = (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 19)) << 19) & 0x80000;
v6 = v5 | (((unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 15)) << 18) & 0x40000 | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 19)) << 17) & 0x20000 | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 19)) << 16) & 0x10000 | v4;
v7 = (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 22) & 0x400000 | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 19)) << 21) & 0x200000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 18)) << 20) & 0x100000 | v6;
v8 = (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 25) & 0x2000000 | (((unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 19)) << 24) & 0x1000000 | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 2) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 23) & 0x800000 | v7;
v9 = (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 2) ^ (unsigned int)(a1 >> 18)) << 28) & 0x10000000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 27) & 0x8000000 | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 15) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 18)) << 26) & 0x4000000 | v8;
v10 = (((a1 >> 17) ^ (a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 10) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1) ^ (a1 >> 18)) << 32) & 0x100000000LL | (((unsigned int)(a1 >> 18) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 14) ^ (unsigned int)(a1 >> 13) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 6) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 3) ^ (unsigned int)a1 ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 19)) << 31) | (((unsigned int)(a1 >> 17) ^ (unsigned int)(a1 >> 16) ^ (unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 11) ^ (unsigned int)(a1 >> 9) ^ (unsigned int)(a1 >> 8) ^ (unsigned int)(a1 >> 7) ^ (unsigned int)(a1 >> 4) ^ (unsigned int)(a1 >> 19)) << 30) & 0x40000000 | (((unsigned int)(a1 >> 12) ^ (unsigned int)(a1 >> 10) ^ (unsigned int)(a1 >> 5) ^ (unsigned int)(a1 >> 1) ^ (unsigned int)(a1 >> 17)) << 29) & 0x20000000 | v9;
v11 = (((a1 >> 15) ^ (a1 >> 14) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ a1 ^ (a1 >> 3) ^ (a1 >> 17)) << 37) & 0x2000000000LL | (((a1 >> 15) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1) ^ (a1 >> 17)) << 36) & 0x1000000000LL | (((a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 8) ^ (a1 >> 5) ^ (a1 >> 3) ^ (a1 >> 2) ^ (a1 >> 1) ^ (a1 >> 16)) << 35) & 0x800000000LL | (((a1 >> 17) ^ (a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 8) ^ (a1 >> 4) ^ (a1 >> 2) ^ (a1 >> 1) ^ (a1 >> 18)) << 34) & 0x400000000LL | (((a1 >> 13) ^ (a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 9) ^ (a1 >> 6) ^ (a1 >> 5) ^ (a1 >> 4) ^ a1 ^ (a1 >> 3) ^ (a1 >> 16)) << 33) & 0x200000000LL | v10;
return (((a1 >> 18) ^ (a1 >> 16) ^ (a1 >> 15) ^ (a1 >> 11) ^ (a1 >> 10) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 3) ^ (a1 >> 2) ^ a1 ^ (a1 >> 1) ^ (a1 >> 19)) << 38) & 0x4000000000LL | v11 | (((a1 >> 12) ^ (a1 >> 11) ^ (a1 >> 9) ^ (a1 >> 8) ^ (a1 >> 7) ^ (a1 >> 6) ^ (a1 >> 4) ^ (a1 >> 3) ^ a1 ^ (a1 >> 2) ^ (a1 >> 18)) << 39) & 0x8000000000LL;
};
int hasExactlyTwoOnes(unsigned long a) {
int count = 0;
// 비트 연산을 통해 1의 개수를 셈
while (a != 0) {
if (a & 1) {
count++;
}
a >>= 1; // 오른쪽으로 한 비트 이동
}
// 1의 개수가 2개인지 확인
return count <= 2;
}
void createTable(){
FILE *file;
file = fopen("table", "w");
int i, j;
unsigned long(*func)(unsigned long);
for(i = 0; i < 4; i++){
for(j = 0; j <= 0xfffff; j++){
if(i == 0){
func = sub_12E9;
}
else if(i == 1){
func = sub_264D;
}
else if(i == 2){
func = sub_3977;
}
else if(i == 3){
func = sub_4C0E;
}
table[i][j] = func(j);
fprintf(file, "%d %d %ld\n", i, j, table[i][j]);
}
fprintf(file, "----------\n");
}
}
위 코드는 테이블을 생성하는 코드인데, gdb script로 함수 결과를 알 수 있지만 귀찮기 때문에 함수 코드를 복붙해왔습니다.
from tqdm import tqdm
def gen_numbers():
result = [0]
for i in range(0, 40):
result.append(1 << i)
for j in range(1, 40):
for i in range(0, j):
result.append((1 << j) | (1 << i))
return result
numbers = gen_numbers()
with open('table', 'r') as f:
buf = f.read().split('----------')[:-1]
table = [{} for _ in range(4)]
for data in buf:
for line in data.split('\n')[:-1]:
arr = list(map(int, line.split()))
try:
table[arr[0]][arr[2]] = arr[1]
except:
pass
with open('flag_enc', 'rb') as f:
buf = f.read()
content = b''
for i in tqdm(range(0, len(buf), 20)):
write_data = 0
for j in range(0, 20, 5):
data = int.from_bytes(buf[i+j:i+j+5], 'little')
for number in numbers:
tmp = data ^ number
try:
result = table[j // 4][tmp]
write_data |= result << (20 * (j // 4))
break
except:
pass
content += write_data.to_bytes(10, byteorder='little')
with open('movie.mp4', 'wb') as f:
f.write(content)
print('Done')
복호화하는 코드는 위의 파이썬 코드입니다.

실행하면 위 사진처럼 진행도를 표현해주는데, 저는 복호화하는데 대략 40분 걸린 것 같습니다.
복호화가 끝나면 mp4 파일이 생성되는데, 거기에 플래그가 있는 것을 확인할 수 있습니다.
후기
처음 참여해 본 코드게이트 CTF... 많이 어렵네요. 지난번 .HACK Invitational에서는 한 문제도 못 풀었었는데 그래도 이번 코게때는 한 문제는 해결했네요 ..ㅎㅎ..
드림핵에서 c로 작성된 ELF, EXE 파일만 디버깅 했었는데 앞으로 rust나 Basic, 기타 다른 프로그램 분석을 좀 더 많이 해봐야할 것 같습니다.(+ 수학공부도..)
'CTF' 카테고리의 다른 글
| [CTF] CCE 2024 Qual Write-up (0) | 2024.08.13 |
|---|---|
| [CTF] LINE CTF 2023 (0) | 2023.03.28 |
| [CTF] wolvCTF (0) | 2023.03.20 |