// File: akw0088[P]openssl/aes_download_reverse.cpp
// Function: aes_file_download_reverse(unsigned short, unsigned char*, int)
int aes_file_download_reverse(unsigned short int port, unsigned char *prikey, int max_malloc_size)
{
	int			connfd;
	unsigned int		socklen = sizeof(struct sockaddr_in);
	struct sockaddr_in	servaddr, client;
	time_t			ticks;
	int listenfd;

#ifdef _WIN32
	WSADATA		WSAData;

	WSAStartup(MAKEWORD(2, 0), &WSAData);
#endif

	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if (listenfd == -1)
	{
		perror("socket error");
		return -1;
	}

	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(port);

	if ((::bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) == -1)
	{
		perror("bind error");
		return 0;
	}

	printf("Server listening on: %s:%d\n", inet_ntoa(servaddr.sin_addr), htons(servaddr.sin_port));

	if (listen(listenfd, 3) == -1)
	{
		perror("listen error");
		return -1;
	}

	printf("Allocating %d bytes\r\n", max_malloc_size);
	char *response = (char *)malloc(max_malloc_size);
	if (response == NULL)
	{
		perror("malloc failed");
		return -1;
	}


	for (;;)
	{
		unsigned int final_size = 0;
		char hash[33] = {0};
		unsigned char encrypted_key[256] = {0};
		unsigned int download_size = 0;
		char file_name[128] = {0};




		printf("listening for connections...\n");
		connfd = accept(listenfd, (struct sockaddr *)&client, (socklen_t *)&socklen);
		if (connfd == INVALID_SOCKET)
			continue;

		printf("Client: %s\r\n", inet_ntoa(client.sin_addr));

		int expected_size = 0;
		int magic = 0;
		recv(connfd, (char *)&magic, 4, 0);

		if (magic != 0xF0F0F0F0)
		{
			closesocket(connfd);
			continue;
		}

		printf("Client passed magic cookie %X: Downloading\r\n", magic);

		recv(connfd, (char *)&expected_size, 4, 0);
		recv(connfd, (char *)file_name, 128, 0);
		recv(connfd, (char *)&final_size, 4, 0);
		recv(connfd, (char *)hash, 32, 0);
		recv(connfd, (char *)encrypted_key, 256, 0);

		while (download_size < expected_size)
		{
			download_size += recv(connfd, &response[download_size], expected_size - download_size, 0);
		}

		if (download_size != expected_size)
		{
			printf("expected %d bytes, got only %d bytes\r\n", expected_size, download_size);
		}
		closesocket(connfd);
		process_download(file_name, hash, response, download_size, encrypted_key, prikey, max_malloc_size);
		expected_size = 0;
		memset(file_name, 0, 128);
		final_size = 0;
		memset(hash, 0, 33);
		memset(encrypted_key, 0, 256);

	}
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x230, %rsp            # imm = 0x230
movw %di, %ax
movw %ax, -0x6(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl $0x10, -0x1c(%rbp)
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x20b0
movl %eax, -0x4c(%rbp)
cmpl $-0x1, -0x4c(%rbp)
jne 0x2792
leaq 0x18cb(%rip), %rdi      # 0x404c
callq 0x21d0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2ad0
leaq -0x2c(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x2150
movw $0x2, -0x2c(%rbp)
xorl %edi, %edi
callq 0x21b0
movl %eax, -0x28(%rbp)
movzwl -0x6(%rbp), %edi
callq 0x2060
movw %ax, -0x2a(%rbp)
movl -0x4c(%rbp), %edi
leaq -0x2c(%rbp), %rsi
movl $0x10, %edx
callq 0x2070
cmpl $-0x1, %eax
jne 0x27ed
leaq 0x187d(%rip), %rdi      # 0x4059
callq 0x21d0
movl $0x0, -0x4(%rbp)
jmp 0x2ad0
movl -0x28(%rbp), %eax
movl %eax, -0x50(%rbp)
movl -0x50(%rbp), %edi
callq 0x2120
movq %rax, -0x228(%rbp)
movzwl -0x2a(%rbp), %edi
callq 0x2060
movq -0x228(%rbp), %rsi
movzwl %ax, %edx
leaq 0x1848(%rip), %rdi      # 0x4064
movb $0x0, %al
callq 0x2050
movl -0x4c(%rbp), %edi
movl $0x3, %esi
callq 0x2230
cmpl $-0x1, %eax
jne 0x284d
leaq 0x1844(%rip), %rdi      # 0x4080
callq 0x21d0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2ad0
movl -0x14(%rbp), %esi
leaq 0x1836(%rip), %rdi      # 0x408d
movb $0x0, %al
callq 0x2050
movslq -0x14(%rbp), %rdi
callq 0x2290
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
jne 0x288a
leaq 0x182a(%rip), %rdi      # 0x40a3
callq 0x21d0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2ad0
jmp 0x288c
movl $0x0, -0x5c(%rbp)
leaq -0x80(%rbp), %rdi
xorl %esi, %esi
movl $0x21, %edx
callq 0x2150
leaq -0x180(%rbp), %rdi
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x2150
movl $0x0, -0x184(%rbp)
leaq -0x210(%rbp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0x2150
leaq 0x17d7(%rip), %rdi      # 0x40b1
movb $0x0, %al
callq 0x2050
movl -0x4c(%rbp), %edi
leaq -0x3c(%rbp), %rsi
leaq -0x1c(%rbp), %rdx
callq 0x20c0
movl %eax, -0x18(%rbp)
cmpl $-0x1, -0x18(%rbp)
jne 0x28fc
jmp 0x288c
movl -0x38(%rbp), %eax
movl %eax, -0x214(%rbp)
movl -0x214(%rbp), %edi
callq 0x2120
movq %rax, %rsi
leaq 0x17b5(%rip), %rdi      # 0x40cf
movb $0x0, %al
callq 0x2050
movl $0x0, -0x218(%rbp)
movl $0x0, -0x21c(%rbp)
movl -0x18(%rbp), %edi
leaq -0x21c(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x20e0
cmpl $0xf0f0f0f0, -0x21c(%rbp) # imm = 0xF0F0F0F0
je 0x2964
movl -0x18(%rbp), %edi
callq 0x2300
jmp 0x288c
movl -0x21c(%rbp), %esi
leaq 0x176b(%rip), %rdi      # 0x40dc
movb $0x0, %al
callq 0x2050
movl -0x18(%rbp), %edi
leaq -0x218(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x20e0
movl -0x18(%rbp), %edi
leaq -0x210(%rbp), %rsi
movl $0x80, %edx
xorl %ecx, %ecx
callq 0x20e0
movl -0x18(%rbp), %edi
leaq -0x5c(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x20e0
movl -0x18(%rbp), %edi
leaq -0x80(%rbp), %rsi
movl $0x20, %edx
xorl %ecx, %ecx
callq 0x20e0
movl -0x18(%rbp), %edi
leaq -0x180(%rbp), %rsi
movl $0x100, %edx            # imm = 0x100
xorl %ecx, %ecx
callq 0x20e0
movl -0x184(%rbp), %eax
cmpl -0x218(%rbp), %eax
jae 0x2a29
movl -0x18(%rbp), %edi
movq -0x58(%rbp), %rsi
movl -0x184(%rbp), %eax
addq %rax, %rsi
movl -0x218(%rbp), %eax
subl -0x184(%rbp), %eax
movl %eax, %eax
movl %eax, %edx
xorl %ecx, %ecx
callq 0x20e0
movq %rax, %rcx
movl -0x184(%rbp), %eax
addq %rcx, %rax
movl %eax, -0x184(%rbp)
jmp 0x29e0
movl -0x184(%rbp), %eax
cmpl -0x218(%rbp), %eax
je 0x2a51
movl -0x218(%rbp), %esi
movl -0x184(%rbp), %edx
leaq 0x16bf(%rip), %rdi      # 0x4109
movb $0x0, %al
callq 0x2050
movl -0x18(%rbp), %edi
callq 0x2300
leaq -0x210(%rbp), %rdi
leaq -0x80(%rbp), %rsi
movq -0x58(%rbp), %rdx
movl -0x184(%rbp), %ecx
leaq -0x180(%rbp), %r8
movq -0x10(%rbp), %r9
movl -0x14(%rbp), %eax
movl %eax, (%rsp)
callq 0x2ae0
movl $0x0, -0x218(%rbp)
leaq -0x210(%rbp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0x2150
movl $0x0, -0x5c(%rbp)
leaq -0x80(%rbp), %rdi
xorl %esi, %esi
movl $0x21, %edx
callq 0x2150
leaq -0x180(%rbp), %rdi
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x2150
jmp 0x288c
movl -0x4(%rbp), %eax
addq $0x230, %rsp            # imm = 0x230
popq %rbp
retq
nopl (%rax)