Hooks and stubs
Software is not made up of a unique function, and no longer of a unique binary file. Software interacts with environment and often depends of several libraries. It is now time to learn how to deal with external (dynamically linked) functions, using DBA function stubs.
In this chapter, we will use the simple challenge named level1
which comes from the site crackmes.one.
What is inside?
This challenge consist of an ELF x86-64
executable that dynamically links with libraries.
Even if it is quite small (~16KB
), it is already bigger than the previous examples.
By default, compilers tend to put a lot of metadata and to pad the content of sections to align on page boundaries (4KB
), leading easily to binary files of tens of kilobytes.
Hexdump
As before, we put here the summary of basic information that can be extracted via BINSEC.
Legend |
---|
Headers Magic |
Code Instructions |
Read-Only Data Strings |
Data Other Sections |
- Headers
- Disassembly
ELF Header: Class: ELF64 Data: 2's complement, little endian Type: DYN OS/ABI: Linux - GNU Kernel Version: 3.2.0 Machine: x86 Entry point address: 0x1060 Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .interp PROGBITS 0000000000000318 000318 00001c 00 A 0 0 1 [ 2] .note.gnu.p... NOTE 0000000000000338 000338 000020 00 A 0 0 8 [ 3] .note.gnu.b... NOTE 0000000000000358 000358 000024 00 A 0 0 4 [ 4] .note.ABI-tag NOTE 000000000000037c 00037c 000020 00 A 0 0 4 [ 5] .gnu.hash GNU_HASH 00000000000003a0 0003a0 000024 00 A 6 0 8 [ 6] .dynsym DYNSYM 00000000000003c8 0003c8 0000c0 18 A 7 1 8 [ 7] .dynstr STRTAB 0000000000000488 000488 0000a8 00 A 0 0 1 [ 8] .gnu.version VERSYM 0000000000000530 000530 000010 02 A 6 0 2 [ 9] .gnu.version_r VERNEED 0000000000000540 000540 000040 00 A 7 1 8 [10] .rela.dyn RELA 0000000000000580 000580 0000c0 18 A 6 0 8 [11] .rela.plt RELA 0000000000000640 000640 000030 18 AI 6 24 8 [12] .init PROGBITS 0000000000001000 001000 000017 00 AX 0 0 4 [13] .plt PROGBITS 0000000000001020 001020 000030 10 AX 0 0 16 [14] .plt.got PROGBITS 0000000000001050 001050 000008 08 AX 0 0 8 [15] .text PROGBITS 0000000000001060 001060 000208 00 AX 0 0 16 [16] .fini PROGBITS 0000000000001268 001268 000009 00 AX 0 0 4 [17] .rodata PROGBITS 0000000000002000 002000 000064 00 A 0 0 4 [18] .eh_frame_hdr PROGBITS 0000000000002064 002064 000034 00 A 0 0 4 [19] .eh_frame PROGBITS 0000000000002098 002098 0000cc 00 A 0 0 8 [20] .init_array INIT_ARRAY 0000000000003dd0 002dd0 000008 08 WA 0 0 8 [21] .fini_array FINI_ARRAY 0000000000003dd8 002dd8 000008 08 WA 0 0 8 [22] .dynamic DYNAMIC 0000000000003de0 002de0 0001e0 10 WA 7 0 8 [23] .got PROGBITS 0000000000003fc0 002fc0 000028 08 WA 0 0 8 [24] .got.plt PROGBITS 0000000000003fe8 002fe8 000028 08 WA 0 0 8 [25] .data PROGBITS 0000000000004010 003010 000010 00 WA 0 0 8 [26] .bss NOBITS 0000000000004020 003020 000008 00 WA 0 0 1 [27] .comment PROGBITS 0000000000000000 003020 00001f 01 MS 0 0 1 [28] .symtab SYMTAB 0000000000000000 003040 000390 18 29 18 8 [29] .strtab STRTAB 0000000000000000 0033d0 000203 00 0 0 1 [30] .shstrtab STRTAB 0000000000000000 0035d3 00011a 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), G (group), T (TLS), O (extra OS processing required) Symbol table '.dynsym' contains 8 entries: Num: Value Size Type Bind Section Name 0: 0000000000000000 0 NOTYPE LOCAL UND 1: 0000000000000000 0 FUNC GLOBAL UND __libc_start_main 2: 0000000000000000 0 NOTYPE WEAK UND _ITM_deregiste... 3: 0000000000000000 0 FUNC GLOBAL UND printf 4: 0000000000000000 0 NOTYPE WEAK UND __gmon_start__ 5: 0000000000000000 0 FUNC GLOBAL UND __isoc99_scanf 6: 0000000000000000 0 NOTYPE WEAK UND _ITM_registerT... 7: 0000000000000000 0 FUNC WEAK UND __cxa_finalize Symbol table '.symtab' contains 38 entries: Num: Value Size Type Bind Section Name 0: 0000000000000000 0 NOTYPE LOCAL UND 1: 0000000000000000 0 FILE LOCAL ABS Scrt1.o 2: 000000000000037c 32 OBJECT LOCAL .note.ABI-tag __abi_tag 3: 0000000000000000 0 FILE LOCAL ABS crtstuff.c 4: 0000000000001090 0 FUNC LOCAL .text deregister_tm_clones 5: 00000000000010c0 0 FUNC LOCAL .text register_tm_clones 6: 0000000000001100 0 FUNC LOCAL .text __do_global_dtors... 7: 0000000000004020 1 OBJECT LOCAL .bss completed.0 8: 0000000000003dd8 0 OBJECT LOCAL .fini_array __do_global_dtors... 9: 0000000000001140 0 FUNC LOCAL .text frame_dummy 10: 0000000000003dd0 0 OBJECT LOCAL .init_array __frame_dummy_ini... 11: 0000000000000000 0 FILE LOCAL ABS ch_first.c 12: 0000000000000000 0 FILE LOCAL ABS crtstuff.c 13: 0000000000002160 0 OBJECT LOCAL .eh_frame __FRAME_END__ 14: 0000000000000000 0 FILE LOCAL ABS 15: 0000000000003de0 0 OBJECT LOCAL .dynamic _DYNAMIC 16: 0000000000002064 0 NOTYPE LOCAL .eh_frame_hdr __GNU_EH_FRAME_HDR 17: 0000000000003fe8 0 OBJECT LOCAL .got.plt _GLOBAL_OFFSET_TA... 18: 0000000000000000 0 FUNC GLOBAL UND __libc_start_main... 19: 0000000000000000 0 NOTYPE WEAK UND _ITM_deregisterTM... 20: 0000000000004010 0 NOTYPE WEAK .data data_start 21: 0000000000004020 0 NOTYPE GLOBAL .data _edata 22: 0000000000001268 0 FUNC GLOBAL .fini _fini 23: 0000000000000000 0 FUNC GLOBAL UND printf@GLIBC_2.2.5 24: 0000000000004010 0 NOTYPE GLOBAL .data __data_start 25: 0000000000000000 0 NOTYPE WEAK UND __gmon_start__ 26: 0000000000004018 0 OBJECT GLOBAL .data __dso_handle 27: 0000000000002000 4 OBJECT GLOBAL .rodata _IO_stdin_used 28: 0000000000004028 0 NOTYPE GLOBAL .bss _end 29: 0000000000001060 34 FUNC GLOBAL .text _start 30: 0000000000001149 140 FUNC GLOBAL .text checkPass 31: 0000000000004020 0 NOTYPE GLOBAL .bss __bss_start 32: 00000000000011d5 147 FUNC GLOBAL .text main 33: 0000000000000000 0 FUNC GLOBAL UND __isoc99_scanf@GL... 34: 0000000000004020 0 OBJECT GLOBAL .data __TMC_END__ 35: 0000000000000000 0 NOTYPE WEAK UND _ITM_registerTMCl... 36: 0000000000000000 0 FUNC WEAK UND __cxa_finalize@GL... 37: 0000000000001000 0 FUNC GLOBAL .init _init
Disassembly of section .init:
00001000 <_init>: 001000: 48 83 ec 08 sub $0x8,%rsp
0: %%0<64> := (rsp<64> - 8<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rsp<64>) & %%0<64>)));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rsp<64> & ! (%%0<64>))));7: rsp<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x001004, 0)
001004: 48 8b 05 c5 2f 00 00 mov 0x2fc5(%rip),%rax
0: %%0<64> := @[0x0000000000003fd0,<-,8];
1: rax<64> := %%0<64>;
2: goto (0x00100b, 0)
00100b: 48 85 c0 test %rax,%rax
0: %%0<1> :=
!
((((rax<64>{0} ^ rax<64>{4}) ^ (rax<64>{2} ^ rax<64>{6})) ^
((rax<64>{1} ^ rax<64>{5}) ^ (rax<64>{3} ^ rax<64>{7}))));1: %%1<1> := undef;
2: %%2<1> := (0<64> = rax<64>);
3: %%3<1> := (rax<64> <s 0<64>);
4: of<1> := 0<1>;
5: sf<1> := %%3<1>;
6: zf<1> := %%2<1>;
7: af<1> := %%1<1>;
8: pf<1> := %%0<1>;
9: cf<1> := 0<1>;
10: goto (0x00100e, 0)
00100e: 74 02 je 0x1012
0: if zf<1> goto 2 else goto 1
1: goto (0x001010, 0)
2: goto (0x001012, 0)
001010: ff d0 call *%rax
0: %%0<64> := (rsp<64> - 8<64>);
1: %%1<64> := rax<64>;
2: @[%%0<64>,<-,8] := 0x0000000000001012;
3: rsp<64> := %%0<64>;
4: goto %%1<64> #call with return address @ (0x001012, 0)
001012: 48 83 c4 08 add $0x8,%rsp
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rsp<64> & ! (%%0<64>))));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rsp<64>) & %%0<64>)));7: rsp<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x001016, 0)
001016: c3 ret
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rsp<64> := %%0<64>;
3: goto %%1<64> #return
Disassembly of section .plt:
001020: ff 35 ca 2f 00 00 pushq 0x2fca(%rip)
0: %%0<64> := (rsp<64> - 8<64>);
1: %%1<64> := @[0x0000000000003ff0,<-,8];
2: @[%%0<64>,<-,8] := %%1<64>;
3: rsp<64> := %%0<64>;
4: goto (0x001026, 0)
001026: ff 25 cc 2f 00 00 jmp *0x2fcc(%rip)
0: %%0<64> := @[0x0000000000003ff8,<-,8];
1: goto %%0<64>
00102c: 0f 1f 40 00 nop
0: goto (0x001030, 0)
00001030 <printf@plt>: 001030: ff 25 ca 2f 00 00 jmp *0x2fca(%rip)
0: %%0<64> := @[0x0000000000004000,<-,8];
1: goto %%0<64>
001036: 68 00 00 00 00 pushq $0x0
0: %%0<64> := (rsp<64> - 8<64>);
1: @[%%0<64>,<-,8] := 0<64>;
2: rsp<64> := %%0<64>;
3: goto (0x00103b, 0)
00103b: e9 e0 ff ff ff jmp 0x1020
0: goto (0x001020, 0)
00001040 <__isoc99_scanf@plt>: 001040: ff 25 c2 2f 00 00 jmp *0x2fc2(%rip)
0: %%0<64> := @[0x0000000000004008,<-,8];
1: goto %%0<64>
001046: 68 01 00 00 00 pushq $0x1
0: %%0<64> := (rsp<64> - 8<64>);
1: @[%%0<64>,<-,8] := 1<64>;
2: rsp<64> := %%0<64>;
3: goto (0x00104b, 0)
00104b: e9 d0 ff ff ff jmp 0x1020
0: goto (0x001020, 0)
Disassembly of section .plt.got:
001050: ff 25 8a 2f 00 00 jmp *0x2f8a(%rip)
0: %%0<64> := @[0x0000000000003fe0,<-,8];
1: goto %%0<64>
001056: 66 90 nop
0: goto (0x001058, 0)
Disassembly of section .text:
00001060 <_start>: 001060: 31 ed xor %ebp,%ebp
0: %%0<1> := undef;
1: rbp<64> := 0<64>;
2: of<1> := 0<1>;
3: sf<1> := 0<1>;
4: zf<1> := -1<1>;
5: af<1> := %%0<1>;
6: pf<1> := -1<1>;
7: cf<1> := 0<1>;
8: goto (0x001062, 0)
001062: 49 89 d1 mov %rdx,%r9
0: %%0<64> := rdx<64>;
1: r9<64> := %%0<64>;
2: goto (0x001065, 0)
001065: 5e pop %rsi
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rsi<64> := %%1<64>;
3: rsp<64> := %%0<64>;
4: goto (0x001066, 0)
001066: 48 89 e2 mov %rsp,%rdx
0: %%0<64> := rsp<64>;
1: rdx<64> := %%0<64>;
2: goto (0x001069, 0)
001069: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
0: %%0<64> := (-16<64> & rsp<64>);
1: %%1<1> := ! (((rsp<64>{4} ^ rsp<64>{6}) ^ (rsp<64>{5} ^ rsp<64>{7})));
2: %%2<1> := undef;
3: %%3<1> := (0<64> = %%0<64>);
4: %%4<1> := (%%0<64> <s 0<64>);
5: rsp<64> := %%0<64>;
6: of<1> := 0<1>;
7: sf<1> := %%4<1>;
8: zf<1> := %%3<1>;
9: af<1> := %%2<1>;
10: pf<1> := %%1<1>;
11: cf<1> := 0<1>;
12: goto (0x00106d, 0)
00106d: 50 push %rax
0: %%0<64> := (rsp<64> - 8<64>);
1: %%1<64> := rax<64>;
2: @[%%0<64>,<-,8] := %%1<64>;
3: rsp<64> := %%0<64>;
4: goto (0x00106e, 0)
00106e: 54 push %rsp
0: %%0<64> := (rsp<64> - 8<64>);
1: %%1<64> := rsp<64>;
2: @[%%0<64>,<-,8] := %%1<64>;
3: rsp<64> := %%0<64>;
4: goto (0x00106f, 0)
00106f: 45 31 c0 xor %r8d,%r8d
0: %%0<1> := undef;
1: r8<64> := 0<64>;
2: of<1> := 0<1>;
3: sf<1> := 0<1>;
4: zf<1> := -1<1>;
5: af<1> := %%0<1>;
6: pf<1> := -1<1>;
7: cf<1> := 0<1>;
8: goto (0x001072, 0)
001072: 31 c9 xor %ecx,%ecx
0: %%0<1> := undef;
1: rcx<64> := 0<64>;
2: of<1> := 0<1>;
3: sf<1> := 0<1>;
4: zf<1> := -1<1>;
5: af<1> := %%0<1>;
6: pf<1> := -1<1>;
7: cf<1> := 0<1>;
8: goto (0x001074, 0)
001074: 48 8d 3d 5a 01 00 00 lea 0x15a(%rip),%rdi
0: rdi<64> := 0x00000000000011d5;
1: goto (0x00107b, 0)
00107b: ff 15 3f 2f 00 00 call *0x2f3f(%rip)
0: %%0<64> := (rsp<64> - 8<64>);
1: %%1<64> := @[0x0000000000003fc0,<-,8];
2: @[%%0<64>,<-,8] := 0x0000000000001081;
3: rsp<64> := %%0<64>;
4: goto %%1<64> #call with return address @ (0x001081, 0)
001081: f4 hlt
0: #unsupported hlt
001082: 66 2e 0f 1f 84 00 00 00 00 00 nop
0: goto (0x00108c, 0)
00108c: 0f 1f 40 00 nop
0: goto (0x001090, 0)
00001090 <deregister_tm_clones>: 001090: 48 8d 3d 89 2f 00 00 lea 0x2f89(%rip),%rdi
0: rdi<64> := 0x0000000000004020;
1: goto (0x001097, 0)
001097: 48 8d 05 82 2f 00 00 lea 0x2f82(%rip),%rax
0: rax<64> := 0x0000000000004020;
1: goto (0x00109e, 0)
00109e: 48 39 f8 cmp %rdi,%rax
0: %%0<64> := ! (rax<64>);
1: %%1<64> := (rax<64> - rdi<64>);
2: %%2<64> := ! (%%1<64>);
3: %%3<64> := (%%0<64> & rdi<64>);
4: %%4<1> :=
(0x8000000000000000 =
(0x8000000000000000 &
(((%%0<64> | rdi<64>) & %%1<64>) | (%%3<64> & %%2<64>))));5: %%5<1> :=
!
((((%%1<64>{0} ^ %%1<64>{4}) ^ (%%1<64>{2} ^ %%1<64>{6})) ^
((%%1<64>{1} ^ %%1<64>{5}) ^ (%%1<64>{3} ^ %%1<64>{7}))));6: %%6<1> := undef;
7: %%7<1> := (0<64> = %%1<64>);
8: %%8<1> := (%%1<64> <s 0<64>);
9: %%9<1> :=
(0x8000000000000000 =
(0x8000000000000000 &
(((rax<64> & ! (rdi<64>)) & %%2<64>) | (%%3<64> & %%1<64>))));10: of<1> := %%9<1>;
11: sf<1> := %%8<1>;
12: zf<1> := %%7<1>;
13: af<1> := %%6<1>;
14: pf<1> := %%5<1>;
15: cf<1> := %%4<1>;
16: goto (0x0010a1, 0)
0010a1: 74 15 je 0x10b8
0: if zf<1> goto 2 else goto 1
1: goto (0x0010a3, 0)
2: goto (0x0010b8, 0)
0010a3: 48 8b 05 1e 2f 00 00 mov 0x2f1e(%rip),%rax
0: %%0<64> := @[0x0000000000003fc8,<-,8];
1: rax<64> := %%0<64>;
2: goto (0x0010aa, 0)
0010aa: 48 85 c0 test %rax,%rax
0: %%0<1> :=
!
((((rax<64>{0} ^ rax<64>{4}) ^ (rax<64>{2} ^ rax<64>{6})) ^
((rax<64>{1} ^ rax<64>{5}) ^ (rax<64>{3} ^ rax<64>{7}))));1: %%1<1> := undef;
2: %%2<1> := (0<64> = rax<64>);
3: %%3<1> := (rax<64> <s 0<64>);
4: of<1> := 0<1>;
5: sf<1> := %%3<1>;
6: zf<1> := %%2<1>;
7: af<1> := %%1<1>;
8: pf<1> := %%0<1>;
9: cf<1> := 0<1>;
10: goto (0x0010ad, 0)
0010ad: 74 09 je 0x10b8
0: if zf<1> goto 2 else goto 1
1: goto (0x0010af, 0)
2: goto (0x0010b8, 0)
0010af: ff e0 jmp *%rax
0: %%0<64> := rax<64>;
1: goto %%0<64>
0010b1: 0f 1f 80 00 00 00 00 nop
0: goto (0x0010b8, 0)
0010b8: c3 ret
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rsp<64> := %%0<64>;
3: goto %%1<64> #return
0010b9: 0f 1f 80 00 00 00 00 nop
0: goto (0x0010c0, 0)
000010c0 <register_tm_clones>: 0010c0: 48 8d 3d 59 2f 00 00 lea 0x2f59(%rip),%rdi
0: rdi<64> := 0x0000000000004020;
1: goto (0x0010c7, 0)
0010c7: 48 8d 35 52 2f 00 00 lea 0x2f52(%rip),%rsi
0: rsi<64> := 0x0000000000004020;
1: goto (0x0010ce, 0)
0010ce: 48 29 fe sub %rdi,%rsi
0: %%0<64> := ! (rsi<64>);
1: %%1<64> := (rsi<64> - rdi<64>);
2: %%2<64> := ! (%%1<64>);
3: %%3<64> := (%%0<64> & rdi<64>);
4: %%4<1> :=
(0x8000000000000000 =
(0x8000000000000000 &
(((%%0<64> | rdi<64>) & %%1<64>) | (%%3<64> & %%2<64>))));5: %%5<1> :=
!
((((%%1<64>{0} ^ %%1<64>{4}) ^ (%%1<64>{2} ^ %%1<64>{6})) ^
((%%1<64>{1} ^ %%1<64>{5}) ^ (%%1<64>{3} ^ %%1<64>{7}))));6: %%6<1> := undef;
7: %%7<1> := (0<64> = %%1<64>);
8: %%8<1> := (%%1<64> <s 0<64>);
9: %%9<1> :=
(0x8000000000000000 =
(0x8000000000000000 &
(((rsi<64> & ! (rdi<64>)) & %%2<64>) | (%%3<64> & %%1<64>))));10: rsi<64> := %%1<64>;
11: of<1> := %%9<1>;
12: sf<1> := %%8<1>;
13: zf<1> := %%7<1>;
14: af<1> := %%6<1>;
15: pf<1> := %%5<1>;
16: cf<1> := %%4<1>;
17: goto (0x0010d1, 0)
0010d1: 48 89 f0 mov %rsi,%rax
0: %%0<64> := rsi<64>;
1: rax<64> := %%0<64>;
2: goto (0x0010d4, 0)
0010d4: 48 c1 ee 3f shr $0x3f,%rsi
0: %%0<64> := (rsi<64> lsr 63<64>);
1: %%1<1> := rsi<64>{62};
2: %%2<1> := ! (rsi<64>{63});
3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> := undef;
7: rsi<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x0010d8, 0)
0010d8: 48 c1 f8 03 sar $0x3,%rax
0: %%0<64> := (rax<64> asr 3<64>);
1: %%1<1> := rax<64>{2};
2: %%2<1> :=
!
((((rax<64>{3} ^ rax<64>{7}) ^ (rax<64>{5} ^ rax<64>{9})) ^
((rax<64>{4} ^ rax<64>{8}) ^ (rax<64>{6} ^ rax<64>{10}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> := undef;
7: rax<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x0010dc, 0)
0010dc: 48 01 c6 add %rax,%rsi
0: %%0<64> := (rsi<64> & rax<64>);
1: %%1<64> := (rsi<64> + rax<64>);
2: %%2<64> := ! (%%1<64>);
3: %%3<1> :=
(0x8000000000000000 =
(0x8000000000000000 &
(((rsi<64> | rax<64>) & %%2<64>) | (%%0<64> & %%1<64>))));4: %%4<1> :=
!
((((%%1<64>{0} ^ %%1<64>{4}) ^ (%%1<64>{2} ^ %%1<64>{6})) ^
((%%1<64>{1} ^ %%1<64>{5}) ^ (%%1<64>{3} ^ %%1<64>{7}))));5: %%5<1> := undef;
6: %%6<1> := (0<64> = %%1<64>);
7: %%7<1> := (%%1<64> <s 0<64>);
8: %%8<1> :=
(0x8000000000000000 =
(0x8000000000000000 &
((%%0<64> & %%2<64>) | ((! (rsi<64>) & ! (rax<64>)) & %%1<64>))));9: rsi<64> := %%1<64>;
10: of<1> := %%8<1>;
11: sf<1> := %%7<1>;
12: zf<1> := %%6<1>;
13: af<1> := %%5<1>;
14: pf<1> := %%4<1>;
15: cf<1> := %%3<1>;
16: goto (0x0010df, 0)
0010df: 48 d1 fe sar $0x1,%rsi
0: %%0<64> := (rsi<64> asr 1<64>);
1: %%1<1> := (0<64> <> (1<64> & rsi<64>));
2: %%2<1> :=
!
((((rsi<64>{1} ^ rsi<64>{5}) ^ (rsi<64>{3} ^ rsi<64>{7})) ^
((rsi<64>{2} ^ rsi<64>{6}) ^ (rsi<64>{4} ^ rsi<64>{8}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: rsi<64> := %%0<64>;
7: of<1> := 0<1>;
8: sf<1> := %%5<1>;
9: zf<1> := %%4<1>;
10: af<1> := %%3<1>;
11: pf<1> := %%2<1>;
12: cf<1> := %%1<1>;
13: goto (0x0010e2, 0)
0010e2: 74 14 je 0x10f8
0: if zf<1> goto 2 else goto 1
1: goto (0x0010e4, 0)
2: goto (0x0010f8, 0)
0010e4: 48 8b 05 ed 2e 00 00 mov 0x2eed(%rip),%rax
0: %%0<64> := @[0x0000000000003fd8,<-,8];
1: rax<64> := %%0<64>;
2: goto (0x0010eb, 0)
0010eb: 48 85 c0 test %rax,%rax
0: %%0<1> :=
!
((((rax<64>{0} ^ rax<64>{4}) ^ (rax<64>{2} ^ rax<64>{6})) ^
((rax<64>{1} ^ rax<64>{5}) ^ (rax<64>{3} ^ rax<64>{7}))));1: %%1<1> := undef;
2: %%2<1> := (0<64> = rax<64>);
3: %%3<1> := (rax<64> <s 0<64>);
4: of<1> := 0<1>;
5: sf<1> := %%3<1>;
6: zf<1> := %%2<1>;
7: af<1> := %%1<1>;
8: pf<1> := %%0<1>;
9: cf<1> := 0<1>;
10: goto (0x0010ee, 0)
0010ee: 74 08 je 0x10f8
0: if zf<1> goto 2 else goto 1
1: goto (0x0010f0, 0)
2: goto (0x0010f8, 0)
0010f0: ff e0 jmp *%rax
0: %%0<64> := rax<64>;
1: goto %%0<64>
0010f2: 66 0f 1f 44 00 00 nop
0: goto (0x0010f8, 0)
0010f8: c3 ret
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rsp<64> := %%0<64>;
3: goto %%1<64> #return
0010f9: 0f 1f 80 00 00 00 00 nop
0: goto (0x001100, 0)
00001100 <__do_global_dtors_aux>: 001100: f3 0f 1e fa hint<16> %rdi,%rdx
0: goto (0x001104, 0)
001104: 80 3d 15 2f 00 00 00 cmpb $0x0,0x2f15(%rip)
0: %%0<8> := @[0x0000000000004020,<-,1];
1: %%1<8> := %%0<8>;
2: %%2<1> := (-128<8> = (-128<8> & (! (%%0<8>) & %%1<8>)));
3: %%3<1> :=
!
((((%%1<8>{0} ^ %%1<8>{4}) ^ (%%1<8>{2} ^ %%1<8>{6})) ^
((%%1<8>{1} ^ %%1<8>{5}) ^ (%%1<8>{3} ^ %%1<8>{7}))));4: %%4<1> := undef;
5: %%5<1> := (0<8> = %%1<8>);
6: %%6<1> := (%%1<8> <s 0<8>);
7: %%7<1> := (-128<8> = (-128<8> & (%%0<8> & ! (%%1<8>))));
8: of<1> := %%7<1>;
9: sf<1> := %%6<1>;
10: zf<1> := %%5<1>;
11: af<1> := %%4<1>;
12: pf<1> := %%3<1>;
13: cf<1> := %%2<1>;
14: goto (0x00110b, 0)
00110b: 75 2b jne 0x1138
0: if ! (zf<1>) goto 2 else goto 1
1: goto (0x00110d, 0)
2: goto (0x001138, 0)
00110d: 55 push %rbp
0: %%0<64> := (rsp<64> - 8<64>);
1: %%1<64> := rbp<64>;
2: @[%%0<64>,<-,8] := %%1<64>;
3: rsp<64> := %%0<64>;
4: goto (0x00110e, 0)
00110e: 48 83 3d ca 2e 00 00 00 cmpq $0x0,0x2eca(%rip)
0: %%0<64> := @[0x0000000000003fe0,<-,8];
1: %%1<64> := %%0<64>;
2: %%2<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (%%0<64>) & %%1<64>)));3: %%3<1> :=
!
((((%%1<64>{0} ^ %%1<64>{4}) ^ (%%1<64>{2} ^ %%1<64>{6})) ^
((%%1<64>{1} ^ %%1<64>{5}) ^ (%%1<64>{3} ^ %%1<64>{7}))));4: %%4<1> := undef;
5: %%5<1> := (0<64> = %%1<64>);
6: %%6<1> := (%%1<64> <s 0<64>);
7: %%7<1> :=
(0x8000000000000000 = (0x8000000000000000 & (%%0<64> & ! (%%1<64>))));8: of<1> := %%7<1>;
9: sf<1> := %%6<1>;
10: zf<1> := %%5<1>;
11: af<1> := %%4<1>;
12: pf<1> := %%3<1>;
13: cf<1> := %%2<1>;
14: goto (0x001116, 0)
001116: 48 89 e5 mov %rsp,%rbp
0: %%0<64> := rsp<64>;
1: rbp<64> := %%0<64>;
2: goto (0x001119, 0)
001119: 74 0c je 0x1127
0: if zf<1> goto 2 else goto 1
1: goto (0x00111b, 0)
2: goto (0x001127, 0)
00111b: 48 8b 3d f6 2e 00 00 mov 0x2ef6(%rip),%rdi
0: %%0<64> := @[0x0000000000004018,<-,8];
1: rdi<64> := %%0<64>;
2: goto (0x001122, 0)
001122: e8 29 ff ff ff call 0x1050
0: %%0<64> := (rsp<64> - 8<64>);
1: @[%%0<64>,<-,8] := 0x0000000000001127;
2: rsp<64> := %%0<64>;
3: goto (0x001050, 0) #call with return address @ (0x001127, 0)
001127: e8 64 ff ff ff call 0x1090
0: %%0<64> := (rsp<64> - 8<64>);
1: @[%%0<64>,<-,8] := 0x000000000000112c;
2: rsp<64> := %%0<64>;
3: goto (0x001090, 0) #call with return address @ (0x00112c, 0)
00112c: c6 05 ed 2e 00 00 01 movb $0x1,0x2eed(%rip)
0: @[0x0000000000004020,<-,1] := 1<8>;
1: goto (0x001133, 0)
001133: 5d pop %rbp
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rbp<64> := %%1<64>;
3: rsp<64> := %%0<64>;
4: goto (0x001134, 0)
001134: c3 ret
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rsp<64> := %%0<64>;
3: goto %%1<64> #return
001135: 0f 1f 00 nop
0: goto (0x001138, 0)
001138: c3 ret
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rsp<64> := %%0<64>;
3: goto %%1<64> #return
001139: 0f 1f 80 00 00 00 00 nop
0: goto (0x001140, 0)
00001140 <frame_dummy>: 001140: f3 0f 1e fa hint<16> %rdi,%rdx
0: goto (0x001144, 0)
001144: e9 77 ff ff ff jmp 0x10c0
0: goto (0x0010c0, 0)
00001149 <checkPass>: 001149: 55 push %rbp
0: %%0<64> := (rsp<64> - 8<64>);
1: %%1<64> := rbp<64>;
2: @[%%0<64>,<-,8] := %%1<64>;
3: rsp<64> := %%0<64>;
4: goto (0x00114a, 0)
00114a: 48 89 e5 mov %rsp,%rbp
0: %%0<64> := rsp<64>;
1: rbp<64> := %%0<64>;
2: goto (0x00114d, 0)
00114d: 48 89 7d f8 mov %rdi,-0x8(%rbp)
0: %%0<64> := rdi<64>;
1: %%1<64> := (rbp<64> + -8<64>);
2: @[%%1<64>,<-,8] := %%0<64>;
3: goto (0x001151, 0)
001151: 48 8b 45 f8 mov -0x8(%rbp),%rax
0: %%0<64> := @[(rbp<64> + -8<64>),<-,8];
1: rax<64> := %%0<64>;
2: goto (0x001155, 0)
001155: 0f b6 00 movzbl (%rax),%eax
0: %%0<64> := (uext64 @[rax<64>,<-,1]);
1: rax<64> := %%0<64>;
2: goto (0x001158, 0)
001158: 3c 73 cmp $0x73,%al
0: %%0<8> := rax<64>{7..0};
1: %%1<8> := (%%0<8> - 115<8>);
2: %%2<1> := (-128<8> = (-128<8> & (! (%%0<8>) & %%1<8>)));
3: %%3<1> :=
!
((((%%1<8>{0} ^ %%1<8>{4}) ^ (%%1<8>{2} ^ %%1<8>{6})) ^
((%%1<8>{1} ^ %%1<8>{5}) ^ (%%1<8>{3} ^ %%1<8>{7}))));4: %%4<1> := undef;
5: %%5<1> := (0<8> = %%1<8>);
6: %%6<1> := (%%1<8> <s 0<8>);
7: %%7<1> := (-128<8> = (-128<8> & (%%0<8> & ! (%%1<8>))));
8: of<1> := %%7<1>;
9: sf<1> := %%6<1>;
10: zf<1> := %%5<1>;
11: af<1> := %%4<1>;
12: pf<1> := %%3<1>;
13: cf<1> := %%2<1>;
14: goto (0x00115a, 0)
00115a: 75 70 jne 0x11cc
0: if ! (zf<1>) goto 2 else goto 1
1: goto (0x00115c, 0)
2: goto (0x0011cc, 0)
00115c: 48 8b 45 f8 mov -0x8(%rbp),%rax
0: %%0<64> := @[(rbp<64> + -8<64>),<-,8];
1: rax<64> := %%0<64>;
2: goto (0x001160, 0)
001160: 48 83 c0 01 add $0x1,%rax
0: %%0<64> := (rax<64> + 1<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rax<64> & ! (%%0<64>))));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rax<64>) & %%0<64>)));7: rax<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x001164, 0)
001164: 0f b6 00 movzbl (%rax),%eax
0: %%0<64> := (uext64 @[rax<64>,<-,1]);
1: rax<64> := %%0<64>;
2: goto (0x001167, 0)
001167: 3c 75 cmp $0x75,%al
0: %%0<8> := rax<64>{7..0};
1: %%1<8> := (%%0<8> - 117<8>);
2: %%2<1> := (-128<8> = (-128<8> & (! (%%0<8>) & %%1<8>)));
3: %%3<1> :=
!
((((%%1<8>{0} ^ %%1<8>{4}) ^ (%%1<8>{2} ^ %%1<8>{6})) ^
((%%1<8>{1} ^ %%1<8>{5}) ^ (%%1<8>{3} ^ %%1<8>{7}))));4: %%4<1> := undef;
5: %%5<1> := (0<8> = %%1<8>);
6: %%6<1> := (%%1<8> <s 0<8>);
7: %%7<1> := (-128<8> = (-128<8> & (%%0<8> & ! (%%1<8>))));
8: of<1> := %%7<1>;
9: sf<1> := %%6<1>;
10: zf<1> := %%5<1>;
11: af<1> := %%4<1>;
12: pf<1> := %%3<1>;
13: cf<1> := %%2<1>;
14: goto (0x001169, 0)
001169: 75 61 jne 0x11cc
0: if ! (zf<1>) goto 2 else goto 1
1: goto (0x00116b, 0)
2: goto (0x0011cc, 0)
00116b: 48 8b 45 f8 mov -0x8(%rbp),%rax
0: %%0<64> := @[(rbp<64> + -8<64>),<-,8];
1: rax<64> := %%0<64>;
2: goto (0x00116f, 0)
00116f: 48 83 c0 02 add $0x2,%rax
0: %%0<64> := (rax<64> + 2<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rax<64> & ! (%%0<64>))));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rax<64>) & %%0<64>)));7: rax<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x001173, 0)
001173: 0f b6 00 movzbl (%rax),%eax
0: %%0<64> := (uext64 @[rax<64>,<-,1]);
1: rax<64> := %%0<64>;
2: goto (0x001176, 0)
001176: 3c 64 cmp $0x64,%al
0: %%0<8> := rax<64>{7..0};
1: %%1<8> := (%%0<8> - 100<8>);
2: %%2<1> := (-128<8> = (-128<8> & (! (%%0<8>) & %%1<8>)));
3: %%3<1> :=
!
((((%%1<8>{0} ^ %%1<8>{4}) ^ (%%1<8>{2} ^ %%1<8>{6})) ^
((%%1<8>{1} ^ %%1<8>{5}) ^ (%%1<8>{3} ^ %%1<8>{7}))));4: %%4<1> := undef;
5: %%5<1> := (0<8> = %%1<8>);
6: %%6<1> := (%%1<8> <s 0<8>);
7: %%7<1> := (-128<8> = (-128<8> & (%%0<8> & ! (%%1<8>))));
8: of<1> := %%7<1>;
9: sf<1> := %%6<1>;
10: zf<1> := %%5<1>;
11: af<1> := %%4<1>;
12: pf<1> := %%3<1>;
13: cf<1> := %%2<1>;
14: goto (0x001178, 0)
001178: 75 52 jne 0x11cc
0: if ! (zf<1>) goto 2 else goto 1
1: goto (0x00117a, 0)
2: goto (0x0011cc, 0)
00117a: 48 8b 45 f8 mov -0x8(%rbp),%rax
0: %%0<64> := @[(rbp<64> + -8<64>),<-,8];
1: rax<64> := %%0<64>;
2: goto (0x00117e, 0)
00117e: 48 83 c0 03 add $0x3,%rax
0: %%0<64> := (rax<64> + 3<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rax<64> & ! (%%0<64>))));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rax<64>) & %%0<64>)));7: rax<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x001182, 0)
001182: 0f b6 00 movzbl (%rax),%eax
0: %%0<64> := (uext64 @[rax<64>,<-,1]);
1: rax<64> := %%0<64>;
2: goto (0x001185, 0)
001185: 3c 6f cmp $0x6f,%al
0: %%0<8> := rax<64>{7..0};
1: %%1<8> := (%%0<8> - 111<8>);
2: %%2<1> := (-128<8> = (-128<8> & (! (%%0<8>) & %%1<8>)));
3: %%3<1> :=
!
((((%%1<8>{0} ^ %%1<8>{4}) ^ (%%1<8>{2} ^ %%1<8>{6})) ^
((%%1<8>{1} ^ %%1<8>{5}) ^ (%%1<8>{3} ^ %%1<8>{7}))));4: %%4<1> := undef;
5: %%5<1> := (0<8> = %%1<8>);
6: %%6<1> := (%%1<8> <s 0<8>);
7: %%7<1> := (-128<8> = (-128<8> & (%%0<8> & ! (%%1<8>))));
8: of<1> := %%7<1>;
9: sf<1> := %%6<1>;
10: zf<1> := %%5<1>;
11: af<1> := %%4<1>;
12: pf<1> := %%3<1>;
13: cf<1> := %%2<1>;
14: goto (0x001187, 0)
001187: 75 43 jne 0x11cc
0: if ! (zf<1>) goto 2 else goto 1
1: goto (0x001189, 0)
2: goto (0x0011cc, 0)
001189: 48 8b 45 f8 mov -0x8(%rbp),%rax
0: %%0<64> := @[(rbp<64> + -8<64>),<-,8];
1: rax<64> := %%0<64>;
2: goto (0x00118d, 0)
00118d: 48 83 c0 04 add $0x4,%rax
0: %%0<64> := (rax<64> + 4<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rax<64> & ! (%%0<64>))));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rax<64>) & %%0<64>)));7: rax<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x001191, 0)
001191: 0f b6 00 movzbl (%rax),%eax
0: %%0<64> := (uext64 @[rax<64>,<-,1]);
1: rax<64> := %%0<64>;
2: goto (0x001194, 0)
001194: 3c 30 cmp $0x30,%al
0: %%0<8> := rax<64>{7..0};
1: %%1<8> := (%%0<8> - 48<8>);
2: %%2<1> := (-128<8> = (-128<8> & (! (%%0<8>) & %%1<8>)));
3: %%3<1> :=
!
((((%%1<8>{0} ^ %%1<8>{4}) ^ (%%1<8>{2} ^ %%1<8>{6})) ^
((%%1<8>{1} ^ %%1<8>{5}) ^ (%%1<8>{3} ^ %%1<8>{7}))));4: %%4<1> := undef;
5: %%5<1> := (0<8> = %%1<8>);
6: %%6<1> := (%%1<8> <s 0<8>);
7: %%7<1> := (-128<8> = (-128<8> & (%%0<8> & ! (%%1<8>))));
8: of<1> := %%7<1>;
9: sf<1> := %%6<1>;
10: zf<1> := %%5<1>;
11: af<1> := %%4<1>;
12: pf<1> := %%3<1>;
13: cf<1> := %%2<1>;
14: goto (0x001196, 0)
001196: 75 34 jne 0x11cc
0: if ! (zf<1>) goto 2 else goto 1
1: goto (0x001198, 0)
2: goto (0x0011cc, 0)
001198: 48 8b 45 f8 mov -0x8(%rbp),%rax
0: %%0<64> := @[(rbp<64> + -8<64>),<-,8];
1: rax<64> := %%0<64>;
2: goto (0x00119c, 0)
00119c: 48 83 c0 05 add $0x5,%rax
0: %%0<64> := (rax<64> + 5<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rax<64> & ! (%%0<64>))));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rax<64>) & %%0<64>)));7: rax<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x0011a0, 0)
0011a0: 0f b6 00 movzbl (%rax),%eax
0: %%0<64> := (uext64 @[rax<64>,<-,1]);
1: rax<64> := %%0<64>;
2: goto (0x0011a3, 0)
0011a3: 3c 78 cmp $0x78,%al
0: %%0<8> := rax<64>{7..0};
1: %%1<8> := (%%0<8> - 120<8>);
2: %%2<1> := (-128<8> = (-128<8> & (! (%%0<8>) & %%1<8>)));
3: %%3<1> :=
!
((((%%1<8>{0} ^ %%1<8>{4}) ^ (%%1<8>{2} ^ %%1<8>{6})) ^
((%%1<8>{1} ^ %%1<8>{5}) ^ (%%1<8>{3} ^ %%1<8>{7}))));4: %%4<1> := undef;
5: %%5<1> := (0<8> = %%1<8>);
6: %%6<1> := (%%1<8> <s 0<8>);
7: %%7<1> := (-128<8> = (-128<8> & (%%0<8> & ! (%%1<8>))));
8: of<1> := %%7<1>;
9: sf<1> := %%6<1>;
10: zf<1> := %%5<1>;
11: af<1> := %%4<1>;
12: pf<1> := %%3<1>;
13: cf<1> := %%2<1>;
14: goto (0x0011a5, 0)
0011a5: 75 25 jne 0x11cc
0: if ! (zf<1>) goto 2 else goto 1
1: goto (0x0011a7, 0)
2: goto (0x0011cc, 0)
0011a7: 48 8b 45 f8 mov -0x8(%rbp),%rax
0: %%0<64> := @[(rbp<64> + -8<64>),<-,8];
1: rax<64> := %%0<64>;
2: goto (0x0011ab, 0)
0011ab: 48 83 c0 06 add $0x6,%rax
0: %%0<64> := (rax<64> + 6<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rax<64> & ! (%%0<64>))));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rax<64>) & %%0<64>)));7: rax<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x0011af, 0)
0011af: 0f b6 00 movzbl (%rax),%eax
0: %%0<64> := (uext64 @[rax<64>,<-,1]);
1: rax<64> := %%0<64>;
2: goto (0x0011b2, 0)
0011b2: 3c 31 cmp $0x31,%al
0: %%0<8> := rax<64>{7..0};
1: %%1<8> := (%%0<8> - 49<8>);
2: %%2<1> := (-128<8> = (-128<8> & (! (%%0<8>) & %%1<8>)));
3: %%3<1> :=
!
((((%%1<8>{0} ^ %%1<8>{4}) ^ (%%1<8>{2} ^ %%1<8>{6})) ^
((%%1<8>{1} ^ %%1<8>{5}) ^ (%%1<8>{3} ^ %%1<8>{7}))));4: %%4<1> := undef;
5: %%5<1> := (0<8> = %%1<8>);
6: %%6<1> := (%%1<8> <s 0<8>);
7: %%7<1> := (-128<8> = (-128<8> & (%%0<8> & ! (%%1<8>))));
8: of<1> := %%7<1>;
9: sf<1> := %%6<1>;
10: zf<1> := %%5<1>;
11: af<1> := %%4<1>;
12: pf<1> := %%3<1>;
13: cf<1> := %%2<1>;
14: goto (0x0011b4, 0)
0011b4: 75 16 jne 0x11cc
0: if ! (zf<1>) goto 2 else goto 1
1: goto (0x0011b6, 0)
2: goto (0x0011cc, 0)
0011b6: 48 8b 45 f8 mov -0x8(%rbp),%rax
0: %%0<64> := @[(rbp<64> + -8<64>),<-,8];
1: rax<64> := %%0<64>;
2: goto (0x0011ba, 0)
0011ba: 48 83 c0 07 add $0x7,%rax
0: %%0<64> := (rax<64> + 7<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rax<64> & ! (%%0<64>))));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rax<64>) & %%0<64>)));7: rax<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x0011be, 0)
0011be: 0f b6 00 movzbl (%rax),%eax
0: %%0<64> := (uext64 @[rax<64>,<-,1]);
1: rax<64> := %%0<64>;
2: goto (0x0011c1, 0)
0011c1: 3c 38 cmp $0x38,%al
0: %%0<8> := rax<64>{7..0};
1: %%1<8> := (%%0<8> - 56<8>);
2: %%2<1> := (-128<8> = (-128<8> & (! (%%0<8>) & %%1<8>)));
3: %%3<1> :=
!
((((%%1<8>{0} ^ %%1<8>{4}) ^ (%%1<8>{2} ^ %%1<8>{6})) ^
((%%1<8>{1} ^ %%1<8>{5}) ^ (%%1<8>{3} ^ %%1<8>{7}))));4: %%4<1> := undef;
5: %%5<1> := (0<8> = %%1<8>);
6: %%6<1> := (%%1<8> <s 0<8>);
7: %%7<1> := (-128<8> = (-128<8> & (%%0<8> & ! (%%1<8>))));
8: of<1> := %%7<1>;
9: sf<1> := %%6<1>;
10: zf<1> := %%5<1>;
11: af<1> := %%4<1>;
12: pf<1> := %%3<1>;
13: cf<1> := %%2<1>;
14: goto (0x0011c3, 0)
0011c3: 75 07 jne 0x11cc
0: if ! (zf<1>) goto 2 else goto 1
1: goto (0x0011c5, 0)
2: goto (0x0011cc, 0)
0011c5: b8 01 00 00 00 mov $0x1,%eax
0: rax<64> := 1<64>;
1: goto (0x0011ca, 0)
0011ca: eb 07 jmp 0x11d3
0: goto (0x0011d3, 0)
0011cc: b8 00 00 00 00 mov $0x0,%eax
0: rax<64> := 0<64>;
1: goto (0x0011d1, 0)
0011d1: eb 00 jmp 0x11d3
0: goto (0x0011d3, 0)
0011d3: 5d pop %rbp
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rbp<64> := %%1<64>;
3: rsp<64> := %%0<64>;
4: goto (0x0011d4, 0)
0011d4: c3 ret
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rsp<64> := %%0<64>;
3: goto %%1<64> #return
000011d5 <main>: 0011d5: 55 push %rbp
0: %%0<64> := (rsp<64> - 8<64>);
1: %%1<64> := rbp<64>;
2: @[%%0<64>,<-,8] := %%1<64>;
3: rsp<64> := %%0<64>;
4: goto (0x0011d6, 0)
0011d6: 48 89 e5 mov %rsp,%rbp
0: %%0<64> := rsp<64>;
1: rbp<64> := %%0<64>;
2: goto (0x0011d9, 0)
0011d9: 48 83 ec 50 sub $0x50,%rsp
0: %%0<64> := (rsp<64> - 80<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rsp<64>) & %%0<64>)));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rsp<64> & ! (%%0<64>))));7: rsp<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x0011dd, 0)
0011dd: 89 7d bc mov %edi,-0x44(%rbp)
0: %%0<32> := rdi<64>{31..0};
1: %%1<64> := (rbp<64> + -68<64>);
2: @[%%1<64>,<-,4] := %%0<32>;
3: goto (0x0011e0, 0)
0011e0: 48 89 75 b0 mov %rsi,-0x50(%rbp)
0: %%0<64> := rsi<64>;
1: %%1<64> := (rbp<64> + -80<64>);
2: @[%%1<64>,<-,8] := %%0<64>;
3: goto (0x0011e4, 0)
0011e4: 48 8d 05 19 0e 00 00 lea 0xe19(%rip),%rax
0: rax<64> := 0x0000000000002004;
1: goto (0x0011eb, 0)
0011eb: 48 89 c7 mov %rax,%rdi
0: %%0<64> := rax<64>;
1: rdi<64> := %%0<64>;
2: goto (0x0011ee, 0)
0011ee: b8 00 00 00 00 mov $0x0,%eax
0: rax<64> := 0<64>;
1: goto (0x0011f3, 0)
0011f3: e8 38 fe ff ff call 0x1030
0: %%0<64> := (rsp<64> - 8<64>);
1: @[%%0<64>,<-,8] := 0x00000000000011f8;
2: rsp<64> := %%0<64>;
3: goto (0x001030, 0) #call with return address @ (0x0011f8, 0)
0011f8: 48 8d 05 1e 0e 00 00 lea 0xe1e(%rip),%rax
0: rax<64> := 0x000000000000201d;
1: goto (0x0011ff, 0)
0011ff: 48 89 c7 mov %rax,%rdi
0: %%0<64> := rax<64>;
1: rdi<64> := %%0<64>;
2: goto (0x001202, 0)
001202: b8 00 00 00 00 mov $0x0,%eax
0: rax<64> := 0<64>;
1: goto (0x001207, 0)
001207: e8 24 fe ff ff call 0x1030
0: %%0<64> := (rsp<64> - 8<64>);
1: @[%%0<64>,<-,8] := 0x000000000000120c;
2: rsp<64> := %%0<64>;
3: goto (0x001030, 0) #call with return address @ (0x00120c, 0)
00120c: 48 8d 45 c0 lea -0x40(%rbp),%rax
0: %%0<64> := (rbp<64> + -64<64>);
1: rax<64> := %%0<64>;
2: goto (0x001210, 0)
001210: 48 89 c6 mov %rax,%rsi
0: %%0<64> := rax<64>;
1: rsi<64> := %%0<64>;
2: goto (0x001213, 0)
001213: 48 8d 05 18 0e 00 00 lea 0xe18(%rip),%rax
0: rax<64> := 0x0000000000002032;
1: goto (0x00121a, 0)
00121a: 48 89 c7 mov %rax,%rdi
0: %%0<64> := rax<64>;
1: rdi<64> := %%0<64>;
2: goto (0x00121d, 0)
00121d: b8 00 00 00 00 mov $0x0,%eax
0: rax<64> := 0<64>;
1: goto (0x001222, 0)
001222: e8 19 fe ff ff call 0x1040
0: %%0<64> := (rsp<64> - 8<64>);
1: @[%%0<64>,<-,8] := 0x0000000000001227;
2: rsp<64> := %%0<64>;
3: goto (0x001040, 0) #call with return address @ (0x001227, 0)
001227: 48 8d 45 c0 lea -0x40(%rbp),%rax
0: %%0<64> := (rbp<64> + -64<64>);
1: rax<64> := %%0<64>;
2: goto (0x00122b, 0)
00122b: 48 89 c7 mov %rax,%rdi
0: %%0<64> := rax<64>;
1: rdi<64> := %%0<64>;
2: goto (0x00122e, 0)
00122e: e8 16 ff ff ff call 0x1149
0: %%0<64> := (rsp<64> - 8<64>);
1: @[%%0<64>,<-,8] := 0x0000000000001233;
2: rsp<64> := %%0<64>;
3: goto (0x001149, 0) #call with return address @ (0x001233, 0)
001233: 85 c0 test %eax,%eax
0: %%0<32> := rax<64>{31..0};
1: %%1<1> :=
!
((((rax<64>{0} ^ rax<64>{4}) ^ (rax<64>{2} ^ rax<64>{6})) ^
((rax<64>{1} ^ rax<64>{5}) ^ (rax<64>{3} ^ rax<64>{7}))));2: %%2<1> := undef;
3: %%3<1> := (0<32> = %%0<32>);
4: %%4<1> := (%%0<32> <s 0<32>);
5: of<1> := 0<1>;
6: sf<1> := %%4<1>;
7: zf<1> := %%3<1>;
8: af<1> := %%2<1>;
9: pf<1> := %%1<1>;
10: cf<1> := 0<1>;
11: goto (0x001235, 0)
001235: 74 16 je 0x124d
0: if zf<1> goto 2 else goto 1
1: goto (0x001237, 0)
2: goto (0x00124d, 0)
001237: 48 8d 05 f9 0d 00 00 lea 0xdf9(%rip),%rax
0: rax<64> := 0x0000000000002037;
1: goto (0x00123e, 0)
00123e: 48 89 c7 mov %rax,%rdi
0: %%0<64> := rax<64>;
1: rdi<64> := %%0<64>;
2: goto (0x001241, 0)
001241: b8 00 00 00 00 mov $0x0,%eax
0: rax<64> := 0<64>;
1: goto (0x001246, 0)
001246: e8 e5 fd ff ff call 0x1030
0: %%0<64> := (rsp<64> - 8<64>);
1: @[%%0<64>,<-,8] := 0x000000000000124b;
2: rsp<64> := %%0<64>;
3: goto (0x001030, 0) #call with return address @ (0x00124b, 0)
00124b: eb 14 jmp 0x1261
0: goto (0x001261, 0)
00124d: 48 8d 05 f6 0d 00 00 lea 0xdf6(%rip),%rax
0: rax<64> := 0x000000000000204a;
1: goto (0x001254, 0)
001254: 48 89 c7 mov %rax,%rdi
0: %%0<64> := rax<64>;
1: rdi<64> := %%0<64>;
2: goto (0x001257, 0)
001257: b8 00 00 00 00 mov $0x0,%eax
0: rax<64> := 0<64>;
1: goto (0x00125c, 0)
00125c: e8 cf fd ff ff call 0x1030
0: %%0<64> := (rsp<64> - 8<64>);
1: @[%%0<64>,<-,8] := 0x0000000000001261;
2: rsp<64> := %%0<64>;
3: goto (0x001030, 0) #call with return address @ (0x001261, 0)
001261: b8 00 00 00 00 mov $0x0,%eax
0: rax<64> := 0<64>;
1: goto (0x001266, 0)
001266: c9 leave
0: %%0<64> := (rbp<64> + 8<64>);
1: %%1<64> := @[rbp<64>,<-,8];
2: rbp<64> := %%1<64>;
3: rsp<64> := %%0<64>;
4: goto (0x001267, 0)
001267: c3 ret
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rsp<64> := %%0<64>;
3: goto %%1<64> #return
Disassembly of section .fini:
00001268 <_fini>: 001268: 48 83 ec 08 sub $0x8,%rsp
0: %%0<64> := (rsp<64> - 8<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rsp<64>) & %%0<64>)));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rsp<64> & ! (%%0<64>))));7: rsp<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x00126c, 0)
00126c: 48 83 c4 08 add $0x8,%rsp
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<1> :=
(0x8000000000000000 = (0x8000000000000000 & (rsp<64> & ! (%%0<64>))));2: %%2<1> :=
!
((((%%0<64>{0} ^ %%0<64>{4}) ^ (%%0<64>{2} ^ %%0<64>{6})) ^
((%%0<64>{1} ^ %%0<64>{5}) ^ (%%0<64>{3} ^ %%0<64>{7}))));3: %%3<1> := undef;
4: %%4<1> := (0<64> = %%0<64>);
5: %%5<1> := (%%0<64> <s 0<64>);
6: %%6<1> :=
(0x8000000000000000 = (0x8000000000000000 & (! (rsp<64>) & %%0<64>)));7: rsp<64> := %%0<64>;
8: of<1> := %%6<1>;
9: sf<1> := %%5<1>;
10: zf<1> := %%4<1>;
11: af<1> := %%3<1>;
12: pf<1> := %%2<1>;
13: cf<1> := %%1<1>;
14: goto (0x001270, 0)
001270: c3 ret
0: %%0<64> := (rsp<64> + 8<64>);
1: %%1<64> := @[rsp<64>,<-,8];
2: rsp<64> := %%0<64>;
3: goto %%1<64> #return
Reverse engineering
If we run it, we are asked to enter a password.
./level1
./level1
Welcome to Easy Crack MeWhat is the Secret ?
Better luck next time. :(
As we fail to provide the good one, it simply prompts the message Better luck next time. :(
before exiting.
If we look at the strings in the .rodata
section (0x2000
), we can guess that the success is rewarded by the prompt You are correct :)
.
Thus, our goal will be to find the password that lead the program to call a printing function (any of putc
, puts
, printf
, etc.) with the string You are correct :)
as argument.
Looking at the dynamic symbol table shows us the dynamically linked
functions the program may call: here printf
for output and isoc99 scanf
for input.
Symbol table '.dynsym' contains 8 entries:
Num: Value Size Type Bind Section Name
0: 0000000000000000 0 NOTYPE LOCAL UND
1: 0000000000000000 0 FUNC GLOBAL UND __libc_start_main
2: 0000000000000000 0 NOTYPE WEAK UND _ITM_deregiste...
3: 0000000000000000 0 FUNC GLOBAL UND printf
4: 0000000000000000 0 NOTYPE WEAK UND __gmon_start__
5: 0000000000000000 0 FUNC GLOBAL UND __isoc99_scanf
6: 0000000000000000 0 NOTYPE WEAK UND _ITM_registerT...
7: 0000000000000000 0 FUNC WEAK UND __cxa_finalize
The ELF format use the special section .plt
, for Procedure Linkage Table, in order to call the dynamically loaded functions.
The caller first jumps to a fixed entry in the PLT that plays the role of a trampoline and that dispatchs to the actual function implementation.
The disassembly sometimes refers to the pseudo symbol @plt
to identifies an entry in the PLT.
BINSEC partially supports this syntax, so we will be able to use <printf@plt>
and <__isoc99_scanf@plt>
.
Writing a function stubs
Since the functions printf
and __isoc99_scanf
are absent of the binary, BINSEC is not able to to explore their code.
Yet, we can write a substitute body for them directly in the script.
For instance, we can model the printf
function to do nothing else than simply returning to the caller.
replace <printf@plt> by
return 0
end
Even if we use a function name, the replace
statement does not replace the function itself, it just hook the address of the symbol (which is used to be the function entrypoint).
The function isoc99_scanf
can be more tricky to model, but we do not have to implement all the behaviors of the original function. Here, it seems that the scan is only called once in the main
function (0x1222
). It has a concrete format specifier %64s
(0x2032
in .rodata
) which means it will read a string of maximum 64 bytes.
We can model it with the following script.
replace <__isoc99_scanf@plt> (format, ptr) by
assert @[format, 5] = "%64s"z
@[ptr, 64] := stdin[0, 64]
return 1
end
The important points here are:
- BINSEC can match the function arguments according to the calling convention for us (e.g.
format
instead ofrdi
andptr
instead ofrsi
); - we put an
assert
to make sure our prior guess is correct: the analysis will raise an error if the function is called with another argument than"%64s"
; - the main memory of the program is accessed via the builtin
@
array. Using another name will automatically declare a new symbolic array that we can use to model string'like objects like command line arguments or files. Here, we are (wisely) chose the namestdin
to model the password input entered by the user.
The variable format
and ptr
are copies of the original values.
Straight assignment of a new values (:=
) will not affect the original argument.
The z
at the end of "%64s"z
stands for zero terminated string and is a shortcut for "%64s\x00"
.
Final script
We can put the pieces together and run the following script.
replace <printf@plt> by
return 0
end
replace <__isoc99_scanf@plt> (format, ptr) by
assert @[format, 5] = "%64s"z
@[ptr, 64] := stdin[0, 64]
return 1
end
load sections .rodata, .data from file
starting from <main>
with concrete stack pointer
reach <printf@plt> (str) such that @[str, 19] = "You are correct :)"z
then print c string stdin
cut at <main> return
- Browser
- Command-line
Download or copy the content of the script in the file level1_script_1.ini
, then run the following command.
binsec -sse -sse-script level1_script_1.ini level1
[sse:info] Load section .data (0x0000000000004010, 0x10)
[sse:info] Load section .rodata (0x0000000000002000, 0x64)
[sse:result] Path 9 reached address 0x00001030 (<printf@plt>) (0 to go)
[sse:result] C string stdin[0<64>, *] : "sudo0x18"
[sse:info] SMT queries
Preprocessing simplifications
total 9
true 2
false 3
constant enum 4
Satisfiability queries
total 8
sat 8
unsat 0
unknown 0
time 0.01
average 0.00
Exploration
total paths 9
completed/cut paths 0
pending paths 9
stale paths 0
failed assertions 0
branching points 13
max path depth 74
visited instructions (unrolled) 74
visited instructions (static) 84
Remember that non initialized locations are treated as symbolic by BINSEC. So, here we use 2 initialization commands to automatically concretize:
- the content of the memory in the
.rodata
and.data
sections; - the initial stack pointer.
It is always safe to load read-only section like .rodata
from the file. It is also highly recommended to concretize or restrict the range of the stack and other pointers to help the symbolic engine to efficiently reason on memory.
Non replacement hook
Hooks are not limited to replacement and can also be used to instrument the code while still retaining the original behavior.
In fact, we already used hooks since most of the script commands are actually a syntactic sugar around the hook mechanism.
Thus, both versions are equivalent in the following code.
at 0x400089 assert !of
hook 0x400089 with
assert !of
end
Hooks are somehow concatenated in the same order they appear in the script.
reach <fibonacci> return then print dec rax
cut at <fibonacci> return
hook <fibonacci> return with
reach then print dec rax
cut
end
The hook
form fallthrough the underlying code at the end of the block if no explicit control flow instruction like return
or jump at
is used. On the other hand, the replace
form raises an error if it reaches the end of the block.
Now you have learned how to replace or instrument the code with hooks, it is time to put it into practice to solve another challenge.