Linux甚の1k / 4kむントロの䜜成、パヌト2

半幎も経っおいたせん 緊匵しお、蚘憶に残るように、私たちが最埌に萜胆ずアセンブラヌに飛び蟌む玄束に萜ち着いたずき 、あなたはそうするこずができたす。
たあ、少幎は蚀った-少幎はやった。 この䞍栌奜な文字の山から、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 

結果のファむルず䞭間ファむルのサむズを確認するず、次のこずがわかりたす。
  1. sstripが決定-ストリップされたsimple-cのサむズは、simple-c-origのサむズのほが3倍小さい
  2. 圧瞮はほずんど問題ではありたせん-解凍コヌドのある圧瞮ファむルは、圧瞮されおいないファむルずほが同じくらいかかりたす
  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 

さらに、以䞋を修正する必芁がありたす。
  1. 明らかにe_phnumを3に倉曎したす
  2. ファむルの最埌に远加したす
     ; BSS-,      absolute $ bss: ;      rel_dlopen: resd 1 rel_dlsym: resd 1 mem_size equ ($-$$) 
  3. mem_sizeに蚭定されたPT_LOADヘッダヌp_memsz内


これで、人工゚ルフは動的にリンクできるようになりたした。 これをチェックしおください。
これは単なるテストではなく、朜圚的なむントラなので、ファむルの名前をintro.asmに倉曎したす。 それを集めたしょう
 $ nasm -f bin intro.asm -o intro && chmod +x intro 

そしお、straceを実行しお、圌が実際にあらゆる皮類の読み取りを詊みおいるこずを確認したす。
 $ strace ./intro execve("./intro", ["./intro"], [/* 67 vars */]) = 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バむトを入力したす。この結果を改善するこずは可胜ですか
もちろん次のこずができたす。
  1. 倚くの構造は、他の構造が終わるものず同じものから始たりたす
  2. 同様のデヌタを䞊べお配眮するず䟿利ですヘッダヌが緩んでいる、行が揃っおいる、x86呜什をむンタヌリヌブできない
  3. 組織倉曎
  4. 投げ捚おる-たずえば、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月にたた䌚いたしょう

Source: https://habr.com/ru/post/J143766/


All Articles