เราสร้างไฟล์ ELF พร้อมข้อมูลภาษี (DWARF) ด้วยตนเอง (สำหรับไมโครคอนโทรลเลอร์ ARM) จัดรูปแบบนามสกุลไฟล์ ELF และ PE EXE Elf

โกลอฟน่า / ฟังก์ชันเพิ่มเติม

เวอร์ชันที่มี TOC ที่ดีและมีเนื้อหามากมาย: http://www.cirosantilli.com/elf-hello-world (กด 30k char exchange ที่นี่)

มาตรฐาน

ELF มอบให้โดย LSB:

  • หลักทั่วไป: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/elf-generic.html
  • คอร์ AMD64: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-AMD64/LSB-Core-AMD64/book1.html

LSB มีความสำคัญที่ต้องพึ่งพามาตรฐานอื่นที่มีส่วนขยายเล็กน้อย ยกเว้น:

    ทั่วไป (ละเมิด SCO):

    • System V ABI 4.1 (1997) http://www.sco.com/developers/devspecs/gabi41.pdf ไม่ใช่ 64 บิต ต้องการหมายเลขวิเศษที่สงวนไว้ สำหรับไฟล์หลัก
    • System V ABI Update DRAFT 17 (2003) http://www.sco.com/developers/gabi/2003-12-17/contents.html เพิ่ม 64 บิต เพียงอัปเดตส่วน 4 และ 5 ของเอกสารด้านหน้า: เย็บแผลด้วยคางและถามเหมือนก่อนหน้านี้
  • สถาปัตยกรรมเฉพาะ:

    • IA-32: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-IA32/LSB-Core-IA32/elf-ia32.html ส่วนใหญ่ที่ http://www.sco.com/developers /devspecs /abi386-4.pdf
    • AMD64: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-AMD64/LSB-Core-AMD64/elf-amd64.html ส่วนใหญ่จะอยู่ที่ http://www.x86-64.org/ documentation/ abi.pdf

สามารถดูบทสรุปที่ดีกว่าได้ที่:

คุณสามารถดูโครงสร้างนี้เพื่อหาวิธีการที่มีประโยชน์เพิ่มเติม เช่น readelf และ objdump

สร้างก้น

ให้ฉันแยกย่อยตัวอย่างขั้นต่ำที่ Linux x86-64 ชนะ:

ส่วน .data hello_world db "Hello world!", 10 hello_world_len เท่ากับ $ - ส่วน hello_world .text

รวบรวมมาให้ช่วย

Nasm -w+all -f elf64 -o "hello_world.o" "hello_world.asm" ld -o "hello_world.out" "hello_world.o"

  • นาสเอ็ม 2.10.09
  • Binutils เวอร์ชัน 2.24 (แทนที่ ld)
  • อูบุนตู 14.04

เราไม่ได้เอาชนะโปรแกรม C เพื่อให้เราสามารถลดความซับซ้อนของการวิเคราะห์ซึ่งจะเท่ากับ 2 :-)

16 อาการไบนารี

hd hello_world.o hd hello_world.out

โครงสร้างไฟล์ส่วนกลาง

ไฟล์ ELF ประกอบด้วยส่วนต่อไปนี้:

  • ส่วนหัวของเอลฟ์ ระบุตำแหน่งของตารางส่วนหัวที่แบ่งและตารางส่วนหัวของโปรแกรม

    ตารางหัวเรื่องในหน่วยงาน (จำเป็นในภาษาของไฟล์ไอคอน) ผิวหนังอาจเป็นส่วนหัวของส่วน e_shnum;

    N ดิวิชั่น N<= e_shnum (необязательно в исполняемом файле)

    ตารางส่วนหัวของโปรแกรม (สำหรับเลือกไฟล์เท่านั้น) บางส่วนอาจเป็นส่วนหัวของโปรแกรม e_phnum บางส่วนระบุตำแหน่งของส่วน

    N ส่วน s N<= e_phnum (необязательно в исполняемом файле)

ลำดับของส่วนเหล่านี้ไม่ได้รับการแก้ไข: หนึ่งส่วนคงที่ - ส่วนหัวของ ELF ซึ่งอาจเป็นส่วนแรกในไฟล์: เอกสารส่วนกลางดูเหมือนจะเป็น:

ส่วนหัวของเอลฟ์

วิธีที่ง่ายที่สุดในการพาดหัวข่าว:

readelf -h hello_world.o readelf -h hello_world.out

ไบต์ในไฟล์วัตถุ:

00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF..........| 00000010 01 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 |..>............| 00000020 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 | [ป้องกันอีเมล]| 00000030 00 00 00 00 40 00 00 00 00 00 40 00 07 00 03 00 |[ป้องกันอีเมล]@.....|

00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF..........| 00000010 02 00 3e 00 01 00 00 00 b0 00 40 00 00 00 00 00 |..> [ป้องกันอีเมล]| 00000020 40 00 00 00 00 00 00 00 10 01 00 00 00 00 00 00 |@...............| 00000030 00 00 00 00 40 00 38 00 02 00 40 00 06 00 03 00 |[ป้องกันอีเมล]@.....|

โครงสร้างยื่น:

Typedef struct ( unsigned char e_ident; Elf64_Half e_type; Elf64_Half e_machine; Elf64_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off e_shoff; Elf64_Word e_flags; Elf64_Half e_ehsize; Elf64_Half e_phentsize; Elf64_Half e_phnum; Elf64_Half e_shentsize; Elf64_Half e_shnum; Elf64_Half e_shstrndx; ) Elf64_Ehdr;

สลายตัวด้วยตนเอง:

    0 0: EI_MAG = 7f 45 4c 46 = 0x7f "E", "L", "F": เลขวิเศษเอลฟ์

    0 4: EI_CLASS = 02 = ELFCLASS64: เอลฟ์ 64 บิต

    0 5: EI_DATA = 01 = ELFDATA2LSB: ข้อมูลกลุ่มใหญ่

    0 6: EI_VERSION = 01: เวอร์ชันรูปแบบ

    0 7: EI_OSABI (เฉพาะในปี 2546) = 00 = ELFOSABI_NONE: ไม่มีนามสกุล

    08: EI_PAD = 8x 00: ไบต์ที่สงวนไว้ มีความผิด แต่ตั้งค่าเป็น 0

    1 0: e_type = 01 00 = 1 (ตัวท้ายใหญ่) = ET_REl: รูปแบบที่จะย้าย

    ไฟล์มี 02 00 สำหรับ ET_EXEC

    1 2: e_machine = 3e 00 = 62 = EM_X86_64: สถาปัตยกรรม AMD64

    1 4: e_version = 01 00 00 00: สามารถเป็น 1

    1 8: e_entry = 8x 00: จุดเริ่มต้นของที่อยู่ของรายการหรือ 0 ดังนั้นจึงไม่ zastoovuetsya สำหรับไฟล์วัตถุเนื่องจากไม่มีจุดเริ่มต้น

    ไฟล์มี b0 00 40 00 00 00 00 00 สิ่งที่ต้องทำ: เราสามารถติดตั้งอะไรได้บ้าง? เคอร์เนลที่นี่กำหนด IP โดยไม่มีค่ากลางไม่ยากที่จะตั้งโปรแกรม

    2 0: e_phoff = 8x 00: ใช้ตารางส่วนหัวของโปรแกรม 0 แต่ไม่ใช่

    40 00 00 00 สำหรับไฟล์ ดังนั้น vin จะเริ่มต้นทันทีหลังจากส่วนหัวของ ELF

    2 8: e_shoff = 40 7x 00 = 0x40: ใช้เพื่อแยกไฟล์ตารางส่วนหัว 0 มิฉะนั้นจะไม่

    3 0: e_flags = 00000000 สิ่งที่ต้องทำ พิเศษสำหรับอาร์ค

    3 4: e_ehsize = 4000: ขนาดของหัวเอลฟ์ ทำไมต้องสนาม? คุณจะเปลี่ยนได้อย่างไร?

    3 6: e_phentsize = 00 00: ขนาดส่วนหัวของสกินโปรแกรม, 0 แต่ไม่ใช่

    38 00 สำหรับไฟล์ที่ถูกแฮ็ก: ความยาวของไฟล์คือ 56 ไบต์

    3 8: e_phnum = 0000: จำนวนรายการส่วนหัวของโปรแกรม 0 ซึ่งไม่ใช่

    02 00 สำหรับไฟล์ที่เชื่อมโยง: є 2 รายการ

    3 A: e_sentsize และ e_shnum = 40 00 07 00: heading size เพื่อแบ่งเรคคอร์ดจำนวนนี้

ตารางส่วนหัว

อาร์เรย์ของโครงสร้าง Elf64_Shdr

บันทึกหนังเรียกข้อมูลเมตาเกี่ยวกับแผนกนี้

e_shoff ของส่วนหัว ELF ให้ตำแหน่งสแปม 0x40

e_shentsize และ e_shnum จากส่วนหัวของ ELF ดูเหมือนว่าเรามี 7 รายการ ผิวลิ่ม 0x40

อีกครั้ง ตารางรับไบต์จาก 0x40 ถึง 0x40 + 7 + 0x40 - 1 = 0x1FF

ตั้งชื่อส่วนที่สงวนไว้สำหรับการร้องเพลงประเภทต่างๆ เช่น http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html#special_sections .text ประเภทที่ต้องการ SHT_PROGBITS และ SHF_ALLOC + SHF_EXECINSTR

readelf -S hello_world.o:

มีส่วนหัว 7 ส่วนเริ่มต้นที่ออฟเซ็ต 0x40: ส่วนหัว: ชื่อประเภทที่อยู่ออฟเซ็ตขนาด entsize ธงข้อมูลการเชื่อมโยง [0] NULL000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002] .text PROGBITS 0000000000000000 00000210 0000000000000027 0000000000000000 AX 0 0 16 [ 3] .shstrtab STRTAB 0000000000000000 00000240 0000000000000032 0000000000000000 0 0 1 [ 4] .symtab SYMTAB 0000000000000000 00000280 00000000000000a8 0000000000000018 5 6 4 [ 5] .strtab STRTAB 0000000000000000 00000330 0000000000000034 0000000000000000 0 O (ต้องการการประมวลผล OS เพิ่มเติม) o (เฉพาะ OS), p (เฉพาะโปรเซสเซอร์)

struct ในรูปแบบสกิน:

โครงสร้าง Typedef ( Elf64_Word sh_name; Elf64_Word sh_type; Elf64_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf64_Xword sh_size; Elf64_Word sh_link; 64;

กระจาย

กระจายไปยังดัชนี 0

ย้ายจากไบต์จาก 0x40 เป็น 0x7F

ส่วนแรกมีเสน่ห์เสมอ: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html

นอกจากนี้ จำนวนของส่วน SHN_LORESERVE (0xff00) หรือมากกว่านั้น e_shnum อาจมีค่า SHN_UNDEF (0) และจำนวนระเบียนในตารางส่วนหัวของการกระจายจะถูกเก็บไว้ในฟิลด์ sh_size ของส่วนหัวของพาร์ติชันด้วย ดัชนี 0 (บันทึกสมาชิก sh_size ด้วย)

ส่วนรูปที่ 4-7: ดัชนีส่วนพิเศษสำหรับส่วนมายากลอื่นๆ

ในดัชนี 0 SHT_NULL є obov'yazykovim Chi іsnuyet іnshі vidi vikoristannya: อะไรคือความเสียหายในการแยกวิเคราะห์ SHT_NULL ใน ELF? ?

.data แยก

ข้อมูล - ส่วนที่ 1:

00000080 01 00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 |................| 00000090 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 |................| 000000a0 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000000b0 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

    ที่นี่ 1 เพื่อบอกว่าอักขระตัวแรกของส่วนนี้เริ่มต้นด้วยอักขระตัวแรกของส่วนและสิ้นสุดด้วยอักขระตัวแรก NUL การตั้งค่า row.data

    ข้อมูล - ชื่อหนึ่งของการกระจาย เนื่องจากอาจเป็นค่าเดียวกัน http://www.sco.com/developers/gabi/2003-12-17/ch4.strtab.html

    ในส่วนเหล่านี้ ข้อมูลเริ่มต้นจะถูกบันทึก เพื่อช่วยในการสร้างอิมเมจของหน่วยความจำของโปรแกรม

  • 80 4: sh_type = 01 00 00 00: SHT_PROGBITS: แทนที่จะแจกจ่ายงานที่ไม่ใช่ของ ELF เช่นเดียวกับที่โปรแกรมตีความโยคะ ไม่เป็นไรเพราะ .data

    80 8: sh_flags = 03 7x 00: SHF_ALLOC และ SHF_EXECINSTR: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html#sh_flags ตามที่กำหนดโดยการกระจาย

    90 0: sh_addr = 8x 00: ในที่อยู่เสมือนนี้จะถูกวางตำแหน่งในตอนท้ายของวัน ดังนั้นจึงไม่มีตำแหน่ง

    90 8: sh_offset = 00 02 00 00 00 00 00 00 = 0x200: จำนวนไบต์ในตอนเริ่มต้นของโปรแกรมถึงไบต์แรกในการกระจายนี้

    a0 0: sh_size = 0d 00 00 00 00 00 00 00

    ดังนั้นใช้ 0xD ไบต์เริ่มต้นด้วย sh_offset 200, mi bachimo:

    00000200 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 |สวัสดีชาวโลก!.. |

    อะฮ่า! Otzhe แถวของเรา "สวัสดีชาวโลก!" รู้ในการกระจายข้อมูลตามที่เรากล่าวไว้ tse NASM

    เมื่อเราดูแบบ HD เสร็จ เราจะเห็นดังนี้:

    Readelf-x.data สวัสดี_world.o

    อันไหนที่จะป้อน:

    ดัมพ์เลขฐานสิบหกของส่วน ".data": 0x00000000 48656c6c 6f20776f 726c6421 0a สวัสดีชาวโลก!.

    NASM กำหนดวันพลังงานสำหรับแผนกซึ่งถูกวางไว้อย่างน่าอัศจรรย์ก่อน: ข้อมูล: http://www.nasm.us/doc/nasmdoc7.html#section-7.9.2

    นอกจากนี้ ให้ความสนใจกับความจริงที่ว่ามีการเลือกผิด: คอมไพเลอร์ C ที่ดีโดยการวางแถวใน .rodata เพื่อแทนที่บางสิ่งที่มีไว้สำหรับการอ่านเท่านั้น และเพื่อให้สามารถปรับแต่งระบบปฏิบัติการต่อไปได้

    a0 8: sh_link และ sh_info = 8x 0: อย่าหยุดที่ประเภทของการกระจาย http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html#special_sections

    b0 0: sh_addralign = 04 = สิ่งที่ต้องทำ: ต้องการเปลี่ยนแปลงหรือไม่ มีเป้าหมายสำหรับ sh_addr และสำหรับสัญลักษณ์ที่อยู่ตรงกลางของ sh_addr หรือไม่

    b0 8: sh_entsize = 00 = แยกไม่ล้างแค้นโต๊ะ ยักโช! = 0 ซึ่งหมายความว่ามีการแจกจ่ายตารางบันทึกขนาดคงที่ ไฟล์ใดควรมีลิงก์ readelf แต่มีที่ว่างสำหรับการแจกแจง .symtab และ .rela.text

.text แยก

ตอนนี้ถ้าเราแบ่งส่วนด้วยมือให้บัณฑิตและบัณฑิต readelf -S ของส่วนอื่น ๆ

ชื่อ ประเภท ที่อยู่ ขนาดออฟเซ็ต EntSize แฟล็ก ข้อมูลลิงก์ จัดตำแหน่ง [ 2 ] .text PROGBITS 0000000000000000 00000210 000000000000020 000

ข้อความจะถูกเขียนหากไม่สามารถเขียนได้: ดังนั้นเราจึงสามารถลองเขียน segfaults ของ Linux ได้ เราสงสัยว่าทำไมเราถึงมีรหัส:

Objdump -d hello_world.o

Hello_world.o: รูปแบบไฟล์ elf64-x86-64 การแยกส่วน .text: 0000000000000000<_start>: 0: b8 01 00 00 00 mov $0x1,%eax 5: bf 01 00 00 00 mov $0x1,%edi a: 48 be 00 00 00 00 00 movabs $0x0,%rsi 11:00 0 0d 00 00 00 mov $0xd,%edx 19:0f 05 syscall 1b:b8 3c 00 00 00 mov $0x3c,%eax 20:bf 00 00 00 00 mov $0x0,%edi 25:0

เราจะ grep b8 01 00 00 บน hd ได้อย่างไร เราจะเห็นเฉพาะใน 00000210 ตามที่กล่าวไว้ในการกระจายนี้ І rozmir dorivnyuє 27 ซึ่งได้รับการยืนยันเช่นกัน นั่นเป็นเหตุผลที่เราสามารถพูดคุยเกี่ยวกับการแบ่งที่ถูกต้อง

ดูเหมือนว่ารหัสที่ถูกต้อง: a write ตามด้วย exit

Naytsіkavіsha part - แถว a ซึ่งจะปล้น:

เคลื่อนย้าย $0x0,%rsi

ส่งแถวที่อยู่ไปยังวิกิระบบ ในเดนมาร์ก ชั่วโมง 0x0 เป็นเพียง zapovnyuvachem หลังจากวางสาย จะมีการเปลี่ยนแปลงโยคะ:

4000ba: 48 be d8 00 60 00 00 movabs $0x6000d8,%rsi

การแก้ไขนี้สามารถทำได้ผ่านข้อมูลการแจกแจง rela.text

SHT_STRTAB

พาร์ติชันที่มี sh_type == SHT_STRTAB เรียกว่าตารางแถว

ดังนั้นพวกไวโคริสต์จึงถูกแบ่งออกเป็นฝ่ายอื่น ๆ ถ้าเรียงแถวของพวกไวโคริสต์ ส่วน "วิคตอเรีย" พูดว่า:

  • ช่างเป็นแถวของ vikoristovuyut กลิ่นเหม็น
  • ดัชนีของตารางของทั้งแถวคืออะไร แถวเริ่มต้นที่ใด

ตัวอย่างเช่น เราสามารถสร้างตารางแถว วิธีล้างแค้น: สิ่งที่ต้องทำ: คุณต้องเริ่มด้วย \0 อะไร

ข้อมูล: \0 abc \0 d e f \0 ดัชนี: 0 1 2 3 4 5 6 7 8

І yakscho іnshiy razdіlต้องการที่จะชนะแถว d e f กลิ่นเหม็นของการตำหนิเพื่อระบุในดัชนี 5 ของ tsgo razdіlu (ตัวอักษร d)

ดูตารางแถว:

  • .shstrtab
  • .strtab

.shstrtab

ประเภทพาร์ติชัน: sh_type == SHT_STRTAB

Zagalne im'ya: แถวชื่อเรื่องถูกแบ่งออก

ฉันแชร์แล้ว shstrtab ถูกสงวนไว้ มาตรฐานมี:

Tsey แยกเพื่อล้างแค้นชื่อแยก

สาขาใดควรมีฟิลด์ e_shstrnd ของส่วนหัว ELF

ดัชนีแถวของส่วนนี้ระบุโดยฟิลด์ sh_name ของส่วนหัวของส่วน ซึ่งระบุแถว

สาขาใดที่ไม่ได้เปิดใช้งาน SHF_ALLOC จะใช้งานไม่ได้กับโปรแกรมที่ชนะ

Readelf-x.shstrtab สวัสดี_world.o

Hex dump of section ".shstrtab": 0x00000000 002e6461 7461002e 74657874 002e7368 ..data..text..sh 0x00000010 73747274 6162002e 73796d74 6162002e strtab..symtab.. 0x00000020 73747274 6162002e 72656c61 2e746578 strtab..rela.tex 0x00000030 7400 t.

ข้อมูลที่คุณเผยแพร่อาจแก้ไขรูปแบบ: http://www.sco.com/developers/gabi/2003-12-17/ch4.strtab.html

ในขณะที่เราประหลาดใจกับชื่อของแผนกอื่นๆ จะดีกว่าที่กลิ่นเหม็นทั้งหมดจะล้างแค้นให้กับตัวเลข เป็นต้น section.text อาจหมายเลข 7 .

จากนั้นแถวสกินจะสิ้นสุดลงหากพบอักขระ NUL ตัวแรก อักขระ 12 \ 0 ในครั้งต่อไป ข้อความ \ 0 .

.symtab

ประเภทพาร์ติชัน: sh_type == SHT_SYMTAB

ชื่อสามัญ: ตารางสัญลักษณ์.

มีนัยสำคัญกลับไปกลับมาว่า:

  • sh_link = 5
  • sh_info=6

ในส่วน SHT_SYMTAB ตัวเลขหมายความว่า:

  • แถว
  • วิธีการตั้งชื่อสัญลักษณ์, เปลี่ยนจากสาขา 5, .strtab
  • ข้อมูลการย้ายจะถูกซื้อใหม่ที่สาขา 6, .rela.text

เครื่องมือที่ดีในระดับสูงสำหรับการแยกแยะส่วนนี้:

Nm hello_world.o

อันไหนคือ:

0000000000000000 T _start 0000000000000000d hello_world 000000000000000d a hello_world_len

อย่างไรก็ตาม Tse เป็นการแสดงออกถึงระดับสูงซึ่งไม่มีการละเว้นประเภทของสัญลักษณ์และสัญลักษณ์ที่กำหนด สามารถวิเคราะห์รายละเอียดเพิ่มเติมเพื่อขอความช่วยเหลือ:

Readelf -s hello_world.o

อันไหนคือ:

ตารางสัญลักษณ์ ".symtab" มี 7 รายการ: NUM: ค่าขนาดประเภทประเภทการผูก vis ndx ชื่อ 0: 0000000000000000 0 Notype ท้องถิ่นเริ่มต้นและเริ่มต้น 1: 0000000000000000 0 ไฟล์ท้องถิ่นเริ่มต้น abs hello_world.asm 2: 00000000000000 0 ส่วน ค่าเริ่มต้นในท้องถิ่น 2 4: 0000000000000000 0 ค่าเริ่มต้นในท้องถิ่นที่ไม่ใช่ประเภท 1 hello_world 5: 000000000000000d 0 ค่าเริ่มต้นในท้องถิ่นที่ไม่ใช่ประเภท ABS hello_world_len 6: 00000000000

รูปแบบตารางไบนารีมีบันทึกไว้ที่ http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html

Readelf-x.symtab สวัสดี_world.o

คุณให้อะไร:

ดัมพ์เลขฐานสิบหกของส่วน ".symtab": 0x00000000 00000000 00000000 00000000 00000000 ................ 0x00000010 00000000 00000000 01000 .... . 0x00000020 00000000 000000 00000000 000000 000000 .......................... 0x00000050 00000000 00000000 00000000 00000000 ............ .... 0x00000060 11000000 00000100 00000000 000 ...... 0x00000070 00000000 0000000000 ................ 0x00000080 0D000000000000000000..... 0x000000a0 00000000 00000000 ....... .

ประเภทการบันทึก:

Typedef struct ( Elf64_Word st_name; unsigned char st_info; unsigned char st_other; Elf64_Half st_shndx; Elf64_Addr st_value; Elf64_Xword st_size; ) Elf64_Sym;

เช่นเดียวกับในตารางการแบ่ง รายการแรกเป็นการกุศลและกำหนดเป็นค่าว่างคงที่

บันทึก 1 พฤษภาคม ELF64_R_TYPE == STT_FILE ELF64_R_TYPE คือสามตัวที่อยู่ตรงกลางของ st_info

การวิเคราะห์ไบต์:

    10 8: st_name = 01000000 = ตัวละคร 1 st.strtab ซึ่งขึ้นอยู่กับฝ่ายรุก \0 เพื่อปล้น hello_world.asm

    ส่วนของไฟล์ข้อมูลนี้สามารถแบ่งออกเป็นตัวเชื่อมโยงซึ่งจะกำหนดว่าเซ็กเมนต์ควรไปอย่างไร

    10 12: st_info = 04

    บิต 0-3 = ELF64_R_TYPE = Type = 4 = STT_FILE: เมตาเรกคอร์ดหลัก - แท็ก st_name เพื่อให้ตรงกับชื่อไฟล์ที่สร้างโดยไฟล์วัตถุนี้

    บิต 4-7 = ELF64_ST_BIND = การผูก = 0 = STB_LOCAL ค่าที่จำเป็นสำหรับ STT_FILE

    10 13: st_shndx = ตารางสัญลักษณ์ ส่วนหัวของตาราง ดัชนี = f1ff = SHN_ABS จำเป็นสำหรับ STT_FILE

    20 0: st_value = 8x 00: จำเป็นสำหรับค่าสำหรับ STT_FILE

    20 8: st_size = 8x 00: ไม่เห็นขนาด

ทีนี้จาก readelf ผมจะรีบตีความ

STT_SECTION

มีสององค์ประกอบดังกล่าว หนึ่งชี้ไปที่ .data และอีกองค์ประกอบหนึ่งชี้ไปที่ .text (ดัชนีแบ่ง 1 และ 2)

จำนวน: ค่า ขนาด ประเภท เชื่อมโยง Vis Ndx ชื่อ 2: 0000000000000000 0 ส่วน ค่าเริ่มต้นในท้องถิ่น 1 3: 0000000000000000 0 ส่วน ค่าเริ่มต้นในท้องถิ่น 2

TODO เมตาคืออะไร?

STT_NOTYPE

จากนั้นป้อนอักขระที่สำคัญที่สุด:

Num: ค่า ขนาด ประเภท ผูก Vis Ndx ชื่อ 4: 0000000000000000 0 ค่าเริ่มต้นท้องถิ่น NOTYPE 1 hello_world 5: 000000000000000d 0 ค่าเริ่มต้นท้องถิ่น NOTYPE ABS hello_world_len 00 0

hello_world ตั้งอยู่ใน distribution.data (ดัชนี 1) ค่า ค่า 0: ตรวจสอบไบต์แรกของการกระจาย

เริ่มตั้งค่าการเปิดเผยของ GLOBAL ตามที่เราเขียน:

global_start

ที่ NASM ไม่จำเป็น เศษสามารถเห็นเป็นจุดเริ่มต้น ในมุมมอง C สำหรับป้ายส่งเสริมการขาย NASM є local

hello_world_len อ้างถึง st_shndx == SHN_ABS == 0xF1FF พิเศษ

0xF1FF ถูกเลือกในลักษณะที่จะไม่โกงสาขาอื่นๆ

st_value == 0xD == 13 แล้วแต่ว่าจะมีค่าใด ซึ่งเราได้บันทึกไว้ที่นั่นสำหรับการเลือก: ด้านหลังของแถว Hello World! .

Tse หมายความว่าการเคลื่อนไหวไม่สอดคล้องกับค่า: เป็นค่าคงที่

มันไม่ใช่การเพิ่มประสิทธิภาพขนาดใหญ่ วิธีการทำงานของแอสเซมเบลอร์สำหรับเราที่สามารถรองรับเอลฟ์ได้

Yakby mi vikoristovuvali ที่อยู่ hello_world_len ในสถานที่ใด ๆ แอสเซมเบลอร์จะไม่ zmіg bi pomiti yogo yak SHN_ABS และตัวเชื่อมโยงจะถูกย้ายเพิ่มเติม

SHT_SYMTAB สำหรับไฟล์ที่เป็นไอคอน

สำหรับการโปรโมต NASM ให้วาง .symtab ในไฟล์ที่เป็นไอคอน

Tse vikoristovuєtsya น้อยลงสำหรับ nagodzhennya หากไม่มีสัญลักษณ์ เราตาบอดสนิทและอาจออกแบบทุกอย่างใหม่

คุณสามารถดูได้เพื่อขอความช่วยเหลือ objcopy และดาวน์โหลดไฟล์ทั้งหมดจะใช้งานได้ ไฟล์ดังกล่าวที่เป็นไอคอนเรียกว่าไฟล์แยกไอคอน

.strtab

กำจัดแถวสำหรับสัญลักษณ์ตาราง

ซึ่งการแจกแจงมี sh_type == SHT_STRTAB

แสดงใน sh_link == 5 การกระจาย

Readelf-x.strtab สวัสดี_world.o

Hex dump of section ".strtab": 0x00000000 0068656c 6c6f5f77 6f726c64 2e61736d .hello_world.asm 0x00000010 0068656c 6c6f5f77 6f726c64 0068656c .hello_world.hel 0x00000020 6c6f5f77 6f726c64 5f6c656e 005f7374 lo_world_len._st 0x00000030 61727400 art.

ซึ่งหมายความว่ามีการแลกเปลี่ยน ELF ซึ่งมีการเปลี่ยนแปลงทั่วโลกซึ่งเป็นไปไม่ได้ที่จะลบอักขระ NUL

.rela.ข้อความ

ประเภทการกระจาย: sh_type == SHT_RELA

ชื่อหัวเรื่อง : แยกย้าย.

Rela.text ตอบกลับข้อมูลของการย้ายตำแหน่ง ซึ่งถูกกำหนดให้เป็นที่อยู่ที่จะเปลี่ยนแปลง หากพบไฟล์ที่เหลือของ Hit tse vkazuєบนไบต์ของพื้นที่ข้อความ, yakіmаyut buti zmіnіnі, ถ้า zv'yazuvannya vіdbuvaєєєє zaznachennymi їїїїїїїїїїїї

ในไวน์หลักฉันเขียนข้อความของวัตถุใหม่เพื่อล้างแค้นที่อยู่ของ 0x0 zapovnyuvacha:

A:48 รู 00 00 00 00 00 movabs $0x0,%rsi 11:00 00 00

ไปที่รหัสที่ถูกแฮ็กจริงเพื่อลบ 0x6000d8 ที่เหลือ:

4000ba: 48 เป็น d8 00 60 00 00 movabs $0x6000d8,%rsi 4000c1:00 00 00

ระบุ Sh_info = 6

readelf -r hello_world.o ใช่:

ส่วนการย้ายตำแหน่ง ".rela.text" ที่ offset 0x3b0 offset 1 point: Offset Info Type Sym. ค่าซิม ชื่อ + เพิ่ม 00000000000c 000200000001 R_X86_64_64 0000000000000000 .data + 0

การแจกจ่ายไม่ได้ขึ้นอยู่กับไฟล์ที่กำลังตรวจสอบ

ไบต์จริง:

00000370 0c 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 |................| 00000380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

ตัวแทนโครงสร้าง:

โครงสร้าง Typedef ( Elf64_Addr r_offset; Elf64_Xword r_info; Elf64_Sxword r_addend; ) Elf64_Rela;

    370 0: r_offset = 0xC: ที่อยู่ไปยัง address.text ที่อยู่ที่จะเปลี่ยนแปลง

    370 8: r_info = 0x200000001. หมอก 2 ช่อง:

    • ELF64_R_TYPE = 0x1: ค่าที่จะฝากเป็นสถาปัตยกรรมที่แน่นอน
    • ELF64_R_SYM = 0x2: ดัชนีแบ่งพาร์ติชัน, ที่อยู่, volume.data ซึ่งมีดัชนี 2

    AMD64 ABI กล่าวว่าประเภท 1 เรียกว่า R_X86_64_64 และ VIN นั้นแสดงถึงการดำเนินการ S+A de:

    • S: ค่าอักขระในอ็อบเจกต์ไฟล์คือ 0 ที่นี่ ดังนั้นเราสามารถตั้งค่าเป็น 00 00 00 00 00 00 00 00 s movabs $0x0,%rsi
    • a: เพิ่มลงในฟิลด์ r_added

    ที่อยู่ Tsya จะถูกเพิ่มในการแจกจ่ายโดยการย้ายถิ่นฐาน

    การดำเนินการย้ายนี้คือ 8 ไบต์

    380 0: r_addend = 0

ในอันดับนี้เราใส่ไว้ในก้นของเราว่าที่อยู่ใหม่จะเป็น: S + A \u003d .data + 0 i ในอันดับนี้ อันดับแรกในการกระจายข้อมูล

ตารางชื่อโปรแกรม

ปรากฏน้อยลงในไฟล์ที่ได้รับชัยชนะ

ขึ้นอยู่กับหน่วยความจำเสมือนของกระบวนการในการลบข้อมูลเกี่ยวกับสิ่งเหล่านั้น เช่น ไฟล์ที่กำลังดูอยู่

ไฟล์ที่เชื่อมโยงถูกสร้างขึ้นโดยไฟล์ตัวเชื่อมโยงวัตถุ งานหลักในฐานะตัวเชื่อมโยง viconous:

    กำหนดวิธีการแบ่งวัตถุเพื่อดูว่าส่วนใดของไฟล์ที่เลือก

    ด้วย Binutils จำเป็นต้องวิเคราะห์สคริปต์ตัวเชื่อมโยงและทำงานกับความหมายของค่าเริ่มต้น

    คุณสามารถเลือกสคริปต์ตัวเชื่อมโยงที่ผสานกับ ld --verbose และติดตั้งด้วย ld -T

    vikonuvat remіshchennyaข้อความrasdіla มันคุ้มค่าที่จะวางตามลำดับเช่นกิ่งก้านของrozdіlіvrozmіshchuyusyaในหน่วยความจำ

readelf -l hello_world.out ใช่:

Elf file type is EXEC (Executable file) Entry point 0x4000b0 There are 2 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x00000000000000d7 0x00000000000000d7 R E 200000 LOAD 0x00000000000000d8 0x00000000006000d8 0x00000000006000d8 0x000000000000000d 0x000000000000000d RW 200000 Section ไปยังการแมปเซกเมนต์: เซ็กเมนต์ ส่วน... 00 .text 01 .data

ส่วนหัวของ ELF e_phoff , e_phnum และ e_phentsize บอกเราว่ามี 2 ส่วนหัวของโปรแกรมที่เริ่มต้นที่ 0x40 และมากถึง 0x38 ไบต์ของสกิน ดังนั้นกลิ่นเหม็น:

00000040 01 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 |................| 00000050 00 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 |[ป้องกันอีเมล]@..... | 00000060 d7 00 00 00 00 00 00 00 d7 00 00 00 00 00 00 00 |................| 00000070 00 00 20 00 00 00 00 00 |.. ..... |

00000070 01 00 00 00 06 00 00 00 | ........| 00000080 d8 00 00 00 00 00 00 00 d8 00 60 00 00 00 00 00 |.............`.....| 00000090 d8 00 60 00 00 00 00 00 0d 00 00 00 00 00 00 00 |..`.............| 000000a0 0d 00 00 00 00 00 00 00 00 20 00 00 00 00 00 |............. | โครงสร้าง typedef ( Elf64_Word p_type; Elf64_Word p_flags; Elf64_Off p_offset; Elf64_Addr p_vaddr; Elf64_Addr p_paddr; Elf64_Xword p_filesz; Elf64_Xword p_memsz; Elf64_X

ลองครั้งแรก:

  • 40 0: p_type = 01 00 00 00 = PT_LOAD: สิ่งที่ต้องทำ ฉันคิดว่า tse หมายความว่าคุณจะสนใจปริศนา ประเภทอื่นสามารถเป็นได้ แต่ไม่ใช่ obov'yazkovo buti
  • 40 4: p_flags = 05 00 00 00 = อ่านและอ่านได้ ไม่ต้องเขียน TODO
  • 40 8: p_offset = 8x 00 สิ่งที่ต้องทำ: อะไร ดูเหมือนว่า usunennya บนซังของกลุ่ม ส่วนที่พันกันหมายความว่าอย่างไร คุณสามารถเล่นกับมันได้: gcc -Wl,-Ttext-segment=0x400030 hello_world.c
  • 50 0: p_vaddr = 00 00 40 00 00 00 00 00: ที่อยู่เมลหน่วยความจำเสมือนสำหรับเซ็กเมนต์ที่ถูกครอบครองใน
  • 50 8: p_paddr = 00 00 40 00 00 00 00 00: ที่อยู่ทางกายภาพเริ่มต้นที่จะบันทึกในหน่วยความจำ พลังงานสำหรับระบบเท่านั้น ซึ่งโปรแกรมสามารถตั้งค่าที่อยู่จริงได้ ในทางที่แตกต่างกัน เช่นในระบบ System V ก็อาจจะเป็นเช่นนั้น ดูเหมือนว่า NASM เพียงแค่คัดลอก p_vadrr
  • 60 0: p_filesz = d7 00 00 00 00 00 00 00: สิ่งที่ต้องทำ vs p_memsz
  • 60 8: p_memsz = d7 00 00 00 00 00 00 00: สิ่งที่ต้องทำ
  • 70 0: p_align = 00 00 20 00 00 00 00 00: 0 หรือ 1 หมายความว่าไม่จำเป็นต้องจัดตำแหน่ง TODO หมายความว่าอย่างไร ในแบบที่แตกต่างเหนือโลกกับสนามอื่นๆ

อีกอันก็คล้ายๆ

การแมปส่วนไปยังส่วน:

ให้ผู้อ่านบอกเราว่า:

  • 0-segment.ข้อความ Aha ที่ชนะและไม่สามารถเขียนได้
  • 1-segment.data.
เครื่องมือส่วนขยายมาตรฐานจะรวบรวมโปรแกรมของคุณเป็นไฟล์ ELF (Executable and Linkable Format) ซึ่งอาจรวมถึงข้อมูลภาษีด้วย คุณสามารถอ่านข้อกำหนดรูปแบบ ในอีกด้านหนึ่ง สถาปัตยกรรมสกินมีลักษณะเฉพาะของตัวเอง ตัวอย่างเช่น ลักษณะเฉพาะของ ARM มาดูรูปแบบคร่าวๆ กัน
ไฟล์การแปลงเป็นรูปแบบ ELF ประกอบด้วยส่วนต่อไปนี้:
1. ส่วนหัว (ส่วนหัวของเอลฟ์)
ดึงข้อมูลทั่วไปเกี่ยวกับไฟล์และลักษณะสำคัญ
2. ตารางส่วนหัวของโปรแกรม
ตาราง Tse ของส่วนที่เกี่ยวข้องกับส่วนไฟล์ของหน่วยความจำแสดงการจับภาพเป็นพื้นที่ของหน่วยความจำในการเขียนส่วนสกิน
3. ส่วน
ส่วนสำหรับลบข้อมูลทั้งหมดออกจากไฟล์ (โปรแกรม ข้อมูล ข้อมูลภาษี ฯลฯ)
ส่วนสกินอาจพิมพ์ ชื่อ และพารามิเตอร์อื่นๆ ในส่วน ".text" เลือกรหัส ใน ".symtab" - ตารางสัญลักษณ์ของโปรแกรม (ชื่อไฟล์ ขั้นตอน และการเปลี่ยนแปลง) ใน ".strtab" - ตารางแถว ในส่วนที่มี คำนำหน้า ".debug_" - ข้อมูลการปรับแต่ง ฯลฯ .d. .d. นอกจากนี้ ไฟล์ยังมีส่วนว่างที่มีดัชนี 0
4. ตารางส่วนหัวของส่วน
นี่คือตารางสำหรับแทนที่อาร์เรย์ของส่วนหัวของส่วน
รูปแบบรายงานได้รับการตรวจสอบโดย ELF Creation

จุดชมวิว DWARF

DWARF เป็นรูปแบบมาตรฐานสำหรับข้อมูลที่ปรับแต่งได้ สามารถดาวน์โหลดมาตรฐานได้จากเว็บไซต์อย่างเป็นทางการ มีการดูรูปแบบสั้น ๆ ที่ยอดเยี่ยม: บทนำสู่รูปแบบการดีบัก DWARF (Michael J. Eager)
ต้องการข้อมูลภาษีเพิ่มเติม? วอห์นอนุญาต:
  • ติดตั้งเบรกพอยต์ไม่ได้อยู่ในที่อยู่จริง แต่ในหมายเลขแถวของรหัสเอาต์พุตไฟล์ของชื่อฟังก์ชัน
  • แสดงและเปลี่ยนค่าของการเปลี่ยนแปลงส่วนกลางและท้องถิ่นตลอดจนพารามิเตอร์ของฟังก์ชัน
  • แสดงสแต็กของ Wiki (ย้อนรอย)
  • เพื่อแปลงโปรแกรม pokrokovo ไม่ใช่สำหรับคำสั่งแอสเซมเบลอร์เดียว แต่สำหรับแถวของรหัสเอาต์พุต
ข้อมูลนี้รวบรวมจากโครงสร้างแบบต้นไม้ สกินวูซอลของต้นไม้สามารถเป็นพ่อได้ เป็นแม่ของแม่ได้ และเรียกว่า DIE (Debugging Information Entry) สกิน vuzol มีแท็ก (ประเภท) ของตัวเองและรายการคุณลักษณะ (พลัง) ที่อธิบาย vuzol แอตทริบิวต์สามารถล้างแค้นทุกสิ่งที่คุ้มค่า เช่น ให้หรือส่งไปมหาวิทยาลัยอื่น นอกจากนี้ยังมีข้อมูลว่าท่าของต้นไม้ถูกถ่าย
โหนดแบ่งออกเป็นสองประเภทหลัก: โหนดที่อธิบายข้อมูลและโหนดที่อธิบายรหัส
Woozley เพื่ออธิบายข้อมูล:
  1. ข้อมูล Tipi:
    • ประเภทฐานของข้อมูล (wuzole ที่มีประเภท DW_TAG_base_type) เช่น ประเภท int C
    • ประเภทของข้อมูลคลังสินค้า (ฝักบัว)
    • มาซิวิ
    • โครงสร้าง คลาส การเชื่อมโยง อินเทอร์เฟซ
  2. วัตถุข้อมูล:
    • ค่าคงที่
    • พารามิเตอร์ของฟังก์ชัน
    • เปลี่ยน
    • และอื่น ๆ.
ผิวของวัตถุข้อมูลอาจมีแอตทริบิวต์ DW_AT_location ซึ่งระบุวิธีการคำนวณที่อยู่ซึ่งทราบข้อมูล ตัวอย่างเช่น คุณสามารถเปลี่ยนแม่ของคุณเป็นที่อยู่คงที่ เปลี่ยนเป็นการลงทะเบียนหรือบนสแต็ก เป็นสมาชิกของคลาสหรือวัตถุ สามารถนับที่อยู่ Tsya ได้อย่างราบรื่น ดังนั้นมาตรฐานจึงถ่ายโอนสิ่งที่เรียกว่า Location Expressions เพื่อให้สามารถล้างแค้นลำดับของผู้ปฏิบัติงานในเครื่องติดภายในแบบพิเศษได้
Woozley เพื่ออธิบายรหัส:
  1. ขั้นตอน (ฟังก์ชัน) – โหนดที่มีแท็ก DW_TAG_subprogram โหนดบนกระดานสามารถแทนที่คำอธิบายของการเปลี่ยนแปลง - พารามิเตอร์ในฟังก์ชันและการเปลี่ยนแปลงในฟังก์ชันในเครื่อง
  2. หน่วยรวบรวม. ดึงข้อมูลของโปรแกรมและแก้ไขปัญหากับพ่อ
ข้อมูลที่อธิบายข้างต้นสามารถพบได้ในส่วน ".debug_info" และ ".debug_abbrev"
ข้อมูลมากกว่านี้:
  • ข้อมูลเกี่ยวกับหมายเลขบรรทัด (ส่วน ".debug_line")
  • ข้อมูลเกี่ยวกับมาโคร (ส่วน ".debug_macinfo")
  • ข้อมูลเฟรมการโทร (ส่วน ".debug_frame")

การสร้างเอลฟ์

เราจะใช้ความช่วยเหลือของไลบรารี libelf จากแพ็คเกจ elfutils เพื่อสร้างไฟล์ในรูปแบบ EFL Merezha มีบทความดีๆ เกี่ยวกับ libelf - LibELF by Example (น่าเสียดายที่คำอธิบายเกี่ยวกับการสร้างไฟล์ในนั้นสั้น ๆ เท่านั้น) รวมถึงเอกสารประกอบ
การสร้างไฟล์ประกอบด้วยหลายขั้นตอน:
  1. การเริ่มต้นการหมิ่นประมาท
  2. การสร้างส่วนหัวของไฟล์ (ส่วนหัวของ ELF)
  3. การสร้างตารางส่วนหัวของโปรแกรม
  4. การสร้างส่วน
  5. เขียนลงไฟล์
มาดูขั้นตอนของรายงานกัน
การเริ่มต้นการหมิ่นประมาท
คุณจะต้องเรียกใช้ฟังก์ชัน elf_version (EV_CURRENT) เป็นครั้งคราวและสลับผลลัพธ์ Yakshto vіndіvnyuє EV_NONE - vinikla ให้อภัยที่ไม่สามารถทำงานdiїต่อไปได้ จากนั้นเราต้องสร้างไฟล์ที่ต้องการบนดิสก์ ใช้ที่จับแล้วส่งต่อไปยังฟังก์ชัน elf_begin:
เอลฟ์*elf_begin(int fd, Elf_Cmd cmd, Elf*elf)
  • fd - ตัวอธิบายไฟล์
  • cmd - mode (ELF_C_READ สำหรับการอ่านข้อมูล, ELF_C_WRITE สำหรับการเขียน หรือ ELF_C_RDWR สำหรับการอ่าน/เขียน), vin เกิดจากโหมดของไฟล์ที่กำลังเปิด (ELF_C_WRITE ในโหมดของเรา)
  • เอลฟ์ - จำเป็นสำหรับโรบ็อตที่มีไฟล์เก็บถาวร (.a) เท่านั้น เครื่องมือเลือกของเราต้องผ่าน 0
ฟังก์ชันจะหมุนตัวอธิบายเกี่ยวกับการสร้างสรรค์ซึ่งใช้โดยฟังก์ชันหมิ่นประมาททั้งหมด 0 จะหมุนตามเวลาของการให้อภัย
การสร้างส่วนหัว
ส่วนหัวของไฟล์ใหม่ถูกสร้างขึ้นโดยฟังก์ชัน elf32_newehdr:
Elf32_Ehdr*elf32_newehdr(เอลฟ์*เอลฟ์);
  • elf - ที่จับหมุนโดยฟังก์ชัน elf_begin
เปิด 0 เมื่อล้าง หรือตัวบ่งชี้สำหรับโครงสร้างคือส่วนหัวของไฟล์ ELF:
#define EI_NIDENT 16 typedef struct ( unsigned char e_ident; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; ) Elf32_Ehdr;

ฟิลด์Deyakіїїzapovnenіอันดับมาตรฐาน deyakіจำเป็นต้องกรอกเรา:

  • e_ident - อาร์เรย์ของการระบุตัวตนซึ่งอาจมีดัชนีดังกล่าว:
    • EI_MAG0, EI_MAG1, EI_MAG2, EI_MAG3 - สัญลักษณ์ผิดพลาด 4 ไบต์ 0x7f, "ELF" ซึ่งฟังก์ชัน elf32_newehdr ทำเพื่อเราแล้ว
    • EI_DATA - ระบุประเภทของการเข้ารหัสข้อมูลสำหรับไฟล์: ELFDATA2LSB หรือ ELFDATA2MSB คุณต้องตั้งค่า ELFDATA2LSB ดังนี้: e_ident = ELFDATA2LSB
    • EI_VERSION - เวอร์ชันส่วนหัวของไฟล์ที่ติดตั้งให้เราแล้ว
    • EI_PAD - ไม่ชิป
  • e_type - ประเภทไฟล์สามารถเป็นได้ ET_NONE - ไม่มีประเภท ET_REL - ไฟล์ที่จะย้าย ET_EXEC - การรวมไฟล์ ET_DYN - การแยกไฟล์วัตถุ เป็นต้น เราต้องตั้งค่าประเภทไฟล์เป็น ET_EXEC
  • e_machine - สถาปัตยกรรมที่จำเป็นสำหรับไฟล์นี้ เช่น EM_386 - สำหรับสถาปัตยกรรม Intel สำหรับ ARM เราต้องเขียนที่นี่ EM_ARM (40) - div ELF สำหรับสถาปัตยกรรม ARM
  • e_version - เวอร์ชันของไฟล์ จำเป็นต้องติดตั้งภาษาใหม่ใน EV_CURRENT
  • e_entry - ที่อยู่จุดเริ่มต้นไม่ผูกมัดกับเรา
  • e_phoff - การใช้ส่วนหัวของโปรแกรมในไฟล์ e_shoff - การใช้ส่วนหัวของส่วน ไม่สามารถกู้คืนได้
  • e_flags - เฉพาะสำหรับโปรเซสเซอร์ prapori สำหรับสถาปัตยกรรมของเรา (Cortex-M3) จำเป็นต้องตั้งค่าเท่ากับ 0x05000000 (ABI เวอร์ชัน 5)
  • e_ehsize, e_phentsize, e_phnum, e_sentsize, e_shnum - ไม่ฉลาด
  • e_shstrndx - ซ่อนหมายเลขส่วนที่แถวตารางของส่วนหัวของส่วนตั้งอยู่ เรายังไม่มีส่วนที่เหมือนกันเหลือ เราจะใส่จำนวนทั้งหมดในภายหลัง
การสร้างส่วนหัวของโปรแกรม
อย่างที่เคยเกิดขึ้นก่อนหน้านี้ ตารางส่วนหัวของโปรแกรมคือตารางความถูกต้องของส่วนไปยังส่วนไฟล์ของหน่วยความจำ ดังนั้นฉันจึงอยากทราบว่าควรเขียนส่วนสกินไว้ที่ใด ส่วนหัวถูกสร้างขึ้นหลังฟังก์ชันวิธีใช้ elf32_newphdr:
Elf32_Phdr * elf32_newphdr(เอลฟ์ * เอลฟ์ นับ size_t);
  • เอลฟ์คือมือของเรา
  • นับ - จำนวนองค์ประกอบที่สร้างขึ้นในตาราง เนื่องจากเราจะมีเพียงหนึ่งส่วน (พร้อมรหัสโปรแกรม) ดังนั้นการนับจะเท่ากับ 1
เปิด 0 เมื่อ miltsi หรือkazіvnikในชื่อโปรแกรม
องค์ประกอบสกินของตารางส่วนหัวอธิบายโดยโครงสร้างต่อไปนี้:
โครงสร้าง typedef ( Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_W;
  • p_type - ประเภทของกลุ่ม (ส่วน) ที่นี่เรามีหน้าที่รับผิดชอบในการระบุ PT_LOAD - ส่วนที่จะได้รับ
  • p_offset - การชดเชยไฟล์, zvіdki pochinaєtsya, จามรี zavantazhuvatemeetsya ในปริศนา เรามี section.text เพื่อให้คุณทราบจำนวนส่วนหัวของไฟล์และส่วนหัวของโปรแกรม เราสามารถคำนวณผลรวมของส่วนหัวทั้งหมดเหล่านี้ได้ นานๆทีจะเอาแบบไหนก็ได้สำหรับฟังก์ชั่นช่วยเหลือ elf32_fsize:
    size_t elf32_fsize (ประเภท Elf_Type, จำนวน size_t, รุ่น int ที่ไม่ได้ลงนาม); พิมพ์ - ค่าคงที่ ELF_T_ххх ที่นี่เราจะต้องขยาย ELF_T_EHDR และ ELF_T_PHDR นับ - จำนวนองค์ประกอบของประเภทที่ต้องการ เวอร์ชัน - เลือกตั้งค่าเป็น EV_CURRENT
  • p_vaddr, p_paddr - ที่อยู่จริงเสมือนซึ่งจะถูกครอบครองในส่วนเดียวกัน เนื่องจากเราไม่มีที่อยู่เสมือน เราจะติดตั้งให้เท่ากับที่อยู่จริงด้วยวิธีที่ง่ายที่สุด - 0 เพื่อให้โปรแกรมของเราสามารถใช้ประโยชน์จากที่อยู่นั้นได้
  • p_filesz, p_memsz - การขยายส่วนสำหรับไฟล์และหน่วยความจำ เรามีกลิ่นเหม็นเหมือนกัน แต่ยังไม่มีส่วนของรหัสโปรแกรมเราจะติดตั้งในภายหลัง
  • p_flags - เปิดใช้งานสำหรับส่วนหน่วยความจำส่วนตัว สามารถเป็น PF_R - อ่าน, PF_W - เขียน, PF_X - ดูชุดค่าผสมใดก็ได้ ตั้งค่า p_flags เท่ากับ PF_R + PF_X
  • p_align - การจัดตำแหน่งกลุ่ม เรามี 4
การสร้างส่วน
หลังจากสร้างหัวเรื่องแล้ว สามารถเปิดส่วนต่างๆ ได้ ส่วนว่างถูกสร้างขึ้นสำหรับฟังก์ชันเพิ่มเติม elf_newscn:
Elf_Scn*elf_newscn(เอลฟ์*เอลฟ์);
  • elf – แฮนเดิล หมุนก่อนหน้านี้โดยฟังก์ชัน elf_begin
ฟังก์ชั่นหมุนผู้โทรไปยังส่วนหรือ 0 สำหรับการให้อภัย
หลังจากสร้างส่วนแล้ว จำเป็นต้องจำชื่อเรื่องของส่วนและสร้างคำอธิบายของส่วนเหล่านี้
เราสามารถดูที่ส่วนหัวของส่วนสำหรับฟังก์ชันเพิ่มเติม elf32_getshdr:
Elf32_Shdr * elf32_getshdr (เอลฟ์_Scn * scn);
  • scn - ตัวบ่งชี้ส่วนที่เรานำมาจากฟังก์ชัน elf_newscn
ส่วนหัวของส่วนมีลักษณะดังนี้:
โครงสร้าง typedef ( Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf3__d_sh;
  • sh_name - ชื่อส่วน - ใช้สำหรับส่วนหัวของตารางแถว (section.shstrtab) - div "ตารางแถว"
  • sh_type - พิมพ์แทนที่ส่วนสำหรับส่วนที่มีรหัสโปรแกรมจำเป็นต้องตั้งค่า SHT_PROGBITS สำหรับส่วนที่มีตารางแถว - SHT_STRTAB สำหรับตารางสัญลักษณ์ - SHT_SYMTAB
  • sh_flags - ธงของส่วนที่สามารถรวมกันได้และเราต้องการเพียงสามอย่าง:
    • SHF_ALLOC - หมายความว่าส่วนนี้สนใจปริศนา
    • SHF_EXECINSTR - ส่วนที่จะตอบโต้รหัสที่ชนะ
    • SHF_STRINGS - ส่วนที่จะกวาดแถวตาราง
    เห็นได้ชัดว่าสำหรับ section.text จากโปรแกรมจำเป็นต้องตั้งค่าธง SHF_ALLOC + SHF_EXECINSTR
  • sh_addr - ที่อยู่สำหรับส่วนที่จะหลงเสน่ห์ปริศนา
  • sh_offset - ใช้ไฟล์ส่วน - อย่าโกง ติดตั้งห้องสมุดให้เรา
  • sh_size - ขนาดส่วน - ไม่ใช่chіpaєmo
  • sh_link - รับจำนวนของส่วนที่เชื่อมโยงซึ่งจำเป็นสำหรับการเชื่อมโยงส่วนกับตารางแถวที่คล้ายกัน (ระยะทาง div.)
  • sh_info - ข้อมูลเพิ่มเติม วิธีฝากตามประเภทส่วน ตั้งค่าเป็น 0
  • sh_addralign - การจัดตำแหน่งที่อยู่ ไม่สามารถอ่านได้
  • sh_entsize - วิธีการซ้อนส่วนจากองค์ประกอบจำนวนหนึ่งที่มีค่าเท่ากัน โดยระบุค่าขององค์ประกอบดังกล่าว ไม่ใช่chіpaєmo
หลังจากกรอกส่วนหัวแล้ว จำเป็นต้องสร้างคำอธิบายของข้อมูลส่วนโดยใช้ฟังก์ชัน elf_newdata:
Elf_Data * elf_newdata (เอลฟ์_Scn * scn);
  • scn - เลือกลบตัวบ่งชี้สำหรับส่วนใหม่
ฟังก์ชันจะเปลี่ยนเป็น 0 เพื่อให้อภัย หรือตัวบ่งชี้สำหรับโครงสร้าง Elf_Data ดังนั้นคุณจะต้องจำไว้ว่า:
โครงสร้าง typedef ( void * d_buf; Elf_Type d_type; size_t d_size; off_t d_off; size_t d_align; d_version ที่ไม่ได้ลงชื่อ; ) Elf_Data;
  • d_buf - ตัวบ่งชี้ข้อมูลดังนั้นจึงจำเป็นต้องเขียนลงในส่วนนี้
  • d_type - ประเภทของข้อมูล เราจำเป็นต้องรู้ ELF_T_BYTE
  • d_size - ขนาดข้อมูล
  • d_off - ใช้ในส่วน ตั้งค่าเป็น 0
  • d_align - การจัดตำแหน่ง สามารถตั้งค่าเป็น 1 - ไม่มีการจัดตำแหน่ง
  • d_version - เวอร์ชัน ภาษาที่ตั้งค่าสำหรับ EV_CURRENT
ส่วนพิเศษ
เพื่อจุดประสงค์ของเรา เราจะต้องสร้างชุดของส่วนที่จำเป็นขั้นต่ำ:
  • .text - ส่วนที่มีรหัสโปรแกรม
  • .symtab - ตารางสัญลักษณ์ในไฟล์
  • .strtab - ตารางของแถวสำหรับลบชื่อสัญลักษณ์ออกจากส่วน .symtab ส่วนย่อยในส่วนที่เหลือไม่ใช่ชื่อตัวเอง แต่เป็นดัชนี
  • .shstrtab - ตารางของแถวเพื่อลบชื่อส่วน
ทุกส่วนถูกสร้างขึ้นตามที่อธิบายไว้ในส่วนหน้า แต่ส่วนพิเศษของผิวหนังอาจมีลักษณะเฉพาะของมันเอง
ส่วน.
ส่วนนี้เป็นการลบโค้ดที่กำลังเช็คเอาท์ ดังนั้นคุณต้องตั้งค่า sh_type เป็น SHT_PROGBITS, sh_flags - เป็น SHF_EXECINSTR + SHF_ALLOC, sh_addr - ตั้งค่าเป็นที่อยู่เดียวกัน ซึ่งโค้ดทั้งหมดจะถูกดักจับ
ส่วน.
ส่วนค้นหาคำอธิบายสัญลักษณ์ (ฟังก์ชัน) ของโปรแกรมและไฟล์ซึ่งได้อธิบายถึงกลิ่นเหม็น ประกอบด้วยองค์ประกอบต่อไปนี้ของส่วนหัว แต่ละรายการมี 16 ไบต์:
โครงสร้าง typedef ( Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Half st_shndx; ) Elf32_Sym;
  • st_name - ชื่ออักขระ (ดัชนีตารางแถว strtab)
  • st_value - ค่า (ที่อยู่อินพุตสำหรับฟังก์ชันหรือ 0 สำหรับไฟล์) เศษ Cortex-M3 สามารถใช้ระบบคำสั่ง Thumb-2 ในขณะที่ที่อยู่ของภาษาสามารถยกเลิกการจับคู่ได้ (ที่อยู่จริง + 1)
  • st_size - ความยาวของโค้ดฟังก์ชัน (0 สำหรับไฟล์)
  • st_info - ประเภทสัญลักษณ์และขอบเขต หากต้องการกำหนดค่าของฟิลด์ ให้ใช้แมโคร
    #กำหนด ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
    โดยที่ b คือขอบเขต และ t คือประเภทอักขระ
    ขอบเขตสามารถเป็น STB_LOCAL (สัญลักษณ์ไม่ปรากฏในไฟล์วัตถุอื่น) หรือ STB_GLOBAL (มองเห็นได้) เพื่อความง่าย เราใช้ STB_GLOBAL
    ประเภทสัญลักษณ์ - STT_FUNC สำหรับฟังก์ชัน STT_FILE สำหรับไฟล์
  • st_other - ตั้งค่าเป็น 0
  • st_shndx – ดัชนีส่วน ซึ่งกำหนดสัญลักษณ์ (ส่วน index.text) หรือ SHN_ABS สำหรับไฟล์
    ดัชนีส่วนที่อยู่เบื้องหลังคำอธิบาย її scn สามารถกำหนดให้กับตัวช่วย elf_ndxscn:
    size_t elf_ndxscn(เอลฟ์_Scn *scn);

ส่วนนี้สร้างด้วยอันดับ เฉพาะ sh_type เท่านั้นที่ควรตั้งค่าเป็น SHT_SYMTAB และส่วน index.strtab ควรเขียนในฟิลด์ sh_link ด้วยอันดับดังกล่าว ts_sections จะเกี่ยวข้องกัน
ส่วน.
ส่วนนี้จะลบชื่อของสัญลักษณ์ทั้งหมดออกจาก section.symtab สร้างเป็นส่วนปกติ แต่จำเป็นต้องตั้งค่า sh_type เป็น SHT_STRTAB, sh_flags เป็น SHF_STRINGS ดังนั้นส่วนนี้จึงกลายเป็นตารางแถว
สามารถเลือกข้อมูลสำหรับส่วนได้เมื่อผ่านอาร์เรย์ข้อความเอาต์พุต ซึ่งเป็นตัวบ่งชี้ที่เราสามารถเขียนในคำอธิบายของส่วนข้อมูล (d_buf)
ส่วน.
ส่วน - ตารางของแถวเพื่อแทนที่ส่วนหัวของทุกส่วนของไฟล์รวมถึงส่วนหัวของตัวเอง สร้างเช่นนี้ section.strtab หลังจากสร้างดัชนีแล้วจำเป็นต้องเขียนในฟิลด์ e_shstrndx ของส่วนหัวของไฟล์
ตารางแถว
แถวของตารางที่จะแทนที่แถวที่อยู่ในแถวจะลงท้ายด้วยศูนย์ไบต์ ไบต์แรกในตารางนี้คือ 0 เช่นกัน ดัชนีแถวในตารางเป็นเพียงการเลื่อนเป็นไบต์บน cob ของตารางตามลำดับนี้ แถวแรก "ชื่อ" อาจเป็นดัชนี 1 แถวรุก "var" อาจเป็นดัชนี 6
ดัชนี 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \0 n am e \0 v a r \0
เขียนลงไฟล์
นอกจากนี้ส่วนหัวของส่วนนั้นได้ถูกสร้างขึ้นแล้วตอนนี้คุณต้องเขียนลงในไฟล์และทำงานให้เสร็จด้วยการหมิ่นประมาท การบันทึกฟังก์ชัน elf_update:
off_t elf_update (เอลฟ์ * เอลฟ์, Elf_Cmd cmd);
  • เอลฟ์ - จัดการ
  • cmd - คำสั่งที่ดีสำหรับการเขียน ELF_C_WRITE
ฟังก์ชันจะหมุน -1 เพื่อขอโทษ ข้อความของการให้อภัยสามารถลบออกได้โดยการเรียกใช้ฟังก์ชัน elf_errmsg(-1) เพื่อให้คุณสามารถหมุนตัวบ่งชี้ไปยังแถวที่มีการให้อภัย
เราทำงานให้เสร็จด้วยไลบรารีฟังก์ชัน elf_end ซึ่งผ่านตัวอธิบายของเรา มากเกินไปที่จะปิดไฟล์ก่อนหน้านี้
อย่างไรก็ตาม การสร้างไฟล์ไม่ได้เป็นการตอบโต้ข้อมูลส่วนรวม เนื่องจากเราเพิ่มข้อมูลนั้นลงในการแจกจ่ายที่ไม่เหมาะสม

การสร้าง DWARF

การรวบรวมข้อมูลที่คล้ายกันสำหรับไลบรารีเพิ่มเติม ซึ่งรวมอยู่ในไฟล์ pdf พร้อมเอกสาร (libdwarf2p.1.pdf - อินเทอร์เฟซไลบรารีของผู้ผลิตไปยัง DWARF)
การสร้างข้อมูลภาษีประกอบด้วยขั้นตอนต่อไปนี้:
  1. การสร้างVuzlіv (DIE - การดีบักรายการข้อมูล)
  2. การสร้างคุณลักษณะของมหาวิทยาลัย
  3. การสร้างประเภทข้อมูล
  4. การสร้างขั้นตอน (ฟังก์ชัน)
มาดูขั้นตอนของรายงานกัน
การเริ่มต้นผู้ผลิต libdwarf
เราจะสร้างข้อมูลภาษีในเวลาที่รวบรวมพร้อมกับการสร้างสัญลักษณ์ในส่วน
สำหรับการเริ่มต้น เราจะชนะฟังก์ชัน dwarf_producer_init_c ไลบรารีมีฟังก์ชันการเริ่มต้นเพิ่มเติมอีกเล็กน้อย (dwarf_producer_init, dwarf_producer_init_b) ซึ่งขึ้นอยู่กับลักษณะบางอย่างที่อธิบายไว้ในเอกสารประกอบ ตามหลักการแล้ว คุณสามารถเอาชนะพวกมันได้

Dwarf_P_Debug dwarf_producer_init_c (Dwarf_Unsigned flag, Dwarf_Callback_Func_c func, Dwarf_Handler errhand, Dwarf_Ptr errarg, void *user_data, Dwarf_Error *ข้อผิดพลาด)

  • แฟล็ก - การรวมกันของ "หรือ" ของค่าคงที่จำนวนหนึ่งเพื่อกำหนดพารามิเตอร์ต่างๆ ตัวอย่างเช่น ขนาดของข้อมูล ลำดับของไบต์ (little-endian, big-endian) รูปแบบการย้ายตำแหน่ง ภาษาที่เราต้องการ DW_DLC_WRITE และ DW_DLC_SYMBOLIC_RELOCATIONS
  • func - ฟังก์ชันการโทรกลับ ซึ่งจะถูกเรียกใช้เมื่อยุบส่วน ELF ด้วยข้อมูลที่กำหนดเอง ส่วนรายงาน ที่สาขา "การสร้างส่วนที่มีข้อมูลภาษี"
  • errhand - ตัวบ่งชี้สำหรับฟังก์ชั่นราวกับว่าคุณจะโทรออกเมื่อคุณได้รับอภัยโทษ ผ่านได้ 0
  • errarg - ข้อมูลที่จะส่งผ่านไปยังฟังก์ชัน errhand สามารถตั้งค่าเป็น 0
  • user_data - ข้อมูลที่จะส่งผ่านไปยังฟังก์ชัน func สามารถตั้งค่าเป็น 0
  • ข้อผิดพลาด - รหัสอภัยโทษสิ่งที่ต้องเปลี่ยน
ฟังก์ชันการเปลี่ยน Dwarf_P_Debug - คำอธิบายที่ใช้สำหรับฟังก์ชันที่กำลังจะมาถึงทั้งหมด หรือ -1 สำหรับเวลาของการให้อภัย ซึ่งในกรณีนี้จะมีรหัสอภัยโทษในข้อผิดพลาด
การสร้าง Woozliv (DIE - การดีบักรายการข้อมูล)
ตามที่ได้อธิบายเพิ่มเติม ข้อมูล nalagodzhuvalnaya สร้างโครงสร้างคล้ายต้นไม้ ในการสร้าง vuzol ของต้นไม้นั้น คุณต้อง:
  • สร้างฟังก์ชัน yogo dwarf_new_die
  • เพิ่มแอตทริบิวต์ใหม่
wuzol ถูกสร้างขึ้นสำหรับฟังก์ชันเพิ่มเติม dwarf_new_die:
Dwarf_P_Die dwarf_new_die(Dwarf_P_Debug dbg, Dwarf_Tag new_tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, คนแคระ
  • new_tag – node tag (type) – ค่าคงที่ DW_TAG_xxxx ซึ่งสามารถพบได้ในไฟล์ libdwarf.h
  • ผู้ปกครอง, ลูก, พี่น้องซ้าย, พี่น้องขวา - พ่อที่ดี, เหยื่อ, สิงโตและขวา sus_di vuzla ไม่จำเป็นต้องระบุพารามิเตอร์ทั้งหมดก็เพียงพอแล้วที่จะระบุพารามิเตอร์ให้ตั้งค่า 0 แทนพารามิเตอร์อื่น
  • ข้อผิดพลาด - แก้ไขรหัสของการให้อภัยเมื่อїїviniknіnі
ฟังก์ชันเปลี่ยน DW_DLV_BAADADDR สำหรับการให้อภัยหรือตัวอธิบายโหนด Dwarf_P_Die ในเวลาที่สำเร็จ
การสร้างคุณลักษณะของมหาวิทยาลัย
สำหรับการสร้างแอตทริบิวต์ของโหนด ค่านี้เป็นโฮมของฟังก์ชัน บางครั้งการระบุว่าฟังก์ชันใดจำเป็นในการสร้างแอตทริบิวต์ที่จำเป็นนั้นเป็นปัญหา ดังนั้นฉันจึงพบว่ามีการขุดคุ้ยที่เอาต์พุตโค้ดของไลบรารีอยู่สองสามครั้ง การกระทำที่มีหน้าที่จะอธิบายไว้ที่นี่ การกระทำด้านล่าง - ในหน่วยงานที่เกี่ยวข้อง กลิ่นเหม็นทั้งหมดยอมรับพารามิเตอร์ Ownerdie - คำอธิบายของโหนดที่จะเพิ่มแอตทริบิวต์ และเปลี่ยนรหัสให้อภัยในพารามิเตอร์ข้อผิดพลาด
ฟังก์ชัน dwarf_add_AT_name เพิ่มแอตทริบิวต์ "im'ya" (DW_AT_name) ไปยังไซต์ โหนดส่วนใหญ่อาจมีชื่อ (เช่น โพรซีเดอร์ การเปลี่ยนแปลง ค่าคงที่) บางชื่ออาจมีหรือไม่มีชื่อก็ได้ (เช่น Compilation Unit)
Dwarf_P_Attribute dwarf_add_AT_name (เจ้าของ Dwarf_P_Die, ถ่าน * ชื่อ, Dwarf_Error * ข้อผิดพลาด)
  • ชื่อ - ค่าของแอตทริบิวต์ (ชื่อของโหนด)

ฟังก์ชัน dwarf_add_AT_signed_const, dwarf_add_AT_unsigned_const เพิ่มแอตทริบิวต์ของค่าที่ลงนาม (ไม่ได้ลงนาม) ไปยังโหนดคำสั่ง แอตทริบิวต์ที่ลงนามและไม่ได้ลงนามถูกเลือกสำหรับการตั้งค่าของค่าคงที่, rozmіrіv, ตัวเลขในแถว, จากนั้น รูปแบบฟังก์ชัน:
Dwarf_P_Attribute dwarf_add_AT_(un)signed_const(Dwarf_P_Debug dbg, เจ้าของ Dwarf_P_Die, Dwarf_Half attr, ค่า Dwarf_Signed, Dwarf_Error *ข้อผิดพลาด)
  • dbg – Dwarf_P_Debug descriptor ซึ่งถูกลบออกในระหว่างการเริ่มต้นไลบรารี
  • attr - แอตทริบิวต์ค่าที่ตั้งไว้ - ค่าคงที่ DW_AT_xxxx ซึ่งสามารถพบได้ในไฟล์ libdwarf.h
  • ค่า - ค่าแอตทริบิวต์
เปิด DW_DLV_BADADDR ในเวลาของการให้อภัยหรือคำอธิบายแอตทริบิวต์เมื่อดำเนินการสำเร็จ
หน่วยรวบรวม
ต้นไม้สามารถมีรากได้หรือไม่ - เรามีการรวบรวมเพียงรายการเดียว เพื่อให้เราสามารถค้นหาข้อมูลเกี่ยวกับโปรแกรม (ตัวอย่างเช่น ชื่อของไฟล์ส่วนหัว การเขียนโปรแกรม mov สิ่งที่เขียน ชื่อของคอมไพเลอร์ ความไวของสัญลักษณ์ (การเปลี่ยนแปลง, ฟังก์ชัน) ของฟังก์ชัน, โปรแกรมการลงทะเบียนส่วนหัว, ที่อยู่อีเมล ฯลฯ) โดยหลักการแล้ว คุณลักษณะประจำวันคือ obov'yazkovimi ตัวอย่างเช่น ลองสร้างข้อมูลเกี่ยวกับไฟล์หลักและคอมไพเลอร์
ข้อมูลเกี่ยวกับไฟล์ส่วนหัว
เพื่อบันทึกข้อมูลเกี่ยวกับไฟล์ส่วนหัว เลือกแอตทริบิวต์ "ชื่อ" (DW_AT_name) ปิดใช้งานฟังก์ชัน dwarf_add_AT_name ดังแสดงในส่วน "การสร้างแอตทริบิวต์โหนด"
ข้อมูลเกี่ยวกับคอมไพเลอร์
ฟังก์ชันชัยชนะ dwarf_add_AT_producer:
Dwarf_P_Attribute dwarf_add_AT_name (เจ้าของ Dwarf_P_Die, ถ่าน *producer_string, Dwarf_Error *ข้อผิดพลาด)
  • Producer_string - แถวของข้อมูลข้อความ
ตั้งค่า DW_DLV_BADADDR ในเวลาของการให้อภัยหรือคำอธิบายแอตทริบิวต์เมื่อดำเนินการสำเร็จ
สร้างรายการข้อมูลทั่วไป
โทรเมื่อเรียกใช้ฟังก์ชัน (โปรแกรมย่อย) และวางพารามิเตอร์ของที่อยู่ของเทิร์นไว้บนสแต็ก (หากคอมไพเลอร์สามารถทำงานได้ในแบบของมันเอง) จะเรียกว่า Call Frame ตัวควบคุมต้องการข้อมูลเกี่ยวกับรูปแบบของเฟรมเพื่อให้กำหนดที่อยู่ของฟังก์ชันส่งคืนได้อย่างถูกต้องและชักนำการย้อนกลับ - การเรียกกลับของฟังก์ชันซึ่งปลูกฝังฟังก์ชันการสตรีมและพารามิเตอร์ของฟังก์ชันเหล่านี้ให้กับเรา นอกจากนี้ยังมีการเรียกรีจิสเตอร์ของโปรเซสเซอร์เนื่องจากบันทึกไว้ในสแต็ก รหัสที่จองพื้นที่บนสแต็กและบันทึกการลงทะเบียนตัวประมวลผลเรียกว่าอารัมภบทของฟังก์ชัน รหัสที่คืนค่าการลงทะเบียนสแต็กเรียกว่าบทส่งท้าย
ข้อมูลนี้ควรเก็บไว้ในคอมไพเลอร์ ตัวอย่างเช่น อารัมภบทและบทส่งท้ายเป็น neobov'yazkovo เนื่องมาจาก cob และ ตัวอย่างเช่น ฟังก์ชัน; ชนะเฟรม; การลงทะเบียนโปรเซสเซอร์สามารถบันทึกไว้ในการลงทะเบียนอื่น ๆ เป็นต้น
ดังนั้นเจ้าของจำเป็นต้องรู้วิธีเปลี่ยนค่าของการลงทะเบียนโปรเซสเซอร์และ de stink จะถูกบันทึกเมื่อเข้าสู่ขั้นตอน ข้อมูลนี้เรียกว่า Call Frame Information - ข้อมูลเกี่ยวกับรูปแบบเฟรม สำหรับที่อยู่สกินในโปรแกรม (เพื่อล้างโค้ด) มีการระบุที่อยู่ของเฟรมในหน่วยความจำ (Canonical Frame Address - CFA) และข้อมูลเกี่ยวกับการลงทะเบียนของโปรเซสเซอร์ เช่น คุณสามารถระบุได้ว่า:
  • การลงทะเบียนไม่ได้นำมาจากขั้นตอน
  • รีจิสเตอร์ไม่เปลี่ยนค่าในโพรซีเดอร์
  • รีจิสเตอร์จะถูกบันทึกไว้ในสแต็กหลังที่อยู่ CFA+n
  • บันทึกการลงทะเบียนในการลงทะเบียนอื่น
  • การลงทะเบียนจะถูกบันทึกไว้ในหน่วยความจำสำหรับที่อยู่เฉพาะเนื่องจากสามารถนับได้ด้วยวิธีที่ไม่ชัดเจน
  • และอื่น ๆ.
ต้องมีการระบุข้อมูลบางอย่างสำหรับที่อยู่สกินของโค้ด แต่จะมีการสรุปและนำมาสรุปในส่วน .debug_frame ด้วย ดังนั้น เนื่องจากที่อยู่ไปยังที่อยู่จะไม่เปลี่ยนแปลงมากนัก มีเพียง її เท่านั้นที่เปลี่ยนตามคำสั่ง DW_CFA_хххх ที่ได้รับการเข้ารหัส คำสั่งสกินสำหรับการเปลี่ยนแปลงหนึ่งครั้ง เช่น:
  • DW_CFA_set_loc - ชี้ไปที่ที่อยู่ปัจจุบันของโปรแกรม
  • DW_CFA_advance_loc - ตัวบ่งชี้ผ่านสำหรับ sprat ของไบต์
  • DW_CFA_def_cfa - ระบุที่อยู่ของเฟรมสแต็ก (ค่าคงที่ที่เป็นตัวเลข)
  • DW_CFA_def_cfa_register - ระบุที่อยู่ของเฟรมสแต็ก (นำมาจากการลงทะเบียนโปรเซสเซอร์)
  • DW_CFA_def_cfa_expression - ระบุวิธีคำนวณที่อยู่ของเฟรมสแต็ก
  • DW_CFA_same_value - ระบุว่าไม่มีการเปลี่ยนแปลงการลงทะเบียน
  • DW_CFA_register - ระบุการลงทะเบียนที่จะบันทึกในการลงทะเบียนอื่น
  • และอื่น ๆ.
องค์ประกอบส่วน .debug_frame เป็นรายการที่มีได้สองประเภท: Common Information Entry (CIE) และ Frame Description Entry (FDE) CIE เพื่อล้างแค้นข้อมูลที่เป็นเรื่องธรรมดาสำหรับบันทึก FDE ดูเหมือนว่าจะอธิบายขั้นตอนประเภทเดียวกันอย่างหยาบคาย FDE อธิบายถึงขั้นตอนเฉพาะของผิวหนัง เมื่อคุณเข้าสู่ขั้นตอน ตัวควบคุมจะเริ่มด้วยการคลิกคำแนะนำจาก CIE จากนั้นคลิกจาก FDE
คอมไพเลอร์ของฉันสร้างขั้นตอนที่มี CFA ในการลงทะเบียน sp(r13) เราสร้าง CIE สำหรับขั้นตอนทั้งหมด ข้อใดคือฟังก์ชัน dwarf_add_frame_cie:
Dwarf_Unsigned dwarf_add_frame_cie (Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small ret_addr_reg, Dwarf_Ptr init_bytes, Dwarf_Un
  • ตัวขยาย - สตริงสำหรับการเข้ารหัส UTF-8 ซึ่งแสดงว่าก่อน CIE หรือ FDE เป็นข้อมูลแพลตฟอร์มเพิ่มเติม เราใส่แถวว่าง
  • code_align - การจัดตำแหน่งรหัสเป็นไบต์ (เรามี 2)
  • data_align - การจัดตำแหน่งข้อมูลสำหรับเฟรม (ตั้งค่าเป็น -4 ซึ่งหมายความว่าพารามิเตอร์ทั้งหมดใช้ 4 ไบต์ในสแต็กและขยายลงในหน่วยความจำ)
  • ret_addr_reg - ลงทะเบียนเพื่อรับที่อยู่ของขั้นตอน (เรามี 14)
  • init_bytes - อาร์เรย์สำหรับดึงคำสั่ง DW_CFA_хххх น่าเสียดายที่ไม่มีวิธีการสร้างอาร์เรย์นี้ด้วยตนเอง คุณสามารถสร้างด้วยตนเองหรือดูในไฟล์ elf ไม่ว่าคอมไพเลอร์ใดจะสร้างซึ่งฉันสร้างขึ้น สำหรับรหัสผ่านของฉัน 3 ไบต์: 0x0C, 0x0D, 0 ซึ่งถอดรหัสเช่น DW_CFA_def_cfa: r13 ofs 0
  • init_bytes_len - ความยาวของอาร์เรย์ init_bytes
ฟังก์ชันจะหมุน DW_DLV_NOCOUNT เมื่อทำการ militating หรือตัวอธิบาย CIE ซึ่งสามารถเปลี่ยนแปลงได้ในชั่วโมงการสร้าง FDE สำหรับกระบวนการทางผิวหนัง ซึ่งดูได้จากสาขา "การสร้างขั้นตอน FDE"
การสร้างประเภทข้อมูล
ก่อนหน้านั้นในการสร้างขั้นตอนสำหรับการเปลี่ยนแปลงนั้นจำเป็นต้องสร้างปมที่ด้านหลังศีรษะซึ่งสอดคล้องกับประเภทของข้อมูล ประเภทของข้อมูลไม่มีตัวตน แต่กลิ่นจะขึ้นอยู่กับประเภทพื้นฐาน (ประเภทพื้นฐานในตาราง int, เพิ่มเป็นสองเท่า) ประเภทอื่นๆ จะขึ้นอยู่กับประเภทพื้นฐาน
ประเภทฐาน - แท็ก wuzol іz DW_TAG_base_type ใหม่สามารถมีแอตทริบิวต์ buti:
  • "im'ya" (DW_AT_name)
  • "การเข้ารหัส" (DW_AT_encoding) - หมายถึงวิธีที่ข้อมูลอธิบายประเภทฐานที่กำหนด (เช่น DW_ATE_boolean - ตรรกะ DW_ATE_float - จุดลอยตัว DW_ATE_signed - cel ที่เซ็นชื่อ DW_ATE_unsigned - cel ที่ไม่ได้ลงชื่อ ฯลฯ)
  • "ขนาด" (DW_AT_byte_size - ขนาดสำหรับไบต์ หรือ DW_AT_bit_size - ขนาดสำหรับบิต)
นอกจากนี้ สถาบันการศึกษาระดับอุดมศึกษาสามารถแก้แค้นคุณลักษณะ neobov'yazkovy อื่น ๆ ได้
ตัวอย่างเช่น ในการสร้าง int ประเภทฐานเครื่องหมาย cilium 32 บิต เราจะต้องสร้าง vuzel ด้วยแท็ก DW_TAG_base_type และตั้งค่าแอตทริบิวต์ DW_AT_name - int, DW_AT_encoding - DW_ATE_signed, DW_AT_byte_size - 4
หลังจากสร้างประเภทพื้นฐานแล้ว คุณสามารถสร้างประเภทที่คล้ายกันได้ โหนดดังกล่าวมีหน้าที่รับผิดชอบแอตทริบิวต์ DW_AT_type - ส่งประเภทฐาน ตัวอย่างเช่น ตัวชี้ไปยัง int - vuzol ที่มีแท็ก DW_TAG_pointer_type มีความผิดในการแก้แค้นในแอตทริบิวต์ DW_AT_type ซึ่งถูกกำหนดไว้ในการสร้างประเภท "int" ก่อนหน้านี้
คุณลักษณะจากการร้องขอไปยังโหนดอื่นถูกสร้างขึ้นโดยฟังก์ชัน dwarf_add_AT_reference:
Dwarf_P_Attribute dwarf_add_AT_reference (Dwarf_P_Debug dbg, เจ้าของ Dwarf_P_Die, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error *ข้อผิดพลาด)
  • attr - แอตทริบิวต์ ครั้ง DW_AT_type
  • otherdie - คำอธิบายของโหนดประเภทที่ขอ
รวมขั้นตอนต่างๆ
สำหรับการสร้างขั้นตอน จำเป็นต้องอธิบายข้อมูลภาษีประเภทหนึ่ง - ข้อมูลหมายเลขบรรทัด มันจะทำหน้าที่ในการตั้งค่าคำสั่งสกินแมชชีนเป็นบรรทัดเดียวของรหัสเอาต์พุต และสำหรับความเป็นไปได้ในการปรับแต่งภายหลังบรรทัดของโปรแกรม ข้อมูลนี้รวบรวมจากส่วน .debug_line ถ้าเรามีพื้นที่เล็กพอ มันก็จะถูกบันทึกจากรูปลักษณ์ของเมทริกซ์ หนึ่งแถวสำหรับคำสั่งสกินที่มีคอลัมน์ดังกล่าว:
  • ชื่อไฟล์พร้อมรหัสทางออก
  • หมายเลขแถวของไฟล์ใด
  • หมายเลขคอลัมน์ไฟล์
  • chi єคำสั่งโดย cob ของตัวดำเนินการ chi ไปยังบล็อกของตัวดำเนินการ
  • และอื่น ๆ.
เมทริกซ์ดังกล่าวจะยิ่งใหญ่กว่าดังนั้นควรบีบїї ประการแรก แถวที่ทำซ้ำ เห็น และด้วยวิธีอื่น ไม่ใช่แถวที่ตัวเองได้รับการบันทึก แต่จะมีการเปลี่ยนแปลงเท่านั้น การเปลี่ยนแปลงเหล่านี้มีลักษณะเหมือนคำสั่งสำหรับเครื่องเทอร์มินัล และข้อมูลเองก็ได้รับการพิจารณาโดยโปรแกรมแล้ว ราวกับว่ามัน "ชนะ" โดยเครื่องอัตโนมัติ คำสั่งของโปรแกรมมีลักษณะดังนี้: DW_LNS_advance_pc - ใส่ตัวนำคำสั่งไปยังที่อยู่ deuce, DW_LNS_set_file - แทรกไฟล์ซึ่งมีขั้นตอนกำหนดไว้ DW_LNS_const_add_pc - ใส่ตัวนำคำสั่งของไม่กี่ไบต์
ในระดับต่ำเช่นนี้ การสร้างข้อมูลทำได้ยาก ดังนั้นในไลบรารี libdwarf จึงมีการถ่ายโอนฟังก์ชันบางอย่าง ซึ่งทำให้งานง่ายขึ้น
การบันทึกชื่อไฟล์สำหรับคำแนะนำเกี่ยวกับสกินมีราคาแพง ดังนั้นควรบันทึกชื่อไว้ในตารางพิเศษ ในการสร้างดัชนีไฟล์ จำเป็นต้องแทนที่ฟังก์ชัน dwarf_add_file_decl:
Dwarf_Unsigned dwarf_add_file_decl (Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Error *ข้อผิดพลาด)
  • ชื่อ - ชื่อของไฟล์
  • dir_idx – ดัชนีของโฟลเดอร์ที่มีไฟล์อยู่ ดัชนีสามารถนำมาจากฟังก์ชันช่วยเหลือ dwarf_add_directory_decl หากคุณต้องการผูกพาธเพิ่มเติม คุณสามารถตั้งค่า 0 เป็นดัชนีโฟลเดอร์และไม่ต้องผูก dwarf_add_directory_decl
  • time_mod – ชั่วโมงการแก้ไขไฟล์ ไม่สามารถระบุได้ (0)
  • ความยาว - ขยายไฟล์และไม่ผูกมัด (0)
ฟังก์ชั่นในการเปลี่ยนดัชนีไฟล์หรือ DW_DLV_NOCOUNT ในเวลาให้อภัย
สำหรับการสร้างข้อมูลเกี่ยวกับหมายเลขบรรทัด มีสามฟังก์ชัน: dwarf_add_line_entry_b, dwarf_lne_set_address, dwarf_lne_end_sequence ดังที่เราเห็นด้านล่าง
การสร้างข้อมูลภาษีสำหรับขั้นตอนจะได้รับในตอนท้ายของขั้นตอน:
  • สร้างเป็นสัญลักษณ์ขั้นตอนของส่วน
  • การสร้างโหนดโพรซีเดอร์ด้วยแอตทริบิวต์
  • การสร้างขั้นตอน FDE
  • การตั้งค่าพารามิเตอร์ในโพรซีเดอร์
  • การรวบรวมข้อมูลเกี่ยวกับหมายเลขแถว
การสร้างสัญลักษณ์ขั้นตอน
สัญลักษณ์ขั้นตอนถูกสร้างขึ้นตามที่อธิบายไว้ในส่วน "Section.symtab" สำหรับพวกเขา สัญลักษณ์ของขั้นตอนจะถูกแทรกด้วยสัญลักษณ์ของไฟล์ที่พวกเขาเปลี่ยนรหัสอินพุตของขั้นตอนเหล่านี้ ฉันสร้างสัญลักษณ์ให้กับไฟล์ก่อน จากนั้นตามด้วยขั้นตอน ซึ่งไฟล์จะแม่นยำยิ่งขึ้น และหากมีการซื้อซ้ำขั้นตอนดังกล่าวจากไฟล์สตรีม ไฟล์นั้นไม่จำเป็นต้องสร้างอีก
การสร้างโหนดขั้นตอนด้วยแอตทริบิวต์
ในทางกลับกัน เราสร้างโหนดสำหรับฟังก์ชันเพิ่มเติม dwarf_new_die (ส่วน div. "Creation of Wuzley") โดยระบุเป็นแท็ก DW_TAG_subprogram และเป็นตัวพ่อ - Compilation Unit (ซึ่งเป็นขั้นตอนส่วนกลาง) หรือ DIE (ซึ่ง เป็นของท้องถิ่น) มาสร้างแอตทริบิวต์กัน:
  • ชื่อโพรซีเดอร์ (ฟังก์ชัน dwarf_add_AT_name, div. "สร้างแอตทริบิวต์ของโหนด")
  • หมายเลขแถวของไฟล์ ซึ่งรหัสขั้นตอนเริ่มต้น (แอตทริบิวต์ DW_AT_decl_line) ฟังก์ชัน dwarf_add_AT_unsigned_const (div. "สร้างแอตทริบิวต์ของโหนด")
  • ที่อยู่อีเมลของขั้นตอน (แอตทริบิวต์ DW_AT_low_pc), ฟังก์ชัน dwarf_add_AT_targ_address, div
  • ที่อยู่สิ้นสุดของขั้นตอน (แอตทริบิวต์ DW_AT_high_pc), ฟังก์ชัน dwarf_add_AT_targ_address, div
  • ประเภทของผลลัพธ์ที่เปลี่ยนตามขั้นตอน (แอตทริบิวต์ DW_AT_type - ตั้งค่าก่อนประเภทการสร้าง div "ประเภทข้อมูลที่สร้างขึ้น") เนื่องจากขั้นตอนนี้ไม่ได้หมุนอะไรเลย จึงไม่จำเป็นต้องสร้างแอตทริบิวต์ใดๆ
แอตทริบิวต์ DW_AT_low_pc และ DW_AT_high_pc จำเป็นต้องตั้งค่าเป็นฟังก์ชัน dwarf_add_AT_targ_address_b ที่รู้จักเป็นพิเศษสำหรับสิ่งนี้:
Dwarf_P_Attribute dwarf_add_AT_targ_address_b (Dwarf_P_Debug dbg, เจ้าของ Dwarf_P_Die, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *ข้อผิดพลาด)
  • attr - แอตทริบิวต์ (DW_AT_low_pc หรือ DW_AT_high_pc)
  • pc_value - ค่าที่อยู่
  • sym_index – ดัชนีของสัญลักษณ์ขั้นตอนในตาราง Neobov'viscous สามารถส่งได้ 0
ฟังก์ชั่นในการเปลี่ยน DW_DLV_BADADDR สำหรับการให้อภัย
การสร้างขั้นตอน FDE
ดังที่ได้กล่าวไว้ก่อนหน้านี้ในหัวข้อ "การสร้างรายการข้อมูลทั่วไป" สำหรับขั้นตอนเกี่ยวกับผิวหนัง จำเป็นต้องสร้างคำอธิบายของเฟรม ซึ่งควรใช้ในขั้นตอนคิลกา:
  • การสร้าง FDE ใหม่ (div. การสร้างรายการข้อมูลทั่วไป)
  • นำ FDE ที่สร้างขึ้นไปยังรายการ
  • การเพิ่มคำแนะนำให้กับ FDE ที่สร้างขึ้น
คุณสามารถสร้าง FDE ใหม่ได้โดยใช้ฟังก์ชัน dwarf_new_fde:
Dwarf_P_Fde dwarf_new_fde (Dwarf_P_Debug dbg, Dwarf_Error *ข้อผิดพลาด)
ฟังก์ชันจะเปลี่ยนหมายเลขอ้างอิง FDE ใหม่เป็น DW_DLV_BADADDR ขออภัย
คุณสามารถรับ FDE ใหม่ไปยังรายการโดยใช้ dwarf_add_frame_fde:
Dwarf_Unsigned dwarf_add_frame_fde(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym
  • fde - ตัวบ่งชี้ที่เลือก
  • ตาย - ขั้นตอน DIE (div. สร้างโหนดขั้นตอนด้วยแอตทริบิวต์)
  • cie - ตัวอธิบาย CIE (รายการข้อมูลทั่วไป div.)
  • virt_addr - ที่อยู่อีเมลของขั้นตอนของเรา
  • code_len - ความยาวขั้นตอนเป็นไบต์
ฟังก์ชั่นที่จะเปิด DW_DLV_NOCOUNT ในเวลาของการให้อภัย
ในกรณีนี้ คุณสามารถเพิ่มคำแนะนำ DW_CFA_хххх ไปยัง FDE ของเราได้ ใช้ฟังก์ชัน dwarf_add_fde_inst และ dwarf_fde_cfa_offset ขั้นแรก เพิ่มคำสั่งที่กำหนดลงในรายการ:
Dwarf_P_Fde dwarf_add_fde_inst (Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *ข้อผิดพลาด)
  • op - รหัสคำสั่ง (DW_CFA_хххх)
  • val1, val2 - พารามิเตอร์คำสั่ง (ต่างกันสำหรับคำสั่งสกิน, div. Standard, ส่วน 6.4.2 คำสั่ง Call Frame)
ฟังก์ชัน dwarf_fde_cfa_offset เพิ่มคำสั่ง DW_CFA_offset:
Dwarf_P_Fde dwarf_fde_cfa_offset (Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error *ข้อผิดพลาด)
  • fde - จัดการเพื่อสร้าง FDE
  • reg - register ซึ่งเขียนลงในเฟรม
  • ออฟเซ็ต - ออฟเซ็ตของเฟรม (ไม่ใช่ไบต์ แต่เป็นองค์ประกอบเฟรม div การป้อนข้อมูลทั่วไป data_align)
ตัวอย่างเช่น คอมไพเลอร์สร้างโพรซีเดอร์ที่บันทึก register lr (r14) สำหรับ prolose เช่น stack frame Насамперед потрібно додати інструкцію DW_CFA_advance_loc з першим параметром, рівним 1, що означає просування регістра pc на 2 байти (див. Створення Common Information Entry, code_align), потім додати DW_CFA_def_cfa_offset з параметром 4 (завдання зміщення даних у ф функцію dwarf_fde_cfa_offset з параметром reg=14 offset=1 ซึ่งหมายความว่า register r14 ถูกเขียนไปยังเฟรมโดยมีค่า offset เท่ากับ -4 ไบต์ใน CFA
การสร้างพารามิเตอร์ขั้นตอน
การสร้างพารามิเตอร์ของขั้นตอนนั้นคล้ายกับการสร้างการเปลี่ยนแปลงที่สำคัญที่สุด divs "การสร้างการเปลี่ยนแปลงและค่าคงที่"
การสร้างข้อมูลเกี่ยวกับหมายเลขแถว
การสร้างข้อมูลนี้มีดังนี้:
  • ที่จุดเริ่มต้นของขั้นตอน เราเริ่มบล็อกคำสั่งด้วยฟังก์ชัน dwarf_lne_set_address
  • สำหรับรหัสสกินไลน์ (หรือคำสั่งเครื่อง) เราสร้างข้อมูลเกี่ยวกับรหัสออก (dwarf_add_line_entry)
  • ตัวอย่างเช่น โพรซีเดอร์สิ้นสุดบล็อกคำสั่งด้วยฟังก์ชัน dwarf_lne_end_sequence
ฟังก์ชัน dwarf_lne_set_address ตั้งค่าที่อยู่ซึ่งบล็อกคำสั่งเริ่มต้น:
Dwarf_Unsigned dwarf_lne_set_address (Dwarf_P_Debug dbg, Dwarf_Addr off, Dwarf_Unsigned symidx, Dwarf_Error *ข้อผิดพลาด)
  • offs - ที่อยู่ของขั้นตอน (ที่อยู่ของคำสั่งเครื่องแรก)
  • sym_idx - ดัชนีสัญลักษณ์ (ไม่ผูกมัด คุณสามารถป้อน 0)

ฟังก์ชัน dwarf_add_line_entry_b เพิ่มข้อมูล section.debug_line เกี่ยวกับบรรทัดของโค้ดผลลัพธ์ ฉันเรียกฟังก์ชันนี้สำหรับคำสั่งสกินแมชชีน:
Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_offset, Dwarf_Unsigned lineno, Dwarf_Signed column_number, Dwarf_Bool is_source_stmt_begin, Dwarf_Bool is_basic_block_begin, Dwarf_Bool is_epilogue_begin, Dwarf_Bool is_prologue_end, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error *error)
  • file_index - ดัชนีไฟล์ของโค้ดเอาต์พุต ซึ่งก่อนหน้านี้ถูกลบออกโดยฟังก์ชัน dwarf_add_file_decl (div. "ขั้นตอนการสร้าง")
  • code_offset - ที่อยู่ของคำสั่งเครื่องเธรด
  • lineno - หมายเลขแถวของไฟล์โค้ดเอาต์พุต
  • column_number - หมายเลขคอลัมน์ของไฟล์โค้ดเอาต์พุต
  • is_source_stmt_begin - คำสั่งบรรทัดที่ 1 ก่อนในโค้ดในแถว lineno (ฉันเริ่ม vicorist 1)
  • is_basic_block_begin - คำสั่งบรรทัดที่ 1 ก่อนในกลุ่มคำสั่ง (ฉันต้องเริ่ม 0)
  • is_epilogue_begin - คำแนะนำแบบอินไลน์ลำดับที่ 1 ก่อนในบทส่งท้ายของขั้นตอน (ไม่ผูกมัด ฉันมี 0)
  • is_prologue_end - คำแนะนำแบบอินไลน์ลำดับที่ 1 เพื่อหยุดที่บทนำของขั้นตอน (obv'yazykovo!)
  • isa - สถาปัตยกรรมชุดคำสั่ง (สถาปัตยกรรมชุดคำสั่ง) Obov'yazkovo เลื่อนเพื่อระบุ DW_ISA_ARM_thumb สำหรับ ARM Cortex M3!
  • ผู้เลือกปฏิบัติ หนึ่งตำแหน่ง (ไฟล์ แถว stompchik) ของรหัสเอาต์พุตสามารถใช้กับคำสั่งเครื่องต่างๆ ได้ ในช่วงเวลาดังกล่าว สำหรับชุดคำสั่งดังกล่าว จำเป็นต้องติดตั้งตัวแยกความแตกต่าง ไม่มีพฤติกรรมดังกล่าว แต่สามารถเป็น 0 ได้
ฟังก์ชันเปลี่ยน 0 (สำเร็จ) หรือ DW_DLV_NOCOUNT (ให้อภัย)
เมื่อคุณทำเสร็จแล้ว ฟังก์ชัน dwarf_lne_end_sequence จะสิ้นสุดขั้นตอน:
Dwarf_Unsigned dwarf_lne_end_sequence (Dwarf_P_Debug dbg, ที่อยู่ Dwarf_Addr; Dwarf_Error *ข้อผิดพลาด)
  • ที่อยู่ - ที่อยู่ของคำสั่งเครื่องเธรด
เปิด 0 (สำเร็จ) หรือ DW_DLV_NOCOUNT (ให้อภัย)
ซึ่งเราทำการสร้างขั้นตอนให้เสร็จสมบูรณ์
การสร้างการเปลี่ยนแปลงและค่าคงที่
Zagalom zminnі dosi เรียบง่าย พวกเขามี є іm'ya ซึ่งเป็นสถานที่แห่งหน่วยความจำ (หรือรีจิสเตอร์ของโปรเซสเซอร์) ซึ่งพวกเขารู้ข้อมูลของพวกเขา เช่นเดียวกับประเภทของข้อมูล ราวกับว่ามีการเปลี่ยนแปลงไปทั่วโลก - їїพ่อสามารถเป็น Odinitsa Compilation เช่นเดียวกับในท้องถิ่น - มหาวิทยาลัยอื่น (โดยเฉพาะอย่างยิ่งพารามิเตอร์ของขั้นตอนจะถูกนำมาพิจารณาพวกเขาสามารถเป็นขั้นตอนได้) นอกจากนี้ยังสามารถระบุได้ว่ามีการเปลี่ยนแปลงของเสียงในไฟล์ใดในแถวและคอลัมน์
ในวิธีที่ง่ายที่สุด ค่าของการเปลี่ยนแปลงเป็นที่รู้จักสำหรับแอดเดรสคงที่บางตัว แต่การเปลี่ยนแปลงจำนวนมากถูกสร้างขึ้นแบบไดนามิกเมื่อป้อนโพรซีเดอร์บนสแต็กหรือรีจิสเตอร์ และบางครั้งการคำนวณแอดเดรสของค่าอาจไม่ใช่ เล็กน้อย มาตรฐานมีกลไกในการอธิบายว่าค่าของการเปลี่ยนแปลงอยู่ที่ใด - นิพจน์ที่อยู่ (นิพจน์ตำแหน่ง) ที่อยู่ viraz - ราคาของคำแนะนำในการพิมพ์ (ค่าคงที่ DW_OP_хххх) สำหรับจักรเย็บผ้าแบบป้อม ในความเป็นจริงราคาของ mov พร้อมการดีบัก ขั้นตอนและการดำเนินการทางคณิตศาสตร์ ฉันไม่สามารถย้อนกลับคำพูดของฉันได้ จริง ๆ แล้วเราเรียกว่าคำแนะนำเล็กน้อยเท่านั้น:
  • DW_OP_addr - ระบุที่อยู่การเปลี่ยนแปลง
  • DW_OP_fbreg - ระบุการเปลี่ยนแปลงการลงทะเบียนฐาน (ตั้งชื่อตัวบ่งชี้สแต็ค)
  • DW_OP_reg0… DW_OP_reg31 - บ่งบอกถึงการเปลี่ยนแปลงโดยการลงทะเบียนที่เลือก
ในการสร้างที่อยู่ virase คุณต้องสร้างไวรัสเปล่า (dwarf_new_expr) ก่อน เพิ่มคำสั่งใหม่ (dwarf_add_expr_addr, dwarf_add_expr_gen ฯลฯ) และเพิ่มลงในโหนดเป็นค่าของแอตทริบิวต์ DW_AT_location (dwarf_add_AT_location
ฟังก์ชันของการสร้างหน้าต่างที่อยู่ว่างจะเปลี่ยนคำอธิบายหรือ 0 สำหรับการให้อภัย:
Dwarf_Expr dwarf_new_expr (Dwarf_P_Debug dbg, Dwarf_Error *ข้อผิดพลาด)
ในการเพิ่มคำอธิบายให้กับไวรัส จำเป็นต้องรวมฟังก์ชัน dwarf_add_expr_gen:
Dwarf_Unsigned dwarf_add_expr_gen (Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *ข้อผิดพลาด)
  • opcode - รหัสการดำเนินการ ค่าคงที่ DW_OP_хххх
  • val1, val2 – พารามิเตอร์คำสั่ง (div. Standard)

สำหรับการตั้งค่าที่ชัดเจนของที่อยู่ที่สามารถเปลี่ยนแปลงได้ การเปลี่ยนแปลงที่อยู่ข้างหน้าเกิดจากฟังก์ชัน dwarf_add_expr_addr:
Dwarf_Unsigned dwarf_add_expr_addr (Dwarf_P_Expr expr, Dwarf_Unsigned address, Dwarf_Signed sym_index, Dwarf_Error *ข้อผิดพลาด)
  • expr - คำอธิบายของที่อยู่ virase ซึ่งได้รับคำแนะนำ
  • ที่อยู่ - เปลี่ยนที่อยู่
  • sym_index - ดัชนีสัญลักษณ์ในตาราง Neobov'viscous สามารถส่งได้ 0
ฟังก์ชันนี้ยังหมุน DW_DLV_NOCOUNT เมื่อให้อภัยที่แตกต่างกัน
คุณสามารถเพิ่มที่อยู่ไวรัสลงในไซต์ได้โดยใช้ฟังก์ชัน dwarf_add_AT_location_expr:
Dwarf_P_Attribute dwarf_add_AT_location_expr (Dwarf_P_Debug dbg, เจ้าของ Dwarf_P_Die, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_Error *ข้อผิดพลาด)
  • เจ้าของ - vuzol ซึ่ง viraz สามารถเข้าถึงได้
  • attr - คุณลักษณะ (ครั้ง DW_AT_location)
  • loc_expr - จัดการกับไวรัสที่อยู่ที่สร้างไว้ก่อนหน้านี้
ฟังก์ชันจะหมุนตัวอธิบายแอตทริบิวต์หรือ DW_DLV_NOCOUNT ในเวลาที่ให้อภัย
การเปลี่ยนแปลง (เช่นเดียวกับพารามิเตอร์ขั้นตอน) และค่าคงที่ - โหนดหลักที่มีแท็ก DW_TAG_variable, DW_TAG_formal_parameter และ DW_TAG_const_type เป็นทางเลือก คุณต้องมีคุณสมบัติดังต่อไปนี้:
  • เปลี่ยน/ชื่อคงที่ (ฟังก์ชัน dwarf_add_AT_name, div. "สร้างแอตทริบิวต์ของโหนด")
  • หมายเลขแถวของไฟล์ ประกาศการเปลี่ยนแปลง (แอตทริบิวต์ DW_AT_decl_line) ฟังก์ชัน dwarf_add_AT_unsigned_const (div. "สร้างแอตทริบิวต์ของโหนด")
  • ดัชนีชื่อไฟล์ (แอตทริบิวต์ DW_AT_decl_file) ฟังก์ชัน dwarf_add_AT_unsigned_const (div. "สร้างแอตทริบิวต์ของโหนด")
  • ประเภทข้อมูลเปลี่ยนแปลง/คงที่ (แอตทริบิวต์ DW_AT_type - ตั้งค่าก่อนประเภทการสร้าง div. "ประเภทข้อมูลที่สร้างขึ้น")
  • ที่อยู่ virase (div. vishche) - จำเป็นสำหรับการเปลี่ยนแปลงหรือพารามิเตอร์ขั้นตอน
  • หรือค่าคงที่ (แอตทริบิวต์ DW_AT_const_value, div. "สร้างแอตทริบิวต์ของโหนด")
การสร้างส่วนที่มีข้อมูลภาษี
หลังจากสร้างโหนดทั้งหมดของต้นไม้ของ nalagodzhuvalnoї іnformatsії คุณสามารถดำเนินการสร้างส่วนเอลฟ์กับมันได้ มีสองขั้นตอน:
  • เราจำเป็นต้องเรียกใช้ฟังก์ชัน dwarf_transform_to_disk_form กลับไปกลับมา เหมือนกับที่เราเขียนฟังก์ชันการเรียกกลับเพื่อสร้างส่วนเอลฟ์ที่จำเป็นสำหรับส่วนสกิน
  • สำหรับส่วนสกิน ฟังก์ชัน dwarf_get_section_bytes จะส่งคืนข้อมูลให้เรา เนื่องจากจำเป็นต้องจดส่วนที่เกี่ยวข้อง
การทำงาน
dwarf_transform_to_disk_form (Dwarf_P_Debug dbg, ข้อผิดพลาด Dwarf_Error*)
แปลข้อมูลที่กำหนดเองที่เราสร้างขึ้นเป็นรูปแบบไบนารี แต่อย่าเขียนอะไรลงดิสก์ โปรดกลับมาหาเราในส่วนเอลฟ์ที่สร้างขึ้นจำนวนมากหรือ DW_DLV_NOCOUNT สำหรับการให้อภัย สำหรับส่วนของสกิน จะมีการเรียกใช้ฟังก์ชันการเรียกกลับ ซึ่งถูกส่งผ่านในระหว่างการเริ่มต้นไลบรารีไปยังฟังก์ชัน dwarf_producer_init_c คุณสามารถเขียนฟังก์ชันนี้ได้เอง Її ข้อกำหนดมีดังนี้:
typedef int (*Dwarf_Callback_Func_c)(ชื่อถ่าน*, ขนาด int, ประเภท Dwarf_Unsigned, แฟล็ก Dwarf_Unsigned, ลิงก์ Dwarf_Unsigned, ข้อมูล Dwarf_Unsigned, Dwarf_Unsigned* sect_name_index, void * user_da,
  • ชื่อ - ชื่อของส่วนเอลฟ์ วิธีสร้าง
  • ขนาด – ขนาดส่วน
  • ประเภท - ประเภทส่วน
  • ธง - ธงส่วน
  • ลิงค์ - ฟิลด์ลิงค์ส่วน
  • ข้อมูล - ฟิลด์ข้อมูลส่วน
  • sect_name_index – เลือกหมุนดัชนีส่วนด้วยการย้ายตำแหน่ง (ไม่ผูกมัด)
  • user_data - ส่งถึงเราเช่นนี้เนื่องจากโยคะของฉันถูกตั้งค่าในฟังก์ชั่นการเริ่มต้นของไลบรารี
  • ข้อผิดพลาด - คุณสามารถส่งรหัสอภัยโทษได้ที่นี่
หน้าที่ของเรามีหน้าที่รับผิดชอบ:
  • สร้างส่วนใหม่ (ฟังก์ชัน elf_newscn, div. สร้างส่วน)
  • สร้างส่วนหัวของส่วน (ฟังก์ชัน elf32_getshdr, ibid.)
  • จำ yogo ได้อย่างถูกต้อง (div. ibid.) ง่ายมาก เนื่องจากฟิลด์ส่วนหัวตรงกับพารามิเตอร์ของฟังก์ชันของเรา ฟิลด์ sh_addr, sh_offset, sh_entsize ถูกตั้งค่าเป็น 0 และ sh_addralign เป็น 1
  • หมุนดัชนีของส่วนที่สร้างขึ้น (ฟังก์ชัน elf_ndxscn, div. "section.symtab") หรือ -1 สำหรับการให้อภัย (โดยการตั้งค่ารหัสให้อภัยในข้อผิดพลาด)
  • นอกจากนี้ ยังเป็นความผิดของเราที่ข้ามส่วน ".rel" (ในวิวพอร์ตของเรา) ด้วยการเปลี่ยน 0 เมื่อเปิดฟังก์ชัน
เมื่อฟังก์ชัน dwarf_transform_to_disk_form เสร็จสิ้น มันจะส่งคืนจำนวนส่วนที่สร้างขึ้นมาให้เรา เราจะต้องวนลูปจาก 0 ไปยังส่วนสกินตามบรรทัดเหล่านี้:
  • สร้างข้อมูลเพื่อเขียนลงในส่วนโดยใช้ฟังก์ชัน dwarf_get_section_bytes:
    Dwarf_Ptr dwarf_get_section_bytes (Dwarf_P_Debug dbg, Dwarf_Signed dwarf_section, Dwarf_Signed *elf_section_index, Dwarf_Unsigned *ความยาว, Dwarf_Error* ข้อผิดพลาด)
    • dwarf_section - หมายเลขส่วน อาจอยู่ในช่วง 0..n โดยที่ n คือตัวเลขที่ส่งคืนให้เราโดยฟังก์ชัน dwarf_transform_to_disk_form
    • elf_section_index - หมุนดัชนีส่วน จำเป็นต้องเขียนข้อมูลลงในกล่อง
    • ความยาว - dozhina tsikh danih
    • ข้อผิดพลาด - อย่าทวีต
    ฟังก์ชันหมุนตัวบ่งชี้เพื่อลบข้อมูลหรือ 0 (ในกรณีนั้น
    หากไม่มีส่วนให้พับแล้ว)
  • สร้างตัวจัดการข้อมูลของส่วนการสตรีม (ฟังก์ชัน elf_newdata, div. สร้างส่วน) และบันทึก (div. ibid.) การตั้งค่า:
    • d_buf - ตัวบ่งชี้ข้อมูลที่เรานำมาจากฟังก์ชันส่งต่อ
    • d_size - rozmir tsikh danih (อ้างแล้ว)
เสร็จสิ้นการทำงานกับห้องสมุด
หลังจากสร้างส่วนต่างๆ คุณสามารถทำให้หุ่นยนต์เสร็จได้ด้วยฟังก์ชัน libdwarf dwarf_producer_finish:
Dwarf_Unsigned dwarf_producer_finish (Dwarf_P_Debug dbg, ข้อผิดพลาด Dwarf_Error*)
ฟังก์ชันเปลี่ยน DW_DLV_NOCOUNT สำหรับการให้อภัย
ฉันเคารพว่าขั้นตอนนี้จะไม่ถูกบันทึกลงในแผ่นดิสก์ การบันทึกจำเป็นต้องทำงานสำหรับฟังก์ชันเพิ่มเติมของการแจกจ่าย "การสร้าง ELF - การบันทึกไปยังไฟล์"

วิสโนวอค

ทุกอย่างอยู่ที่ใคร
ฉันทำซ้ำการสร้าง nalagodzhuvalnoi іnformatsiї - หัวข้อนั้นยอดเยี่ยมอยู่แล้วและฉันไม่ได้แตะต้องหัวข้อที่หลากหลาย แต่แสดงเฉพาะม่านเท่านั้น Bazhayuchi สามารถมองด้วยความไม่ประมาท
ทันทีที่คุณมีอาหาร ฉันจะพยายามเป็นพยานถึงพวกเขา

สำหรับการมองเห็นในคอมพิวเตอร์ที่ติดตั้ง โปรแกรมแอนตี้ไวรัสเป็นไปได้ เป็นไปได้ สแกนไฟล์ทั้งหมดในคอมพิวเตอร์รวมถึงไฟล์สกิน okremo. คุณสามารถสแกนไฟล์ใดก็ได้โดยคลิกขวาที่ไฟล์แล้วเลือกตัวเลือกตรวจสอบเพื่อตรวจสอบไฟล์เพื่อหาไวรัส

ตัวอย่างเช่นใครเห็นเด็กน้อย ไฟล์ my-file.elfจากนั้นคลิกขวาที่ไฟล์ที่ต้องการ แล้วเลือกตัวเลือกในเมนูไฟล์ "สแกนเพื่อขอความช่วยเหลือ AVG". เมื่อคุณเลือกตัวเลือกนี้ AVG Antivirus จะถูกขอให้สแกนไฟล์เพื่อหาไวรัส


บางครั้งการให้อภัยอาจถูกตำหนิในผลลัพธ์ การติดตั้งซอฟต์แวร์ไม่ถูกต้องเกี่ยวโยงกับปัญหาอะไรได้บ้าง ไวนิล คืออะไร ในกระบวนการติดตั้ง คุณสามารถตั้งค่าระบบปฏิบัติการของคุณ เชื่อมโยงไฟล์ ELF ของคุณกับซอฟต์แวร์ที่ถูกต้องคายชื่อดังกล่าว "เชื่อมโยงนามสกุลไฟล์".

บางครั้งเรียบง่าย การติดตั้ง Dolphin (โปรแกรมจำลอง) อีกครั้งคุณสามารถแก้ปัญหาของคุณได้โดยเรียก ELF จาก Dolphin (โปรแกรมจำลอง) อย่างถูกต้อง ในกรณีอื่น ๆ ปัญหาเกี่ยวกับความสัมพันธ์ของไฟล์สามารถถูกตำหนิได้ การเขียนโปรแกรมซอฟต์แวร์ที่น่ารังเกียจผู้ค้าปลีก และคุณอาจต้องติดต่อผู้ค้าปลีกเพื่อขอความช่วยเหลือเพิ่มเติม


ภราดา:ลองอัปเดต Dolphin (โปรแกรมจำลอง) กับเวอร์ชันที่เหลือเพื่อดูว่ามีการติดตั้งการอัปเดตที่เหลือหรือไม่


อาจจะชัดเจน แต่บ่อยครั้ง ตรงกลาง ไฟล์ ELF เองอาจเป็นสาเหตุของปัญหา. หากคุณได้รับไฟล์ผ่านทางไฟล์แนบทางอีเมล หรือคุณได้บันทึกไฟล์จากเว็บไซต์ และกระบวนการจับภาพถูกขัดจังหวะ (เช่น เปิดการถ่ายทอดสดหรือด้วยเหตุผลอื่นบางประการ) ไฟล์อาจเสียหายได้. หากเป็นไปได้ ให้ลองทำสำเนาไฟล์ ELF ใหม่แล้วลองอีกครั้ง


อย่างระมัดระวัง:ไฟล์ Poshkodzhenie อาจทำให้เกิดการอุดตันที่ตามมาในด้านหน้า หรือแม้ว่าจะเป็นโปรแกรมฟลุคบนพีซีของคุณก็ตาม สิ่งสำคัญยิ่งกว่าคือต้องอัปเดตคอมพิวเตอร์ของคุณด้วยการอัปเดตป้องกันไวรัสอยู่เสมอ


เช่นเดียวกับไฟล์ ELF ของคุณ ปัญหาเกี่ยวกับความปลอดภัยของฮาร์ดแวร์ในคอมพิวเตอร์ของคุณคุณอาจต้องเปิดไฟล์ อัปเดตไดรเวอร์อุปกรณ์, pov'yazanih іz cim ครอบครอง

อะไรคือปัญหา ดังขึ้นตามประเภทของไฟล์มัลติมีเดีย, yakіนอนลงในรูปแบบของโซลูชันความปลอดภัยของฮาร์ดแวร์ที่ประสบความสำเร็จตรงกลางคอมพิวเตอร์เช่น การ์ดเสียงหรือการ์ดแสดงผล. ตัวอย่างเช่น ถ้าคุณต้องการเปิดไฟล์เสียง หากคุณไม่สามารถเปิดได้ คุณอาจต้องใช้ อัปเดตไดรเวอร์การ์ดเสียง.


ภราดา:ดังนั้นเมื่อพยายามเปิดไฟล์ ELF คุณจะยอมรับ การแจ้งเตือนการให้อภัย ไฟล์ pov'yazanu z.SYS, ปัญหา, ymovіrno, อาจจะเป็น buti เชื่อมต่อกับ poshkogenimi หรือไดรเวอร์อุปกรณ์ที่ล้าสมัยเนื่องจากจำเป็นต้องเปลี่ยน กระบวนการนี้สามารถอำนวยความสะดวกได้ด้วยความช่วยเหลือของซอฟต์แวร์สำหรับอัพเดตไดรเวอร์ เช่น DriverDoc


เด็กน้อยแก้ปัญหาอย่างไรและคุณยังคงมีปัญหาในการเปิดไฟล์ ELF แต่อาจเกี่ยวข้องกับ จำนวนทรัพยากรระบบที่มีอยู่. สำหรับไฟล์ ELF บางเวอร์ชัน คุณอาจต้องการทรัพยากรจำนวนมาก (เช่น หน่วยความจำ / RAM แรงดันการแจงนับ) สำหรับฮาร์ดไดรฟ์ในคอมพิวเตอร์ของคุณ ปัญหาดังกล่าวมักเกิดขึ้นเนื่องจากคุณสามารถดาวน์โหลดฮาร์ดแวร์คอมพิวเตอร์เครื่องเก่าได้อย่างง่ายดายโดยไม่มีการรักษาความปลอดภัย และในขณะเดียวกันก็เติมระบบปฏิบัติการใหม่

ปัญหาดังกล่าวสามารถถูกตำหนิได้ หากเป็นสิ่งสำคัญที่คอมพิวเตอร์จะไม่ทำงาน เศษระบบปฏิบัติการ (บริการอื่น ๆ ที่ทำงานในพื้นหลัง) สามารถ ประหยัดทรัพยากรจำนวนมากเพื่ออ่านไฟล์ ELF. ลองปิดโปรแกรมทั้งหมดบนพีซีของคุณ เปิดไฟล์เกม Nintendo Wii ก่อน เมื่อใช้ทรัพยากรทั้งหมดที่มีในคอมพิวเตอร์ของคุณ คุณจะมีสมองที่ดีที่สุดสำหรับการพยายามเปิดไฟล์ ELF


ยัคโช วี vikonali ทั้งหมดที่อธิบายไว้ข้างต้น crokiและไฟล์ ELF ของคุณไม่แสดงเหมือนเมื่อก่อน คุณอาจต้อง การต่ออายุการครอบครอง. У більшості випадків, навіть при використанні старих версій обладнання, обчислювальна потужність може бути більш ніж достатньою для більшості додатків користувача (якщо ви не виконуєте багато ресурсомісткої роботи процесора, такий як 3D-рендеринг, фінансове/наукове моделювання або інтенсивна мультимедійна робота) . ในลักษณะดังกล่าว ไม่สามารถเคลื่อนย้ายได้อย่างสมบูรณ์ เพื่อให้คอมพิวเตอร์ของคุณไม่ได้รับหน่วยความจำที่จำเป็น(มักเรียกว่า "RAM" หน่วยความจำปฏิบัติการ chi) การตั้งเวลาไฟล์

เราหวังว่าพวกเขาจะช่วยคุณแก้ปัญหาเกี่ยวกับไฟล์ ELF หากคุณไม่ทราบว่าคุณสามารถดาวน์โหลดโปรแกรมจากรายการของเราได้ที่ไหน คลิกที่ลิงค์ (ชื่อโปรแกรม) - คุณจะทราบข้อมูลรายงานเกี่ยวกับตำแหน่งที่ตั้ง ดาว ดาวน์โหลดเวอร์ชันการติดตั้งที่ปลอดภัยของโปรแกรมที่ต้องการ

เราสามารถช่วยคุณด้วยคำแนะนำเฉพาะเกี่ยวกับราคาหรือโภชนาการที่ใกล้เคียงกัน:

  • จะเปิดไฟล์ที่มีนามสกุล ELF ได้อย่างไร?
  • จะแปลงไฟล์ ELF เป็นรูปแบบอื่นได้อย่างไร?
  • ส่วนขยายของรูปแบบ ELF คืออะไร
  • โปรแกรมใดที่สามารถให้บริการไฟล์ ELF ได้

จากการตรวจสอบเนื้อหาในอีกด้านหนึ่ง คุณไม่ได้นำหลักฐานที่เพียงพอในสิ่งเดียวกันนี้ออกจากการส่งอาหาร หมายความว่าข้อมูลเกี่ยวกับไฟล์ ELF ที่ให้ไว้ที่นี่ไม่ถูกต้อง ติดต่อกับเรา แบบฟอร์มการติดต่อ vikoristovuyuchi และเขียน ข้อมูลอะไรที่คุณไม่รู้

อะไรอีกที่อาจทำให้เกิดปัญหา?

อาจมีสาเหตุหลายประการที่ทำให้คุณไม่สามารถเปิดไฟล์ ELF ได้ (ไม่ใช่เฉพาะโปรแกรมทั่วไปเท่านั้น)
เพิร์ช- ไฟล์ ELF อาจเชื่อมต่อไม่ถูกต้อง (เสียสติ) จากภาคผนวกที่ติดตั้งสำหรับการบำรุงรักษานี้ ในเวลานี้ คุณต้องเปลี่ยนลิงก์ของคุณโดยอิสระ ดังนั้น ฉันสามารถคลิกขวาที่ปุ่มหมีบนไฟล์ ELF ซึ่งจำเป็นต้องแก้ไข คลิกตัวเลือก "Vіdkritiเพื่อขอความช่วยเหลือ"จากนั้นเลือกโปรแกรมจากรายการตามที่เราติดตั้ง ในกรณีที่เกิดปัญหาดังกล่าว คงต้องโทษไฟล์ ELF อีกครั้ง
ด้วยวิธีที่แตกต่างกัน- ไฟล์ที่คุณต้องการเปิดคุณสามารถใช้งานได้ ในเวลานี้จะเป็นการดีกว่าที่จะทราบเวอร์ชันใหม่หรือดาวน์โหลดอีกครั้งจาก dzherel เดียวกัน (อาจเป็นเพราะไดรฟ์ในเซสชั่นหน้าการจับภาพไฟล์ ELF ไม่สิ้นสุดและไม่สามารถป้อนไวน์ได้อย่างถูกต้อง ).

คุณต้องการที่จะช่วย?

หากคุณมีข้อมูลเพิ่มเติมเกี่ยวกับการขยายไฟล์ ELF เรายินดีที่จะแบ่งปันกับ coristuvachi ของไซต์ของเรา รีบกรอกแบบฟอร์มและส่งข้อมูลของคุณเกี่ยวกับไฟล์ ELF

© 2022 androidas.ru - ทั้งหมดเกี่ยวกับ Android