SYSCALL_INLINE в Android - PullRequest
       55

SYSCALL_INLINE в Android

0 голосов
/ 29 мая 2018

Мне нужно использовать syscall внутри Android NDK для предотвращения перехвата функций-оболочек.В Linux есть макросы, такие как SYSCALL_INLINE, которые позволяют использовать syscall без функции-оболочки.Таким образом, макрос напрямую внедряет код сборки syscall в проект.

Я не смог найти подобный макрос в Android NDK.

Возможно, я смогу написать свои собственные функции, подобные этой;https://git.busybox.net/uClibc/tree/libc/sysdeps/linux/arm/syscall.c

Но мне нужны версии одной и той же функции arm, arm_64, x86 и x86_64.

Можете ли вы мне помочь?Как мне найти решение?

1 Ответ

0 голосов
/ 29 мая 2018

Ядро Linux Android все еще использует те же номера системных вызовов и ABI, что и обычный Linux, не так ли?(Итак Как получить доступ к системному вызову из пространства пользователя? ). Таким образом, вы должны иметь возможность использовать обычные методы с номерами вызовов от <asm/unistd.h>.

. Вы можете использовать MUSL.Встроенные функции системного вызова libc в arch/x86_64/syscall_arch.h.Он имеет разные значения для каждого различного числа аргументов, вместо одного большого.


MUSL имеет версии syscall_arch.h для ARM , AArch64, i386 иx86-64 , а также другие поддерживаемые архитектуры.Он лицензируется под разрешительной лицензией MIT , поэтому вы можете просто скопировать эти заголовки.

Например, их версия ARM имеет

static inline long __syscall3(long n, long a, long b, long c)
{
    register long r7 __ASM____R7__ = n;  // macro trickery for not clobbering r7 in thumb mode (where it may be the frame pointer)
    register long r0 __asm__("r0") = a;
    register long r1 __asm__("r1") = b;
    register long r2 __asm__("r2") = c;
    __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2));
 // FIXME: add a "memory" clobber because pointed-to memory can be an input or output
}

К сожалению, этоне совсем безопасно: это не говорит компилятору, что операнды указателя разыменовываются, поэтому он может обработать хранилища в буфере до write() как мертвые хранилища и оптимизировать их!

Этоисправить тривиально: добавьте "memory" clobber.

IDK, если это было частью мотивации glibc по удалению похожих макросов syscall и предоставлению только функции in-syscall ,Или, может быть, они не хотели поощрять людей встраивать системный вызов ABI в свою программу, чтобы теоретически он мог измениться и стать более эффективным в будущем.

Вы бы использовали его как

#include <asm/unistd.h>   // for __NR_write
#include <stdlib.h>       // for ssize_t
#include "syscall_arch.h"

// doesn't set errno or force all error returns to -1
// return values from -1 to -4095 are errors, e.g. -EBADF or -EFAULT

__attribte__((noinline))  // hack for inline asm unsafety
ssize_t my_write(int fd, const void *buf, size_t count) {
    return __syscall3(__NR_write, fd, (long)buf, count);
}

Я поместил это в проводник компилятора Godbolt с достаточным количеством ARM syscall_arch.h, скопированным для создания этой компиляции.В некоторых установках Godbolt ARM gcc отсутствует <asm/unistd.h>, но в gcc5.4 есть работающий.Результат в режиме ARM:

my_write:
    str     r7, [sp, #-4]!
    mov     r7, #4
@ system-calling convention mostly matches function-calling convention
@ so args are in the right registers already
    svc 0
    ldr     r7, [sp], #4
    bx      lr

И, конечно, эта функция может быть встроена в вызывающую программу, поэтому сохранение / восстановление r7 происходит один раз для всей функции.

(редактировать): это было бы небезопасно, если бы он был встроен в вызывающую программу, где можно было бы оптимизировать мертвые хранилища Лучшей опцией грубой силы будет расширение памяти в встроенном операторе asm или дополнительная работа по добавлению фиктивного операнда памяти для системных вызовов, которые читают или записывают память пользовательского пространства (см. at & t asm inlinec ++ проблема ). Или для munmap, чтобы убедиться, что никакие сохраненные на странице (страницах) страницы не проходят мимо нее и происходят после того, как память не отображена.

...