In my Android project, I'm using std::thread.
I use the same C++ code also in some Linux and OSX projects.
For debugging purpose, I want to assign human-readable thread names and I do that by calling pthread_setname_np() (because lack of std::thread::set_name()).
In case of later debug output, I try to obtain the current thread name by calling pthread_getname_np() and this works e.g. on Linux target.
But for my surprise, there is no pthread_getname_np() in Android Ndk pthread.h, not in e.g. ndk-bundle/platforms/android-19/arch-arm/usr/include/pthread.h nor in ndk-bundle/platforms/android-21/arch-arm/usr/include/pthread.h
A stupid trying with a forward declaration like:
extern "C" int pthread_getname_np(pthread_t, char*, size_t);
fails with a linker error (as expected).
Any idea how to obtain the human readable name of the current thread in Android from C/C++ code?
You can see how Dalvik sets them in dalvik/vm/Thread.cpp. It uses pthread_setname_np() if available, prctl(PR_SET_NAME) if not. So if pthread_getname_np() isn't available -- and bear in mind that "np" means "non-portable" -- you can use prctl(PR_GET_NAME) to get a 16-byte null-terminated string under Linux.
You can find other bits by fishing around in /proc entries.
If you have specific requirements for the size and format of the name then you may want to define a pthread key and tuck it into thread-local storage. It's more work, but it's consistent and portable.
Related
I'm a student in computer science. As part of my master's project, I'm trying to intercept calls to functions in native libraries on the Android platform. The goal is to decide whether to allow the call or deny it in order to improve security.
Following the approach of a research paper 1, I want to modify the Procedure Linkage Table (PLT) and the Global Offset Table (GOT) of the ELF file. The idea is that I want to make all the function calls point to my own intercepting function, which decides whether to block the call or pass it through to the original target function.
The ELF specification 2 says (in Book III, Chapter 2 Program Loading and Dynamic Linking, page 2-13, Sections "Global Offset Table" and "Procedure Linkage Table") that the actual contents and form of the PLT and the GOT depend upon the processor. However, in the documentation "ELF for the ARM Architecture" 3, I was unable to see the exact specification of either of those tables. I am concentrating on ARM and not considering other architectures at the moment.
I have 3 questions:
How can I map a symbol to a GOT or PLT entry?
Where do I find the precise specification of the GOT and PLT for ARM processors?
As the PLT contains machine code; will I have to parse that code in order to modify the target address, or do all PLT entries look identical, so that I could just modify the memory at a constant offset for each PLT entry?
Thanks,
Manuel
You need to parse ELF headers and look up the symbol index by the string name in the SHT_DYNSYM. Then iterate over the GOT (which would be called ".rela.plt") and find the entry with the matching index.
I don't know about the formal spec, but you can always study the android linker source and disassemble some binaries to notice the patterns
Usually PLT is just common code and you don't need to modify it. It's actually designed this way because if linker had to modify it, you would end up with RWX memory which is undesirable. So you just need to rewrite the entry in the GOT. By default the GOT entries point to the resolver routine that will find the needed function and write the entry to the GOT. That's on Linux. On Android the address are already resolved.
I did something for the x86_64 Linux
https://github.com/astarasikov/sxge/blob/vaapi_recorder/apps/src/sxge/apps/demo1_cube/hook-elf.c
And also there's a blog about doing what you want on Android
https://www.google.de/amp/shunix.com/android-got-hook/amp/
I am going to learn a little bit about Dalvik VM, dex and Smali.
I have read about smali, but still cannot clearly understand where its place in chain of compilers. And what its purpose.
Here some questions:
As I know, dalvik as other Virtual Machines run bytecode, in case of Android it is dex byte code.
What is smali? Does Android OS or Dalvik Vm work with it directly, or it is just the same dex bytecode but more readable for the human?
Is it something like dissasembler for Windows (like OllyDbg) program executable consist of different machines code (D3 , 5F for example) and there is appropriate assembly command to each machine code, but Dalvik Vm also is software, so smali is readable representation of bytecodes
There is new ART enviroment. Is it still use bytecodes or it executes directly native code?
Thank you in advance.
When you create an application code, the apk file contains a .dex file, which contains binary Dalvik bytecode. This is the format that the platform actually understands. However, it's not easy to read or modify binary code, so there are tools out there to convert to and from a human readable representation. The most common human readable format is known as Smali. This is essentially the same as the dissembler you mentioned.
For example, say you have Java code that does something like
int x = 42
Assuming this is the first variable, then the dex code for the method will most likely contain the hexadecimal sequence
13 00 2A 00
If you run baksmali on it, you'd get a text file containing the line
const/16 v0, 42
Which is obviously a lot more readable then the binary code. But the platform doesn't know anything about smali, it's just a tool to make it easier to work with the bytecode.
Dalvik and ART both take .dex files containing dalvik bytecode. It's completely transparent to the application developer, the only difference is what happens behind the scenes when the application is installed and run.
High level language programming include extra tools to make programming easier & save time for the programmer. After compiling the program, if it was to be decompiled, going back to the original source code would need a lot of code analysis, to determine structure & flow of program code, most likely a few more than 1 pass/parse. Then the decompiler would have to structure the source based on the features of the compiler that compiled the code, the version or the compiler, and the operating system it was compiled on eg. if an OS specific features or frameworks or parsers or external libraries were involved, such as .net or dome.dll, and their versions, etc
The next best result would be to output the whole program flow, as if the source code was written in one large file ie. no separate objects, libraries, dependencies, inheritances, classes or api. This is where the decompiler would spit out code which when compiled, would result in errors since there's no access to the source codes & structure of the other files/dependencies. See example here.
The 3rd & best option would be to follow what the operating system is doing based on the programmed instructions, which would be machine code, or dex (in case of Android). Unless you're sitting in the Nebuchadnezzar captained by Morpheus and don't have time to decode every opcode in the instruction set of the architecture your processor is running, you'd want something more readable than unicode characters scrolling on the screen as you monitor the program flow/execution.
This is where assembly code makes the difference; it's almost the direct translation of machine code, in a human readable format. I say "almost" direct because microprocessors have helpers like microcodes, multithreaders for pipelining & hardware accelerators to give a better user experience.
If you have the source code, you'd be editing in the language the code is written in. Similarly, if you don't have the source code, and you're editing the compiled app, you'd still be editing in the language the code is written in; in this case, it's machine code, or the next best thing: smali.
Here's a diagram to illustrate "Dalvik VM, dex and Smali" and "its place in chain of compilers".
In Android, when we call native code via JNI, can it corrupt the Dalvik VM, and the Java code running inside it?
For example, suppose we have this C method and we call it via JNI:
JNIEXPORT void JNICALL Java_MemoryCorruptor_corruptMemory()
{
while (1) {
char *p = randomAddress();
*p = randomChar();
}
}
If the VM just loads the .so files and the native code is running in the same context/address space as the VM, then I assume the VM could get corrupted.
On the other hand, if the VM creates a child process to hold the .so files and uses some form of IPC to call methods, then the Java code can't get corrupted by the native code.
Native code runs in the same process as the Java code it interacts with via JNI, so yes, it is very much able to corrupt key data structures. Most often you might see this as a crash within the library implementing the VM itself, shortly after the return from misbehaving native code, but in theory another thread could mis-operate.
To the extent that there is isolation between native and VM-hosted code of the same process, it is merely that the information needed to usefully and safely modify implementation data structures is only available to a limited degree under certain JNI support calls - but it is all exposed to blindfolded poking, if your native code does that. Of course it is also possible that your code will crash the process by attempting an illegal access itself. Depending on the details of the VM implementation some of the "code" of the app may well be in read-only memory pages, and attempting to write to those would cause a memory protection fault. However, data, and any JIT "compiled on the fly" code will presumably be in a writable pages. And actively nefarious code can change the protection settings, swapping read-only file-backed mappings for writable anonymous pages with the same contents if necessary.
It is possible to run components of an Android app in a distinct process, but that will have its own VM wrapping any JNI code you use there - classes like Activity and Service are fundamentally Java level, even if you use stock JNI glue Java code to do the work in a native version. Some web browser apps for example may do this, to put a little more isolation around their javascript interpreter engines.
It has also been possible (to date) to start up an independent native-only process and talk to it via IPC, however this is not encouraged as it will lack the lifecycle hooks for management by Android, and there are some tricky parts of it you will have to accomplish yourself. Further, such a program cannot use most Java-defined Android platform APIs, or at least not in a portable manner. Historically people have resorted to this primarily when using an "su" root shim on a hacked device to start up a helper process running as the superuser, or occasionally as a pathway to port a complicated Linux-style tool without re-architecting it as a JNI library.
I'm currently developing an algorithm for texture classification based on Machine Learning, primarily Support Vector Machines (SVM). I was able to gain some very good results on my test data and now want to use the SVM in productive environment.
Productive in my case means, it is going to run on multiple Desktop- and Mobile platforms (i.e. Android, iOS) and always somewhere deep down in native threads. For reasons of software structure and the platform's access policies, I'm not able to access the file system from where I use the SVM. However, my framework supports reading Files in an environment where access the file system is granted and channel the file's content as a std::string to the SVM-part of my application.
The standard procedure how to configure an SVM is by using filenames and OpenCV reads directly from the file:
cv::SVM _svm;
_svm.load("/home/<usrname>/DEV/TrainSoftware/trained.cfg", "<trainSetName>");
I want this (basically reading from the file somewhere else and passing the file's content as a string to the SVM):
cv::SVM _svm;
std::string trainedCfgContentStr="<get the content here>";
_svm.loadFromString(trainedCfgContentStr, "<trainSetName>") // This method is desired
I couldn't find anything in OpenCV's docs or source that this is possible somehow, but it wouldn't be the first OpenCV-Feature that's there and not documented or widely known. Of course, I could hack the OpenCV source and cross-compile to each of my target platforms, but I'd try to avoid that since it is a hell lot of work, besides I'm pretty convinced I'm not the first one with this problem.
All ideas (also unconventional) and/or hints are highly appreciated!
as long as you stick with the c++ api it's quite easy, FileStorage can read from memory:
string data_string; //containing xml/yml data
FileStorage fs( data_string, FileStorage::READ | FileStorage::MEMORY);
svm.read(fs.getFirstTopLevelNode()); // or the node with your trainset
(unfortunately not exposed to java)
I'm currently developing an OpenGL-ES application for Android using the NDK.
The application would greatly benefit from the following Open-GL extension:
GL_EXT_texture_array
(details here: GL_EXT_texture_arary)
The extension is supported by my Tegra-3 device (Asus EeePad Transformer Prime Tf-201)
The issue I'm now facing is, that I have no clue how to make the extension available for my application as it is not included by the Open-GL ES API registry.
(see "Extension Specifications": http://www.khronos.org/registry/gles/)
However I noticed an extension called "GL_NV_texture_array" which seems to be of the same use, but is not supported by my Tegra-3 device.
I'm aware of the possibility to include extensions using function pointers.
But I thought there might be a more comfortable way.
I have also found a header file (gl2ext_nv.h), which contains the necessary extension.
But when you search for it through google, the file is always part of particular projects, not something official.
I have also downloaded the Tegra Android Development Pack (2.0) in which neither this header file nor the desired extension is included.
Can anyone explain this to me, please?
How can I use Open-GL ES extension supported by my Tegra-3 device,
which are seemingly not supported by any official Open-GL ES specific headers (in the NDK)?
Thanks in advance!
When you say that your Tegra 3 device supports GL_EXT_texture_array but not GL_NV_texture_array, I'm assuming that you determined that through a call to glGetString(GL_EXTENSIONS).
GL_NV_texture_array is very similar to GL_EXT_texture_array, just limited to 2d texture arrays. Not surprisingly, it uses many of the same constants as GL_EXT_texture_array, just with different names.
GL_NV_texture_array:
TEXTURE_2D_ARRAY_NV 0x8C1A
TEXTURE_BINDING_2D_ARRAY_NV 0x8C1D
MAX_ARRAY_TEXTURE_LAYERS_NV 0x88FF
FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_NV 0x8CD4
SAMPLER_2D_ARRAY_NV 0x8DC1
GL_EXT_texture_array:
TEXTURE_2D_ARRAY_EXT 0x8C1A
TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D
MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF
FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
SAMPLER_2D_ARRAY_EXT 0x8DC1
This version of gl2ext_nv.h defines the constants for GL_EXT_texture_array but not for GL_NV_texture_array, so perhaps nVidia is using the the old name now. If you can't find a more recent version of the header, just include this one.
To gain access to functions offered by GL extensions, use eglGetProcAddress to assign the function to a function pointer.
// The function pointer, declared in a header.
// You can put this in a class instance or at global scope.
// If the latter, declare it with "extern", and define the actual function
// pointer without "extern" in a single source file.
PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glFramebufferTextureLayerEXT;
In your function that checks for the presence of the GL_EXT_texture_array extension, if it's found, get the address of the function and store it in your function pointer. With OpenGL-ES, that means asking EGL:
glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) eglGetProcAddress("glFramebufferTextureLayerEXT");
Now you can use the function just like it was part of regular OpenGL.