bits 64 global _start _start: push rax push rcx push rdx push rsi push rdi lea rdi, [rel _start] sub rdi, qword [rel load_ptr] mov rsi, qword [rel load_size] mov rdx, qword [rel private_key] decrypt_last_block: ; rcx = 8 * (8 - load_size % 8) ; Then crop the private key by rcx bits ; That's to decrypt the end of the section in case the section size ; isn't a multiple of 64 bits mov rcx, rsi not rcx and rcx, 7 inc rcx shl rcx, 3 mov rax, rdx shl rax, cl shr rax, cl ; make section size a multiple of 64bits with this and and rsi, 0xfffffffffffffff8 xor [rdi + rsi], rax decrypt_whole_blocks: sub rsi, 8 cmp rsi, -8 je end_decrypt xor [rdi + rsi], rdx jmp decrypt_whole_blocks end_decrypt: lea rsi, [rel msg] mov rdi, 1 mov rdx, 14 mov rax, 1 syscall pop rdi pop rsi pop rdx pop rcx pop rax jmp 0xdadadada ; this needs to be just before that msg db "....WOODY....",10 ; that needs to be just after this load_ptr dq 0xbabababababababa load_size dq 0xcacacacacacacaca private_key dq 0xabcdefabcdefabcd