I managed to find address of the sys_call_table by looking into /proc/kallsyms. I have the following code:
void **sys_call_table;
#include <linux/kernel.h>
#include <asm/unistd.h>
void Java_com_example_testlib_LibLoader_test() {
sys_call_table = (void *) 0xc023cd28;
LOGD("backup original sys_open %p", sys_call_table[__NR_open]);
}
The problem is that the code causes Fatal Signal Exeption why trying to get the sys_call_table entry sys_call_table[__NR_open]
I tried to get entry 0, 1, 2, ... as well.
Ok so the answer is like Crhis said "You cannot modify the kernel from a user mode program!"
I compiled it as a LKM and loaded it using insmod command and it worked
PS: I have also found that only LKM modules can read /proc/kallsyms. User space programs are no longer to do so due to a kernel patch in Android 4.1. /proc/sys/kernel/kptr_restrict is introduced to avoid leaking kernel addresses.
So now in order for userspace programs to see the kallsym address, we can either set kptr_restrict to either 0 or 1.
echo 1 > /proc/sys/kernel/kptr_restrict
Info can be found here:
https://blog.duosecurity.com/2012/07/exploit-mitigations-in-android-jelly-bean-4-1/
And here: http://insitusec.blogspot.sg/2013/01/kallsyms-on-android.html
Related
I'm porting android to a display device, and have nearly completed this. The device use the Freescale/NXP i.MX6 Dual Lite Soc. The Android version used is Android 8.0.0, and the build is based on the Board Support Packages from NXP/Freescale (link below).
https://www.nxp.com/support/developer-resources/software-development-tools/i.mx-developer-resources/android-os-for-i.mx-applications-processors:IMXANDROID?tab=Design_Tools_Tab
The OS builds fine, and the images (u-boot, boot.img, system.img, vendor.img) resuling from the "make" process works perfercly fine on the device. So my last step is basically to sign the images, and this is where I struggle to get stuff working.
I am following the the guide found here:
https://source.android.com/devices/tech/ota/sign_builds
After completing the steps, I use the now signed images found in the "signed-img.zip" file to flash the device (using the NXP Manufacturing Tool, and not Fast Boot). However, the device now fails to boot the Kernel, giving me an error that the DTB is missing.
Hit any key to stop autoboot: 0
boota mmc0
kernel # 14008000 (8183104)
ramdisk # 15000000 (2036048)
## Booting Android Image at 0x12000000 ...
Kernel load addr 0x14008000 size 7992 KiB
Kernel command line: console=ttymxc0,115200 init=/init video=mxcfb0:dev=ldb video=mxcfb1:off video=mxcfb2:off video=mxcfb3:off vmalloc=128M androidboot.console=ttymxc0 consoleblank=0 ldo_active=on androidboot.hardware=sedevices cma=448M android.selinux=permissive android.dm_verify=disable androidboot.selinux=enforce androidboot.dm_verity=disable androidboot.storage_type=emmc loglevel=8 vt.global_cursor_default=0 buildvariant=userdebug androidboot.serialno=0b2861d4df668b47 androidboot.soc_type=imx6dl androidboot.storage_type=emmc
ERROR: Did not find a cmdline Flattened Device Tree
Could not find a valid device tree
resetting ...
I've narrowed the problem down to the very first step in the guide, where "make dist" is executed in the build directory. This produces a number of ZIP files in the "out/dist" folder, which is processed further in the following steps in the guide. I've tried flashing the device with the images produced in this step (found in the resulting "out/dist/*-img-*.zip" file), and this produces the exact same issue.
So my question is, what does really "make dist" do which cause the DTB to be missing in the "boot.img"? I would've expected it to use the already working "boot.img" found in "out/target/product//". But it instead seems to re-build this image, and in this case not include the DTB. As with so many other aspects of building Android from Source, the workings of "make dist" does not seem to be explained anywhere in the documentation.
I hope anyone with some experience in building Android from source knows something about this, because I seem to be royally stuck.
Just FYI; when I flash the "boot.img" produced after a normal "make", the output after U-boot is as follows:
Hit any key to stop autoboot: 0
boota mmc0
Error: blob decap job completed with errors 0x2000081A
In boota get fastboot lock status error. Set lock status
kernel # 14008000 (8183104)
ramdisk # 15000000 (2036754)
fdt # 14f00000 (40998)
## Booting Android Image at 0x12000000 ...
Kernel load addr 0x14008000 size 7992 KiB
Kernel command line: console=ttymxc0,115200 init=/init video=mxcfb0:dev=ldb video=mxcfb1:off video=mxcfb2:off video=mxcfb3:off vmalloc=128M androidboot.console=ttymxc0 consoleblank=0 ldo_active=on androidboot.hardware=sedevices cma=448M android.selinux=permissive android.dm_verify=disable androidboot.selinux=enforce androidboot.dm_verity=disable androidboot.storage_type=emmc loglevel=8 vt.global_cursor_default=0 buildvariant=userdebug androidboot.serialno=0b2861d4df668b47 androidboot.soc_type=imx6dl androidboot.storage_type=emmc
## Flattened Device Tree blob at 14f00000
Booting using the fdt blob at 0x14f00000
Loading Kernel Image ... OK
Using Device Tree in place at 14f00000, end 14f0d025
switch to ldo_bypass mode!
Starting kernel ...
It seem NXP/Freescale have modified the Build Scripts in their AOSP Board Support Package, and broken the DTB inclusion in the process. It may seem like they where happy when the output from the standard "make" process worked on their Dev Board, and never bothered checking if it was possible to create working signed Release images with it.
The mechanism to include a DTB in the dist package was in place (specifying the location of the DTB in BOARD_KERNEL_DTS), and was also used for their "make otapackage" target. However, that target only generates an unsigned (or signed with dev keys) OTA package, which can not be used with the signing scripts.
In order to make it work as it should, I had to make a small change in the main Makefile which specifies the location of the DTB defined in the BoardConfig.mk. The change was simple enough to make, but the hard part was figuring out where the problem was and how it was intended to work in the first place.
The following patch in "build/make/" fixes the issue, as long as a BoardConfig.mk ONLY specifies one DTB (which at least suits my needs):
diff --git a/core/Makefile b/core/Makefile
index a650565a1..92f3025a9 100644
--- a/core/Makefile
+++ b/core/Makefile
## -621,6 +621,19 ## ifdef INTERNAL_KERNEL_CMDLINE
INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(INTERNAL_KERNEL_CMDLINE)"
endif
+# NOTE! This script has a defect which cause the kernel DTB to be left out when ever 'make dist'
+# is executed. The following addition "fixes" this by adding the first dtb specified in the
+# BoardConfig.mk file. (I would guess in most cases there is never more than one!)
+ifdef dist_goal
+ifndef BOARD_KERNEL_DTS
+ifdef TARGET_BOARD_DTS_CONFIG
+DTS_BOARD=$(word 2, $(subst :, ,$(word 1, $(TARGET_BOARD_DTS_CONFIG))))
+BOARD_KERNEL_DTS="$(KERNEL_OUT)/$(DTS_BOARD)"
+$(info FIXUP: Defining BOARD_KERNEL_DTS:=[$(BOARD_KERNEL_DTS)] for BOOT packaging)
+endif
+endif
+endif
+
INTERNAL_MKBOOTIMG_VERSION_ARGS := \
--os_version $(PLATFORM_VERSION) \
--os_patch_level $(PLATFORM_SECURITY_PATCH)
I am using getline function and compiling using ndk but i am getting error :
'getline' was not declared in this scope
is this error due to limitations of armeabi-v7a or due to glib?How can it be resolved for the same function.
I have already #define _GNU_SOURCE before <stdio.h>
In general, when you encounter such an error, you go to your NDK directory and user either Midnight Commander (Linux) or Far Manager (Windows, Linux+Wine) to search the files (file mask: *.h) for your function, getline in this case. You will get a screenful of search results, and it's up to you to #include the right file.
Once in a while your function will not be found; in this case you search the 'net for a place where you can borrow the source.
Sometimes the function in the code being ported has just no meaning, e.g. if the function reads a line from stdin but the program going to invoke it is not a command-line utility, there is a problem.
Most likely, the source that you port #define-s switches for Linux, Mac (Darwin) and Windows, you have to choose the right configuration to derive the Android configuration from (and probably the Mac one will be the best).
I am trying to read the cycle count register on an ARM cortex-a8 CPU from an android native library on an emulator, emulating the Nexus S.
Here are links regarding the two registers I am trying to read and write:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344b/Bgbcjifb.html
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344b/Bgbjjhaj.html
Here is what I have done:
Started the emulator with a modified goldfish kernel, with the line CONFIG_MODULES=y insterted into the .config file to enable module loading.
Created a module from the following C file:
android_module.c
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE ("GPL");
int init_module(void)
{
/* enable user-mode access to the performance counter*/
asm volatile ("mcr p15, 0, %0, c9, c14, 0\n" : : "r" (1));
/* disable counter overflow interrupts (just in case)*/
asm volatile ("MCR p15, 0, %0, C9, C14, 2\n\t" :: "r"(0x8000000f));
printk (KERN_INFO "User-level access to CCR has been turned on.\n");
return 0;
}
void cleanup_module(void)
{
printk (KERN_INFO "Goodbye Module\n");
}
The library has the following lines that attempt to read the cycle counter:
unsigned int result;
asm volatile ("MRC p15, 0, %0, c9, c13, 0\n\t": "=r" (result)::);
I start the emulator from eclipse with the following command line options:
-kernel /home/developer/AndroidDevelopment/kernel/goldfish/arch/arm/boot/zImage
I push the module into the emulator then:
$adb shell insmod android_module.ko
$dmesg
and the last line of that is:
<6>User-level access to CCR has been turned on.
so I know that the module has been installed.
However when I run the App that uses the library, I get the following message in Logcat and the App terminates.
06-20 19:16:03.860: A/libc(806): Fatal signal 4 (SIGILL) at 0x4e9c31b8 (code=1), thread 826 (Thread-75)
Does anyone know why I am still getting this error? It goes away when I delete the line trying to access the cycle count register, so some how I must still not be allowed to read it even though I think I did everything to allow reading.
I think you are seeing this problem because you have to enable user-mode access for all the cores. Try using on_each_cpu, and see if it works.
A question from https://stackoverflow.com/a/11467040/1442443
my final target is to dump user space stack.
I try to build a cpp file as below to a executable on android platform. Therefore, by calling tryToGetStack(), I can get call stack of my executable in run time.
#include <utils/CallStack.h>
namespace android
{
extern "C" void tryToGetStack()
{
CallStack stack;
stack.update();
stack.dump("");
}
}
and add lib setting to to Android.mak since CallStack.tpp is in libutils
LOCAL_SHARED_LIBRARIES += libutils
but I always get error with message:
error: undefined reference to 'android::CallStack::CallStack()'
error: undefined reference to 'android::CallStack::update(int, int)'
...
It seems the executable resolve the symbols at link time rather than load the .so file in runtime?
Do I missing something or there is some limit in Android build system?
I know it is a simple question, but I really need help...
update1
I try to add the code to another executable. The result is same... Does anyone knows the rule of android build system?
update2
There are some key words in my console "target StaticExecutable: ...", I think is is the answer.
http://en.wikipedia.org/wiki/Static_executable
my final target is to dump user space stack.
after google so many information from internet, I found there are 4 ways:
ptraceļ¼ http://en.wikipedia.org/wiki/Ptrace
It is really hard to use ptrace, and we need to stop the thread before using ptrace to attach
_unwind_backtrace: the way used by CallStack (CallStack class in CallStack.cpp)
example: http://git.stlinux.com/?p=stm/uclibc.git;a=blob;f=libubacktrace/sysdeps/sh/backtrace.c;h=18b91b1bb3fa26344a521927c631553a410fcf56;hb=d6a3d9ece5922a337800a8e2ed4db7e226f9ccb3
It is work with a drawback: if you use it as the thread is processing signal, it would dump signal stack rather than dump thread stack
The same problen: How to get fullstacktrace using _Unwind_Backtrace on SIGSEGV
backtrace: http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
a GNU extension function, not be implemented in Bionic libc used by Android
reference: https://stackoverflow.com/a/8295238/1442443
reference: http://lists.puredata.info/pipermail/pd-list/2012-02/094258.html
a patch to dump user space thread stack: http://www.gossamer-threads.com/lists/linux/kernel/1525096
but only be implemented in X86 architecture... orz
I try to port it to android, no it only shows the first frame of stack since arm does not use frame pointer.
So... 2 is the answer.
However, I wonder if someone can resolve the problem : How to get fullstacktrace using _Unwind_Backtrace on SIGSEGV
update:
if you can use cross compiler to use glic to compile your code, maybe you can use 3. backtrace !
http://communities.mentor.com/community/cs/archives/arm-gnu/msg02514.html
update2
a good article
http://codingrelic.geekhold.com/2009/05/pre-mortem-backtracing.html
Since this is such an important question here is my answer that worked for me. My code is in C so it has to call a C++ function that can access android::CallStack.
stackdump.cpp:
#include < utils/CallStack.h >
extern "C" void dumpCallStack( char *label)
{
android::CallStack cs;
cs.update();
cs.dump(label);
}
my main code (foo.c):
void dumpCallStack(char *label);
...
dumpCallStack(\__FUNCTION__);
I have had the same problem once. And it is hard to interpret.
The syntax is of course correct and reasonable!
I have tried many methods but it did not work.
Finally, I got an idea that, the lib reference "LOCAL_SHARED_LIBRARIES += libutils" should be put into a makefile generating a dynamic library rather than into a makefile generating a static library. This is the final reason.
Reference:
http://yongbingchen.github.io/blog/2013/05/09/dump-stack-in-android-native-c-code/
I also received this error, but I added:
LOCAL_STATIC_LIBRARIES += libutils
before line of LOCAL_MODULE := xxx in vm/Android.m of three targets and added
LOCAL_SHARED_LIBRARIES += libcorkscrew
in vm/Android.mk
and libdex/Android.mk, and same for the dexlist/Android.mk, dexdump/Android.mk
After all these done, it works for me.
I was wondering if there is any way to access the logcat logging data from native code ?
Also if someone knows what kind of shell can be accessed on the native linux system directly on the device itself (so NOT by starting a shell through adb on a client pc !!!) ?
Thanks in advance
You can either read the raw data fom /dev/log/main or you can run the built-in shell command logcat and pipe the result to a file descriptor as usual. The logcat command is usually preferably because then the printout is easier to filter and format.
As for the built-in shell, it is called toolbox and the source can be found in the Android open source project. The shell is rather similar to bash. Toolbox contains lots more functionality than just a shell. It is very similar to Busybox, but released under another license.
You can set it up using a log tag in your source file and then include the library as so:
#define LOG_TAG "some.unique.identifier" //I usually use the class name
#include <utils/Log.h>
Then in the Android.mk file you will need to add the liblog library dependency to your LOCAL_SHARED_LIBRARIES.
LOCAL_SHARED_LIBRARIES += liblog
Also, take note that logcat looks for the LOG_TAG definition to include as part of the tagging so it makes searching for your logs easier. Then you can log as such:
int my_int = 0;
ALOGI("some logs.... print my int: %d", my_int);
ALOGI is for info, you can also use ALOGE, ALOGD, ALOGV and ALOGW for error, debug, verbose and warning logging, respectively.
ALOG* is analogous to printf. I interchange them at times if I need to debug on different platforms, say Linux.