Skip to content

Instantly share code, notes, and snippets.

@rprichard
Last active July 9, 2020 02:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rprichard/048f976eac4f5c1402e4ae55b229ba1c to your computer and use it in GitHub Desktop.
Save rprichard/048f976eac4f5c1402e4ae55b229ba1c to your computer and use it in GitHub Desktop.
AArch64 Bionic unwind through __kernel_rt_sigreturn and either a kill syscall or a segfaulting leaf function (https://android-review.googlesource.com/c/platform/bionic/+/1355684)
/*
$ /x/android-ndk-r21d/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang segv_leaf_unwind.c -funwind-tables -Wl,--export-dynamic -Os
$ adb push a.out /data/local/tmp
./a.out: 1 file pushed, 0 skipped. 49.8 MB/s (119472 bytes in 0.002s)
$ adb shell /data/local/tmp/a.out
0x60e1e2f3a8 [sigsegv_handler]
0x73fcfe58c0 [__kernel_rt_sigreturn]
0x60e1e2f3b8 [crashing_leaf_func]
0x60e1e2f3dc [main]
0x73fba5e858 [__libc_init]
0x0 [(null)]
00000000000013b0 <crashing_leaf_func>:
13b0: f0000028 adrp x8, 8000 <adds.7607>
13b4: f9400d08 ldr x8, [x8, #24]
13b8: b900011f str wzr, [x8]
13bc: d65f03c0 ret
00000058 0000000000000014 0000005c FDE cie=00000000 pc=00000000000013b0..00000000000013c0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000000 0000000000000014 00000000 CIE
Version: 1
Augmentation: "zR"
Code alignment factor: 1
Data alignment factor: -4
Return address column: 30
Augmentation data: 1b
DW_CFA_def_cfa: r31 (sp) ofs 0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
*/
#include <dlfcn.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <unwind.h>
_Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) {
size_t ip = _Unwind_GetIP(ctx);
Dl_info info = { 0 };
dladdr((void*)ip, &info);
fprintf(stderr, "0x%zx [%s]\n", ip, info.dli_sname ?: "(null)");
return _URC_NO_REASON;
}
void sigsegv_handler(int signo) {
_Unwind_Backtrace(frame_handler, NULL);
_Exit(0);
}
int* g_nullptr = NULL;
__attribute__((noinline)) void crashing_leaf_func(void) {
*g_nullptr = 0;
}
int main() {
signal(SIGSEGV, sigsegv_handler);
crashing_leaf_func();
return 0;
}
/*
$ /x/android-ndk-r21d/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang unwind_through_kill.c -funwind-tables -Wl,--export-dynamic
$ adb push a.out /data/local/tmp
./a.out: 1 file pushed, 0 skipped. 49.8 MB/s (119472 bytes in 0.002s)
$ adb shell /data/local/tmp/a.out
0x5ec644b424 [sigusr_handler]
0x77e840d8b0 [__kernel_rt_sigreturn]
0x77e70dafe8 [kill]
0x5ec644b46c [main]
0x77e7089538 [__libc_init]
0x0 [(null)]
*/
#include <dlfcn.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <unwind.h>
_Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) {
size_t ip = _Unwind_GetIP(ctx);
Dl_info info = { 0 };
dladdr((void*)ip, &info);
fprintf(stderr, "0x%zx [%s]\n", ip, info.dli_sname ?: "(null)");
return _URC_NO_REASON;
}
void sigusr_handler(int signo) {
_Unwind_Backtrace(frame_handler, NULL);
}
int main() {
signal(SIGUSR1, sigusr_handler);
kill(getpid(), SIGUSR1);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment