1

I have implemented packer of x86_64 shared library. Briefly, a loader is injected to a shared library, and the rela.dyn entry is modified such that it points to the address of the loader. Once the loader is triggered, it decrypts the .text section and finally jump to the address of the .text section.

The mechanism works fine for x86_64 shared library. But it failed on aarch64 shared library.

Questions:

  1. Did I miss any steps that specifically for the aarch64 ?
  2. Is there any other ways to pack an aarch64 shared library ?

The result of readelf is provided bellow. libtest.so is the library before packing. While libtest_packed.so is the library after packing.

here is the result of readelf --relocs libtest.so

Relocation section '.rela.dyn' at offset 0x550 contains 7 entries:
000000010df0  000000000403 R_AARCH64_RELATIV                    780
000000010df8  000000000403 R_AARCH64_RELATIV                    738
000000011018  000000000403 R_AARCH64_RELATIV                    11018
000000010fc8  000300000401 R_AARCH64_GLOB_DA 0000000000000000 _ITM_deregisterTMClone + 0
000000010fd0  000400000401 R_AARCH64_GLOB_DA 0000000000000000 __cxa_finalize@GLIBC_2.17 + 0
000000010fd8  000500000401 R_AARCH64_GLOB_DA 0000000000000000 __gmon_start__ + 0
000000010fe0  000700000401 R_AARCH64_GLOB_DA 0000000000000000 _ITM_registerTMCloneTa + 0

the functions corresponding to the first 3 entries are:

0000000000000780 t frame_dummy
0000000000000738 t __do_global_dtors_aux
000000000011018 d __dso_handle

here is the result of readelf --relocs libtest_packed.so

Relocation section '.rela.dyn' at offset 0x550 contains 7 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000010df0  000000000403 R_AARCH64_RELATIV                    11028
000000010df8  000000000403 R_AARCH64_RELATIV                    738
000000011018  000000000403 R_AARCH64_RELATIV                    11018
000000010fc8  000300000401 R_AARCH64_GLOB_DA 0000000000000000 _ITM_deregisterTMClone + 0
000000010fd0  000400000401 R_AARCH64_GLOB_DA 0000000000000000 __cxa_finalize@GLIBC_2.17 + 0
000000010fd8  000500000401 R_AARCH64_GLOB_DA 0000000000000000 __gmon_start__ + 0
000000010fe0  000700000401 R_AARCH64_GLOB_DA 0000000000000000 _ITM_registerTMCloneTa + 0

As you can see, the first entry is overwritten by the address of the loader.

------------ Update ---------

  1. if I xor-ed the .text section, the xor-loader is bypassed
  • I got Illegal instruction (core dumped), since the .text section has not been decrypted by the xor-loader. (confirmed by inspecting the .text section by gdb)
  • I have the loader objdump-ed, the loader is intact.
  1. if I don't xor the .text section, the xor-loader is called and work normally. (But the decryption is wrong, since the .text section has not been xor-ed beforehand).

Since shared library don't have an entry point. I overwrite the frame_dummy pointer such that the program can jump to the .text section, base on this project

https://github.com/0xN3utr0n/Noteme/blob/master/injection.c

The mechanism of my loader is inspired by https://github.com/sebastiencs/Packer_ELF

1
  • it's unclear to me how is this supposed to work. Can you add the x64 version?
    – Igor Skochinsky
    Dec 2, 2021 at 19:13

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.