================================================================================
  FICTIONAL DISASSEMBLY — CTF Red Team Lesson 06
  Tool: objdump -d -M intel challenge_keychecker
  Section: .text (key-checking function)
  Architecture: x86-64
  NOTE: This is a text representation for educational purposes only.
================================================================================

challenge_keychecker:     file format elf64-x86-64


Disassembly of section .text:

0000000000401000 <main>:
  401000:   55                      push   rbp
  401001:   48 89 e5                mov    rbp,rsp
  401004:   48 83 ec 50             sub    rsp,0x50
  401008:   48 8d 3d f1 0f 00 00    lea    rdi,[rip+0xff1]        # 402000 <_IO_stdin_used+0x0>
  40100f:   e8 ec fe ff ff          call   400f00 <puts@plt>
  401014:   48 8d 3d f5 0f 00 00    lea    rdi,[rip+0xff5]        # 402010 <_IO_stdin_used+0x10>
  40101b:   31 c0                   xor    eax,eax
  40101d:   e8 de fe ff ff          call   400f00 <printf@plt>
  401022:   48 8d 45 b0             lea    rax,[rbp-0x50]
  401026:   48 89 c6                mov    rsi,rax
  401029:   48 8d 3d f0 0f 00 00    lea    rdi,[rip+0xff0]        # 402020 <_IO_stdin_used+0x20>
  401030:   31 c0                   xor    eax,eax
  401032:   e8 c9 fe ff ff          call   400f00 <scanf@plt>
  401037:   48 8d 7d b0             lea    rdi,[rbp-0x50]
  40103b:   e8 10 00 00 00          call   401050 <check_key>
  401040:   85 c0                   test   eax,eax
  401042:   74 0e                   je     401052 <main+0x52>
  401044:   48 8d 3d e5 0f 00 00    lea    rdi,[rip+0xfe5]        # 402030 <"Access granted!">
  40104b:   eb 0c                   jmp    401059 <main+0x59>
  40104d:   48 8d 3d ec 0f 00 00    lea    rdi,[rip+0xfec]        # 402040 <"Access denied!">
  401054:   e8 a7 fe ff ff          call   400f00 <puts@plt>
  401059:   31 c0                   xor    eax,eax
  40105b:   c9                      leave
  40105c:   c3                      ret

; ==========================================================================
; check_key — validates user input against hardcoded password
; Arguments: rdi = pointer to user input string
; Returns: eax = 1 if valid, 0 if invalid
; ==========================================================================

0000000000401050 <check_key>:
  401050:   55                      push   rbp
  401051:   48 89 e5                mov    rbp,rsp
  401054:   48 89 7d f8             mov    QWORD PTR [rbp-0x8],rdi    ; save input pointer
  401058:   48 83 ec 20             sub    rsp,0x20

  ; --- Step 1: Check input length ---
  40105c:   48 8b 7d f8             mov    rdi,QWORD PTR [rbp-0x8]
  401060:   e8 9b fe ff ff          call   400f00 <strlen@plt>
  401065:   48 83 f8 10             cmp    rax,0x10                   ; length must be 16
  401069:   75 60                   jne    4010cb <check_key+0x7b>    ; fail if wrong length

  ; --- Step 2: Check first 4 characters directly ---
  40106b:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  40106f:   0f b6 00                movzx  eax,BYTE PTR [rax]         ; input[0]
  401072:   3c 73                   cmp    al,0x73                    ; 's' = 0x73
  401074:   75 55                   jne    4010cb <check_key+0x7b>

  401076:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  40107a:   0f b6 40 01             movzx  eax,BYTE PTR [rax+0x1]    ; input[1]
  40107e:   3c 33                   cmp    al,0x33                    ; '3' = 0x33
  401080:   75 49                   jne    4010cb <check_key+0x7b>

  401082:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  401086:   0f b6 40 02             movzx  eax,BYTE PTR [rax+0x2]    ; input[2]
  40108a:   3c 63                   cmp    al,0x63                    ; 'c' = 0x63
  40108c:   75 3d                   jne    4010cb <check_key+0x7b>

  40108e:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  401092:   0f b6 40 03             movzx  eax,BYTE PTR [rax+0x3]    ; input[3]
  401096:   3c 72                   cmp    al,0x72                    ; 'r' = 0x72
  401098:   75 31                   jne    4010cb <check_key+0x7b>

  ; --- Step 3: XOR-check remaining characters against key array ---
  ; The expected values (XOR'd with 0x42) are stored at 0x402050
  ; Expected XOR'd bytes: 0x27 0x76 0x2a 0x74 0x27 0x24 0x20 0x22
  ;                        0x75 0x2c 0x2b 0x24
  ; After XOR with 0x42:  'e'  '4'  'h'  '6'  'e'  'f'  'b'  '`'  -- wait
  ; Let's make this spell something:
  ; We want "s3cr" + "3t_k3y_v4lu3" = "s3cr3t_k3y_v4lu" (16 chars with null...
  ;   actually "s3cr" already set, need 12 more to get 16 total)
  ; Remaining 12 chars: "3t_k3y_v4lu3"
  ; XOR with 0x42:
  ;   '3'^0x42=0x71, 't'^0x42=0x36, '_'^0x42=0x1d, 'k'^0x42=0x29
  ;   '3'^0x42=0x71, 'y'^0x42=0x3b, '_'^0x42=0x1d, 'v'^0x42=0x34
  ;   '4'^0x42=0x76, 'l'^0x42=0x2e, 'u'^0x42=0x37, '3'^0x42=0x71

  40109a:   48 c7 45 e8 00 00 00    mov    QWORD PTR [rbp-0x18],0x0  ; i = 0
  4010a1:   00
  4010a2:   eb 1e                   jmp    4010c2 <check_key+0x72>   ; jump to loop check

  ; --- XOR comparison loop ---
  4010a4:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]   ; loop body start
  4010a8:   48 03 45 e8             add    rax,QWORD PTR [rbp-0x18]
  4010ac:   48 83 c0 04             add    rax,0x4                    ; &input[i+4]
  4010b0:   0f b6 10                movzx  edx,BYTE PTR [rax]         ; dl = input[i+4]
  4010b3:   80 f2 42                xor    dl,0x42                    ; dl ^= 0x42
  4010b6:   48 8d 05 93 0f 00 00    lea    rax,[rip+0xf93]           ; 402050 <xor_expected>
  4010bd:   48 03 45 e8             add    rax,QWORD PTR [rbp-0x18]
  4010c1:   0f b6 00                movzx  eax,BYTE PTR [rax]         ; al = expected[i]
  4010c4:   38 c2                   cmp    dl,al                      ; compare XOR'd input vs expected
  4010c6:   75 03                   jne    4010cb <check_key+0x7b>    ; fail if mismatch

  ; --- Loop increment and bounds check ---
  4010c8:   48 ff 45 e8             inc    QWORD PTR [rbp-0x18]      ; i++
  4010cc:   48 83 7d e8 0c          cmp    QWORD PTR [rbp-0x18],0xc  ; i < 12?
  4010d1:   7c d1                   jl     4010a4 <check_key+0x54>   ; continue loop

  ; --- All checks passed ---
  4010d3:   b8 01 00 00 00          mov    eax,0x1                    ; return 1 (success)
  4010d8:   eb 05                   jmp    4010df <check_key+0x8f>

  ; --- Failure path ---
  4010da:   b8 00 00 00 00          mov    eax,0x0                    ; return 0 (failure)

  4010df:   c9                      leave
  4010e0:   c3                      ret


; ==========================================================================
; Data referenced by check_key (in .rodata at 0x402050)
; These are the XOR-expected bytes for characters input[4] through input[15]
; To recover plaintext: expected[i] XOR 0x42 = correct_char
; ==========================================================================

Contents of section .rodata at 0x402050:
  402050:   71 36 1d 29 71 3b 1d 34 76 2e 37 71    q6.)q;.4v.7q

; Decoding the XOR table:
;   0x71 ^ 0x42 = 0x33 = '3'
;   0x36 ^ 0x42 = 0x74 = 't'
;   0x1d ^ 0x42 = 0x5f = '_'
;   0x29 ^ 0x42 = 0x6b = 'k'
;   0x71 ^ 0x42 = 0x33 = '3'
;   0x3b ^ 0x42 = 0x79 = 'y'
;   0x1d ^ 0x42 = 0x5f = '_'
;   0x34 ^ 0x42 = 0x76 = 'v'
;   0x76 ^ 0x42 = 0x34 = '4'
;   0x2e ^ 0x42 = 0x6c = 'l'
;   0x37 ^ 0x42 = 0x75 = 'u'
;   0x71 ^ 0x42 = 0x33 = '3'

; Full password: "s3cr" + "3t_k3y_v4lu3" = "s3cr3t_k3y_v4lu3"


; ==========================================================================
; decode_flag — called after successful key check
; Decodes the flag by XOR'ing stored bytes with key 0x42
; ==========================================================================

0000000000401100 <decode_flag>:
  401100:   55                      push   rbp
  401101:   48 89 e5                mov    rbp,rsp
  401104:   48 83 ec 30             sub    rsp,0x30
  401108:   48 8d 05 f1 0f 00 00    lea    rax,[rip+0xff1]           ; 402100 <encoded_flag>
  40110f:   48 89 45 d0             mov    QWORD PTR [rbp-0x30],rax  ; encoded_flag ptr
  401113:   48 c7 45 e8 00 00 00    mov    QWORD PTR [rbp-0x18],0x0 ; i = 0
  40111a:   00
  40111b:   eb 18                   jmp    401135 <decode_flag+0x35>

  ; --- Decode loop: flag[i] = encoded[i] ^ 0x42 ---
  40111d:   48 8b 45 d0             mov    rax,QWORD PTR [rbp-0x30]
  401121:   48 03 45 e8             add    rax,QWORD PTR [rbp-0x18]
  401125:   0f b6 10                movzx  edx,BYTE PTR [rax]        ; dl = encoded[i]
  401128:   80 f2 42                xor    dl,0x42                   ; dl ^= 0x42
  40112b:   48 8d 45 d8             lea    rax,[rbp-0x28]
  40112f:   48 03 45 e8             add    rax,QWORD PTR [rbp-0x18]
  401133:   88 10                   mov    BYTE PTR [rax],dl         ; decoded[i] = dl
  401135:   48 ff 45 e8             inc    QWORD PTR [rbp-0x18]     ; i++
  401139:   48 83 7d e8 18          cmp    QWORD PTR [rbp-0x18],0x18 ; i < 24?
  40113e:   7c dd                   jl     40111d <decode_flag+0x1d>

  ; --- Print decoded flag ---
  401140:   48 8d 7d d8             lea    rdi,[rbp-0x28]
  401144:   e8 b7 fd ff ff          call   400f00 <puts@plt>
  401149:   c9                      leave
  40114a:   c3                      ret


; ==========================================================================
; Encoded flag data at 0x402100 (24 bytes, XOR'd with 0x42)
;
; 04 2e 23 05 39 70 31 22 25 33 31 36 23 37 24 70 25 22 31 23 27 23 76 39
;
; Decode: each byte XOR 0x42:
;   0x04^0x42='F', 0x2e^0x42='l', 0x23^0x42='A', 0x05^0x42='G',
;   0x39^0x42='{', 0x70^0x42='2', 0x31^0x42='s', 0x22^0x42='`'...
;
; Let's encode FLAG{r3v3rs3_3ng1n33r1ng} (25 chars) with XOR 0x42:
;   F=0x46^0x42=0x04  L=0x4c^0x42=0x0e  A=0x41^0x42=0x03  G=0x47^0x42=0x05
;   {=0x7b^0x42=0x39  r=0x72^0x42=0x30  3=0x33^0x42=0x71  v=0x76^0x42=0x34
;   3=0x33^0x42=0x71  r=0x72^0x42=0x30  s=0x73^0x42=0x31  3=0x33^0x42=0x71
;   _=0x5f^0x42=0x1d  3=0x33^0x42=0x71  n=0x6e^0x42=0x2c  g=0x67^0x42=0x25
;   1=0x31^0x42=0x73  n=0x6e^0x42=0x2c  3=0x33^0x42=0x71  3=0x33^0x42=0x71
;   r=0x72^0x42=0x30  1=0x31^0x42=0x73  n=0x6e^0x42=0x2c  g=0x67^0x42=0x25
;   }=0x7d^0x42=0x3f
; ==========================================================================

Contents of section .rodata at 0x402100:
  402100:   04 0e 03 05 39 30 71 34 71 30 31 71    ....90q4q01q
  40210c:   1d 71 2c 25 73 2c 71 71 30 73 2c 25    .q,%s,qq0s,%
  402118:   3f                                      ?

; Decoded flag: FLAG{r3v3rs3_3ng1n33r1ng}


================================================================================
  ANALYSIS SUMMARY

  Password: s3cr3t_k3y_v4lu3
    - First 4 chars checked via direct byte comparison (0x73, 0x33, 0x63, 0x72)
    - Remaining 12 chars checked via XOR with 0x42 against stored table

  Flag: FLAG{r3v3rs3_3ng1n33r1ng}
    - Encoded in .rodata at 0x402100 using XOR with key 0x42
    - Decoded by decode_flag function after successful authentication

  Key observations for students:
    1. The length check (cmp rax, 0x10) reveals password is 16 characters
    2. Direct character comparisons leak the first 4 bytes of the password
    3. The XOR key (0x42) is visible in the xor dl,0x42 instruction
    4. The expected XOR'd values at 0x402050 can be decoded statically
    5. The encoded flag at 0x402100 uses the same XOR key
    6. No need to run the binary — pure static analysis is sufficient
================================================================================
