Upgrade to Pro — share decks privately, control downloads, hide ads and more …

seccamp2018でセルフホストCコンパイラをつくった

Avatar for Ushitora Anqou Ushitora Anqou
September 22, 2018

 seccamp2018でセルフホストCコンパイラをつくった

セキュリティ・キャンプ全国大会2018でセルフホストCコンパイラをつくりました。キャンプが終わった後にアセンブラとリンカと標準ライブラリを作りました。

Avatar for Ushitora Anqou

Ushitora Anqou

September 22, 2018
Tweet

More Decks by Ushitora Anqou

Other Decks in Programming

Transcript

  1. ͲΜͳͻͱ ࠡ ᲒᲶʢ͏͠ͱΒ ͋Μ͜͏ʣ • Twitter: @ushitora anqou • ීஈ͸

    C++Ͱ༡ΜͩΓ༡͹ΕͨΓɻ • constexpr Ͱ NN ͱ͔ॻ͖·ͨ͠ɻ GitHub ʹ͋ΔͷͰελʔ͍ͩ͘͞ɻ • Kernel ΋ VM ΋Θ͔Γ·ͤΜɻษڧ͠ ·͢ɻ 2
  2. seccamp ͬͯͳʹ ηΩϡϦςΟɾΩϟϯϓશࠃେձ 2018 • 8 ݄ 14 ೔ʙ18 ೔

    @౦ژ౎෎தࢢ • IPA ओ࠵ͷ߹॓ܗࣜͷษڧձ • ʮY-II C ίϯύΠϥΛࣗ࡞ͯ͠ΈΑ ͏ʂʯθϛʹࢀՃ • ߨࢣ͸ Rui ͞Μͱ hikalium ͞Μ 3
  3. ೔ఔ Day N ΍Δ͜ͱ Day 1 ։ձࣜͱ͔ʢ։ൃͳ͠ʣ Day 2 ։ൃ

    Day 3 ։ൃ Day 4 ։ൃ Day 5 ดձࣜͱ͔ʢ։ൃͳ͠ʣ 7 ݄ͷ಄͔Βࣄલֶशͱͯ͠։ൃΛ࢝ΊΔɻ 5
  4. ͓͡͞Μͳʹͨ͠ͷ ηϧϑϗετͷ x86-64 ޲͚ C ίϯύΠϥ aqcc Λॻ͍ͨɻ • System

    V AMD64 ABI ४ڌɻ • C ϓϩάϥϜΛಡΈࠐΈΞηϯϒϦΛ ग़ྗɻ 7
  5. ηϧϑϗετ ࣗ෼ࣗ਎ΛίϯύΠϧͰ͖Δɻ • aqcc ͸ C ݴޠͰॻ͔Ε͍ͯΔɻ • aqcc ͸

    C ݴޠίϯύΠϥͰ͋Δɻ • Ώ͑ʹ aqcc ͸ aqcc ͰίϯύΠϧͰ ͖Δɻ 8
  6. ͭ͘Γ͔ͨ • ೖྗจࣈྻΛτʔΫϯྻʹ෼ׂ͢Δɻ • τʔΫϯྻΛղऍ͠ந৅ߏจ໦ ʢASTʣʹ͢Δɻ • ҙຯղੳΛߦ͍ AST ΛŢœŕͱ͢Δɻ

    • Ţœŕͱͳͬͨ AST ΛݩʹΞηϯϒϦΛ ੜ੒͢Δɻ • ੜ੒ͨ͠ΞηϯϒϦΛ͍͍ײ͡ʹ࠷ద Խ͢Δɻ 11
  7. ͭΒ͔ͬͨͱ͜Ζ • ΞηϯϒϦ͕෼͔Βͳ͍ɻ • ΞηϯϒϦΛॻ͘ͷ͸ॳΊͯɻ • lea ͬͯͳʹɻ • C

    ͷݴޠ࢓༷͕෼͔Βͳ͍ɻ • C ͷݴޠ࢓༷ΛಡΉͷ͸ʢ΄΅ʣॳΊͯɻ • ൚੔਺֦ுͬͯͳʹɻ 12
  8. C ݴޠ࢓༷ͷ͕͜͜ΩϞ͍ʂ • ϙΠϯλ͕ΩϞ͍ʂ • int* p, q; ͷ q

    ͸ int • ؔ਺એݴ͕ΩϞ͍ʂ • int foo(); ͱ int foo(){...} ͱ int foo; ͷ۠ผɻ • Մม௕Ҿ਺͕ΩϞ͍ʂ • va list ͱ͔ va start() ͱ͔ɻ • va list ͷఆٛͱ͔஌ͬͯ·͢ʁ 13
  9. ଓɾC ݴޠ࢓༷ͷ͕͜͜ΩϞ͍ʂ • switch ͕ΩϞ͍ʂ • if-else ͱ͍͏ΑΓ΋࣮࣭ goto switch

    (1) { int a = 2; case 3: 1; int b = 5; break; case 1: a = 1; b = 0; default: printf("%d␣%d", a, b); // 1 0 } 14
  10. ଓʑɾC ݴޠ࢓༷ͷ͕͜͜ΩϞ͍ʂ • ߏ଄ମఆ͕ٛΩϞ͍ʂ • ߏ଄ମఆٛ΋ int ΋ type-specifier ͳͷ

    Ͱಉ͡ͱ͜Ζʹॻ͚Δɻ struct hogehoge { int piyopiyo; } foobar (); int foobar (); 15
  11. 2.3 ⇒ 2 ഒʹ͍ͨ͠ʂ ग़ྗ͢ΔΞηϯϒϦΛ࠷దԽ͢Δɻ ४උ • ग़ྗίʔυΛه߸ʢstruct Codeʣʹ ஔ͖׵͑Δɻ

    • ͦΕ·Ͱ͸จࣈྻͰѻ͍ͬͯͨɻ • େྔʹॻ͖׵͑Δ΂͖৔ॴ͕͋Δɻ • ͱͯ΋ͭΒ͍ɻ 32
  12. 2.3 ⇒ 2 ഒʹ͍ͨ͠ʂ ग़ྗ͢ΔΞηϯϒϦΛ࠷దԽ͢Δɻ • ఆ਺஋৞ΈࠐΈ • a =

    1 + 5 * 8 + 1; =⇒ a = 42; • AST Λ෦෼తʹΠϯλϓϦτ͢Ε͹ ྑ͍ɻ 32
  13. ଓɾ࠷దԽ • dead code elimination ҙຯͷͳ͍ίʔυ͸ੜ੒͠ͳ͍Α͏ʹ ͢Δɻ • propagation mov

    (%rax), %r11 =⇒ mov -8(%rbp), %r11 ૊Έ߹Θ͍͍ͤͯײ͡ʹ࠷దԽ͢Δɻ 33
  14. ଓଓɾ࠷దԽ • ؔ਺ͷதͰ࢖͍ͬͯΔϨδελ͚ͩΛ ୀආ͢Δ • r12, r13, r14, r15 ͸

    callee-saved. • ؔ਺๯಄Ͱ push ͠ऴΘΓͰ pop. • શͯΛอଘ͢Δͱ͕͔͔࣌ؒΔɻ • ॻ͖׵͑Δ΋ͷ͚ͩͰྑ͍ɻ 36
  15. aqcc ͰίϯύΠϧ test.c ΛίϯύΠϧ͍ͨ͠ɻ % ./aqcc test.c > test.s •

    ίϯύΠϧ % gcc -c test.s -o test.o • Ξηϯϒϧ % gcc test.o -o test all.o • ϦϯΫ 39
  16. MOV ໋ྩ mov %eax, %edx =⇒ 89 c2 Opcode Instruction

    89 /r MOV r/m32,r32 7 6 5 4 3 2 1 0 ModR/M mod reg r/m 1 1 0 0 0 0 1 0 46
  17. MOV ໋ྩ mov %rax, %rdx =⇒ 48 89 c2 Opcode

    Instruction REX.W + 89 /r MOV r/m64,r64 47
  18. MOV ໋ྩ mov %rax, %rdx =⇒ 48 89 c2 Opcode

    Instruction REX.W + 89 /r MOV r/m64,r64 7 6 5 4 3 2 1 0 REX Prefix 0 1 0 0 W R X B 0 1 0 0 1 0 0 0 47
  19. MOV ໋ྩ mov %r8, %r10 =⇒ 4d 89 c2 Opcode

    Instruction REX.W + 89 /r MOV r/m64,r64 48
  20. MOV ໋ྩ mov %r8, %r10 =⇒ 4d 89 c2 Opcode

    Instruction REX.W + 89 /r MOV r/m64,r64 7 6 5 4 3 2 1 0 REX Prefix 0 1 0 0 W R X B 0 1 0 0 1 1 0 1 48
  21. MOV ໋ྩ mov %eax, (%rdx) =⇒ 89 02 7 6

    5 4 3 2 1 0 ModR/M mod reg r/m 0 0 0 0 0 0 1 0 49
  22. MOV ໋ྩ mov %eax, -4(%rdx) =⇒ 89 42 fc 7

    6 5 4 3 2 1 0 ModR/M mod reg r/m 0 1 0 0 0 0 1 0 50
  23. MOV ໋ྩ mov %eax, -4(%rbp) =⇒ 89 45 fc 7

    6 5 4 3 2 1 0 ModR/M mod reg r/m 0 1 0 0 0 1 0 1 51
  24. MOV ໋ྩ mov %eax, (%rbp) =⇒ 89 45 00 7

    6 5 4 3 2 1 0 ModR/M mod reg r/m 0 1 0 0 0 1 0 1 52
  25. MOV ໋ྩ mov %eax, -4(%rip) =⇒ 89 05 fc ff

    ff ff 7 6 5 4 3 2 1 0 ModR/M mod reg r/m 0 0 0 0 0 1 0 1 53
  26. ·ͱΊ inst mod r/m code (%rdx) 00 010 89 02

    -4(%rdx) 01 010 89 42 fc -4(%rbp) 01 101 89 45 fc (%rbp) 01 101 89 45 00 -4(%rip) 00 101 89 05 fc ff ff ff ͱͯ΋ͭΒ͍ɻ 54
  27. MOV ໋ྩ mov %eax, -400(%r11) =⇒ 41 89 83 70

    fe ff ff 7 6 5 4 3 2 1 0 ModR/M mod reg r/m 1 0 0 0 0 0 1 1 55
  28. MOV ໋ྩ mov %eax, -400(%r11) =⇒ 41 89 83 70

    fe ff ff mov %eax, -400(%r12) 56
  29. MOV ໋ྩ mov %eax, -400(%r11) =⇒ 41 89 83 70

    fe ff ff mov %eax, -400(%r12) =⇒ 41 89 84 24 70 fe ff ff 56
  30. MOV ໋ྩ mov %eax, -400(%r11) =⇒ 41 89 83 70

    fe ff ff mov %eax, -400(%r12) =⇒ 41 89 84 24 70 fe ff ff 7 6 5 4 3 2 1 0 SIB scale index base 0 0 1 0 0 1 0 0 56
  31. MOV ໋ྩ mov %eax, -400(%r12) =⇒ 41 89 84 24

    70 fe ff ff scale = 20 = 1 index = %rsp base = %r12 disp = -400 ͜ͷͱ͖ scale × index + base + disp 57
  32. MOV ໋ྩ mov %eax, -400(%r12) =⇒ 41 89 84 24

    70 fe ff ff scale = 20 = 1 index = %rsp base = %r12 disp = -400 ͜ͷͱ͖ scale × index + base + disp ͨͩ͠ index = %rsp =⇒ scale = 0 57
  33. ݁ہ n(%r12) ͷͱ͖ʹ 24 ΛຒΊࠐΊ͹͍͍ɻ if (mod == 2 &&

    rm == 4) emit_byte(modrm(0, 4, 4)); ίϝϯτ͕ඞཁ 58
  34. ΞηϯϒϥͭΒ͍ • ELF ෼͔ΒΜɻ • gas ͸೥਺Λײͤ͡͞Δίʔυɻ • aqcc ʹ

    long ͕ແ͍ɻ emit qword( 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00); gas ͷग़ྗ΍ʰϦϯΧɾϩʔμ࣮ફ։ൃς ΫχοΫʱΛ΋ͱʹௐ੔ɻ 60
  35. aqcc ͰίϯύΠϧʢ࠶ܝʣ test.c ΛίϯύΠϧ͍ͨ͠ɻ % ./aqcc test.c > test.s •

    ίϯύΠϧ % gcc -c test.s -o test.o • Ξηϯϒϧ % gcc test.o -o test all.o • ϦϯΫ 61
  36. malloc(3) Λ࣮૷ aqcc ͸ malloc() ͢Δ͕ free() ͠ͳ͍ɻ char *p

    = brk (0); int size = 0x32000000; char *q = brk(p + size ); ... if (malloc_remaining_size < size) return NULL; 69
  37. ػೳΛ෼ׂ • ./aqcc cs main.c main.s ίϯύΠϧ • ./aqcc so

    main.s main.o Ξηϯϒϧ • ./aqcc oe main.o main.exe ϦϯΫ खͰଧͭͷ͸গʑ໘౗ɻ 73
  38. ·ͱΊ • ίϯύΠϥ =⇒ ΍Δ͚ͩ • Ξηϯϒϥ =⇒ ΍Δ͚ͩ •

    ϦϯΧ =⇒ ΍Δ͚ͩ • ඪ४ϥΠϒϥϦ =⇒ ΍Δ͚ͩ 75
  39. ·ͱΊ • ίϯύΠϥ =⇒ ΍Δ͚ͩ • Ξηϯϒϥ =⇒ ΍Δ͚ͩ •

    ϦϯΧ =⇒ ΍Δ͚ͩ • ඪ४ϥΠϒϥϦ =⇒ ΍Δ͚ͩ ʊਓਓਓਓਓਓਓਓਓਓਓਓਓʊ ʼɹ΍Δ͚ͩπʔϧνΣΠϯɹʻ ʉ Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ʉ 75
  40. ࢀߟจݙ • IntelR ⃝ 64 and IA-32 Architectures Software Developer

    Manuals https://software.intel.com/ en-us/articles/intel-sdm • N1548 Committee Draft Š December 2, 2010 ISO/IEC 9899:201x http://www.open-std.org/jtc1/ sc22/wg14/www/docs/n1548.pdf 78