// File: akw0088[P]openssl/aes_upload_reverse.cpp
// Function: aes_file_upload_reverse(char*, char*, unsigned short, unsigned char*, unsigned char*, unsigned char*)
int aes_file_upload_reverse(char *file, char *ip_str, unsigned short port, unsigned char *key, unsigned char *iv, unsigned char *public_key_filename)
{
	struct sockaddr_in	servaddr;
	SOCKET sock;
	int ret;


	unsigned int file_size = 0;
	unsigned char *data = (unsigned char *)get_file(file, &file_size);
	if (data == NULL)
	{
		printf("Error: could not open file %s\r\n", file);
		return -1;
	}
	printf("Opened file %s size %d bytes\r\n", file, file_size);

	char file_name[128] = { 0 };

	unsigned char *ciphertext = NULL;
	unsigned int ciphertext_len = 0;

	printf("Performing AES encryptions\r\n");
	aes_encrypt(key, iv, data, file_size, ciphertext, ciphertext_len);

	char rsa_plaintext[1024] = {0};

	sprintf(rsa_plaintext, "%s %s", iv, key);

	int rsa_plaintext_len = strlen(rsa_plaintext);

	unsigned char encrypted[4098] = {0};
	unsigned int encrypted_length = 0;
	unsigned char hash[33] = {0};

	md5sum((char *)data, file_size, (char *)&hash[0]);
	printf("Unencrypted MD5: %s\r\n", hash);
	printf("AES Encrypted size %d\r\n", ciphertext_len);

	printf("Performing RSA encryptions\r\n");
	rsa_encrypt((char *)public_key_filename, (unsigned char *)&rsa_plaintext[0], rsa_plaintext_len, encrypted, encrypted_length);


	printf("Encryption complete, connecting to server\r\n");
	delete[] data;

	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	memset(&servaddr, 0, sizeof(struct sockaddr_in));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = inet_addr(ip_str);
	servaddr.sin_port = htons(port);

	// 3 way handshake
	printf("Attempting to connect to %s\n", ip_str);
	ret = connect(sock, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in));
	if (ret == SOCKET_ERROR)
	{
#ifdef _WIN32
		ret = WSAGetLastError();

		switch (ret)
		{
		case WSAETIMEDOUT:
			printf("Fatal Error: Connection timed out.\n");
			break;
		case WSAECONNREFUSED:
			printf("Fatal Error: Connection refused\n");
			break;
		case WSAEHOSTUNREACH:
			printf("Fatal Error: Router sent ICMP packet (destination unreachable)\n");
			break;
		default:
			printf("Fatal Error: %d\n", ret);
			break;
		}
#else
		ret = errno;

	        switch(ret)
	        {
		case ENETUNREACH:
			printf("Fatal Error: The network is unreachable from this host at this time.\n(Bad IP address)\n");
			break;
	        case ETIMEDOUT:
	                printf("Fatal Error: Connecting timed out.\n");
	                break;
	        case ECONNREFUSED:
	                printf("Fatal Error: Connection refused\n");
	                break;
	        case EHOSTUNREACH:
	                printf("Fatal Error: router sent ICMP packet (destination unreachable)\n");
	                break;
	        default:
	                printf("Fatal Error: %d\n", ret);
	                break;
	        }
#endif
		return -1;
	}
	printf("TCP handshake completed\n");

	unsigned int magic = 0xF0F0F0F0;

	memcpy(file_name, file, MIN(127, strlen(file)));
	send(sock, (char *)&magic, sizeof(int), 0);
	send(sock, (char *)&ciphertext_len, sizeof(int), 0);
	send(sock, (char *)&file_name, 128, 0);
	send(sock, (char *)&file_size, sizeof(int), 0);
	send(sock, (char *)&hash, 32, 0);
	send(sock, (char *)&encrypted, 256, 0);
	send(sock, ciphertext, ciphertext_len, 0);
	closesocket(sock);
	free((void *)ciphertext);

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1560, %rsp           # imm = 0x1560
movw %dx, %ax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movw %ax, -0x1a(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
movl $0x0, -0x54(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x54(%rbp), %rsi
callq 0x24a0
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
jne 0x29e3
movq -0x10(%rbp), %rsi
leaq 0x723(%rip), %rdi       # 0x30f3
movb $0x0, %al
callq 0x2060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2d97
movq -0x10(%rbp), %rsi
movl -0x54(%rbp), %edx
leaq 0x722(%rip), %rdi       # 0x3113
movb $0x0, %al
callq 0x2060
leaq -0xe0(%rbp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0x2120
movq $0x0, -0xe8(%rbp)
movl $0x0, -0xec(%rbp)
leaq 0x70b(%rip), %rdi       # 0x3132
movb $0x0, %al
callq 0x2060
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x60(%rbp), %rdx
movl -0x54(%rbp), %ecx
leaq -0xe8(%rbp), %r8
leaq -0xec(%rbp), %r9
callq 0x28d0
leaq -0x4f0(%rbp), %rdi
xorl %esi, %esi
movl $0x400, %edx            # imm = 0x400
callq 0x2120
leaq -0x4f0(%rbp), %rdi
movq -0x30(%rbp), %rdx
movq -0x28(%rbp), %rcx
leaq 0x6d6(%rip), %rsi       # 0x314f
movb $0x0, %al
callq 0x2090
leaq -0x4f0(%rbp), %rdi
callq 0x20e0
movl %eax, -0x4f4(%rbp)
leaq -0x1500(%rbp), %rdi
xorl %esi, %esi
movl $0x1002, %edx           # imm = 0x1002
callq 0x2120
movl $0x0, -0x1504(%rbp)
leaq -0x1530(%rbp), %rdi
xorl %esi, %esi
movl $0x21, %edx
callq 0x2120
movq -0x60(%rbp), %rdi
movl -0x54(%rbp), %esi
leaq -0x1530(%rbp), %rdx
callq 0x23e0
leaq -0x1530(%rbp), %rsi
leaq 0x672(%rip), %rdi       # 0x3155
movb $0x0, %al
callq 0x2060
movl -0xec(%rbp), %esi
leaq 0x674(%rip), %rdi       # 0x316b
movb $0x0, %al
callq 0x2060
leaq 0x67e(%rip), %rdi       # 0x3183
movb $0x0, %al
callq 0x2060
movq -0x38(%rbp), %rdi
leaq -0x4f0(%rbp), %rsi
movl -0x4f4(%rbp), %edx
leaq -0x1500(%rbp), %rcx
leaq -0x1504(%rbp), %r8
callq 0x2660
leaq 0x669(%rip), %rdi       # 0x31a0
movb $0x0, %al
callq 0x2060
movq -0x60(%rbp), %rax
movq %rax, -0x1540(%rbp)
cmpq $0x0, %rax
je 0x2b5b
movq -0x1540(%rbp), %rdi
callq 0x2240
movl $0x2, %edi
movl $0x1, %esi
movl $0x6, %edx
callq 0x20b0
movl %eax, -0x4c(%rbp)
leaq -0x48(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x2120
movw $0x2, -0x48(%rbp)
movq -0x18(%rbp), %rdi
callq 0x21d0
movl %eax, -0x44(%rbp)
movzwl -0x1a(%rbp), %edi
callq 0x2070
movw %ax, -0x46(%rbp)
movq -0x18(%rbp), %rsi
leaq 0x620(%rip), %rdi       # 0x31cc
movb $0x0, %al
callq 0x2060
movl -0x4c(%rbp), %edi
leaq -0x48(%rbp), %rsi
movl $0x10, %edx
callq 0x21a0
movl %eax, -0x50(%rbp)
cmpl $-0x1, -0x50(%rbp)
jne 0x2c63
callq 0x2050
movl (%rax), %eax
movl %eax, -0x50(%rbp)
movl -0x50(%rbp), %eax
addl $-0x65, %eax
movl %eax, %ecx
movq %rcx, -0x1548(%rbp)
subl $0xc, %eax
ja 0x2c46
movq -0x1548(%rbp), %rax
leaq 0x407(%rip), %rcx       # 0x3004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x5dc(%rip), %rdi       # 0x31e9
movb $0x0, %al
callq 0x2060
jmp 0x2c57
leaq 0x623(%rip), %rdi       # 0x3240
movb $0x0, %al
callq 0x2060
jmp 0x2c57
leaq 0x637(%rip), %rdi       # 0x3264
movb $0x0, %al
callq 0x2060
jmp 0x2c57
leaq 0x648(%rip), %rdi       # 0x3285
movb $0x0, %al
callq 0x2060
jmp 0x2c57
movl -0x50(%rbp), %esi
leaq 0x675(%rip), %rdi       # 0x32c5
movb $0x0, %al
callq 0x2060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2d97
leaq 0x66c(%rip), %rdi       # 0x32d6
movb $0x0, %al
callq 0x2060
movl $0xf0f0f0f0, -0x1534(%rbp) # imm = 0xF0F0F0F0
leaq -0xe0(%rbp), %rax
movq %rax, -0x1558(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1550(%rbp)
movq -0x10(%rbp), %rdi
callq 0x20e0
movq %rax, %rcx
movl $0x7f, %eax
cmpq %rcx, %rax
jae 0x2cb8
movl $0x7f, %eax
movq %rax, -0x1560(%rbp)
jmp 0x2cc8
movq -0x10(%rbp), %rdi
callq 0x20e0
movq %rax, -0x1560(%rbp)
movq -0x1550(%rbp), %rsi
movq -0x1558(%rbp), %rdi
movq -0x1560(%rbp), %rdx
callq 0x2190
movl -0x4c(%rbp), %edi
leaq -0x1534(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x2100
movl -0x4c(%rbp), %edi
leaq -0xec(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x2100
movl -0x4c(%rbp), %edi
leaq -0xe0(%rbp), %rsi
movl $0x80, %edx
xorl %ecx, %ecx
callq 0x2100
movl -0x4c(%rbp), %edi
leaq -0x54(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x2100
movl -0x4c(%rbp), %edi
leaq -0x1530(%rbp), %rsi
movl $0x20, %edx
xorl %ecx, %ecx
callq 0x2100
movl -0x4c(%rbp), %edi
leaq -0x1500(%rbp), %rsi
movl $0x100, %edx            # imm = 0x100
xorl %ecx, %ecx
callq 0x2100
movl -0x4c(%rbp), %edi
movq -0xe8(%rbp), %rsi
movl -0xec(%rbp), %eax
movl %eax, %edx
xorl %ecx, %ecx
callq 0x2100
movl -0x4c(%rbp), %edi
callq 0x22c0
movq -0xe8(%rbp), %rdi
callq 0x2220
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x1560, %rsp           # imm = 0x1560
popq %rbp
retq
nopw %cs:(%rax,%rax)