å幎ãçµã£ãŠããŸããïŒ ç·åŒµããŠãèšæ¶ã«æ®ãããã«
ãç§ãã¡ã
æåŸã«èœèãšã¢ã»ã³ãã©ãŒã«é£ã³èŸŒãçŽæã«èœã¡çãã
ãšã ãããªãã¯ããããããšãã§ããŸãã
ãŸããå°å¹Žã¯èšã£ã-å°å¹Žã¯ãã£ãã ãã®äžæ Œå¥œãªæåã®å±±ãããGNU / Linuxã®OpenGLã³ã³ããã¹ããçŽ450ãã€ãã«åæåããæèœãå±éããããã®ã¹ããŒã¹ãããã«è§£æŸããæ¹æ³ãåŠç¿ããŸãã
ã«ããã®äžã§ããã®ãããªãã®ã1ãããã€ãã§æç»ããæ¹æ³ãåŠç¿ããŸãã
èå³ã®ãã人ã¯ãããã«ãåºã«åºå®ããŠæŒããç®ãç»é¢ã«åããŸãã
å§ããããã«ãããã«ã€ããŠè©±ããŸãããã ãªãç§ãã¡ã¯ãããªã«æªããšäŸ¡å€ããªãã®ã§ããïŒ äœãæ£ç¢ºã«ç§ãã¡ã«éã¿ãè¿œå ããå£åã®æ·±ãã«ç§ãã¡ãåŒãäžããŸããïŒ
ãããã®è³ªåã«çããã«ã¯ãæ¬ç©ã®ç·æ§ã®ããã®ããŒã«ãreadelfãšobjdumpãå¿
èŠã§ãã
æåã®ãã¡ã€ã«ãèŠã€ããŠãæåŸã«ã€ã³ãããã¡ã€ã«ãèšå®ããŸããããã¯ãsstripãã¡ã€ã«ã§åŠçããåŸãåãã§ãã
$ readelf -a intro ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x8048250 Start of program headers: 52 (bytes into file) Start of section headers: 0 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 8 Size of section headers: 40 (bytes) Number of section headers: 0 Section header string table index: 0 There are no sections in this file. There are no sections in this file. Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x08048034 0x08048034 0x00100 0x00100 RE 0x4 INTERP 0x000134 0x08048134 0x08048134 0x00015 0x00015 R 0x1 [Requesting program interpreter: /lib32/ld-linux.so.2] LOAD 0x000000 0x08048000 0x08048000 0x005ac 0x005ac RE 0x1000 LOAD 0x000f4c 0x08049f4c 0x08049f4c 0x000c4 0x00100 RW 0x1000 DYNAMIC 0x000f4c 0x08049f4c 0x08049f4c 0x000a8 0x000a8 RW 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 GNU_RELRO 0x000f4c 0x08049f4c 0x08049f4c 0x000b4 0x000b4 R 0x1 PAX_FLAGS 0x000000 0x00000000 0x00000000 0x00000 0x00000 0x4 Dynamic section at offset 0xf4c contains 16 entries: Tag Type Name/Value 0x00000001 (NEEDED) Shared library: [libdl.so.2] 0x00000004 (HASH) 0x804814c 0x6ffffef5 (GNU_HASH) 0x8048164 0x00000005 (STRTAB) 0x80481ac 0x00000006 (SYMTAB) 0x804817c 0x0000000a (STRSZ) 45 (bytes) 0x0000000b (SYMENT) 16 (bytes) 0x00000015 (DEBUG) 0x0 0x00000003 (PLTGOT) 0x8049ff4 0x00000002 (PLTRELSZ) 16 (bytes) 0x00000014 (PLTREL) REL 0x00000017 (JMPREL) 0x8048210 0x6ffffffe (VERNEED) 0x80481e0 0x6fffffff (VERNEEDNUM) 1 0x6ffffff0 (VERSYM) 0x80481da 0x00000000 (NULL) 0x0 There are no relocations in this file. There are no unwind sections in this file. Histogram for bucket list length (total of 1 buckets): Length Number % of total Coverage 0 0 ( 0.0%) 1 0 ( 0.0%) 0.0% 2 1 (100.0%) 100.0% No version information found in this file.
ïŒç¹å®ã®æ°ããµã€ãºããªãã»ããã¯ãããŒã«ãã§ãŒã³å
šäœãšãã€ã«ã®å¹Žéœ¢ã¡ã€ããŒãã©ã«äŸåããŸãïŒ
ããã§äœãèŠããŸããïŒ ãã¡ãããæåã®æ®µéã§ã¯ãæšæºã®ELFããããŒã§ãããããããããèšèãæŸãåºãããšã¯ãããŸããã 次ã«ãsstripããã¹ãŠã®ã»ã¯ã·ã§ã³ããããŒãã¹ã¯ã©ããããããšãããããŸãïŒæŒç¿ïŒåºåãreadelf -a intro-origïŒsstripã®åïŒãšæ¯èŒããŠãã ããïŒã ãããããã®åŸãäŒæ¥ããã°ã©ã ã®ããããŒãšåçã»ã¯ã·ã§ã³ïŒãªãã»ããïŒã衚瀺ãããŸãã 圌ãã¯æ¬åœã«çŸãããã¬ã¹ã§ç§ãã¡ãå¿
èŠãšããŠããŸããïŒ
ãã¿ãã¬ïŒãããïŒ*
ïŒ*-ä¿®æ£ïŒã¯ãããããããã§ã¯ãªãïŒ
ãšã«ããåã£ã
å®è¡ããæ£ããelfãã¡ã€ã«ãäœæã§ããæå°ãµã€ãºãèŠãŠã¿ãŸãããã åºç€ãšããŠãç§ãã¡ã¯ä»æã£ãŠãããã®ãåããŸããããã¹ãŠã®æçšãªè
žãæšãŠãŸãã
simple.cïŒ
void _start(void) { asm( "xor %eax,%eax\n" "inc %eax\n" "int $0x80\n" ); }
ãããéããŸãããïŒã¹ã¯ãªããã¯éå»ã®ãã®ã§ãïŒïŒ
cc -Wall -m32 -c simple.c -Os -nostartfiles -o simple-co && \ ld -melf_i386 -dynamic-linker /lib32/ld-linux.so.2 simple-co -o simple-c-orig && \ cp simple-c-orig simple-c && \ sstrip simple-c && \ cat simple-c | 7z a dummy -tGZip -mx=9 -si -so > simple-c.gz && \ cat unpack_header simple-c.gz > simple-c.sh && \ wc -c simple-c.sh && chmod +x simple-c.sh && \ ./simple-c.sh
çµæã®ãã¡ã€ã«ãšäžéãã¡ã€ã«ã®ãµã€ãºã確èªãããšã次ã®ããšãããããŸãã
- sstripã決å®-ã¹ããªãããããsimple-cã®ãµã€ãºã¯ãsimple-c-origã®ãµã€ãºã®ïŒã»ãŒïŒ3åå°ãã
- å§çž®ã¯ã»ãšãã©åé¡ã§ã¯ãããŸãã-解åã³ãŒãã®ããå§çž®ãã¡ã€ã«ã¯ãå§çž®ãããŠããªããã¡ã€ã«ãšã»ãŒåããããããããŸã
- ïŒldã«-sãªãã·ã§ã³ãè¿œå ãããšãã¹ããªãããããäžéã®ãã€ããªã®ãµã€ãºã倱ã£ããè¿œå ãããããã«ãã¹ããªãããããŠããªããã¡ã€ã«ã®ãµã€ãºã®çŽ3åã®1ãç²åŸã§ããŸãã
å°æ¥ãèŠããšããããã®ã³ã¡ã³ãã¯å®å
šã«ãã圹ã«ç«ããªãããšã«æ°ä»ãããšãã§ããŸãããç§ãã¡ã¯å°æ¥ã§ã¯ãããŸããïŒ
ããã§ãreadelfããã€ããªã«èšå®ããŠãæ®ã£ãŠãããã®ãäœã«å€ãã£ãã®ããäœã«ãªã£ãã®ãã確èªã§ããŸãã
$ readelf -a simple-c ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x8048094 Start of program headers: 52 (bytes into file) Start of section headers: 0 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 3 Size of section headers: 40 (bytes) Number of section headers: 0 Section header string table index: 0 There are no sections in this file. There are no sections in this file. Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x08048000 0x08048000 0x0009e 0x0009e RE 0x1000 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 PAX_FLAGS 0x000000 0x00000000 0x00000000 0x00000 0x00000 0x4 There is no dynamic section in this file. There are no relocations in this file. There are no unwind sections in this file. No version information found in this file.
ã ãããã¹ããªããã¯è¯ã仲éã ãšæããããç§ãã¡ã®ãšã«ãã®å¥³ã®åã®ã»ã¯ã·ã§ã³ã¯ããããã®äžèŠãªã»ã¯ã·ã§ã³ã®èŠåºãããã¹ãŠåé€ããŸããã ããããåæã«ãç§ãã¡ã®å¥³æ§ã¯ãŸã æºåãã§ããŠããŸãã-圌女ã¯ãŸã ãã©ãžã£ãŒïŒGNU_STACKãšPAX_FLAGSããããŒïŒãšãã³ãã£ãŒãæã£ãŠããŸãããLOADããããŒã®FileSizãäœããã®çç±ã§ãã¡ã€ã«èªäœã®ãµã€ãºãããå°ãããšããäºå®ã«æ³šæãæããšèŠã€ããããšãã§ããŸãããã¯coç
è
ã§ã¯ãªããåã«ãã¡ã€ã«ã®æåŸã«ãããŽãã§ããããããã¯ãåãå¿
èŠããããŸãã
ããã«ãæ¬åœã«ãããããŠéã³ã³ãã€ã«ããŠããå ŽåïŒobjdumpã¯ããã°ã©ã ã§ã¯ãªãã»ã¯ã·ã§ã³ããããŒãèªã¿åããããobjdump -Dã¯ã¹ãã©ã€ããããŠããªããã¡ã€ã«ã§ã®ã¿åäœããŸãïŒãããã§çæãããã®ã¯ãæåã®é®®åºŠã§ã¯ãªãããšã«æ³šæããå¿
èŠããããŸãå®å
šã«æ害ãªããããŒã°ããã³ãšãããŒã°æ©èœããããããã«å€ããœãã¯ã¹ïŒ
00 55 push ebp 01 89e5 mov ebp, esp 03 31c0 xor eax, eax 05 40 inc eax 06 cd80 int 0x80 08 5d pop ebp 09 c3 ret
ãæçšãªãã³ãŒãã®5ãã€ããš5ãã€ãã®æ¯ç-圹ã«ç«ããªãã³ãŒãã¯ãè¥ãå¿ãæž©ããããšãã§ããŸããã ãããŠãç§ãã¡ã®è¥ãå¿ãæž©ãããã®ã¯äœã§ããïŒ å§çž®ãããæç«ãšæ²Œå°ã®æ®éªžãçãããŸãã ãããã®éåžžã«å§çž®ããã沌å°ã«ãç§ã®å¥œå¥å¿ã®åŒ·ãèªè
ããããªãèªèº«ã浞ãããšããå§ãããŸãã
æã§ãšã«ããäœã
ãšã«ããäœããªããšããããçµã¿ç«ãŠãã®ã¯éåžžã«ç°¡åã§ãã¹ã¿ãŒã¯ã©ããããªãã«ãã/ usr / include / elf.hãã¡ã€ã«ãéããäœãç解ãããelf.pdfãã¡ã€ã«ãã°ãŒã°ã«ã§æ€çŽ¢ããæãã«èªãã§ãæå
ããåŒãã¡ããã ãã§ãã以äžïŒ
bits 32 ; 32- org 0x00040000 ; , , - $$ ; ? . ( ) ; elf- db 0x7f, 'ELF' ; magic , , ELF db 1 ; EI_CLASS = ELFCLASS32 db 1 ; EI_DATA ELFDATA2LSB db 1 ; EI_VERSION = EV_CURRENT times 9 db 0 ; 9 , dw 2 ; e_type = ET_EXEC -- dw 3 ; e_machine = EM_386 dd 1 ; e_version = EV_CURRENT dd _start ; e_entry -- , dd phdrs - $$ ; e_phoff -- , program headers dd 0 ; e_shoff -- --//-- section headers, , , , 0 dd 0 ; e_flags -- dw ehsize ; e_ehsize -- ELF- (52 ) dw phsize ; e_phentsize -- program header (32 ) dw 1 ; e_phnum -- dw 0 ; e_shentsize -- section header dw 0 ; e_shnum -- () dw 0 ; e_shstrndx -- - , ehsize equ ($-$$) ; $ (+ org), ehsize elf- phdrs: ; program header dd 1 ; p_type = PT_LOAD -- " , " dd 0 ; p_offset -- , dd $$ ; p_vaddr -- , dd $$ ; p_paddr -- , - - , , dd file_size ; p_filesz -- , dd file_size ; p_memsz -- . , e_filesz, . -- 6 . . !!11 , , . . dd 7 ; p_flags (=PF_RWX) -- , . dd 0x1000 ; p_align -- , , . 0x1000 phsize equ ($-phdrs) ; program header _start: ; xor eax, eax ; eax = 0 inc eax ; eax = 1 (exit syscall) int 0x80 ; syscall file_size equ ($-$$) ;
ïŒå®éããã®å€±ç€Œãªããããå°ã颚å€ãããªãasmãã¡ã€ã«ãã³ã¡ã³ãã¢ãŠããã代ããã«ãç§ã®æããæ人ãã¡ã«ãæ±ããããŠå€§ããªELF圢åŒã®å³ãæããŠã»ãããšæã£ãã®ã§ãããããã§èšäºãããš2ã3延æãããããšã«æ°ä»ããŸããã幎ïŒ
è¿œå ã®ããããŒãªãã§ãããã©ããããã€ããªã®ã³ã³ãã€ã«ãã£ã¬ã¯ãã£ãã䜿çšããŠãnasmã§ãã®ãã¡ã€ã«ãã³ã³ãã€ã«ããå¿
èŠããããŸãã
$ nasm -f bin simple.asm -o simple-asm
ãã®è¡ã¯ã89ãã€ãã®simple-asmãã¡ã€ã«ãäœæããŸããããã¯ãåã«äœæãã206ãã€ãã®ã¢ã³ã¹ã¿ãŒã«å®å
šã«æ©èœããé¡äŒŒç©ã§ãã ãããã®206ãã€ãããå®éã«ã¯å
ã®å§çž®ãããŠããªãçžæš¡æ§ã®çæ°ã®657ãã€ãã§ãããšããäºå®ã¯èšããŸã§ããããŸããã
ã§ãã
chmod +x simple-asm
ãããŠããããå®éã«æå¹ã§ãããéå§ããããšãã確èªããŠãã ããã 89ãã€ãã¯å¶éããããé¢ããŠãããšèšããŸãããã®ãã¡ã€ã«ãçŽ2åçµãããšãã§ããŸãããšã«ãããããŒãå¯äžã®ããã°ã©ã ããããŒã«é
眮ãããšãè¶
æå¹ãªãšã«ãã ãã§ãªããèµ·åããŠãµã€ãºãå°ããããããšãã§ããŸãã elfããããŒèªäœãããïŒããããã®æåŸã®6ãã€ãã¯ããŒããããã°ãèªåçã«ãŒãã«ãªããŸãïŒ
[1] ã Linuxã«ã¯ãçŽ æŽããããã¡ã€ã«/ dev / fb0ãš/ dev / dspãããã128-256-512ãã€ãã®DOSã¹ã¿ã€ã«ã§ã€ã³ãã©ãå®è¡ã§ããããšãæããããæãæµ®ãã³ãŸãã ãã ããããã§ã¯ãããè¡ããŸãããããã¯ãèšå·ã®å¥ã®å±±ã«é¢ãããããã¯ã§ãã
ãããŠãããã§OpenGLãæ¥ç¶ããæ¹æ³ãèŠã€ãåºããŸãã
æªéã®ãªã³ã¯
OpenGLã³ã³ããã¹ããäœæããããã«ãåã®éšåããããããæŒ ç¶ãšèŠããŠããããã«ãlibSDL.soã®ããã«åçã«æ¥ç¶ãããSDLã©ã€ãã©ãªã䜿çšããŸããã ãã¡ãããããã«å ããŠãlibGL.soã©ã€ãã©ãªã®åœ¢åŒã§æäŸãããOpenGLèªäœãå¿
èŠã§ãã
圌ããèšãããã«ãèªå®¶è£œã®ãã€ããªãäœãã«åçã«ãªã³ã¯ã§ããããã«ããããšãåŠã¶å¿
èŠãããããšãç解ããããšã¯é£ãããããŸããã
äœã¬ãã«ã®Linuxã§ã®åçãªã³ã¯ã®ã¡ã«ããºã ã¯éåžžã«é¢çœãã§ãã ãã€ããªãããŒããããšãã·ã¹ãã ã¯ã€ã³ã¿ãŒããªã¿ãŒãã¡ã€ã«ã®ååã瀺ãPT_INTERPã¿ã€ãã®ããã°ã©ã ããããŒãæ€åºããŸãã ãã¯ããããªãã¯ãã®ãã€ãããã¯ãªã³ã¯ã§ããã«è¡ããããªãããšãŠãè³¢ããªãèªåã§ãããæŽçããŸãããšã·ã¹ãã ã¯èšãããã€ããªãããŒããç¶ãã代ããã«ãã€ã³ã¿ããªã¿ãããŒãããŠå¶åŸ¡ã移ããŸãã
ã€ã³ã¿ããªã¿ã¯ãã§ã«ã¢ããªã±ãŒã·ã§ã³ãããã«ããŒãããŠããŸã-äœãèµ·ãããªãã£ãããã«ãããã»ã¹ã«PT_LOADã»ã¯ã·ã§ã³ãç¬ç«ããŠããŒãããæãéèŠãªããšã«ã¯ãåçãªã³ã¯ã«å¿
èŠãªãã¹ãŠã®èª¬æãžã®ãªã³ã¯ãå«ãPT_DYNAMICãèªã¿èŸŒã¿ãŸã-å¿
èŠãªã©ã€ãã©ãªãé¢æ°ã®ååããããŠéèŠãªããšã«ãããããããŒãããæ¹æ³ã PT_DYNAMICã«ãã£ãŠåç
§ãããããŒã¿åœ¢åŒã¯ãããèªäœéåžžã«åçŽã§ããd_tagãšd_valã®ããã«ã¯ãŒãã®ãã¢ã®ããŒãã«ã§ããd_tagã¯ãã©ã¡ãŒã¿ãŒã³ãŒãã§ãd_valã¯ãã®å€ã§ããããã«ã€ããŠïŒã
ã©ã®ãã©ã¡ãŒã¿ãŒãšå€ãæå®ããå¿
èŠããããŸããïŒ å
ã®ãã¡ã€ã«ã®readelfãã³ãã«æ»ã£ãŠããã¹ãŠãèŠãŠã¿ãŸãããã è¡ããªãã»ãã...ã®åçã»ã¯ã·ã§ã³ãã®åŸã
æã
ç§ãã¡ã¯ããããã®3åã®1ã¯ãŸã£ããå¿
èŠãªããšèããŠå®å¿ããŠããŸãã è奮ã¯ãããããåŸéããŸãã-æ®ãã®ãã£ãŒã«ãã¯ãŸã ã²ã©ãã§ãã ãã ãããã®æå³ã詳现ã«ã¯èª¬æããŸãã-äžéšã¯èªåã§èŠããŠããªãããã§ãïŒããªãåã«åãäžããŸããïŒããèŠããŠããããšã¯å¿ãããã§ãã
ãããã£ãŠãèªè
ã®çãããç§ã¯ãå³ã®ã³ã¡ã³ãã®èãå±€ããã¡ããšæ£ãã°ã£ãæ¢è£œã®ã¬ã·ãããããããŸãã å¥åº·ã«äœ¿çšããŠãã ããã
ãã®ããŒã¹ã¯ãphsizeã®èšç®çŽåŸã«phdrsã«è¿œå ãããŸãã
dd 2 ; p_type = PT_DYNAMIC dd dynamic - $$ ; p_offset dd dynamic ; p_vaddr dd dynamic ; p_paddr dd dynamic_size ; p_filesz dd dynamic_size ; p_memsz dd 6 ; p_flags = PF_RW dd 4 ; p_align dd 3 ; p_type = PT_INTERP dd interp - $$ ; p_offset dd interp ; p_vaddr dd interp ; p_paddr dd interp_size ; p_filesz dd interp_size ; p_memsz dd 4 ; p_flags = PF_R dd 1 ; p_align ; PT_DYNAMIC ; dynamic: dd 1, st_libdl_name ; DT_NEEDED -- , st_libdl_name ( ) ; , , ;dd 1, st_libSDL_name ;dd 1, st_libGL_name dd 4, dt_hash ; DT_HASH -- dd 5, dt_strtab ; DT_STRTAB -- . dd 6, dt_symtab ; DT_SYMTAB -- dd 10, dt_strtab_size ; DT_STRSZ -- dd 11, dt_symtab_size ; DT_SYMENT -- dd 17, dt_rel ; DT_REL -- dd 18, dt_rel_size; DT_RELSZ -- dd 19, 8 ; DT_RELENT -- dd 0, 0 ; DT_NULL -- DT_DYNAMIC dynamic_size equ $ - dynamic ; DT_HASH ; - ; , ; dt_hash: dd 1, 3, 0, 0, 0, 0 ; DT_SYMTAB ; , dt_symtab: ; 0 -- (?!) dd 0, 0, 0 dw 0, 0 ; SHN_UNDEF ; 1 'dlopen' dd st_dlopen_name, 0, 0 dw 0x12 ; = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), .., , -- dw 0 ; SHN_UNDEF , , ; 2 'dlsym' dd st_dlsym_name, 0, 0 dw 0x12, 0 ; --//-- dt_symtab_size equ $ - dt_symtab ; DT_REL ; . , dt_rel: dd rel_dlopen ; , dd 0x0101 ; ELF32_R_INFO(1,R_386_32) : dt_symtab[1] ('dlopen'), = + r_addend(=0 ) dd rel_dlsym ; --//-- dd 0x0201 ; ELF32_R_INFO(2,R_386_32) : dt_symtab[2] ('dlsym'), --//-- dt_rel_size equ $ - dt_rel ; -- , ; DT_STRTAB ; . , PT_DYNAMIC -- dt_strtab: st_libdl_name equ $ - dt_strtab ; db 'libdl.so.2', 0 ; -- - st_dlopen_name equ $ - dt_strtab db 'dlopen', 0 st_dlsym_name equ $ - dt_strtab db 'dlsym', 0 dt_strtab_size equ $ - dt_strtab ; interp: db '/lib/ld-linux.so.2', 0 interp_size equ $ - interp
ããã«ã以äžãä¿®æ£ããå¿
èŠããããŸãã
- æããã«e_phnumã3ã«å€æŽããŸã
- ãã¡ã€ã«ã®æåŸã«è¿œå ããŸã
; BSS-, absolute $ bss: ; rel_dlopen: resd 1 rel_dlsym: resd 1 mem_size equ ($-$$)
- mem_sizeã«èšå®ãããPT_LOADããããŒp_memszå
ããã§ã人工ãšã«ãã¯åçã«ãªã³ã¯ã§ããããã«ãªããŸããã ããããã§ãã¯ããŠãã ããã
ããã¯åãªããã¹ãã§ã¯ãªããæœåšçãªã€ã³ãã©ãªã®ã§ããã¡ã€ã«ã®ååãintro.asmã«å€æŽããŸãã ãããéããŸãããïŒ
$ nasm -f bin intro.asm -o intro && chmod +x intro
ãããŠãstraceãå®è¡ããŠã圌ãå®éã«ããããçš®é¡ã®èªã¿åããè©Šã¿ãŠããããšã確èªããŸãã
$ strace ./intro execve("./intro", ["./intro"], []) = 0 [ Process PID=24135 runs in 32 bit mode. ] ... open("/lib32/libdl.so.2", O_RDONLY) = 3 ...
ããã§ããã¡ã€ã«ãµã€ãº-368ã®éå§çž®ãã€ãã確èªã§ããŸãã éåžžã®æ¹æ³ïŒcc + ldïŒã§ãåæ§ã®éå§çž®ãã¡ã€ã«ãããã«4ãããã€ãã«èšåŒµããããšãåå¥ã«ç¢ºèªã§ããŸãã
å§çž®ãã¡ã€ã«ã®ééã¯ãããã§ããïŒ
nasm -f bin intro.asm -o intro && chmod +x intro && \ cat intro | 7z a dummy -tGZip -mx=9 -si -so > intro.gz && \ cat unpack_header intro.gz > intro.sh && \ wc -c intro.sh && chmod +x intro.sh && \ ./intro.sh
254ãã€ãã
ãããã圌ã¯ãŸã äœãããŠããŸããã
圌ã«ããããŠãã ããïŒ
ããŠãdlopenãšdlsymãèªç±ã«äœ¿ããããã«ãªã£ãããlibSDLãšlibGLããããã€ãã®é¢æ°ãããŒãããŠããã®ãããªãã®ãååŸããããšãã§ããŸãã
ç§ãã¡ã¯ç¹ã«èªæ
¢ããããäºãã«ãã£ãããšããã¹ãŠã¢ã»ã³ãã©ãŒã«ç§»æ€ããŸãã
; , libs_to_dl: st_libSDL_name equ $ - dt_strtab db 'libSDL-1.2.so.0', 0 ; - , db 'SDL_Init', 0 db 'SDL_SetVideoMode', 0 db 'SDL_PollEvent', 0 db 'SDL_GetTicks', 0 db 'SDL_ShowCursor', 0 db 'SDL_GL_SwapBuffers', 0 db 'SDL_Quit', 0 db 0 ; = st_libGL_name equ $ - dt_strtab db 'libGL.so.1', 0 db 'glViewport', 0 db 'glCreateShader', 0 db 'glShaderSource', 0 db 'glCompileShader', 0 db 'glCreateProgram', 0 db 'glAttachShader', 0 db 'glLinkProgram', 0 db 'glUseProgram', 0 db 'glRectf', 0 db 0, 0 ; = _start: ; mov ebp, bss ; ebp bss -- , ! ; - , %define BSSADDR(a) ebp + ((a) - bss) %define F(f) [ebp + ((f) - bss)] ; mov esi, libs_to_dl+1 ; +1, .. ld_load , lea edi, [BSSADDR(libs_syms)] ; edi = , ld_load: dec esi ; 1, ; dlopen, push 1 ; RTLD_LAZY push esi ; call F(rel_dlopen) ; eax = dlopen([esi], 1) ; , <s> </s> mov ebx, eax ; , dlopen , ebx ; 0 ld_skip_to_zero: lodsb test al, al jnz ld_skip_to_zero ; \0 lodsb test al, al jz ld_second_zero dec esi ; 1 push esi ; push ebx ; dlopen call F(rel_dlsym) ; eax = dlsym([ebx], [esi]) stosd ; eax ( ) [edi], edi += 4 jmp ld_skip_to_zero ; ld_second_zero: ; , - ! lodsb test al, al jnz ld_load ; ! ; ! xor eax, eax ; eax = 0 inc eax ; ex = 1 (exit syscall) int 0x80 ; syscall file_size equ ($-$$) ; ; BSS-, absolute $ bss: ; libdl_syms: rel_dlopen: resd 1 rel_dlsym: resd 1 libs_syms: SDL_Init: resd 1 SDL_SetVideoMode: resd 1 SDL_PollEvent: resd 1 SDL_GetTicks: resd 1 SDL_ShowCursor: resd 1 SDL_GL_SwapBuffers: resd 1 SDL_Quit: resd 1 glViewport: resd 1 glCreateShader: resd 1 glShaderSource: resd 1 glCompileShader: resd 1 glCreateProgram: resd 1 glAttachShader: resd 1 glLinkProgram: resd 1 glUseProgram: resd 1 glRectf: resd 1 mem_size equ ($-$$)
_startèªäœãå«ãã_startã®çŽåŸã«çºçãããã¹ãŠã®ä»£ããã«ããã®ããŒã¹ãæ¿å
¥ããå¿
èŠããããŸãã
ã³ã³ãã€ã«ãããµã€ãºã455ãã€ãã®ãã¡ã€ã«ãååŸããŠå®è¡ããã¯ã©ãã·ã¥ããªãããšã確èªããŸãã ã¯ã©ãã·ã¥ããå ŽåãlibSDLãšlibGLã®DT_NEEDEDè¡ã®ã³ã¡ã³ãã解é€ããŠãäœãèµ·ãããã確èªããããšããŸãã
ãã¹ãŠããŸãããã°ãå
ã«é²ã¿ãæåŸã«ã·ã§ãŒããŒã§OpenGLãåæåã§ããŸãã ïŒã³ã¡ã³ãã«æžãããŠããããšãé€ããŠïŒç¹ã«æ³šæãå¿
èŠãªããšã¯ãããŸãããã¢ã»ã³ãã©ãŒã§ä»¥åã«ãã®å Žã§è¡ã£ãããšãç¹°ãè¿ããŸãã
; nasm -f bin intro.asm -o intro && chmod +x intro && \ ; cat intro | 7z a dummy -tGZip -mx=9 -si -so > intro.gz && \ ; cat unpack_header intro.gz > intro.sh && \ ; wc -c intro.sh && chmod +x intro.sh && \ ; ./intro.sh %define WIDTH 640 %define HEIGHT 360 %define FULLSCREEN 0 ;%define FULLSCREEN 0x80000000 bits 32 ; 32- org 0x00040000 ; , , - $$ ; ? . ( ) ; elf- db 0x7f, 'ELF' ; magic , , ELF db 1 ; EI_CLASS = ELFCLASS32 db 1 ; EI_DATA ELFDATA2LSB db 1 ; EI_VERSION = EV_CURRENT times 9 db 0 ; 9 , dw 2 ; e_type = ET_EXEC -- dw 3 ; e_machine = EM_386 dd 1 ; e_version = EV_CURRENT dd _start ; e_entry -- , dd phdrs - $$ ; e_phoff -- , program headers dd 0 ; e_shoff -- --//-- section headers, , , , 0 dd 0 ; e_flags -- dw ehsize ; e_ehsize -- ELF- (52 ) dw phsize ; e_phentsize -- program header (32 ) dw 3 ; e_phnum -- dw 0 ; e_shentsize -- section header dw 0 ; e_shnum -- () dw 0 ; e_shstrndx -- - , ehsize equ ($-$$) ; $ (+ org), ehsize elf- phdrs: ; program header dd 1 ; p_type = PT_LOAD -- " , " dd 0 ; p_offset -- , dd $$ ; p_vaddr -- , dd $$ ; p_paddr -- , - - , , dd file_size ; p_filesz -- , dd mem_size ; p_memsz -- . , e_filesz, . -- 6 . . !!11 , , . . dd 7 ; p_flags (=PF_RWX) -- , . dd 0x1000 ; p_align -- , , . 0x1000 phsize equ ($-phdrs) ; program header dd 2 ; p_type = PT_DYNAMIC dd dynamic - $$ ; p_offset dd dynamic ; p_vaddr dd dynamic ; p_paddr dd dynamic_size ; p_filesz dd dynamic_size ; p_memsz dd 6 ; p_flags = PF_RW dd 4 ; p_align dd 3 ; p_type = PT_INTERP dd interp - $$ ; p_offset dd interp ; p_vaddr dd interp ; p_paddr dd interp_size ; p_filesz dd interp_size ; p_memsz dd 4 ; p_flags = PF_R dd 1 ; p_align ; PT_DYNAMIC ; dynamic: dd 1, st_libdl_name ; DT_NEEDED -- , st_libdl_name ( ) ; , , ;dd 1, st_libSDL_name ;dd 1, st_libGL_name dd 4, dt_hash ; DT_HASH -- dd 5, dt_strtab ; DT_STRTAB -- . dd 6, dt_symtab ; DT_SYMTAB -- dd 10, dt_strtab_size ; DT_STRSZ -- dd 11, 16 ; DT_SYMENT -- dd 17, dt_rel ; DT_REL -- dd 18, dt_rel_size; DT_RELSZ -- dd 19, 8 ; DT_RELENT -- dd 0, 0 ; DT_NULL -- DT_DYNAMIC dynamic_size equ $ - dynamic ; DT_HASH ; - ; , ; dt_hash: dd 1, 3, 0, 0, 0, 0 ; DT_SYMTAB ; , dt_symtab: ; 1 -- (?!) dd 0, 0, 0 dw 0, 0 ; SHN_UNDEF ; 2 'dlopen' dd st_dlopen_name, 0, 0 dw 0x12 ; = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), .., , -- dw 0 ; SHN_UNDEF , , ; 3 'dlsym' dd st_dlsym_name, 0, 0 dw 0x12, 0 ; --//-- ; DT_REL ; . , dt_rel: dd rel_dlopen ; , dd 0x0101 ; ELF32_R_INFO(1,R_386_32) : dt_symtab[1] ('dlopen'), = + r_addend(=0 ) dd rel_dlsym ; --//-- dd 0x0201 ; ELF32_R_INFO(2,R_386_32) : dt_symtab[2] ('dlsym'), --//-- dt_rel_size equ $ - dt_rel ; -- , ; interp: db '/lib/ld-linux.so.2', 0 interp_size equ $ - interp ; DT_STRTAB ; . , PT_DYNAMIC -- dt_strtab: st_libdl_name equ $ - dt_strtab ; db 'libdl.so.2', 0 ; -- - st_dlopen_name equ $ - dt_strtab db 'dlopen', 0 st_dlsym_name equ $ - dt_strtab db 'dlsym', 0 dt_strtab_size equ $ - dt_strtab ; , libs_to_dl: st_libSDL_name equ $ - dt_strtab db 'libSDL-1.2.so.0', 0 ; - , db 'SDL_Init', 0 db 'SDL_SetVideoMode', 0 db 'SDL_PollEvent', 0 db 'SDL_GetTicks', 0 db 'SDL_ShowCursor', 0 db 'SDL_GL_SwapBuffers', 0 db 'SDL_Quit', 0 db 0 ; = st_libGL_name equ $ - dt_strtab db 'libGL.so.1', 0 db 'glViewport', 0 db 'glCreateShader', 0 db 'glShaderSource', 0 db 'glCompileShader', 0 db 'glCreateProgram', 0 db 'glAttachShader', 0 db 'glLinkProgram', 0 db 'glUseProgram', 0 db 'glRectf', 0 db 0, 0 ; = shader_vtx: db 'varying vec4 p;' db 'void main(){gl_Position=p=gl_Vertex;pz=length(p.xy);}' db 0 shader_frg: db 'varying vec4 p;' db 'void main(){' db 'float ' db 'z=1./length(p.xy),' db 'a=atan(px,py)+sin(p.z+z);' db 'gl_FragColor=' db '2.*abs(.2*sin(pz*3.+z*3.)+sin(p.z+a*4.)*p.xyxx*sin(vec4(z,a,a,a)))+(z-1.)*.1;' db '}', 0 _start: ; mov ebp, bss ; ebp bss -- , ! ; - , %define BSSADDR(a) ebp + ((a) - bss) %define F(f) [ebp + ((f) - bss)] ; mov esi, libs_to_dl+1 ; +1, .. ld_load , lea edi, [BSSADDR(libs_syms)] ; edi = , ld_load: dec esi ; 1, ; dlopen, push 1 ; RTLD_LAZY push esi ; call F(rel_dlopen) ; eax = dlopen([esi], 1) ; , <s> </s> mov ebx, eax ; , dlopen , ebx ; 0 ld_skip_to_zero: lodsb test al, al jnz ld_skip_to_zero ; \0 lodsb test al, al jz ld_second_zero dec esi ; 1 push esi ; push ebx ; dlopen call F(rel_dlsym) ; eax = dlsym([ebx], [esi]) stosd ; eax ( ) [edi], edi += 4 jmp ld_skip_to_zero ; ld_second_zero: ; , - ! lodsb test al, al jnz ld_load ; ! push 0x21 ; SDL_INIT_ TIMER | VIDEO call F(SDL_Init) ; SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO); push 2 | FULLSCREEN ; SDL_OPENGL push 32 ; 32 push HEIGHT push WIDTH call F(SDL_SetVideoMode) ; SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL|FULLSCREEN); ; WxH ! cdecl ftw! push 0 push 0 call F(glViewport) ; glViewport(0, 0, WIDTH, HEIGHT); call F(SDL_ShowCursor) ; SDL_ShowCursor(0); ; call F(glCreateProgram) ; eax = glCreateProgram(); mov edi, eax ; edi = program_id push 0x8b31 pop esi ; esi = GL_VERTEX_SHADER ; 4 ebp temp -- dlopen, mov dword [ebp], shader_vtx push esi call F(glCreateShader) ; eax = glCreateShader(GL_VERTEX_SHADER); mov ebx, eax push 0 push ebp push 1 push eax call F(glShaderSource) ; glShaderSource(shader_id, 1, &shader_vtx, 0); push ebx ; nVidia , call F(glCompileShader) ; glCompileShader(shader_id); push ebx ; ! push edi call F(glAttachShader) ; glAttachShader(program_id, shader_id); dec esi ; esi = GL_FRAGMENT_SHADER mov dword [ebp], shader_frg ; , = ! push esi call F(glCreateShader) mov ebx, eax push 0 push ebp push 1 push eax call F(glShaderSource) push ebx call F(glCompileShader) push ebx push edi call F(glAttachShader) push edi call F(glLinkProgram) ; glLinkProgram(program_id); call F(glUseProgram) ; glUseProgram(program_id); mainloop: call F(SDL_GetTicks) ; eax == SDL_GetTicks(); -- mov [ebp], eax fninit ; FPU, fild dword [ebp] ; st(0) = eax == time , st(1) = 1000 push 400 ; , , fild dword [esp] ; st(0) = 1000 fdiv ; st(0) /= 1000 = fld1 ; st(0) = 1, st(1) = faddp st1 ; st(0) = + 1 fst dword [ebp] mov eax, [ebp] ; eax = (float-ieee)t fchs ; st(0) = -st(0) fstp dword [ebp] mov ebx, [ebp] ; ebx = -(float-ieee)t push ebx push ebx push eax push eax call F(glRectf) ; glRectf(-t,-t,t,t) times 5 pop eax ; , , , .. call F(SDL_GL_SwapBuffers) lea edx, [BSSADDR(SDL_Event)] ; SDL_Event push edx call F(SDL_PollEvent) ; SDL_PollEvent(&SDL_Event); pop edx ; edx cmp byte [edx], 2 ; SDL_Event.type != SDL_KEYDOWN jnz mainloop call F(SDL_Quit) ; ; ! xor eax, eax ; eax = 0 inc eax ; ex = 1 (exit syscall) int 0x80 ; syscall file_size equ ($-$$) ; ; BSS-, absolute $ bss: ; libdl_syms: rel_dlopen: resd 1 rel_dlsym: resd 1 libs_syms: SDL_Init: resd 1 SDL_SetVideoMode: resd 1 SDL_PollEvent: resd 1 SDL_GetTicks: resd 1 SDL_ShowCursor: resd 1 SDL_GL_SwapBuffers: resd 1 SDL_Quit: resd 1 glViewport: resd 1 glCreateShader: resd 1 glShaderSource: resd 1 glCompileShader: resd 1 glCreateProgram: resd 1 glAttachShader: resd 1 glLinkProgram: resd 1 glUseProgram: resd 1 glRectf: resd 1 SDL_Event: resb 24 mem_size equ ($-$$)
åç«ããæåŸã«1024ã«ã»ãšãã©åãŸããªã750ãã€ããå
¥åããŸãããã®çµæãæ¹åããããšã¯å¯èœã§ããïŒãã¡ãã次ã®ããšãã§ããŸãã- å€ãã®æ§é ã¯ãä»ã®æ§é ãçµãããã®ãšåããã®ããå§ãŸããŸã
- åæ§ã®ããŒã¿ã䞊ã¹ãŠé
眮ãããšäŸ¿å©ã§ãïŒããããŒãç·©ãã§ãããè¡ãæã£ãŠãããx86åœä»€ãã€ã³ã¿ãŒãªãŒãã§ããªãïŒ
- çµç¹å€æŽ
- æãæšãŠã-ããšãã°ãSDL_ShowCursorã§ãã¹ãŠãã³ã¡ã³ãã¢ãŠãããŸã
å§çž®ãã¡ã€ã«ã®ãµã€ãºã¯ãéå§çž®ãã¡ã€ã«ã®ãµã€ãºã«å¿ããŠå調ã«ã¯ã»ã©é ãããšãèŠããŠãã䟡å€ããããŸããããšãã°ãespãè¿œå ããåã«5ãããeaxã®ãµã€ãºãé¡èã«20åã«ãªããŸããäžæœãªã»ããã§ã³ã¡ã³ãã¢ãŠããããšãæåŸã®3ã€ã®äžèŠãªelfããããŒãã£ãŒã«ãïŒe_shentsizeãšããã«ç¶ã2ã€ã®ã¬ãã§ãŠïŒã¯ãphdrsãšdynamicãdt_hashãdt_symtabã®éã®ãŒããšä»ã®åäžããŒã¿ãåé€ããŸããåèšïŒ718ãã€ããããªããšã®é¢ä¿ã¯ããããŸããããç§ã®æã¯ãã§ã«ããã¿ãæããŠããŸãã 306ãã€ãããããŸãïŒã·ã§ãŒããŒã絶æ»
ãããã³ãã«ã«å®å
šã«çœ®ãæããããšãã§ãããšããäºå®ãèæ
®ãããšãããã«å€§ãããªããŸãïŒïŒãã®ãããªæ³åã絶ããã»ã©å€§ããªãã£ã³ãã¹ã§äœãã§ããã§ããããïŒããšãã°ããã®ãããªãã®ïŒæ
éã«ã匷åãªã°ã©ãã£ãã¯ã«ãŒããå¿
èŠã§ãïŒïŒ shader_vtx: db 'varying vec4 p,v;' db 'void main()' db '{' db 'gl_Position=gl_Vertex;' db 'p=vec4(mat3(cos(length(gl_Vertex.xy)),0.,sin(length(gl_Vertex.xy)),0.,1.,0.,-sin(length(gl_Vertex.xy)),0.,cos(length(gl_Vertex.xy)))*vec3(gl_Vertex.xy*.1,-.9),length(gl_Vertex.xy));' db 'v=vec4(mat3(cos(length(gl_Vertex.xy)),0.,sin(length(gl_Vertex.xy)),0.,1.,0.,-sin(length(gl_Vertex.xy)),0.,cos(length(gl_Vertex.xy)))*vec3(gl_Vertex.xy*.1,.1),length(gl_Vertex.xy));' db '}' db 0 shader_frg: db 'varying vec4 p,v;' ;db 'float mx(vec3 a){return max(ax,max(ay,az));}' db 'float mn(vec3 a){return min(ax,min(ay,az));}' db 'float F(vec3 a){return min(mn(vec3(1.)-abs(a)),-mn(abs(mod(a+vec3(.1),vec3(.4))-vec3(.2))-.15));}' ;db 'float F(vec3 a){return min(mn(vec3(1.)-abs(a)),length(mod(a,vec3(.4))-vec3(.2))-.06);}' db 'vec3 n(vec3 a){' db 'vec3 e=vec3(.0001,.0,.0);' db 'return normalize(vec3(F(a)-F(a+e.xyy),F(a)-F(a+e.yxy),F(a)-F(a+e.yyx)));' db '}' db 'vec4 tr(vec3 E,vec3 D){' db 'D=normalize(D);' db 'float L=.01;' db 'int i=0;' db 'for(i;i<512;++i){' db 'float d=F(E+D*L);' db 'if(d<.0001)break;' db 'L+=d;' db '}' ;db 'return vec2(L,float(i)/512.);' db 'return vec4(E+D*L,float(i)/512.);' db '}' db 'float I(vec3 a){' db 'vec3 l=vec3(sin(pw*1.3),cos(pw*4.2),sin(pw*3.2))*.9,la=la;' db 'return length(tr(a,la).xyz-a)*dot(n(a),-normalize(la))/dot(la,la)+.01;' ;db 'return tr(a,-lv).x*F(a+lv)/dot(lv,lv)+.01;' db '}' db 'void main(){' db 'vec4 t=tr(p.xyz,v.xyz);' db 'gl_FragColor=I(t.xyz)*(abs(t)+vec4(tw*5.));' ;db 'vec2 t=tr(p.xyz,v.xyz);' ;db 'vec3 q=p.xyz+normalize(v.xyz)*tx;' ;db 'gl_FragColor=I(q)+vec4(ty);' db '}' db 0
ãŸãã¯ããïŒ shader_vtx: db 'varying vec4 p,v;' db 'void main()' db '{' db 'gl_Position=gl_Vertex;' db 'p=vec4(mat3(cos(length(gl_Vertex.xy)),0.,sin(length(gl_Vertex.xy)),0.,1.,0.,-sin(length(gl_Vertex.xy)),0.,cos(length(gl_Vertex.xy)))*vec3(gl_Vertex.xy*.1,-.9),length(gl_Vertex.xy));' db 'v=vec4(mat3(cos(length(gl_Vertex.xy)),0.,sin(length(gl_Vertex.xy)),0.,1.,0.,-sin(length(gl_Vertex.xy)),0.,cos(length(gl_Vertex.xy)))*vec3(gl_Vertex.xy*.1,.1),length(gl_Vertex.xy));' db '}' db 0 shader_frg: db 'varying vec4 p,v;' db 'float mn(vec3 a){return min(ax,min(ay,az));}' db 'float F(vec3 a){return min(mn(vec3(1.)-abs(a)),length(mod(a,vec3(.4))-vec3(.2))-.06);}' db 'vec3 n(vec3 a){' db 'vec3 e=vec3(.0001,.0,.0);' db 'return normalize(vec3(F(a)-F(a+e.xyy),F(a)-F(a+e.yxy),F(a)-F(a+e.yyx)));' db '}' db 'vec3 tr(vec3 E,vec3 D){' db 'D=normalize(D);' db 'float L=.01;' db 'int i=0;' db 'for(i;i<512;++i){' db 'float d=F(E+D*L);' db 'if(d<.001)break;' db 'L+=d;' db '}' db 'return E+D*L;' db '}' db 'vec3 I(vec3 a,vec3 l,vec3 c){' db 'return c*(clamp(length(tr(a,la)-a),0.,length(la))*dot(n(a),normalize(al))/dot(la,la));' db '}' db 'void main(){' db 'vec3 t=tr(p.xyz,v.xyz);' db 'gl_FragColor=vec4(' db 'I(t,vec3(sin(pw*1.3),cos(pw*4.2),sin(pw*3.2))*.7,vec3(.9,.6,.2))+' db 'I(t,vec3(sin(pw*3.2),sin(pw*4.2),sin(pw*1.3))*.7,vec3(.0,.3,.5)),1.);' db '}' db 0
ãªããããã®ã·ã§ãŒããŒã¯ãã®ãããªç»åãäžããã®ã§ããïŒæ¥å¹Ž3æã«æçš¿é »åºŠã®è¯ãäŒçµ±ã«åŸã£ãŠãããã«ã€ããŠãäŒãããŸãïŒãã£ãã¡ã§ç¬ç«ããããŒã¯ãŒãïŒã¬ã€ããŒãã³ã°è·é¢ãã£ãŒã«ãïŒãã®ç·ã¯å€ãã®æ
å ±ãæã£ãŠããŸãïŒããšãããŒã°
ãã®ããã¹ãã«ã¯èª€ããæºæé©æ§ãsimplyæ
¢ãªåïŒããã§èªåã®ä¿¡é Œãæªçšããåæ°ãæ°ããŸãïŒããããããããšããäºå®ã«ãããããããç§ã¯ãããæçšã§ããããšãå€æããå°ãªããšã誰ããå¥ã®ã¹ã¿ãŒãã¢ãããäœããªãããšãæã¿ãŸããã代ããã«æ¬åœã«è€éã§ãé¢çœããŠäŸ¡å€ã®ãããã®ãäœæããŸãããã®ãããªåçã§ã¯ãã¯ã©ã¹ã¡ãŒããæ¥ããããã¯ãªãã¯ãã§ãããäžè¬çã«ã¯ãããšãä»ã®ãã¡ã³ã®æ²é³Žã®ããªã声ãèãããã¯ãã§ããããŸã éçºã®äœå°ããããããã¯çµããã§ã¯ãããŸãããããªããè¡ããšãããããã¯çµããã§ã¯ãããŸããïŒæ¬¡åãCããã°ã©ãã³ã°èšèªã§ã¹ãŠã£ã³ã®ã³ã°ããŒã¹ãäœãããåŒãåºããŠãã³ã¹ããã¢ãçç Žããæ¹æ³ã«ã€ããŠã®ã¹ããŒãªãŒãåŸ
ã£ãŠãããšãã10æã«ãŸãäŒããŸãããïŒ