Class: Msf::Exe::ElfInjector::AArch64

Inherits:
Object
  • Object
show all
Defined in:
lib/msf/core/exe/elf_injector/a_arch64.rb

Overview

Builds an AArch64 trampoline that clones before running the payload.

Metasm 1.0.6 cannot parse all instructions used here as AArch64 assembly text. The shared encoder therefore selects opcodes and populates internal fields that may change in future Metasm releases.

Instance Method Summary collapse

Constructor Details

#initialize(entrypoint:, injected_address:) ⇒ AArch64

Returns a new instance of AArch64.

Parameters:

  • entrypoint (Integer) —

    Original ELF entry point.

  • injected_address (Integer) —

    Virtual address of the injected segment.



16
17
18
19
# File 'lib/msf/core/exe/elf_injector/a_arch64.rb', line 16

def initialize(entrypoint:, injected_address:)
  @entrypoint = entrypoint
  @injected_address = injected_address
end

Instance Method Details

#generate ⇒ String

Returns Encoded AArch64 trampoline.

Returns:

  • (String) —

    Encoded AArch64 trampoline.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/msf/core/exe/elf_injector/a_arch64.rb', line 22

def generate
  save = save_registers
  restore = restore_registers
  clone = [
    Msf::Assembly::AArch64.instruction('mov', rt: 0, i16_5: 17), # mov x0, #0x11 (SIGCHLD)
    Msf::Assembly::AArch64.instruction('mov', rt: 1, i16_5: 0),  # mov x1, #0 (child_stack)
    Msf::Assembly::AArch64.instruction('mov', rt: 2, i16_5: 0),  # mov x2, #0 (parent_tid)
    Msf::Assembly::AArch64.instruction('mov', rt: 3, i16_5: 0),  # mov x3, #0 (child_tid)
    Msf::Assembly::AArch64.instruction('mov', rt: 4, i16_5: 0),  # mov x4, #0 (tls)
    Msf::Assembly::AArch64.instruction('mov', rt: 8, i16_5: 220), # mov x8, #220 (clone)
    Msf::Assembly::AArch64.instruction('svc', i16_5: 0) # svc #0
  ]

  prefix_size = save.bytesize + clone.sum(&:bytesize) + 4
  parent_branch_address = @injected_address + prefix_size + restore.bytesize
  # restore; b entrypoint
  parent = restore + Msf::Assembly::AArch64.branch('b', instruction_address: parent_branch_address, destination: @entrypoint, bits: 26, field: :i26_0)
  child_address = @injected_address + prefix_size + parent.bytesize
  clone_branch_address = @injected_address + save.bytesize + clone.sum(&:bytesize)
  # cbz x0, child
  clone << Msf::Assembly::AArch64.branch('cbz', instruction_address: clone_branch_address, destination: child_address, rt: 0)

  save + clone.join + parent + restore
end