armdisassemblycracking

How can I change BNE instruction to BEQ and change its argument?


I have the following code after disassembling an arm program. How can I change bne instruction to beq in binary of this program? And how can I change bne jump offset?

e50b0008        str     r0, [fp, #-8]
e50b100c        str     r1, [fp, #-12]
e51b3008        ldr     r3, [fp, #-8]
e353000d        cmp     r3, #13
1a000001        bne     28 <main+0x28>
e3a03007        mov     r3, #7
ea000000        b       2c <main+0x2c>
e3a03002        mov     r3, #2
e1a00003        mov     r0, r3

Solution

  • Ok, I think I got an answer for question about how to change beq to bne. I compiled and disassembled this C code (maybe it's not the best solution, but I was experimenting and it's just for disassembling):

    int f(int i) {
        if (i == 0) {
            return 1;
        }
        return i + f(i - 1);
    }
    
    int max(int a) {
        int res = 1;
        for (int i = 0; i < a * 2; i++) {
            if (i % 3 != a % 2) {
                res += f(i);
            }
        }
        return res;
    } 
    

    Here if you change i % 3 != a % 2 to i % 3 == a % 2, difference between disassembled codes will be:

    26c26
    <   40: e3a02000    mov r2, #0
    ---
    >   40: e3a0c000    mov ip, #0
    28c28
    <   48: e15e0002    cmp lr, r2
    ---
    >   48: e15e000c    cmp lr, ip
    33,34c33,34
    <   5c: e2822001    add r2, r2, #1
    <   60: e1520004    cmp r2, r4
    ---
    >   5c: e28cc001    add ip, ip, #1
    >   60: e15c0004    cmp ip, r4
    36,39c36,39
    <   68: e0813295    umull   r3, r1, r5, r2
    <   6c: e3c13001    bic r3, r1, #1
    <   70: e08330a1    add r3, r3, r1, lsr #1
    <   74: e0423003    sub r3, r2, r3
    ---
    >   68: e0823c95    umull   r3, r2, r5, ip
    >   6c: e3c23001    bic r3, r2, #1
    >   70: e08330a2    add r3, r3, r2, lsr #1
    >   74: e04c3003    sub r3, ip, r3
    41,44c41,44
    <   7c: 1afffff6    bne 5c <max+0x30>
    <   80: e3520000    cmp r2, #0
    <   84: 11a03002    movne   r3, r2
    <   88: 13a01000    movne   r1, #0
    ---
    >   7c: 0afffff6    beq 5c <max+0x30>
    >   80: e35c0000    cmp ip, #0
    >   84: 11a0300c    movne   r3, ip
    >   88: 13a02000    movne   r2, #0
    46c46
    <   90: e1a0c003    mov ip, r3
    ---
    >   90: e1a01003    mov r1, r3
    48c48
    <   98: e081100c    add r1, r1, ip
    ---
    >   98: e0822001    add r2, r2, r1
    50,53c50,53
    <   a0: e2811001    add r1, r1, #1
    <   a4: e2822001    add r2, r2, #1
    <   a8: e1520004    cmp r2, r4
    <   ac: e0800001    add r0, r0, r1
    ---
    >   a0: e2822001    add r2, r2, #1
    >   a4: e28cc001    add ip, ip, #1
    >   a8: e15c0004    cmp ip, r4
    >   ac: e0800002    add r0, r0, r2
    57c57
    <   bc: e3a01001    mov r1, #1
    ---
    >   bc: e3a02001    mov r2, #1
    
    

    And I think, that 0afffff6 beq 5c <max+0x30> and 1afffff6 bne 5c <max+0x30> is what I need. So, we just need to change 0a to 1a. Considering byte order, one of the solutions on python3 will be:

    # I need it if there are more 1a000001 fragments.
    pref = b"\x0d\x00\x53\xe3"
    suff = b"\x07\x30\xa0\xe3"
    
    # source is file, which code is disassembled
    with open("source", mode="rb") as rfile:
        with open("cracked", mode="wb") as wfile:
            data = rfile.read()
            data = data.replace(pref + b"\x01\x00\x00\x1a" + suff, pref + b"\x01\x00\x00\x0a" + suff)
    
            wfile.write(data)