bits 64 global _start _start: push rbp push rsp push rbx push rax push rcx push rdx push rsi push rdi push r8 lea rsi, [rel msg] mov rbx, rsi sub rbx, qword [rel text_section] ;text_section address because of this and that mov r8, qword [rel section_size] ;text_section size mov rdx, qword [rel private_key] decrypt_last_block: ; rcx = 8 * (8 - section_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, r8 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 r8, 0xfffffffffffffff8 xor [rbx + r8], rax decrypt_whole_blocks: sub r8, 8 cmp r8, -8 je end_decrypt xor [rbx + r8], rdx jmp decrypt_whole_blocks end_decrypt: mov rdi, 1 mov rdx, 14 mov rax, 1 syscall pop r8 pop rdi pop rsi pop rdx pop rcx pop rax pop rbx pop rsp pop rbp jmp 0xdadadada ; this needs to be just before that msg db "....WOODY....",10 ; that needs to be just after this text_section dq 0xbabababababababa section_size dq 0xcacacacacacacaca private_key dq 0xabcdefabcdefabcd