DACR read/write on ARM - android

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.

Related

Understanding how rootadb finds method call in ELF binary

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

Does Android Studio have an NDK memory viewer?

I am porting a C library code for windows into android
When I create a dynamically allocated array in the NDK C code, the variables viewer window only shows me the address of the first element, and the value of the first element
I would like to see all the array's members in the phone's memory
Is there a memory viewer or something similar for NDK in android studio?
Or as an alternative, can I do some kind of memory dump in the lldb console?
You can print a dynamically allocated int array using LLDB print (in short p) command like below:(modify the size and type according to your own case)
(lldb) print *(int (*)[5])foo2
It will give output all the elements of the int array. See below screenshot:
For a GUI style, you can select Variables tab and add a new watch using similar statement as command line said above, see below screenshot:
And then:
Unfold the watched statement, you will see all the elements as below:
Edit #1
Using parray command is simpler:
(lldb) parray 5 foo2
(int *) $5 = 0x000072e200e2da70 {
(int) [0] = 20
(int) [1] = 8
(int) [2] = 55
(int) [3] = 6
(int) [4] = 52
}

Getting a physical address from an allocated buf in a module without using virt_to_phys macro

I am trying to write a android arm kernel module in which I need to use a virt_to_phys translation of a memory var allocated using _kmalloc.
I do know that I can use the macro virt_to_physc to do this task. However, I dont have the specifically full kernel source, and beacuse virt_to_physc is a macro
I can't get a function address reading kallsyms to use in my module , so I would like to find another way to do this task.
I've been trying to do it using MMU (registers ATS1Cxx and PAR) to perform V=>P as Iam working in an ARMv7 proccessor but I couldnt make it work.
That's my test code...
int hello_init_module(void) {
printk("Virtual MEM:0x%X \n", allocated_buf);
//Trying to get the physc mem
asm("\t mcr p15, 0, %[value], c7, c8, 2\n"
"\t isb\n"
\t mrc p15, 0, %[result], c7, c4, 0\n" : [result]"=r" (pa) : [value]"r" (allocated_buf));
printk("Physical using MMU : %x\n", pa );
//This show the right address, but I wanna do it without calling the macro.
printk("Physical using virt_2_physc: 0x%X",virt_to_phys((int *) allocated_buf);)
}
What Iam actually doing is developing a module that is intended to work in two devices with the same 3.4.10 kernel but different memory arquitectures,
I can make the module works as they have the same VER_MAGIC and functions crc, so the module load perfectly in both devices.
The main problem is that because of diferences in their arquitecture, PAGE_OFFSET and PHYS_OFFSET actually change in both of them.
So, I've wondering if there is a way to make the translation without define this values as constant in my module.That's what I tried using MMU to perform V=>P , but MMU hasnt worked in my case, it always returns 0x1F.
According to cat /proc/cpuinfo . Iam working with a
Processor : ARMv7 Processor rev 0 (v7l)
processor : 0
Features : swp half thumb fastmult vfp edsp neon vfpv3 tls
CPU implementer : 0x51
CPU architecture: 7
If it's not possible to do it using MMU as alternative way of using virt_to_phys.
Does somebody know other way to do it?

Pic16F688 has no stable readings via buletooth

I have spent much time trying to find out where is my mistakes while Im flashing the PIC16F688. The Pic has successfully flashed using PicKit2. Im using the Pic to convert analog pressure sensor to digital output and sending the data via Bluetooth, but the Bluetooth is not receiving stable numbers of data. The data is consist of 4 character decimal number that is between 0 and 1023.
The problem is that the Bluetooth can't wait at specific number and keep reading it, instead, it is reading the 4 digits in random.
I think my mistake is within the configuration of internal oscillator.
I'm attaching my code, the code is written to configure the flexiforce sensor circuit that outputs analog voltage up to 5v, and then the pic duty is to convert it to digital as I mentioned above.
it might be my wiring is not correct, please If you could help out with this one
and what configuration "at edit project" do I need to choose for Mikro PRO software?
I used "Bluetooth terminal" app to see my data asynchronous from Bluetooth.
Thank you.
char *temp = "0000";
unsigned int adc_value;
char uart_rd; int i;
void main()
{
OSCCON = 0x77;
ANSEL = 0b00000100;
CMCON0 = 0X07;
TRISA = 0b00001100;
UART1_Init(9600);
Delay_ms(100);
while (1)
{
adc_value = ADC_Read(2);
temp[0] = adc_value/1000+48;
temp[1] = (adc_value/100)%10+48;
temp[2] = (adc_value/10)%10+48;
temp[3] = adc_value%10+48;
for (i=0;i<4; i++)
UART1_Write(temp[i]);
UART1_Write(13);
Delay_ms(1000);
}
}
You can use itoa function to convert ADC integer value to characters for sending over UART. If there is error in calculation then you wont get appropriate value. Below code snippet for your reference :
while (1)
{
adc_value = ADC_Read(2);
itoa(adc_value, temp, 10);
for (i=0;i<4; i++)
UART1_Write(temp[i]);
UART1_Write(13);
Delay_ms(1000);
}
Please check Baud Rate you have configured at both ends is same or not. If baudrate mismatches then you will get Random value at Bluetooth Terminal where you are reading values.
What i would suggest, if you have a logic analyser, hook it up. If you don't recalculate your oscillator speed with the datasheet. It could just be that the internal oscillator is not accurate enough. What also works, is to write a function in assembly that waits a known time (by copy-pasting a lot of NOPs and using this to blink a led. Then start a stopwatch and count, say, 100 blinks. This is what i used to do before i had a logic analyser. (They are quite cheep on ebay).

get all 0 data when capture video using v4l2 on android

i am trying to capture video on android using v4l2 under jni. i found some guide and followed the step:
fd = open("/dev/video0", O_RDWR);
/* init part */
ioctl(fd, VIDIOC_QUERYCAP, &caps);
ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc);
ioctl(fd, VIDIOC_S_FMT, &fmt);
ioctl(fd, VIDIOC_REQBUFS, &req);
ioctl(fd, VIDIOC_QUERYBUF, &buf);
ioctl(fd, VIDIOC_QBUF, &buf);
/* capture part */
FILE *fp = fopen("/sdcard/img.yuv", "wb");
for (i = 0; i < 20; i++)
{
ioctl(fd, VIDIOC_DQBUF, &buf);
fwrite(buffers[buf.index].start, 1, buf.bytesused, fp);
ioctl(fd, VIDIOC_QBUF, &buf);
}
fclose(fp);
this is the main structure of my code. all the function run correctly and return 0. however, when i open the output file with binary viewer, i found that all the data is 0.
is there any problem with my code? i got confused because all the functions returned 0.
Thanks!!
You are using an array called buffers[]. But I can't see where it's declared or what it stands for. If there is no code missing above, you will always get zeros cause you are writing buffer[] to the file and not the stuff you get from v4l2.
Further more, the initial values of caps, fmtdesc, fmt, req and buf prior to the ioctl command would be interesting too. Depending on their inital values, you will have different communication interfaces. Issues could be hidden in these parts.
As you wrote in your question, all ioctl commands would return 0, there should be no error. If everything behaves as expected. Another way to check for issues is calling
perror("<your comment or hint to line above>");
after each ioctl command. This would print you more information about errors on your std-out. ( more details about perror can be found in this thread When should I use perror("...") and fprintf(stderr, "...")?)
Are you trying to get the images from the camera? (on some phones video0 you used above is the back cam) On some android devices the camera has to be started by complex procedure using other device drivers besides videoXY. And trying to get the images from video0 while the official camera app is running might be difficult. The official v4l2 api says:
V4L2 drivers should not support multiple applications reading or writing the same data stream on a device by copying buffers, time multiplexing or similar means. This is better handled by a proxy application in user space.
From: http://linuxtv.org/downloads/v4l-dvb-apis/common.html#idp18553208
Can you post more (detailed) code? I might be able to help, as I'm doing very similar stuff.
To be able to reproduce it, it would be very interesting with which android device you are working (type / model number / android version).

Categories

Resources