Запуск исходную библиотеку на Android Л. ошибки: только Position Independent исполняемые (PIE) поддерживаются

? Maksim Dmitriev @ | Original: StackOverFlow
---

Когда я запускаю родной код на Android L ( Nexus 5 ), я получаю сообщение об ошибке .

об ошибках : единственная позиция, независимые исполняемые (PIE) поддерживаются.

Тот же самый код выполняется корректно на мой Samsung Galaxy S3 ( Android 4.3) .

Вот мой Application.mk

APP_PROJECT_PATH := $(call my-dir)/..
APP_ABI := armeabi
NDK_TOOLCHAIN_VERSION := 4.7
APP_PLATFORM := android-9
APP_GNUSTL_FORCE_CPP_FEATURES := exceptions rtti

Однако, когда я заменить APP_PLATFORM := android-9 с APP_PLATFORM := android-16 ( Когда я читал https://www.duosecurity.com/blog/exploit-mitigations-in-android-jelly-bean-4-1, поддержка PIE появился в желе были ( уровень API 16 )) ,этот исполняемый файл прекрасно работает на Android L.

Естьспособ, чтобы составить собственный код, используя APP_PLATFORM := android-9 и запустить его на Android L ?

---

Top 5 ответ

1Maksim Dmitriev @

Я построил два исполняемых файла: один с APP_PLATFORM := android-9 идругие с APP_PLATFORM := android-16 . Чтобы запустить собственный код в Java Мне нужно это :

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
    // Run the file which was created using APP_PLATFORM := android-16
} else {
    // Run the file which was created using APP_PLATFORM := android-9
}
2Simo Kinnunen @

Если вы можете жить только с поддержкой Android 4.1+, просто установите APP_PLATFORM := android-16, и вы будете хорошо идти. За кулисами он устанавливает APP_PIE := true . Ваше двоичный будет сегментации на старых SDK.

Если вы также должны поддерживать более низкие уровни SDK, вам нужно создать два бинарных файлов . Некоторые другие ответы, которые я видел бы рекомендовала сохранить два отдельных источника деревья с различными APP_PLATFORMs, но вам не нужно этого делать. Это можно сделать один вывод Android.mk какпирог ине пирог в двоичном формате.

NDK 10c:

Убедитесь, что PIE отключена по умолчанию, так как позволяет его вручную легче, чем его отключить. PIE не получить включена по умолчанию, если ваш APP_PLATFORM является> = 16 . Убедитесь, что ваш APP_PLATFORM либо не установлен (по умолчанию для Android- 3 ) ​​, ниже, чем Android - 16, или установить APP_PIE := false .

Следующий Android.mk затем создает пирог и не пирог двоичный, но имеет один нюанс (смотрите ниже) :

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# Enable PIE manually. Will get reset on $(CLEAR_VARS). This
# is what enabling PIE translates to behind the scenes.
LOCAL_CFLAGS += -fPIE
LOCAL_LDFLAGS += -fPIE -pie

LOCAL_MODULE := mymod

LOCAL_SRC_FILES := 
    mymod.c

include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)

LOCAL_MODULE := mymod-nopie

LOCAL_SRC_FILES := 
    mymod.c

include $(BUILD_EXECUTABLE)

Затем вы должны добавить какую-то логику, чтобы вызвать правильный двоичный в коде .

К сожалению, это означает, что вы должны скомпилировать исполняемый модуль в два раза, что может быть медленным . Вы также должны указать LOCAL_SRC_FILES и дополнительные библиотеки дважды, что может быть неприятно и трудно отслеживать. Что вы можете сделать, это составить основной исполняемый файл как статическая библиотека, а также построить исполняемые из ничего, но, что статические библиотеки. Статические библиотеки не требуют пирога.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := mymod-common

LOCAL_SRC_FILES := 
  mymod.c

include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)

# Enable PIE manually. Will get reset on $(CLEAR_VARS). This
# is what enabling PIE translates to behind the scenes.
LOCAL_CFLAGS += -fPIE
LOCAL_LDFLAGS += -fPIE -pie

LOCAL_MODULE := mymod

LOCAL_STATIC_LIBRARIES := mymod-common

include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)

LOCAL_MODULE := mymod-nopie

LOCAL_STATIC_LIBRARIES := mymod-common

include $(BUILD_EXECUTABLE)

Это, кажется, работает вполне, хотяопределенное количество шаблонного -прежнему необходима.

NDK 10b:

NDK 10b позволяет PIE по умолчанию и не позволяет отключить его, кроме как с ужасными хаки. Действительно, просто обновить до 10с . Я ухожу мои старые ответ здесь для справки, но я бы не рекомендовал его никому.

LOCAL_PATH := $(call my-dir)

# Forcefully disable PIE globally. This makes it possible to
# build some binaries without PIE by adding the necessary flags
# manually. These will not get reset by $(CLEAR_VARS). PIE is
# force-enabled on NDK 10b so we'll need this even if APP_PIE
# is set to false.
TARGET_PIE := false
NDK_APP_PIE := false

include $(CLEAR_VARS)

# Enable PIE manually. Will get reset on $(CLEAR_VARS). This
# is what enabling PIE translates to behind the scenes.
LOCAL_CFLAGS += -fPIE
LOCAL_LDFLAGS += -fPIE -pie

LOCAL_MODULE := mymod

LOCAL_SRC_FILES := 
    mymod.c

include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)

LOCAL_MODULE := mymod-nopie

LOCAL_SRC_FILES := 
    mymod.c

include $(BUILD_EXECUTABLE)
3Kevin Cernekee @

Проект Chromium выпустила https://chromium.googlesource.com/chromium/src.git/+/master/tools/android/run_pie/run_pie.c, что позволяет PIE исполняемые файлы для запуска на предварительно JB Android релизы . Обратите внимание, что PIE исполняемый требуетсянесколько дополнительных флагов, чтобы сделать эту работу :

CFLAGS += -fvisibility=default -fPIE
LDFLAGS += -rdynamic -fPIE -pie

В моем случае, я отправка ~ 2 Мб двоичных файлов для 3 архитектур и не хотите, чтобы добавить 6 Мб несжатых данных в АПК просто продолжать оказывать поддержку ICS. run_pie Является очень маленькая ( 6-7kB ), так что отвечать всем требованиям.

run_pie Не должны быть построены с пирога флагов, и он не должен быть выполнен на Android 5.0+ ( потому что, конечно, не PIE двоичные файлы запрещены ) . К сожалению, это не может быть собран статически, потому что она должна быть связана с -ldl и NDK только обеспечивает динамическую версию этой библиотеки .

Сторона Java может выглядеть примерно так:

String dir = mContext.getFilesDir().getPath();
String command = dir + "/busybox netstat";
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
    command = dir + "/run_pie " + command;
}

где busybox являетсяPIE исполняемый файл и живет в частном каталог файлов приложения.

Смотрите также: ранние обсуждения этой темы https://code.google.com/p/android-developer-preview/issues/detail?id=888 и http://forum.xda-developers.com/google-nexus- 5 / развитие / FIX- обход пирог - безопасности проверить - t2797731 .