税金情報 (DWARF) を含む ELF ファイルを手動で作成します (ARM マイクロコントローラーの場合)。 フォーマット ELF および PE EXE Elf ファイル拡張子

ゴロヴナ / 追加機能

優れた TOC と多くのコンテンツを含むバージョン: http://www.cirosantilli.com/elf-hello-world (ここで 30k 文字の交換を押してください)

基準

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 が勝つ最小の例を分析させてください。

Section .data hello_world db "Hello world!", 10 hello_world_len eq $ - hello_world section .text

ヘルプ用にコンパイル

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

  • NASM 2.10.09
  • Binutils バージョン 2.24 (ld を置き換えます)
  • Ubuntu 14.04

2に等しい分析を単純化できるように、Cプログラムに勝るものはありません:-)

16個のバイナリ表現

hd hello_world.o hd hello_world.out

グローバル ファイル構造

ELF ファイルには次の部分が含まれます。

  • ELF ヘッダー。 分割されたヘッダーテーブルの位置とプログラムのヘッダーテーブルを示します。

    部門の見出しの表 (アイコン ファイルの言語で必要)。 スキンは、e_shnum セクションの見出しである場合があります。

    N分割 N<= e_shnum (необязательно в исполняемом файле)

    プログラム ヘッダーのテーブル (選択するファイルのみ)。 それらのいくつかは e_phnum プログラム ヘッダーである可能性があり、それらのいくつかはセグメントの場所を示します。

    N セグメント、s N<= e_phnum (необязательно в исполняемом файле)

これらの部分の順序は固定されていません: 1 つの固定リッチ - ファイルの最初にある可能性がある ELF ヘッダー: グローバル ドキュメントは次のようです:

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": ELF マジックナンバー

    0 4: EI_CLASS = 02 = ELFCLASS64: 64 ビット elf

    0 5: EI_DATA = 01 = ELFDATA2LSB: グランド キント データ

    0 6: EI_VERSION = 01: フォーマット バージョン

    0 7: EI_OSABI (2003 年のみ) = 00 = ELFOSABI_NONE: 拡張なし。

    08: EI_PAD = 8x 00: 予約バイト。 有罪だが0に設定。

    1 0: e_type = 01 00 = 1 (ビッグエンディアン) = ET_REl: 移動するフォーマット

    ファイルには ET_EXEC の 02 00 があります。

    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 があります。 TODO: 何をインストールできますか? ここで、カーネルは中間値なしで 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 TODO。 アーチ専用。

    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_shentsize および e_shnum = 40 00 07 00: この数のレコードを分割するための見出しサイズ

ヘッダー テーブル

Elf64_Shdr 構造体の配列。

この部門に関するメタデータを取得する革の記録。

ELF ヘッダーの e_shoff は、スパムの位置 0x40 を示します。

e_shentsize と e_shnum ELF ヘッダーから、ウェッジ スキン 0x40 の 7 つのエントリがあるようです。

ここでも、テーブルは 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:

There are 7 section headers, starting at offset 0x40: Section Headers: Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .data PROGBITS 0000000000000000 00000200 000000000000000d 0000000000000000 WA 0 0 4 [ 2] .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 0 1 [6] .rela.text RELA 0000000000000000 00000370 000000000000018 0000000000000018 4 2 4 I (情報)、L (リンク順序)、G (グループ)、T (TLS)、E (除外)、x (不明) O (追加) OS 処理が必要) o (OS 固有)、p (プロセッサ固有)

struct 、スキン表記:

Typedef struct ( 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: ELF で SHT_NULL を解析する際のいたずらは何ですか? ?

.データ分割

データ - セクション 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 を設定します。

    データ - 同じ値である可能性があるため、ディストリビューションの名前の 1 つ 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: この仮想アドレスでは、1 日の終わりにプレースメントが配置されるため、プレースメントはありません。

    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

    したがって、sh_offset 200 から始まる 0xD バイトを取得します。mi bachimo:

    00000200 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 |こんにちは世界!.. |

    あはは! Otzhe、私たちの列「Hello world!」 私たちが言ったように、データの分布を知っています, tse NASM.

    hd を終了するとすぐに、次のように表示できます。

    Readelf-x.data hello_world.o

    どちらを入力しますか:

    セクション「.data」の 16 進ダンプ: 0x00000000 48656c6c 6f20776f 726c6421 0a Hello world!.

    NASM は、魔法のようにその前に配置される部門の電力日を設定します: データ: http://www.nasm.us/doc/nasmdoc7.html#section-7.9.2

    また、間違った選択が行われたことに注意してください。.rodata に行を配置して、読み取り専用のものを置き換え、OS のさらなる最適化を可能にする優れた C コンパイラです。

    a0 8: sh_link and sh_info = 8x 0: 配布の種類にとどまらない。 http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html#special_sections

    b0 0: sh_addralign = 04 = TODO: 変更する必要がありますか? sh_addr のターゲットと、sh_addr の途中のシンボルのターゲットはありますか?

    b0 8: sh_entsize = 00 = テーブルを平均しないように分割します。 やっちょ! = 0。これは、固定サイズのレコードのテーブルが分散されたことを意味します。 どのファイルに readelf リンクが含まれている必要がありますが、.symtab および .rela.text ディストリビューションの余地があります。

.テキスト分割

さて、手で1つの部門を作成した場合、卒業生と卒業生に他の部門の-Sを与えます。

Name Type Address Offset Size EntSize Flags Link Info Align [ 2 ] .text PROGBITS 0000000000000000 00000210 000000000000020 000

書き込み可能でない場合は、テキストが書き込まれます。そのため、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

hd で b8 01 00 00 を grep するにはどうすればよいでしょうか。このディストリビューションにあるように、00000210 でしか確認できません。 Іrozmir dorivnyuє 27、これも確認されています。 だからこそ、正しい分割について話すことができます。

これは正しいコードのように見えます: write の後に exit が続きます。

Naytsіkavіsha部分 - 行a、これは奪うことです:

モバブ $0x0,%rsi

行アドレスをシステム wiki に渡します。 デンマークでは、時間 0x0 は単純に zapovnyuvachem です。 電話の後、ヨガの変更があります。

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

この変更は、rela.text 配布データを介して可能です。

SHT_STRTAB

sh_type == SHT_STRTAB のパーティションは行テーブルと呼ばれます。

そのため、暴力団員の列の名前が分割された場合、暴力団員は他の部門に分割されました。 セクション「ビクトリア朝」には次のように書かれています。

  • 何列の悪臭 vikoristovuyut
  • 行全体のテーブルのインデックスは何ですか、行はどこから始まりますか

したがって、たとえば、行テーブルを作成して、復讐する方法は次のとおりです。 TODO: \0 で始めるには何が必要ですか?

データ: \0 a b c \0 d e f \0 インデックス: 0 1 2 3 4 5 6 7 8

І yakscho іnshiyrazdіl は、tsgorazdіlu (文字 d) のインデックス 5 に示すために、非難の行を勝ち取りたいと考えています。

行テーブルを表示:

  • .shstrtab
  • .strtab

.shstrtab

パーティション タイプ: sh_type == SHT_STRTAB 。

Zagalne im'ya: タイトル行が分割されました。

私はshared.shstrtabが予約されています。 標準には次のものがあります。

Tsey は、分割の名前を復讐するために分割します。

どのブランチに ELF ヘッダー自体の e_shstrnd フィールドが必要か。

この部門の行インデックスは、行を示す部門ヘッダーの sh_name フィールドによって指定されます。

どのブランチで SHF_ALLOC が有効になっていないかは、勝ったプログラムでは機能しません。

Readelf-x.shstrtab hello_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 は、記号の種類の deak が省略され、記号が指定されている高レベルの表現です。 より詳細な分析を参考にすることができます。

Readelf -s hello_world.o

どれですか:

シンボルテーブル ".symtab"には7つのエントリが含まれています:num:num:valueサイズタイプバインドVIS NDX名0:000000000000000000 0 NOTYPEローカルデフォルトUND 1:000000000000000000 0ファイルローカルデフォルトABS hellow_world.asm SECTION LOCAL DEFAULT 2 4: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 hello_world 5: 000000000000000d 0 NOTYPE LOCAL DEFAULT ABS hello_world_len 6: 00000000000

バイナリ テーブル形式は、http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html に記載されています。

Readelf-x.symtab hello_world.o

あなたは何を与えますか:

セクション「.symtab」の 16 進ダンプ: 0x00000000 00000000 00000000 00000000 00000000 ................ 0x00000010 00000000 00000000 01000 ... . 0x00000020 00000000 000000 00000000 000000 000000 .................... 0x00000050 00000000 00000000 00000000 00000000 .......... .... 0x00000060 110000000000000100 00000000 000 ...... 0x0000000000000000000000 ................ 0x00000080 0D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000..... 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;

ディビジョンのテーブルと同様に、最初のエントリは慈善的であり、固定の空白の値によって与えられます。

ELF64_R_TYPE == STT_FILE 5 月 1 日を記録します。 ELF64_R_TYPE は st_info の途中にある 3 つです。

バイト分析:

    10 8: st_name = 01000000 = 文字 1 st.strtab 、攻撃的な \0 まであり、hello_world.asm を奪います

    情報ファイルのこのフラグメントは、セグメントのセグメントの移動方法を決定するリンカーに分割できます。

    10 12: st_info = 04

    ビット 0 ~ 3 = ELF64_R_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

このような要素は 2 つあります。1 つは .data を指し、もう 1 つは .text (1 と 2 に分割されたインデックス) を指します。

番号: 値 サイズ タイプ Bind Vis Ndx Name 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 3: 0000000000000000 0 SECTION LOCAL DEFAULT 2

TODO、メタって何?

STT_NOTYPE

次に、最も重要な文字を入力します。

Num: 値 サイズ Type Bind Vis Ndx Name 4: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 hello_world 5: 000000000000000d 0 NOTYPE LOCAL DEFAULT ABS hello_world_len 00 0

hello_world は distribution.data (インデックス 1) にあります。 値 値 0: 分布の最初のバイトを確認します。

GLOBAL の可視性を、私たちが書いたものに設定し始めます。

global_start

NASMで。 必須ではありません。シャードはエントリ ポイントと見なすことができます。 ビュー C で、プロモーション ラベル NASM є ローカル用。

hello_world_len は、特別な st_shndx == SHN_ABS == 0xF1FF を参照します。

0xF1FF は、他のブランチをスーパーチートしないように選択されています。

st_value == 0xD == 13 、選択のためにそこに保存した値のいずれかです: 行の後ろ Hello World! .

Tse は、動きが値と一致していないことを意味します。これは定数です。

ELF をサポートできるアセンブラーをどのように動作させるかは、大きな最適化ではありません。

Yakby mi vikoristovuvali アドレス hello_world_len がどこにいても、アセンブラーは bi pomiti yogo yak SHN_ABS を変更せず、リンカーはさらに再配置されます。

アイコン化されたファイルの SHT_SYMTAB

NASM プロモーションの場合、アイコン化されたファイルに .symtab を配置します。

nagodzhennyaの場合は、Tse vikoristovuєtsyaが少なくなります。 シンボルがなければ、私たちは完全に盲目になり、すべてを再設計する可能性があります。

ヘルプ objcopy を表示して、ファイルをダウンロードすると、すべて同じように機能します。 このようなアイコン化されたファイルは、分割アイコン化ファイルと呼ばれます。

.strtab

テーブル シンボルの行を削除します。

そのディストリビューションは sh_type == SHT_STRTAB です。

sh_link == 5 ディストリビューションに登場。

Readelf-x.strtab hello_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.text

配布タイプ: sh_type == SHT_RELA .

頭の名前: 移転を分割します。

Rela.text ヒットの残りのファイルが見つかった場合、アドレスが変更されるため、割り当てられている再配置のデータに返信します。 テキスト領域のバイト上のtsevkazuє、yakun buti zmthnthinuni、zv'yazuvanneaがvolvuvavauth votidbuvauth noiz zaznachennymiїїї

メインのワインでは、オブジェクトのテキストを書き直して、0x0 zapovnyuvacha のアドレスを復讐します。

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

実際にハッキングされたコードから残りの 0x6000d8 を削除します。

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

Sh_info = 6 が指定されました。

readelf -r hello_world.o はい:

オフセット 0x3b0 オフセット 1 ポイントの再配置セクション「.rela.text」: オフセット情報タイプ 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 struct ( 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 アドレスがディストリビューションに追加され、de pracyuє の再配置が行われます。

    この移動操作は 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 は、スキンの 0x40 から始まり 0x38 バイトまでの 2 つのプログラム ヘッダーがあることを示しています。

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 00 20 00 00 00 00 00 |………………| typedef struct ( 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: TODO。 tse は、あなたがなぞなぞに興味を持つことを意味すると思います。 他のタイプは obov'yazkovo buti の場合もありますが、obov'yazkovo buti の場合はありません。
  • 40 4: p_flags = 05 00 00 00 = 読み取りと読み取りは許可されています。TODO は書き込まないでください。
  • 40 8: p_offset = 8x 00 TODO: 何? セグメントの穂軸にある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_vaddrrをコピーするだけのようです
  • 60 0: p_filesz = d7 00 00 00 00 00 00 00: TODO vs p_memsz
  • 60 8: p_memsz = d7 00 00 00 00 00 00 00: TODO
  • 70 0: p_align = 00 00 20 00 00 00 00 00: 0 または 1 はアライメントが不要であることを意味します TODO、それはどういう意味ですか? 他のフィールドとは違う方法で世界を超えて

もう一つも同様です。

セクションからセグメントへのマッピング:

readelf に教えてもらいましょう:

  • 0 セグメント.テキスト。 ああ、そのVіnが勝ち、書き込み可能ではありません。
  • 1 セグメントのデータ。
標準拡張ツールは、プログラムを ELF (Executable and Linkable Format) ファイルにコンパイルします。これには、税情報が含まれる場合があります。 フォーマット仕様を読むことができます。 反対に、スキン アーキテクチャには独自の特性があります。たとえば、ARM の特性です。 簡単にフォーマットを見てみましょう。
ELF 形式への変換ファイルは、次の部分で構成されます。
1. ヘッダー (ELF ヘッダー)
ファイルとその主な特性に関する一般情報を取得します。
2. プログラムヘッダテーブル
スキン セクションを書き込むメモリの領域としてキャプチャを示す、メモリのファイル セグメントに関連するセクションの Tse テーブル。
3. セクション
ファイルからすべての情報を削除するセクション (プログラム、データ、税金情報など)
スキン セクションには、タイプ、名前、およびその他のパラメータがあります。 「.text」セクションでコードを選択し、「.symtab」 - プログラムのシンボル (ファイル、手順、および変更の名前) のテーブル、「.strtab」 - 行のテーブル、プレフィックス「.debug_」 - カスタマイズ情報など。 .d. さらに、ファイルにはインデックス 0 の空のセクションがあります。
4. セクションヘッダーテーブル
これは、セクション ヘッダーの配列を置き換えるテーブルです。
レポートの形式は、ELF Creation によって審査されます。

ドワーフ ルックアウト

DWARF は、カスタマイズ可能な情報の標準化形式です。 規格は公式サイトからダウンロードできます。 この形式については、素晴らしい概要があります: Introduction to the DWARF Debugging Format (Michael J. Eager)。
さらに税務情報が必要ですか? Vaughn では次のことが可能です。
  • 物理アドレスではなく、関数名の出力コードのファイルの行番号にブレークポイントをインストールします
  • 関数のパラメータだけでなく、グローバルおよびローカルの変更の値を表示および変更する
  • ウィキのスタックを表示する (バックトレース)
  • プログラム pokrokovo を 1 つのアセンブラー命令ではなく、出力コードの行に変換する
この情報は、ツリー状の構造から収集されます。 木の皮膚 vuzol は、父親になることができ、母親の母親になることができ、DIE (Debugging Information Entry) と呼ばれます。 スキン vuzol には、vuzol を説明する独自のタグ (タイプ) と属性 (パワー) のリストがあります。 属性は、たとえば、他の大学に贈ったり送ったりするなど、価値のあるすべてのものに復讐することができます。 また、木のポーズをとっているという情報もある。
ノードは、データを記述するノードとコードを記述するノードの 2 つの主なタイプに分けられます。
データを説明する Woozley:
  1. ティピーデータ:
    • データの基本型 (DW_TAG_base_type 型の wuzole)。たとえば、int C 型。
    • データのウェアハウス タイプ (シャワー)
    • マシビ
    • 構造体、クラス、関連、インターフェース
  2. データ オブジェクト:
    • 定数
    • 関数パラメータ
    • 変化する
    • や。。など。
データ オブジェクトのスキンには、アドレスがどのように計算され、データが既知であるかを示す DW_AT_location 属性がある場合があります。 たとえば、母親を固定アドレスに変更したり、レジスタまたはスタックに変更したり、クラスまたはオブジェクトのメンバーになることができます。 Tsya アドレスはスムーズにカウントできるため、標準はいわゆるロケーション表現を転送し、特別な内部スティック マシン内の一連のオペレーターを復讐できるようにします。
コードを説明する Woozley:
  1. プロシージャ (関数) – DW_TAG_subprogram タグを持つノード。 ノードオンボードは、変更の説明 (関数内のパラメーターおよび関数内のローカル変更) を置き換えることができます。
  2. コンパイルユニット。 プログラムの情報を取得し、お父さんと一緒に問題を解決してください。
上記の情報は、「.debug_info」および「.debug_abbrev」セクションにあります。
より詳しい情報:
  • 行番号に関する情報 (セクション「.debug_line」)
  • マクロに関する情報 (セクション「.debug_macinfo」)
  • 呼び出しフレーム情報 (セクション ".debug_frame")

エルフの作成

elfutils パッケージの libelf ライブラリのヘルプを使用して、EFL 形式でファイルを作成します。 Merezha には libelf に関する優れた記事があります - LibELF by Example (残念ながら、LibELF でのファイルの作成については簡単にしか説明されていません) とドキュメントがあります。
ファイルの作成は、いくつかの段階で構成されています。
  1. 初期化権限
  2. ファイル ヘッダー (ELF ヘッダー) の作成
  3. プログラム ヘッダー テーブルの作成
  4. セクション作成
  5. ファイルに書き込む
レポートの段階を見てみましょう
初期化権限
場合によっては、elf_version(EV_CURRENT) 関数を呼び出して結果を反転する必要があります。 YakshtovіndіvnyuєEV_NONE - それ以上の仕事は不可能であることをvinikla許してください。 次に、ディスク上に必要なファイルを作成し、ハンドルを取得して elf_begin 関数に渡す必要があります。
Elf*elf_begin(int fd, Elf_Cmd cmd, Elf*elf)
  • fd - ファイル記述子
  • cmd - モード (情報の読み取り用の ELF_C_READ、書き込み用の ELF_C_WRITE または読み取り/書き込み用の ELF_C_RDWR)、vin は開かれているファイルのモードによるものです (私たちのモードでは ELF_C_WRITE)
  • elf - アーカイブ ファイル (.a) を持つロボットにのみ必要です。ピッカーは 0 を渡す必要があります
この関数は、すべての libelf 関数で使用される作成の記述子をローテーションします。0 は、恩赦の時点でローテーションされます。
ヘッダー作成
新しいファイル ヘッダーは、elf32_newehdr 関数によって作成されます。
Elf32_Ehdr*elf32_newehdr(elf*elf);
  • 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 - ID のバイト配列。次のようなインデックスを持つ場合があります。
    • 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. ARM アーキテクチャの ELF
  • e_version - ファイルのバージョン。EV_CURRENT に新しい言語をインストールする必要があります。
  • e_entry - エントリ ポイントのアドレスであり、拘束力はありません
  • e_phoff - ファイル内のプログラム ヘッダーの使用、e_shoff - セクション ヘッダーの使用、回復不可
  • e_flags - プラポリ プロセッサに固有で、私たちのアーキテクチャ (Cortex-M3) では、0x05000000 (ABI バージョン 5) に等しく設定する必要があります。
  • e_ehsize、e_phentsize、e_phnum、e_shentsize、e_shnum - スマートではない
  • e_shstrndx - セクション ヘッダーのテーブル行が配置されているセクション番号を非表示にします。 同じセクションの残り物はまだありません。後で整数を入れます。
番組ヘッダー作成
先ほどのとおり、Program Header Table はメモリのファイル セグメントに対するセクションの有効性のテーブルなので、skin セクションをどこに書き込むかを知りたいのです。 ヘッダーは、ヘルプ関数 elf32_newphdr の背後に作成されます。
Elf32_Phdr * elf32_newphdr(エルフ * エルフ, size_t カウント);
  • elf は私たちのハンドルです
  • count - テーブルに作成された要素の数。 (プログラム コードを含む) セクションは 1 つしかないため、count は 1 になります。
プログラムのタイトルにmiltsiまたはkazіvnikがある場合は0にします。
ヘッダー テーブルのスキン要素は、次の構造で記述されます。
typedef struct ( 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 カウント、unsigned int バージョン); type - ここでは ELF_T_ххх 定数です。ELF_T_EHDR と ELF_T_PHDR を展開する必要があります。 count - 必要なタイプの要素の数、バージョン - オプションで 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(Elf_Scn * scn);
  • scn - elf_newscn 関数から取得したセクション インジケータ。
セクションの見出しは次のようになります。
typedef struct ( 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 - セクションのフラグ。これは組み合わせることができ、必要なのは 3 つだけです。
    • 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(Elf_Scn * scn);
  • scn - 新しいセクションのインジケーターを選択的に削除します。
この関数は、恩赦の場合は 0、または Elf_Data 構造の指標は 0 になるため、次のことを覚えておく必要があります。
typedef struct ( void * d_buf; Elf_Type d_type; size_t d_size; off_t d_off; size_t d_align; unsigned 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 struct ( 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 - シンボル タイプとスコープ。 フィールドの値を定義するには、マクロを使用します
    #define 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 - ファイルの SHN_ABS に割り当てられたセクション インデックス、シンボル (セクション index.text)。
    її scn 記述子の後ろのセクション インデックスは、elf_ndxscn ヘルパーに割り当てることができます。
    size_t elf_ndxscn(Elf_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 です。テーブルの行インデックスは、テーブルの穂軸のバイト単位のシフトです。 、最初の行 "name" はインデックス 1、攻撃的な行 "var" はインデックス 6 の場合があります。
インデックス 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \0 名前 \0 変数 \0
ファイルに書き込む
また、そのセクションのヘッダーはすでに形成されているため、ファイルに書き込み、libelf で作業を完了する必要があります。 elf_update 関数の記録:
off_t elf_update(Elf * elf, Elf_Cmd cmd);
  • エルフ - ハンドル
  • cmd - ELF_C_WRITE の書き込みに適したコマンド。
この関数は、恩赦のために -1 回転します。 恩赦のテキストは関数 elf_errmsg(-1) を呼び出すことで削除できるため、恩赦のある行にインジケータを向けることができます。
記述子が渡される elf_end 関数ライブラリで作業を終了します。 先にファイルを閉じるのは多すぎます。
ただし、攻撃的なディストリビューションに追加するため、ファイルの作成はラグーン情報に対して報復しません。

ドワーフの創造

ドキュメント付きの任意の pdf ファイルに含まれる、追加のライブラリに関する同様の情報をコンパイルします (libdwarf2p.1.pdf - A Producer Library Interface to 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 flags, Dwarf_Callback_Func_c func, Dwarf_Handler errhand, Dwarf_Ptr errarg, void *user_data, Dwarf_Error *error)

  • フラグ - さまざまなパラメーターを定義するための「または」多数の定数の組み合わせ。たとえば、情報のサイズ、バイトのシーケンス (リトル エンディアン、ビッグ エンディアン)、再配置形式、必要な言語 DW_DLC_WRITEおよび DW_DLC_SYMBOLIC_RELOCATIONS
  • func - ELF セクションをカスタム情報で折りたたむときに呼び出されるコールバック関数。 報告部 支店「税務情報欄の作成」
  • errhand - 恩赦を勝ち取ったときに呼び出すかのように、関数のインジケーター。 0を渡すことができます
  • errarg - errhand 関数に渡されるデータ。0 に設定できます。
  • user_data - func 関数に渡されるデータで、0 に設定できます
  • エラー - パードン コード、何を変更するか
Turning function Dwarf_P_Debug - 今後のすべての関数に使用される記述子、または許しの時間の場合は -1。この場合、エラーの許しコードが存在します。
Woozliv の作成 (DIE - デバッグ情報入力)
詳しく説明したように、nalagodzhuvalnaya 情報はツリー状の構造を確立します。 そのツリーの vuzol を作成するには、次のものが必要です。
  • yogo 関数を作成する dwarf_new_die
  • 新しい属性を追加
追加関数 dwarf_new_die 用に wuzol が作成されます。
Dwarf_P_Die dwarf_new_die(Dwarf_P_Debug dbg, Dwarf_Tag new_tag, Dwarf_P_Die 親, Dwarf_P_Die 子, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, Dwarf
  • new_tag – ノード タグ (タイプ) – libdwarf.h ファイルにある DW_TAG_xxxx 定数
  • 親、子、left_sibling、right_sibling - 良い父親、餌、ライオン、右の sus_di vuzla。 すべてのパラメータを指定する必要はありません。1 つのパラメータを指定して、他のパラメータの代わりに 0 を設定すれば十分です。
  • エラー - їїviniknіnіのときに許しのコードを修正してください
この関数は、成功時にパードンまたはノード記述子 Dwarf_P_Die に対して DW_DLV_BADADDR を有効にします。
大学の属性の作成
ノード アトリビュートの作成の場合、値は dwarf_add_AT_хххх 関数のホームです。 必要な属性を作成するためにどの関数が必要かを判断するのが難しい場合があるため、ライブラリの出力コードを何度か掘り下げていました。 機能を伴う行為はここで説明され、以下の行為は関連する部門で説明されます。 すべての悪臭は、属性が追加されるノードの記述子である ownerdie パラメーターを受け入れ、エラー パラメーターでパードン コードを返します。
dwarf_add_AT_name 関数は、「im'ya」属性 (DW_AT_name) をサイトに追加します。 ほとんどのノードには名前 (プロシージャー、変更、定数など) があり、一部の名前には名前 (コンパイル ユニットなど) がある場合とない場合があります。
Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die ownerdie, char *name, Dwarf_Error *error)
  • name - 属性の値 (ノードの名前)

関数 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 ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_Error *error)
  • dbg – ライブラリの初期化中に削除される Dwarf_P_Debug 記述子
  • attr - 値が設定される属性 - libdwarf.h ファイルにある DW_AT_xxxx 定数
  • value - 属性値
パードンまたは属性記述子が正常に完了したときに、DW_DLV_BADADDR をオンにします。
コンパイルユニット
ツリーがルートを持つことができるかどうか-プログラムに関する情報を見つけることができるように、コンパイルは1つだけです(たとえば、ヘッドファイルの名前、movプログラミング、何が書かれているか、コンパイラの名前、シンボルの感度など) (変更、機能) 機能、ヘッド レジスタ プログラム、メール アドレスなど)。 原則として、毎日の属性は obov'yazkovimi です。 たとえば、メイン ファイルとコンパイラに関する情報を作成してみましょう。
ヘッドファイルに関する情報
head ファイルに関する情報を保存するには、属性「name」(DW_AT_name) を選択し、「ノード属性の作成」セクションに示すように、dwarf_add_AT_name 関数を無効にします。
コンパイラに関する情報
勝利関数 dwarf_add_AT_producer:
Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die ownerdie, char *producer_string, Dwarf_Error *error)
  • producer_string - テキスト情報の行
パードンまたは属性記述子が正常に完了したときに DW_DLV_BADADDR を設定します。
共通情報エントリを作成しました
関数(サブプログラム)を呼び出すときの呼び出しと、その番地のアドレスのパラメータがスタックに置かれる(コンパイラが独自の方法で動作できる場合)、これは呼び出しフレームと呼ばれます。 コントローラーは、フレームのフォーマットに関する情報を必要とします。これにより、リターン関数のアドレスを正しく割り当て、バックトレース (ストリーミング関数を植え付ける関数コールバック) とこれらの関数のパラメーターを誘導します。 また、スタックに保存されているため、プロセッサのレジスタが呼び出されます。 スタック上のスペースを確保してプロセッサ レジスタを保存するコードは関数プロローグと呼ばれ、スタック レジスタを復元するコードはエピローグと呼ばれます。
この情報は、コンパイラに格納する必要があります。 たとえば、プロローグとエピローグは、まさに穂軸と、たとえば機能に負っているneobov'yazkovoです。 フレームが勝ちました。 プロセッサレジスタは、他のレジスタなどに保存できます。
したがって、所有者はプロセッサレジスタの値を変更する方法を知っている必要があり、手順に入ると悪臭がなくなります。 この情報は Call Frame Information - フレーム形式に関する情報と呼ばれます。 プログラム内のスキン アドレス (コードをクリアするため) には、メモリ内のフレームのアドレス (Canonical Frame Address - CFA) が指定され、プロセッサのレジスタに関する情報は、たとえば次のように指定できます。
  • レジスターはプロシージャーから取得されません
  • register はプロシージャ内でその値を変更しません
  • レジスタは、アドレス CFA+n の後ろのスタックに保存されます
  • レジスタは別のレジスタに保存されます
  • レジスタは、特定のアドレスのメモリに保存されます。これは、明白でない方法でカウントできるためです。
  • や。。など。
一部の情報はコードのスキンアドレスに指定する必要がありますが、.debug_frame セクションにもまとめてまとめてあります。 したがって、アドレスへのアドレスはあまり変わらないため、命令 DW_CFA_хххх がエンコードされているのを見て、変更のみが行われます。 1 つの変更に対するスキンの指示。たとえば、次のとおりです。
  • DW_CFA_set_loc - プログラムの現在のアドレスを指す
  • DW_CFA_advance_loc - 一連のバイトのインジケータを渡す
  • DW_CFA_def_cfa - スタック フレームのアドレスを指定します (数値定数)
  • DW_CFA_def_cfa_register - スタック フレームのアドレスを指定します (プロセッサ レジスタから取得)
  • DW_CFA_def_cfa_expression - スタック フレームのアドレスを計算する方法を指定します
  • DW_CFA_same_value - レジスタが変更されていないことを示します
  • DW_CFA_register - 別のレジスタに保存するレジスタを指定します
  • や。。など。
.debug_frame セクション要素は、共通情報エントリ (CIE) とフレーム記述エントリ (FDE) の 2 つのタイプのエントリです。 CIE は、FDE レコードに共通の情報を報復するために、同じタイプの手順を無礼に説明しているようです。 FDE では、皮膚固有の手順について説明します。 手順に入ると、コントローラーは CIE からの指示をクリックして開始し、次に FDE からの指示をクリックします。
私のコンパイラは、sp(r13) レジスタに CFA を持つプロシージャを作成します。 すべての手順について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 配列の長さ
関数は、「FDE プロシージャの作成」ブランチから見ることができるスキン プロシージャの FDE 作成時間に変更できる、または CIE 記述子を制限するときに DW_DLV_NOCOUNT をローテーションします。
データ型の作成
その前に、その変更の手順を作成するために、データの種類に対応する結び目を後頭部に作成する必要があります。 データの型は非個人的ですが、悪臭は基本型 (平方 int の基本型、次に double) に基づいており、他の型は基本型に基づいています。
ベースタイプ - wuzolіzタグDW_TAG_base_type。 新しいものは buti 属性を持つことができます:
  • 「イムヤ」 (DW_AT_name)
  • "encoding" (DW_AT_encoding) - データ自体が特定の基本型をどのように記述するかを意味します (たとえば、DW_ATE_boolean - 論理、DW_ATE_float - 浮動小数点、DW_ATE_signed - 符号付きセル、DW_ATE_unsigned - 符号なしセルなど)。
  • 「サイズ」 (DW_AT_byte_size - バイトのサイズまたは DW_AT_bit_size - ビットのサイズ)
また、高等教育機関は他のネオボフヤズコビ属性に復讐することができます。
たとえば、32 ビットの繊毛記号の基本型 int を作成するには、DW_TAG_base_type タグを使用して vuzel を作成し、その属性を DW_AT_name - int、DW_AT_encoding - DW_ATE_signed、DW_AT_byte_size - 4 に設定する必要があります。
基本タイプを作成したら、その中に類似のものを作成できます。 そのようなノードは、DW_AT_type 属性を担当し、基本タイプを送信します。 たとえば、int へのポインター - DW_TAG_pointer_type タグを持つ vuzol は、「int」型の以前の作成で設定された DW_AT_type 属性の復讐の罪を犯しています。
リクエストから別のノードへの属性は、dwarf_add_AT_reference 関数によって作成されます。
Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error *error)
  • attr - 属性、時には DW_AT_type
  • otherdie - タイプに対するノードの記述子で、どちらが要求されるか
手続き集
手続きの作成には、税情報の1種類である「行番号情報」の説明が必要です。 これは、スキン マシン命令を出力コードの単一行に設定し、プログラムの行後のカスタマイズを可能にするのに役立ちます。 この情報は、.debug_line セクションから収集されます。 スペースが十分に小さければ、マトリックスの外観から節約されます。そのような列を持つスキン命令の 1 つの行です。
  • 終了コード付きのファイル名
  • どのファイルの行番号
  • ファイル列番号
  • オペレーターchiの穂軸によるオペレーターのブロックへのchiєі指示
  • や。。など。
そのような行列はさらに大きくなるので、її を絞る必要があります。 まず、複製され、表示され、別の方法で行自体が保存されるのではなく、変更される行のみが保存されます。 これらの変更は端末マシンのコマンドのように見え、情報自体はプログラムによって既に考慮されており、あたかも自動マシンによって「獲得」されたかのようです。 プログラムのコマンドは、たとえば次のようになります。 DW_LNS_advance_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 *error)
  • name - ファイルの名前
  • 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 の 3 つの関数があります。
手順の課税情報の作成は、ステージの最後に示されます。
  • セクションの手順記号に作成されます。
  • 属性を持つプロシージャ ノードの作成
  • FDE手順の作成
  • プロシージャーでのパラメーターの設定
  • 行番号に関する情報の収集
手続き記号の作成
プロシージャ シンボルは、「Section.symtab」セクションで説明されているように作成されます。 それらの場合、プロシージャのシンボルは、これらのプロシージャの入力コードを変更するファイルのシンボルとインターリーブされます。 最初にファイルにシンボルを作成し、次に手順を作成します。 誰とファイルがより正確になり、そのような手順がストリーミングファイルから再購入された場合、ファイルを再度作成する必要はありません。
属性を持つプロシージャ ノードの作成
一方、追加機能 dwarf_new_die (div. 部門「Wuzley の作成」) のノードを作成し、DW_TAG_subprogram タグとして指定し、親としてコンパイル ユニット (グローバル プロシージャ) または DIE (これはローカルです)。 属性を作成しましょう:
  • プロシージャ名 (function 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 ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *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 に命令を追加する
dwarf_new_fde 関数を使用して新しい FDE を作成できます。
Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error *エラー)
関数は、新しい FDE ハンドルを DW_DLV_BADADDR に変更します。
dwarf_add_frame_fde を使用して、新しい 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 - プロシージャ DIE (div. 属性を持つプロシージャ ノードを作成)
  • cie - CIE 記述子 (共通情報エントリ部)
  • 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 *error)
  • op - 命令コード (DW_CFA_хххх)
  • val1、val2 - 命令パラメータ (スキン命令では異なる、div. Standard、セクション 6.4.2 Call Frame Instructions)
dwarf_fde_cfa_offset 関数は、DW_CFA_offset 命令を追加します。
Dwarf_P_Fde dwarf_fde_cfa_offset(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed オフセット, Dwarf_Error *error)
  • fde - 作成された FDE へのハンドル
  • reg - フレームに書き込まれるレジスタ
  • offset - フレームのオフセット (バイト単位ではなく、フレーム要素、div。共通情報エントリ、data_align)
たとえば、コンパイラは、スタック フレームのようなプロロースのレジスタ lr (r14) を保存するプロシージャを作成します。 Насамперед потрібно додати інструкцію DW_CFA_advance_loc з першим параметром, рівним 1, що означає просування регістра pc на 2 байти (див. Створення Common Information Entry, code_align), потім додати DW_CFA_def_cfa_offset з параметром 4 (завдання зміщення даних у ф функцію dwarf_fde_cfa_offset з параметром reg=14オフセット = 1 は、レジスタ r14 が CFA の -4 バイトのオフセットでフレームに書き込まれることを意味します。
プロシージャ パラメータの作成
プロシージャのパラメータの作成は、最も重要な変更である div の作成と似ています。 「変化と定数の創造」
行番号情報の作成
この情報の作成は次のとおりです。
  • 手順の最初に、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 offs, Dwarf_Unsigned symidx, Dwarf_Error *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 - lineno 行のコードの最初の 1 行目の命令 (私は vicorist 1 を開始します)
  • is_basic_block_begin - ステートメントのブロックの最初の 1 行目の命令 (0 で開始する必要があります)
  • is_epilogue_begin - プロシージャのエピローグの最初の最初のインライン命令 (バインドされていない、私は 0 を持っています)
  • is_prologue_end - プロシージャのプロローグで停止する最初のインライン命令 (obv'yazykovo!)
  • isa - 命令セット アーキテクチャ (命令セット アーキテクチャ)。 Obov'yazkovo は、ARM Cortex M3 用に DW_ISA_ARM_thumb を指定するようスレッドを立てました!
  • 差別者。 出力コードの 1 つの位置 (ファイル、行、stompchik) は、さまざまなマシン命令に使用できます。 そのようなとき、そのような命令のセットには、異なるディスクリミネータをインストールする必要があります。 そのような動作はありませんが、0 になる可能性があります
関数は 0 (成功) または DW_DLV_NOCOUNT (許し) を返します。
完了したら、dwarf_lne_end_sequence 関数で手順を終了します。
Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug dbg, Dwarf_Addr アドレス; Dwarf_Error *エラー)
  • address - スレッド化されたマシン命令のアドレス
0 (成功) または DW_DLV_NOCOUNT (許し) を返します。
これで、プロシージャの作成が完了します。
変化と定数の作成
Zagalomzminnіdosiシンプル。 彼らは、データの種類だけでなく、データを知っているメモリの場所(またはプロセッサのレジスタ)であるєіm'yaを持っています。 あたかもグローバルに変化するかのように-父親はOdinitsa Compilationである可能性があり、ローカルである可能性もあります-別の大学です(特に、手順のパラメーターが考慮され、手順自体である可能性があります)。 また、どのファイルの行と列で声の変化があるかを示すこともできます。
最も単純な方法では、変更の値は特定の固定アドレスで知られていますが、スタックまたはレジスターでプロシージャーに入るときに多くの変更が動的に作成され、値のアドレスの計算が正しくない場合があります。些細なこと。 標準には、変更の値がどこにあるかを記述するメカニズム、つまりアドレス式 (場所式) があります。 アドレス viraz - 砦のようなミシンのタイピング命令 (定数 DW_OP_хххх) の価格、実際には、デバッグ、プロシージャ、および算術演算を伴う mov の価格。 私は自分の言葉を振り返ることはできません.
  • DW_OP_addr - 変更アドレスを指定
  • DW_OP_fbreg - ベース レジスタへの変更を指定します (スタック インジケータに名前を付けます)
  • DW_OP_reg0… DW_OP_reg31 - 選択したレジスタによって変更されるものを示します
アドレス virase を作成するには、最初に空の 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 *error)
  • opcode - 操作コード、定数 DW_OP_хххх
  • val1、val2 – 命令パラメータ (div. Standard)

変更可能なアドレスの明示的な設定の場合、転送アドレスの変更は dwarf_add_expr_addr 関数によるものです。
Dwarf_Unsigned dwarf_add_expr_addr(Dwarf_P_Expr expr, Dwarf_Unsigned アドレス, Dwarf_Signed sym_index, Dwarf_Error *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 ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_Error *error)
  • ownerdie - viraz が到達できる vuzol
  • attr - 属性 (時々 DW_AT_location)
  • loc_expr - 以前に作成されたアドレス virase へのハンドル
この関数は、恩赦時に属性記述子または DW_DLV_NOCOUNT をローテーションします。
変更 (およびプロシージャー・パラメーター) および定数 - タグ DW_TAG_variable、DW_TAG_formal_parameter、および DW_TAG_const_type を持つプライマリー・ノードはオプションです。 それらには、次の属性が必要です。
  • 変更/定数名 (function 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.「作成されたデータ型」)
  • address virase (div. vishche) - 変更またはプロシージャ パラメータに必要
  • または定数の値 (属性 DW_AT_const_value、div.「作成されたノード属性」)
課税情報セクションの作成
nalagodzhuvalnoїіnformatsіїのツリーのすべてのノードを作成したら、それを使用してエルフセクションの形成に進むことができます。 次の 2 つの段階があります。
  • dwarf_transform_to_disk_form 関数を連続して呼び出す必要があります。これは、スキン セクションに必要なエルフ セクションを作成するためのコールバック関数を 1 回作成したのと同じです。
  • スキン セクションについては、対応するセクションを書き留める必要があるため、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)(char* name, int size, Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info, Dwarf_Unsigned* sect_name_index, void * user_da,
  • name - elf セクションの名前、作成方法
  • サイズ – セクションサイズ
  • タイプ - セクション タイプ
  • フラグ - セクション エンサイン
  • link - セクション リンク フィールド
  • info - セクション情報フィールド
  • sect_name_index – オプションで、セクション インデックスを再配置でローテーション (バインドなし)
  • user_data - 私のヨガがライブラリ初期化関数に設定されているため、そのまま送信されます
  • エラー - ここでパードン コードを渡すことができます
私たちの機能は次のことを担当しています。
  • 新しいセクションを作成します (関数 elf_newscn、div。セクションの作成)
  • セクション ヘッダーを作成します (関数 elf32_getshdr、同上)。
  • ヨゴを正しく覚える(同上)。 セクション ヘッダー フィールドが関数のパラメーターと一致するため、簡単です。 フィールド sh_addr、sh_offset、sh_entsize は 0 に設定され、sh_addralign は 1 に設定されます
  • 作成されたセクション (関数 elf_ndxscn、div. "Section.symtab") のインデックスをローテーションするか、パードンの場合は -1 (誤ってパードン コードを設定することにより)
  • 関数がオンになっているときに 0 をオンにして、(ビューポート内の) ".rel" セクションをスキップするのも私たちの責任です。
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 *length、Dwarf_Error* エラー)
    • dwarf_section - セクション番号。 n は dwarf_transform_to_disk_form 関数によって返される数値です。
    • elf_section_index - セクション インデックスをローテーションします。ボックスにデータを書き込む必要があります。
    • 長さ - dozhina tsikh danih
    • エラー - ツイートしないでください
    関数はインジケーターを回転させてデータまたは 0 を削除します (その場合、
    折り曲げるセクションがなくなった場合)
  • ストリーミング セクションのデータ ハンドルを作成し (関数 elf_newdata、div. セクションを作成)、保存します (div. 同上)。設定:
    • d_buf - forward 関数から取得したデータのインジケーター
    • 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 アンチウイルスはファイルのウイルスをスキャンするよう求められます。


恩赦が結果のせいになることもある 不適切なソフトウェアのインストール問題に接続できるもの、インストールプロセスのビニールは何ですか。 オペレーティング システムをセットアップできますか ELFファイルを正しいソフトウェアにリンクします、そのような名前に唾を吐きます 「関連ファイル拡張子」.

たまにシンプル Dolphin (エミュレーター) の再インストール Dolphin(エミュレータ)からELFを適切に呼び出すことで問題を解決できます。 他のケースでは、結果としてファイルの関連付けの問題が原因である可能性があります 厄介なソフトウェアプログラミングさらにサポートが必要な場合は、販売店に連絡する必要がある場合があります。


ポラダ: Dolphin の更新プログラム (エミュレーター) を残りのバージョンに試して、残りの更新プログラムがインストールされているかどうかを確認します。


当たり前かもしれませんが、しばしば 途中で、ELF ファイル自体が問題の原因である可能性があります。. 電子メールの添付ファイルを介してファイルを受信した場合、または Web サイトからキャプチャした場合、キャプチャ プロセスが中断されます (たとえば、ライブをオンにするか、その他の理由)。 ファイルが破損している可能性があります. 可能であれば、ELF ファイルの新しいコピーを作成して、もう一度やり直してください。


気をつけて: Poshkodzhenie ファイルは、フロントで後続のブロックを引き起こす可能性があります。または、PC 上のまぐれプログラムである場合でも、ウイルス対策の更新プログラムでコンピューターを最新の状態に保つことがさらに重要です。


ELFファイルと同じように コンピューターのハードウェア セキュリティに関する問題、ファイルを開く必要がある場合があります アプライアンス ドライバーの更新、 pov'yazanihіzcimが所有しています。

何が問題ですか マルチメディアファイルの種類に応じて呼び出します、yakіは、コンピューターの真ん中にあるハードウェアセキュリティの成功したソリューションの形で横になります。たとえば、 サウンドカードまたはビデオカード. たとえば、オーディオ ファイルを開きたい場合、それを開くことができない場合は、 サウンドカードのドライバーを更新する.


ポラダ:そのため、ELF ファイルを開こうとすると、受け入れます。 ご容赦のお知らせ、pov'yazanu z.SYSファイル、問題、ymovіrno、多分buti poshkogenimi または古いデバイス ドライバーに接続されている、変更する必要があるため。 このプロセスは、DriverDoc などのドライバーを更新するためのソフトウェアの助けを借りて容易にすることができます。


小さな子供たちはどのように問題を解決しましたか、まだ ELF ファイルを開く際に問題がありますが、関連している可能性があります。 利用可能なシステム リソースの数. ELF ファイルの一部のバージョンでは、コンピューターのハード ドライブに大量のリソース (メモリ/RAM、列挙の負荷など) が必要になる場合があります。 このような問題は、セキュリティなしで古いコンピュータ ハードウェアを簡単にダウンロードでき、同時に新しいオペレーティング システムをいっぱいにすることができるため、よく発生します。

このような問題は、コンピューターが動作を停止することが重要な場合、オペレーティング システムのシャード (バックグラウンドで実行されるその他のサービス) が原因である可能性があります。 ELF ファイルを読み取るために多くのリソースを節約する. PC 上のすべてのプログラムを終了してみてください。まず、Nintendo Wii Game File を開きます。 コンピュータで利用可能なすべてのリソースを使用したので、ELFファイルを開こうとするのに最適な頭脳が得られます。


ヤクショーウィ vikonali 上記のすべてのクロキ、および ELF ファイルが以前のように表示されない場合は、 所有権の更新. У більшості випадків, навіть при використанні старих версій обладнання, обчислювальна потужність може бути більш ніж достатньою для більшості додатків користувача (якщо ви не виконуєте багато ресурсомісткої роботи процесора, такий як 3D-рендеринг, фінансове/наукове моделювання або інтенсивна мультимедійна робота) . そのような方法で、 完全に不動であるため、コンピューターが必要なメモリを取得できません(しばしば「RAM」、chi 操作メモリと呼ばれる) ファイルのスケジューリング。

ELFファイルに関する問題の解決に役立つことを願っています。 リストからプログラムをダウンロードできる場所がわからない場合は、リンク (プログラムの名前) をクリックしてください。場所、星、必要なプログラムの安全なインストール バージョンのダウンロードに関するレポート情報がわかります。

価格や同様の栄養について具体的にアドバイスできます。

  • ELF 拡張子を持つファイルを開く方法は?
  • ELF ファイルを別の形式に変換するには?
  • ELF 形式の拡張子は何ですか?
  • ELF ファイルを提供できるプログラムは何ですか?

反対側の資料を確認した結果、以前と同様に、提出された食品から十分な証拠を取り除かなかったため、ここで提供された ELF ファイルに関する情報が正しくないことを意味します。 私たち、vikoristovyuchi連絡フォームに連絡して、あなたが知らなかった情報を書いてください.

他に何が問題を引き起こす可能性がありますか?

ELF ファイルを開くことができない理由は他にも考えられます (最も一般的なプログラムだけではありません)。
ペルシェ- ELF ファイルは、このメンテナンス用にインストールされた追補から誤って接続されている (非常識な) 可能性があります。 この時点で、リンクを個別に変更する必要があります。 したがって、編集に必要な ELF ファイルのクマのボタンを右クリックして、オプションをクリックします。 「助けを求めるヴィドクリティ」次に、インストールしたとおりに、リストからプログラムを選択します。 このような問題が発生した場合、ELF ファイルが再び非難されることになります。
別の方法で- 開きたいファイルはそのまま使用できます。 この際、新しいバージョンを知っておくか、同じdzherelから再度ダウンロードした方が良いでしょう(フロントセッションでのドライブのせいか、ELFファイルのキャプチャーが終わらず、wineが正しく入力できませんでした) )。

お手伝いしますか?

ELF ファイルの展開に関する追加情報をお持ちでしたら、喜んで私たちのサイトの colistuvachi と共有させていただきます。 お急ぎのフォームで、ELF ファイルに関する情報をお送りください。

© 2022 androidas.ru - Androidに関するすべて