简单ARM任意代码执行程序上的非法指令错误

时间:2019-05-20 13:51:25

标签: c arm

我正在Raspberry Pi 3上编写一个简单的代码执行漏洞,并且收到“非法指令”错误。为了编译该程序,我禁用了ASLR并添加了以下编译器选项:

-fno-inline -O0 -fno-stack-protector -z execstack -Wall

我在g=h分配上收到“来自不兼容指针类型的分配”警告,但我不明白为什么这会成为问题。

代码如下:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

void printFunction(char *f){
    for(int i=0;i<50;i++){
        printf("\\x%x",(f)[i]);
    }
    printf("\n");
}

void f(){
    printf("Success\n");
}

int main(){

    void (*g)();

    g=f;
    printf("%p\n",g);
    g=(void *)0x1053c; // This is the address of f()
    printf("%p\n",g);

    char h[256];
    memcpy(h,f,256);

    printFunction((char *)g);
    printFunction((char *)h);

    g(); // Succeeds
    g=h;
    g(); // Fails
}

我使用printFunction函数查看每个指针指向的内存。 g和h所指向的内存是相同的,但是g指向了文本部分,而h如所预期的那样位于堆栈的某个位置。我了解到某些内存不可执行,但是-z execstack标志应注意这一点。

我还考虑过我的问题可能与对齐方式有关,但我不知道如何解决。

以下是相关功能的反汇编:

0001053c <f>:
   1053c:       e92d4800        push    {fp, lr}
   10540:       e28db004        add     fp, sp, #4
   10544:       e59f0008        ldr     r0, [pc, #8]    ; 10554 <f+0x18>
   10548:       ebffff88        bl      10370 <puts@plt>
   1054c:       e1a00000        nop                     ; (mov r0, r0)
   10550:       e8bd8800        pop     {fp, pc}
   10554:       00010678        .word   0x00010678

00010558 <main>:
   10558:       e92d4800        push    {fp, lr}
   1055c:       e28db004        add     fp, sp, #4
   10560:       e24ddf42        sub     sp, sp, #264    ; 0x108
   10564:       e59f3084        ldr     r3, [pc, #132]  ; 105f0 <main+0x98>
   10568:       e50b3008        str     r3, [fp, #-8]
   1056c:       e51b1008        ldr     r1, [fp, #-8]
   10570:       e59f007c        ldr     r0, [pc, #124]  ; 105f4 <main+0x9c>
   10574:       ebffff77        bl      10358 <printf@plt>
   10578:       e59f3078        ldr     r3, [pc, #120]  ; 105f8 <main+0xa0>
   1057c:       e50b3008        str     r3, [fp, #-8]
   10580:       e51b1008        ldr     r1, [fp, #-8]
   10584:       e59f0068        ldr     r0, [pc, #104]  ; 105f4 <main+0x9c>
   10588:       ebffff72        bl      10358 <printf@plt>
   1058c:       e24b3f42        sub     r3, fp, #264    ; 0x108
   10590:       e3a02c01        mov     r2, #256        ; 0x100
   10594:       e59f1054        ldr     r1, [pc, #84]   ; 105f0 <main+0x98>
   10598:       e1a00003        mov     r0, r3
   1059c:       ebffff70        bl      10364 <memcpy@plt>
   105a0:       e51b0008        ldr     r0, [fp, #-8]
   105a4:       ebffffca        bl      104d4 <printFunction>
   105a8:       e24b3f42        sub     r3, fp, #264    ; 0x108
   105ac:       e1a00003        mov     r0, r3
   105b0:       ebffffc7        bl      104d4 <printFunction>
   105b4:       e24b3f42        sub     r3, fp, #264    ; 0x108
   105b8:       e1a02003        mov     r2, r3
   105bc:       e51b1008        ldr     r1, [fp, #-8]
   105c0:       e59f0034        ldr     r0, [pc, #52]   ; 105fc <main+0xa4>
   105c4:       ebffff63        bl      10358 <printf@plt>
   105c8:       e51b3008        ldr     r3, [fp, #-8]
   105cc:       e12fff33        blx     r3
   105d0:       e24b3f42        sub     r3, fp, #264    ; 0x108
   105d4:       e50b3008        str     r3, [fp, #-8]
   105d8:       e51b3008        ldr     r3, [fp, #-8]
   105dc:       e12fff33        blx     r3
   105e0:       e3a03000        mov     r3, #0
   105e4:       e1a00003        mov     r0, r3
   105e8:       e24bd004        sub     sp, fp, #4
   105ec:       e8bd8800        pop     {fp, pc}
   105f0:       0001053c        .word   0x0001053c
   105f4:       00010680        .word   0x00010680
   105f8:       0001053c        .word   0x0001053c
   105fc:       00010684        .word   0x00010684

1 个答案:

答案 0 :(得分:0)

您不能将函数转换为任何类型的数据指针。因此memcpy(h,f,256);是非法的。

g = h;似乎由于C的慷慨而可以编译,但仍会导致可执行文件损坏。 h将处于不确定状态。