Understanding how rootadb finds method call in ELF binary - android

The android debug bridge daemon adbd that runs on Android devices may be compiled without root support (ALLOW_ADBD_ROOT=0).
There is a tool called rootadb which is able to patch an existing adbd binary by (as I understood it) replacing the calls to setuid() and setgid() with NOP instructions, effectively preventing it from dropping its privileges.
I don't understand how the code finds the place of the syscalls inside the binary.
As far as I see, it iterates over the all the bytes and checks if the bytes match something:
u32 *sgid = (u32*)&setgid;
int fd = open( "/sbin/adbd", O_RDWR );
fstat( fd, &st );
buf = memalign( 32, st.st_size );
read( fd, buf, st.st_size );
lseek64( fd, 0, SEEK_SET );
for( start = buf, end = start + st.st_size - 0x20; start < end; start++ )
if( !memcmp( &start[1], &sgid[1], sizeof( u32 ) * 2 ) )
memcpy( &start[1], patch, sizeof( patch ) );
How does this work?
With what kind of data are sgid and __setuid actually filled?

I'm not 100% sure, but I have a reasonable idea.
The first line of code loads a pointer to the address of setgid, and treats it as a 32 bit pointer.
The loop iterates over the binary, and looks for occurrences of 8 bytes that equal address of the setgid function. If it finds one, it applies the patch, starting at the first byte of that location.

With what kind of data are sgid and __setuid actually filled?
'u32 *sgid' contains the address of the function 'setgid' and 'u32 *cap' contains the address of 'capset'. __setuid is the function itself but written without the parenthesis '()' we can retrieve the function's address.
I am confident that 0xe3a00000 is not an address to any function's stack frame. And it doesn't point to any location in memory.
With the information given I think 0xe3a00000 in 'patch' is used in the program to restore the state after the sub-routine call and prevent operations that happens after the call,
u32 patch[] =
{
0xe3a00000,
0
};
Below is the snippet that searches and replaces instructions following the call,
for( start = buf, end = start + st.st_size - 0x20; start < end; start++ )
if( !memcmp( &start[1], &sgid[1], sizeof( u32 ) * 2 ) )
memcpy( &start[1], patch, sizeof( patch ) );
Here the next 8 bytes from &sgid[1] should have state information along with the jump instructions to setgid function which is replaced by instruction in patch.
This effectively results in no-op. This is my understanding.
Please check how stack and frame tends to grow in android architecture also about the prologue and epilogue of the functions in this architecture. It will point you in the right direction as to why &sgid[1] (or sgid + 4 bytes) was used.
You could also refer,
https://softwareengineering.stackexchange.com/questions/195385/understanding-stack-frame-of-function-call-in-c-c
https://en.wikipedia.org/wiki/Call_stack#Stack_and_frame_pointers

Related

DACR read/write on ARM

I am trying to read and write the DACR on an ARM device running Linux (Android on nexus 5 :)). I have a kernel module. The relevant instructions are as follows:
MRC p15, 0, <Rd>, c3, c0, 0 ; Read DACR
MCR p15, 0, <Rd>, c3, c0, 0 ; Write DACR
I am using C code in the module with assembly inside. I wrote the following to read the current DACR value:
unsigned int x = 0;
__asm__("MRC p15, 0, r1, c3, c0, 0;" : "=r" (x));
printk(KERN_INFO "DACR read - value = %u", x);
The above didn't crash the kernel, and the value read out was 3920437248.
I am not able to write the instruction for DACR write correctly. I was trying to follow from this question and did the following (to write all 1's to DACR to test), but the device crashed and rebooted:
__asm__("MVN r1, #0;");
__asm__("MCR p15, 0, r1, c3, c0, 0;");
Can anyone advice how to write to DACR correctly ?
Also how to parameterize the above instruction - e.g. for using value of x to initialize DACR, would the following be correct:
__asm__("MCR p15, 0, %0, c3, c0, 0;" :: "r" (x));
Oh, you're writing the register correctly alright.
The trouble is, the question is like this:
I am trying to engage reverse gear on my car driving on the motorway. I was trying to follow the directions in the handbook and moved the gear lever firmly into the "R" position, but my gearbox is now in bits all over the road. Can anyone advise how to engage reverse gear correctly?
You're on a live system. The kernel is already using domains. It needs access permissions to work correctly. If you declare open season by marking everything as Manager and removing all permission checks, copy-on-write no longer works; every process starts trashing the zero page via their initial mappings instead of triggering the allocation of real backing pages; cats and dogs live together; chaos.

Is logging Android systrace events directly from native code possible, without JNI?

The Android systrace logging system is fantastic, but it only works in the Java portion of the code, through Trace.beginSection() and Trace.endSection(). In a C/C++ NDK (native) portion of the code it can only be used through JNI, which is slow or unavailable in threads without a Java environment...
Is there any way of either adding events to the main systrace trace buffer, or even generating a separate log, from native C code?
This older question mentions atrace/ftrace as being the internal system Android's systrace uses. Can this be tapped into (easily)?
BONUS TWIST: Since tracing calls would often be in performance-critical sections, it should ideally be possible to run the calls after the actual event time. i.e. I for one would prefer to be able to specify the times to log, instead of the calls polling for it themselves. But that would just be icing on the cake.
Posting a follow-up answer with some code, based on fadden's pointers. Please read his/her answer first for the overview.
All it takes is writing properly formatted strings to /sys/kernel/debug/tracing/trace_marker, which can be opened without problems. Below is some very minimal code based on the cutils header and C file. I preferred to re-implement it instead of pulling in any dependencies, so if you care a lot about correctness check the rigorous implementation there, and/or add your own extra checks and error-handling.
This was tested to work on Android 4.4.2.
The trace file must first be opened, saving the file descriptor in an atrace_marker_fd global:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define ATRACE_MESSAGE_LEN 256
int atrace_marker_fd = -1;
void trace_init()
{
atrace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_WRONLY);
if (atrace_marker_fd == -1) { /* do error handling */ }
}
Normal 'nested' traces like the Java Trace.beginSection and Trace.endSection are obtained with:
inline void trace_begin(const char *name)
{
char buf[ATRACE_MESSAGE_LEN];
int len = snprintf(buf, ATRACE_MESSAGE_LEN, "B|%d|%s", getpid(), name);
write(atrace_marker_fd, buf, len);
}
inline void trace_end()
{
char c = 'E';
write(atrace_marker_fd, &c, 1);
}
Two more trace types are available, which are not accessible to Java as far as I know: trace counters and asynchronous traces.
Counters track the value of an integer and draw a little graph in the systrace HTML output. Very useful stuff:
inline void trace_counter(const char *name, const int value)
{
char buf[ATRACE_MESSAGE_LEN];
int len = snprintf(buf, ATRACE_MESSAGE_LEN, "C|%d|%s|%i", getpid(), name, value);
write(atrace_marker_fd, buf, len);
}
Asynchronous traces produce non-nested (i.e. simply overlapping) intervals. They show up as grey segments above the thin thread-state bar in the systrace HTML output. They take an extra 32-bit integer argument that "distinguishes simultaneous events". The same name and integer must be used when ending traces:
inline void trace_async_begin(const char *name, const int32_t cookie)
{
char buf[ATRACE_MESSAGE_LEN];
int len = snprintf(buf, ATRACE_MESSAGE_LEN, "S|%d|%s|%i", getpid(), name, cookie);
write(atrace_marker_fd, buf, len);
}
inline void trace_async_end(const char *name, const int32_t cookie)
{
char buf[ATRACE_MESSAGE_LEN];
int len = snprintf(buf, ATRACE_MESSAGE_LEN, "F|%d|%s|%i", getpid(), name, cookie);
write(atrace_marker_fd, buf, len);
}
Finally, there indeed seems to be no way of specifying times to log, short of recompiling Android, so this doesn't do anything for the "bonus twist".
I don't think it's exposed from the NDK.
If you look at the sources, you can see that the android.os.Trace class calls into native code to do the actual work. That code calls atrace_begin() and atrace_end(), which are declared in a header in the cutils library.
You may be able to use the atrace functions directly if you extract the headers from the full source tree and link against the internal libraries. However, you can see from the header that atrace_begin() is simply:
static inline void atrace_begin(uint64_t tag, const char* name)
{
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
char buf[ATRACE_MESSAGE_LENGTH];
size_t len;
len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "B|%d|%s", getpid(), name);
write(atrace_marker_fd, buf, len);
}
}
Events are written directly to the trace file descriptor. (Note that the timestamp is not part of the event; that's added automatically.) You could do something similar in your code; see atrace_init_once() in the .c file to see how the file is opened.
Bear in mind that, unless atrace is published as part of the NDK, any code using it would be non-portable and likely to fail in past or future versions of Android. However, as systrace is a debugging tool and not something you'd actually want to ship enabled in an app, compatibility is probably not a concern.
For anybody googling this question in the future.
Native trace events are supported since API Level 23, check out the docs here https://developer.android.com/topic/performance/tracing/custom-events-native.

Sending data from arduino through bluetooth serial

I’m currently trying to design a controller that would communicate through Bluetooth to an android phone (Galaxy Nexus). I’m facing a few challenges. Also, I don’t have much practical programming experience.
At the core of the controller resides an Arduino microcontroller who scans the state of 8 digital pins and six analogue pins (10 bits) and sends the data through serial, to an HC-05 Bluetooth chip.
The android phone should then read the serial information sent through Bluetooth and either transmit the packet to another phone - That will take me a while to implement as I know very little of how the internet works - or analyse and interpret it for further action to be taken
What I’m asking for are insight as to the best way to go about doing this. Now what does best mean?
We’ll I want it to be real time so when I press a button or a combination of bottoms, boom, the android phone takes action fast enough for a human not to perceive a delay.
Then I want to be able to associate the information the phone reads in the serial buffer to the corresponding button or analogue pin. In case there is an error or to avoid that they fall out of sync
Here is what I have so far. I have not tested this code yet, partly because I’m still learning how to program the android part of this project, partly because I want some feedback as to whether I’m being silly or this is actually an effective way to go about doing this:
//Initialization
/*
This Program has three functions:
1) Scan 8 digital pins and compile their state in a single byte ( 8 bits)
2) Scans 6 Analogue inputs corresponding to the joysticks and triggers
3) Send this info as packets through seril --> Bluetooth
*/
#include <SoftwareSerial.h>// import the serial software library
#define A = 2
#define B = 3
#define X = 4
#define Y = 5
#define LB = 6
#define RB = 7
#define LJ = 8
#define RJ = 9
#define RX = 10
#define TX = 11
//Pin 12 and 13 are unused for now
SoftwareSerial Bluetooth(RX,TX); //Setup software serial using the defined constants
// declare other variables
byte state = B00000000
void setup() {
//Setup code here, to run once:
//Setup all digital pin inputs
pinMode(A,INPUT);
pinMode(B,INPUT);
pinMode(X,INPUT);
pinMode(Y,INPUT);
pinMode(LB,INPUT);
pinMode(RB,INPUT);
pinMode(LJ,INPUT);
pinMode(RJ,INPUT);
//Setup all analogue pin inputs
//setup serial bus and send validation message
Bluetooth.begin(9600);
Bluetooth.println("The controller has successfuly connected to the phone")
}
void loop() {
//Main code here, to run repeatedly:
//Loop to sum digital inputs in a byte, left shift the byte every time by 1 and add that if the pin is high
for(byte pin = 2, b = B00000001; pin < 10; pin++, b = b << 1){ if (digitalRead(pin)== HIGH) state += b; }
//Send digital state byte to serial
Bluetooth.write(state);
//Loop to read analgue pin 0 to 5 and send it to serial
for( int pin = 0, testByte = 0x8000; pin < 6 ; pin++, testByte = testByte >> 1) { Bluetooth.write(analogRead(pin)+testByte); }
}
//Adding some validation would be wise. How would I go about doing that?
// Could add a binary value of 1000_0000_0000_0000, 0100_0000_0000_0000, 0010_0000_0000_0000 ... so on and then use a simple AND statement at the other end to veryfy what analogue reading the info came from
// so say the value for analgue is 1023 and came from analgue pin 1 I would have 0100_0011_1111_1111 now using an bitwise && I could check it against 0100_0000_0000_0000 if the result is 0100_0000_0000_0000 then I know this is the analogu reading from pin 1
//could easily implement a test loop with a shiting bit on the android side
Is it pointless for me to be doing bit shifts like this? Ultimately, if I’m not mistaken, all data is sent as bytes ( 8 bits packets) so will the Bluetooth.write(analogRead(pin)+testByte) actually send two bytes or will it truncate the int data? how will it be broken down and how can I recuperate it on the android end?
How would you go about implementing this? Any insights or words of advice?
It's great that you are learning this! Some suggestions:
Your code will be easier to read, understand and maintain if you space it out a bit, particularly by adding newlines...
void loop() {
//Main code here, to run repeatedly:
//Loop to sum digital inputs in a byte,
//left shift the byte every time by 1 and add that if the pin is high
for( byte pin = 2, b = B00000001; pin < 10; pin++, b = b << 1) {
if (digitalRead(pin)== HIGH)
state += b;
}
//Send digital state byte to serial
Bluetooth.write(state);
//Loop to read analgue pin 0 to 5 and send it to serial
for( int pin = 0, testByte = 0x8000; pin < 6 ; pin++, testByte = testByte >> 1) {
Bluetooth.write(analogRead(pin)+testByte);
}
}
Also, you can use the shift operators with values other than one. so instead of keeping a shift mask that you then add in, you just use the a simple variable. A more classic way to do what you expressing in the first looop would be something like this:
#define PIN_OFFSET 2
for ( int i=0; i < 8; i++) {
if (digitalRead( i+PIN_OFFSET)== HIGH)
state += (1 << i);
}
The second loop could be done similarly:
for( int pin = 0; pin < 6; pin++) {
short testByte = 0x8000 >> pin;
short result = analogRead(pin) + testByte;
Bluetooth.write( result >> 8);
Bluetooth.write( result & 0xFF);
}
Note that the Bluetooth.write() call sends a byte, so this code sends first the most significant byte, then the least.
Lastly, you probably want to zero your state variable at be beginning of loop() -- otherwise, once a bit is set it will never get cleared.
You may want to think about what you are sending to the phone. It will be binary data, and that can be difficult to deal with -- how do you know the start and end, and often a value will be misinterpretted as a control character messing you up big time. Consider changing it into a formatted, human readable string, with a newline at the end.
I hope that helps.
The Arduino end of this is more than fast enough to do what you want to do and you need not worry in the slightest about minimising the number of bytes you send out from the micro to the phone when you're talking about such a tiny amount of data. I'm not quite clear what you're sending to the phone; are you wanting a different value for each button so when a button is pressed it sends out something like:
Button Was Pressed, Button Number (Two bytes)
And if it's an analogue value:
Analogue Value Read, Analogue Value MSB, Analogue Value LSB (assuming the analogue value is greater than eight bits
I don't know the Arduino code you're using, but my suspicion is that this line:
Bluetooth.write(analogRead(pin)+testByte)
Would send one byte which is the addition of the analogue value and whatever testByte is.
Would you be able to post a link to the documentation for this API?
Any delay with all this will come at the phone end. Please don't concern yourself in the slightest about trying to save a byte or two at the Arduino end! (I'm currently doing a project with a Cortex M3 sending data via a Bluetooth module to Android phones and we're shipping several k of data around. I know from this experience the difference between two and twenty bytes is not of consequence in terms of delay.)
It may be good for you to opt for ready available bluetooth terminal apps for your android handset. On Google play, few apps are:
1) https://play.google.com/store/apps/details?id=arduino.bluetooth.terminal&hl=en
2) https://play.google.com/store/apps/details?id=com.sena.bterm&hl=en
(and few more are availble on Google play).This will help you to focus only on controller side development.

android NDK mutex locking

I've been porting a cross platform C++ engine to Android, and noticed that it will inexplicably (and inconsistently) block when calling pthread_mutex_lock. This engine has already been working for many years on several platforms, and the problematic code hasn't changed in years, so I doubt it's a deadlock or otherwise buggy code. It must be my port to Android..
So far there are several places in the code that block on pthread_mutex_lock. It isn't entirely reproducible either. When it hangs, there's no suspicious output in LogCat.
I modified the mutex code like this (edited for brevity... real code checks all return values):
void MutexCreate( Mutex* m )
{
#ifdef WINDOWS
InitializeCriticalSection( m );
#else ANDROID
pthread_mutex_init( m, NULL );
#endif
}
void MutexDestroy( Mutex* m )
{
#ifdef WINDOWS
DeleteCriticalSection( m );
#else ANDROID
pthread_mutex_destroy( m, NULL );
#endif
}
void MutexLock( Mutex* m )
{
#ifdef WINDOWS
EnterCriticalSection( m );
#else ANDROID
pthread_mutex_lock( m );
#endif
}
void MutexUnlock( Mutex* m )
{
#ifdef WINDOWS
LeaveCriticalSection( m );
#else ANDROID
pthread_mutex_unlock( m );
#endif
}
I tried modifying MutexCreate to make error-checking and recursive mutexes, but it didn't matter. I wasn't even getting errors or log output either, so either that means my mutex code is just fine, or the errors/logs weren't being shown. How exactly does the OS notify you of bad mutex usage?
The engine makes heavy use of static variables, including mutexes. I can't see how, but is that a problem? I doubt it because I modified lots of mutexes to be allocated on the heap instead, and the same behavior occurred. But that may be because I missed some static mutexes. I'm probably grasping at straws here.
I read several references including:
http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_mutex_init.html
http://www.embedded-linux.co.uk/tutorial/mutex_mutandis
http://linux.die.net/man/3/pthread_mutex_init
Android NDK Mutex
Android NDK problem pthread_mutex_unlock issue
The "errorcheck" mutexes will check a couple of things (like attempts to use a non-recursive mutex recursively) but nothing spectacular.
You said "real code checks all return values", so presumably your code explodes if any pthread call returns a nonzero value. (Not sure why your pthread_mutex_destroy takes two args; assuming copy & paste error.)
The pthread code is widely used within Android and has no known hangups, so the issue is not likely in the pthread implementation itself.
The current implementation of mutexes fits in 32 bits, so if you print *(pthread_mutex_t* mut) as an integer you should be able to figure out what state it's in (technically, what state it was in at some point in the past). The definition in bionic/libc/bionic/pthread.c is:
/* a mutex is implemented as a 32-bit integer holding the following fields
*
* bits: name description
* 31-16 tid owner thread's kernel id (recursive and errorcheck only)
* 15-14 type mutex type
* 13 shared process-shared flag
* 12-2 counter counter of recursive mutexes
* 1-0 state lock state (0, 1 or 2)
*/
"Fast" mutexes have a type of 0, and don't set the tid field. In fact, a generic mutex will have a value of 0 (not held), 1 (held), or 2 (held, with contention). If you ever see a fast mutex whose value is not one of those, chances are something came along and stomped on it.
It also means that, if you configure your program to use recursive mutexes, you can see which thread holds the mutex by pulling the bits out (either by printing the mutex value when trylock indicates you're about to stall, or dumping state with gdb on a hung process). That, plus the output of ps -t, will let you know if the thread that locked the mutex still exists.

Why does glGetIntegerv for GL_NUM_SHADER_BINARY_FORMATS generate GL_INVALID_ENUM?

I am using the official Android port of SDL 1.3, and using it to set up the GLES2 renderer. It works for most devices, but for one user, it is not working. Log output shows the following error:
error of type 0x500 glGetIntegerv
I looked up 0x500, and it refers to GL_INVALID_ENUM. I've tracked down where the problem occurs to the following code inside the SDL library: (the full source is quite large and I cut out logging and basic error-checking lines, so let me know if I haven't included enough information here)
glGetIntegerv( GL_NUM_SHADER_BINARY_FORMATS, &nFormats );
glGetBooleanv( GL_SHADER_COMPILER, &hasCompiler );
if( hasCompiler )
++nFormats;
rdata->shader_formats = (GLenum *) SDL_calloc( nFormats, sizeof( GLenum ) );
rdata->shader_format_count = nFormats;
glGetIntegerv( GL_SHADER_BINARY_FORMATS, (GLint *) rdata->shader_formats );
Immediately after the last line (the glGetIntegerv for GL_SHADER_BINARY_FORMATS), glGetError() returns GL_INVALID_ENUM.
The problem is the GL_ARB_ES2_compatibility extension is not properly supported on your system.
By GL_INVALID_ENUM it means that it does not know the GL_NUM_SHADER_BINARY_FORMATS and GL_SHADER_BINARY_FORMATS enums, which are a part of the said extension.
In contrast, GL_SHADER_COMPILER was recognized, which is strange.
You can try using GL_ARB_get_program_binary and using these two instead:
#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87fe
#define GL_PROGRAM_BINARY_FORMATS 0x87ff
Note that these are different from:
#define GL_SHADER_BINARY_FORMATS 0x8df8
#define GL_NUM_SHADER_BINARY_FORMATS 0x8df9
But they should pretty much do the same.

Categories

Resources