syntax = "proto2";
import "yara.proto";
import "yaml.proto";

package elf;

option (yara.module_options) = {
  name : "elf"
  root_message: "elf.ELF"
  rust_module: "elf"
  cargo_feature: "elf-module"
};

message ELF {
  optional Type type = 1;
  optional Machine machine = 2;
  optional uint64 entry_point = 3;
  optional uint64 sh_offset = 4;
  optional uint32 sh_entry_size = 5;
  optional uint64 ph_offset = 6;
  optional uint32 ph_entry_size = 7;

  optional uint64 number_of_sections = 8;
  optional uint64 number_of_segments = 9;
  optional uint64 symtab_entries = 10;
  optional uint64 dynsym_entries = 11;
  optional uint64 dynamic_section_entries = 12;

  repeated Section sections = 13;
  repeated Segment segments = 14;
  repeated Sym symtab = 15;
  repeated Sym dynsym = 16;
  repeated Dyn dynamic = 17;
}

enum Type {
  option (yara.enum_options).inline = true;
  ET_NONE   = 0x0000;  // no type
  ET_REL    = 0x0001;  // relocatable
  ET_EXEC   = 0x0002;  // executable
  ET_DYN    = 0x0003;  // Shared-Object-File
  ET_CORE   = 0x0004;  // Corefile
  ET_LOPROC = 0xFF00;  // Processor-specific
  ET_HIPROC = 0x00FF;  // Processor-specific
}

enum Machine {
  option (yara.enum_options).inline = true;
  EM_NONE = 0;         // 0x0000 No type
  EM_M32 = 1;          // 0x0001 AT&T WE 32100
  EM_SPARC = 2;        // 0x0002 SPARC
  EM_386 = 3;          // 0x0003 Intel 80386
  EM_68K = 4;          // 0x0004 Motorola 68000
  EM_88K = 5;          // 0x0005 Motorola 88000
  EM_IAMCU = 6;        // 0x0006 Intel MCU
  EM_860 = 7;          // 0x0007 Intel 80860
  EM_MIPS = 8;         // 0x0008 MIPS I Architecture
  EM_S370 = 9;         // 0x0009 IBM S370
  EM_MIPS_RS3_LE = 10; // 0x000A MIPS RS3000 Little-endian
  EM_PPC = 20;         // 0x0014 PowerPC
  EM_PPC64 = 21;       // 0x0015 64-bit PowerPC
  EM_ARM = 40;         // 0x0028 ARM
  EM_X86_64 = 62;      // 0x003E AMD/Intel x86_64
  EM_AARCH64 = 183;    // 0x00B7 64-bit ARM
}

message Section {
  required SectionType type = 1;
  required uint64 flags = 2;
  required uint64 address = 3;
  required uint64 size = 4;
  required uint64 offset = 5;
  optional string name = 6;
}

enum SectionType {
  option (yara.enum_options).inline = true;
  SHT_NULL       = 0;  // Section header table entry unused
  SHT_PROGBITS   = 1;  // Program data
  SHT_SYMTAB     = 2;  // Symbol table
  SHT_STRTAB     = 3;  // String table
  SHT_RELA       = 4;  // Relocation entries with addends
  SHT_HASH       = 5;  // Symbol hash table
  SHT_DYNAMIC    = 6;  // Dynamic linking information
  SHT_NOTE       = 7;  // Notes
  SHT_NOBITS     = 8;  // Program space with no data (bss)
  SHT_REL        = 9;  // Relocation entries, no addends
  SHT_SHLIB      = 10; // Reserved
  SHT_DYNSYM     = 11; // Dynamic linker symbol table
  SHT_INIT_ARRAY = 14; // Array of constructors
  SHT_FINI_ARRAY = 15; // Array of destructors
}

message Segment {
  required SegmentType type = 1;
  required uint32 flags = 2 [(yaml.field).fmt = "flags:SegmentFlags"];
  required uint64 offset = 3;
  required uint64 virtual_address = 4;
  required uint64 physical_address = 5;
  required uint64 file_size = 6;
  required uint64 memory_size = 7;
  required uint64 alignment = 8;
}

enum SegmentType {
  option (yara.enum_options).inline = true;
  PT_NULL         = 0;  // The array element is unused
  PT_LOAD         = 1;  // Loadable segment
  PT_DYNAMIC      = 2;  // Segment contains dynamic linking info
  PT_INTERP       = 3;  // Contains interpreter pathname
  PT_NOTE         = 4;  // Location & size of auxiliary info
  PT_SHLIB        = 5;  // Reserved, unspecified semantics
  PT_PHDR         = 6;  // Location and size of program header table
  PT_TLS          = 7;  // Thread-Local Storage
  PT_GNU_EH_FRAME = 0x6474e550;
  PT_GNU_STACK    = 0x6474e551;
  PT_GNU_RELRO    = 0x6474e552;
  PT_GNU_PROPERTY = 0x6474e553;
}

enum SegmentFlags {
  option (yara.enum_options).inline = true;
  PF_X = 0x1;  // Segment is executable
  PF_W = 0x2;  // Segment is writable
  PF_R = 0x4;  // Segment is readable
}

message Sym {
  optional string name = 1;
  required uint64 value = 2;
  required uint64 size = 3;
  required SymType type = 4;
  required SymBind bind = 5;
  required uint32 shndx = 6;
  required SymVisibility visibility = 7;
}

enum SymType {
  option (yara.enum_options).inline = true;
  STT_NOTYPE  = 0;  // Symbol type is unspecified
  STT_OBJECT  = 1;  // Symbol is a data object
  STT_FUNC    = 2;  // Symbol is a code object
  STT_SECTION = 3;  // Symbol associated with a section
  STT_FILE    = 4;  // Symbol's name is file name
  STT_COMMON  = 5;  // Symbol is a common data object
  STT_TLS     = 6;  // Symbol is thread-local data object
}

enum SymBind {
  option (yara.enum_options).inline = true;
  STB_LOCAL  = 0;  // Local symbol
  STB_GLOBAL = 1;  // Global symbol
  STB_WEAK   = 2;  // Weak symbol
}

enum SymVisibility {
  option (yara.enum_options).inline = true;
  STV_DEFAULT   = 0;  // Visibility by binding
  STV_INTERNAL  = 1;  // Reserved
  STV_HIDDEN    = 2;  // Not visible to other components
  STV_PROTECTED = 3;  // Visible in other but cannot be preempted.
}

message Dyn {
  optional DynType type = 1;
  optional uint64 val = 2;
}

enum DynType {
  option (yara.enum_options).inline = true;
  DT_NULL         = 0;   // End of the dynamic entries
  DT_NEEDED       = 1;   // Name of needed library
  DT_PLTRELSZ     = 2;   // Size in bytes of PLT relocs
  DT_PLTGOT       = 3;   // Processor defined value */
  DT_HASH         = 4;   // Address of symbol hash table
  DT_STRTAB       = 5;   // Address of string table
  DT_SYMTAB       = 6;   // Address of symbol table
  DT_RELA         = 7;   // Address of Rela relocs
  DT_RELASZ       = 8;   // Total size of Rela relocs
  DT_RELAENT      = 9;   // Size of one Rela reloc
  DT_STRSZ        = 10;  // Size of string table
  DT_SYMENT       = 11;  // Size of one symbol table entry
  DT_INIT         = 12;  // Address of init function
  DT_FINI         = 13;  // Address of termination function
  DT_SONAME       = 14;  // Name of shared object
  DT_RPATH        = 15;  // Library search path (deprecated)
  DT_SYMBOLIC     = 16;  // Start symbol search here
  DT_REL          = 17;  // Address of Rel relocs
  DT_RELSZ        = 18;  // Total size of Rel relocs
  DT_RELENT       = 19;  // Size of one Rel reloc
  DT_PLTREL       = 20;  // Type of reloc in PLT
  DT_DEBUG        = 21;  // For debugging; unspecified
  DT_TEXTREL      = 22;  // Reloc might modify .text
  DT_JMPREL       = 23;  // Address of PLT relocs
  DT_BIND_NOW     = 24;  // Process relocations of object
  DT_INIT_ARRAY   = 25;  // Array with addresses of init fct
  DT_FINI_ARRAY   = 26;  // Array with addresses of fini fct
  DT_INIT_ARRAYSZ = 27;  // Size in bytes of DT_INIT_ARRAY
  DT_FINI_ARRAYSZ = 28;  // Size in bytes of DT_FINI_ARRAY
  DT_RUNPATH      = 29;  // Library search path
  DT_FLAGS        = 30;  // Flags for the object being loaded
  DT_ENCODING     = 32;  // Start of encoded range

  DT_LOOS         = 0x6000000d;
  DT_HIOS         = 0x6ffff000;
  DT_VALRNGLO     = 0x6ffffd00;
  DT_VALRNGHI     = 0x6ffffdff;
  DT_ADDRRNGLO    = 0x6ffffe00;
  DT_ADDRRNGHI    = 0x6ffffeff;
  DT_VERSYM       = 0x6ffffff0;
  DT_RELACOUNT    = 0x6ffffff9;
  DT_RELCOUNT     = 0x6ffffffa;
  DT_FLAGS_1      = 0x6ffffffb;
  DT_VERDEF       = 0x6ffffffc;
  DT_VERDEFNUM    = 0x6ffffffd;
  DT_VERNEED      = 0x6ffffffe;
  DT_VERNEEDNUM   = 0x6fffffff;
  DT_LOPROC       = 0x70000000;
  DT_HIPROC       = 0x7fffffff;
}