I found the error.
I forgot to flush the data cache after doing the writing the
executable code to the data segment.
This can be done using the following function:
static void cacheFlush(void* code, size_t size)
{
asm volatile (
"push {r7}\n"
"mov r0, %0\n"
"mov r1, %1\n"
"mov r7, #0xf0000\n"
"add r7, r7, #0x2\n"
"mov r2, #0x0\n"
"svc 0x0\n"
"pop {r7}\n"
:
: "r" (code), "r" (reinterpret_cast<char*>(code) + size)
: "r0", "r1", "r2");
}
Now it works :-).
On 28 Jun., 11:12, "[email protected]"
<[email protected]> wrote:
> I wrote a simple data execution prevention (DEP) test to check if my
> DEP patch for Android is working and to also check the PaX patch.
> This worked pretty fine, but my test program crashes with a SIGSEGV in
> 50% of the test runs. In the other cases the tests work perfectly.
> I don't know why my test does not always succeed. I already tried to
> clear the instruction cache. But this did not help either.
> I tried the same on the x86. There it does always work perfectly. But
> it also has a common instruction and data cache. Maybe that has to do
> with the problem.
>
> Any ideas?
>
> @Google: I think Android should have enabled DEP and ASLR in the
> kernel by default, just like iOS :-). This is only a minimal patch
> (you do not need the complete PaX patch)
>
> Here is my test code:
>
> DepTest.cpp:
> #include <stdlib.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/mman.h>
>
> extern "C" uint32_t jmpToCode(uint32_t address);
>
> int main()
> {
> void* data = new uint32_t[4096];
>
> uint32_t* code = (uint32_t*) data;
> // arm-eabi-objdump -d Test
> // code[0] = 0xef9f0002; // endless loop
> code[0] = 0xe320f000; // nop
> code[1] = 0xe320f000; // nop
> code[2] = 0xe320f000; // nop
> code[3] = 0xe320f000; // nop
> code[4] = 0xe320f000; // nop
> code[5] = 0xe320f000; // nop
> code[6] = 0xe320f000; // nop
> code[7] = 0xe1a0f00e; // jump back to calling function -> mov pc, lr
>
> printf("DEP-Test (1): 0x%X: 0x%X\n", code, code[0]);
> uint32_t rc = jmpToCode((uint32_t)code);
> printf("DEP-Test (2): 0x%X 0x%X: 0x%X\n", rc, code, code[0]);
>
> return 0;
>
> }
>
> Utils.S:
> .text
>
> # The first 4 args are passed via r0 to r3
> # The return code is always in r0
> # pc points to the next instruction to be fetched, not to the
> instructing that will be executed next
> # - in ARM state, the pc always points to the address of the
> instruction plus 8 bytes
> # - in Thumb state, the pc is the instruction address plus 4 bytes
>
> .code 32
> .align 4
> .global jmpToCode
> jmpToCode:
> push {ip, lr}
> mov lr, pc @ lr points to the "mov r0, ..."
> command
> mov pc, r0
> mov r0, r0
> pop {ip, pc}
--
unsubscribe: [email protected]
website: http://groups.google.com/group/android-porting