如何使用 Radare2 更改 local_184h 以跳过跳转命令?

逆向工程 x86 雷达2 登记
2021-06-24 14:21:19

我正在尝试解决 CTF 挑战,但我的深度不够,网上没有什么能帮到我。这就是我目前正在使用的

|           0x55b3fd508a41      4889e5         mov rbp, rsp                                                                                                   
|           0x55b3fd508a44      4881ec900100.  sub rsp, 0x190                                                                                                 
|           0x55b3fd508a4b      89bd7cfeffff   mov dword [local_184h], edi       ; argc                                                                       
|           0x55b3fd508a51      4889b570feff.  mov qword [local_190h], rsi       ; argv                                                                       
|           0x55b3fd508a58      64488b042528.  mov rax, qword fs:[0x28]       ; [0x28:8]=-1 ; '(' ; 40                                                        
|           0x55b3fd508a61      488945f8       mov qword [local_8h], rax                                                                                      
|           0x55b3fd508a65      31c0           xor eax, eax                                                                                                   
|           0x55b3fd508a67      c78588feffff.  mov dword [local_178h], 0x2d       ; '-' ; 45                                                                  
|           0x55b3fd508a71      c7858cfeffff.  mov dword [local_174h], 0x32       ; '2' ; 50                                                                  
|           0x55b3fd508a7b      83bd7cfeffff.  cmp dword [local_184h], 1       ; rdi ; [0x1:4]=-1                                                             
|       ,=< 0x55b3fd508a82      0f8e77010000   jle 0x55b3fd508bff      ;[1]                                                                                   
|       |   0x55b3fd508a88      488b8570feff.  mov rax, qword [local_190h]                                                                                    
|       |   0x55b3fd508a8f      4883c008       add rax, 8                                                                                                     
|       |   0x55b3fd508a93      488b00         mov rax, qword [rax]                                                                                           
|       |   0x55b3fd508a96      488d35fb0200.  lea rsi, str.calc       ; 0x55b3fd508d98 ; "calc"                                                              
|       |   0x55b3fd508a9d      4889c7         mov rdi, rax   

我对线路感兴趣0x55b3fd508a7b,是什么local_184h意思?如何编辑此值以更改即将到来的结果jle或者,如何更改jle命令的结果而不必更改local_184h我读到它检查标志标志,所以我将rflags寄存器编辑0x0080小于它,希望这会改变结果,jle但它没有。

1个回答

根据英特尔的手册

3.4.3.1
Status Flags
The status flags (bits 0, 2, 4, 6, 7, and 11) of the EFLAGS register indicate the results of arithmetic instructions, such as the ADD, SUB, MUL, and DIV instructions. The status flag functions are:
CF (bit 0) Carry flag — Set if an arithmetic operation generates a carry or a borrow out of the most- significant bit of the result; cleared otherwise. This flag indicates an overflow condition for unsigned-integer arithmetic. It is also used in multiple-precision arithmetic.
PF (bit 2) Parity flag — Set if the least-significant byte of the result contains an even number of 1 bits; cleared otherwise.
AF (bit 4) Auxiliary Carry flag — Set if an arithmetic operation generates a carry or a borrow out of bit 3 of the result; cleared otherwise. This flag is used in binary-coded decimal (BCD) arithmetic.
ZF (bit 6) Zero flag — Set if the result is zero; cleared otherwise.
SF (bit 7) Sign flag — Set equal to the most-significant bit of the result, which is the sign bit of a signed integer. (0 indicates a positive value and 1 indicates a negative value.)
OF (bit 11) Overflow flag — Set if the integer result is too large a positive number or too small a negativenumber (excluding the sign-bit) to fit in the destination operand; cleared otherwise. This flag indicates an overflow condition for signed-integer (two’s complement) arithmetic.

所以要设置单独的标志,你需要对单独的位进行操作

清除n第一个位number

number &= ~(1 << n)

对于 SF n = 7,因此要取消设置 SF

eflags &= ~(1 << 7)

用这个简单的代码

int main(int argc, char **argv) {
    int in;
    scanf("%d", &in);
    if (in > 10) {
        puts("greater");
    } else {
        puts("less");
    }
    return 0;
}

这可以轻松实现

[re] r2 -d test
Process with PID 17193 started...
= attach 17193 17193
bin.baddr 0x55c79226b000
Using 0x55c79226b000
asm.bits 64
[0x7fb03234b090]> dcu sym.main
Continue until 0x55c79226b83a using 1 bpsize
hit breakpoint at: 0x55c79226b83a
[0x55c79226b83a]> pd20
            ;-- main:
            ;-- rax:
            ;-- rip:
            0x55c79226b83a      55             push rbp
            0x55c79226b83b      4889e5         mov rbp, rsp
            0x55c79226b83e      4883ec20       sub rsp, 0x20
            0x55c79226b842      897dec         mov dword [rbp - 0x14], edi
            0x55c79226b845      488975e0       mov qword [rbp - 0x20], rsi
            0x55c79226b849      64488b042528.  mov rax, qword fs:[0x28]
            0x55c79226b852      488945f8       mov qword [rbp - 8], rax
            0x55c79226b856      31c0           xor eax, eax
            0x55c79226b858      488d45f4       lea rax, [rbp - 0xc]
            0x55c79226b85c      4889c6         mov rsi, rax
            0x55c79226b85f      488d3dee0100.  lea rdi, [0x55c79226ba54] ; "%d"
            0x55c79226b866      b800000000     mov eax, 0
            0x55c79226b86b      e880feffff     call sym.imp.scanf
            0x55c79226b870      8b45f4         mov eax, dword [rbp - 0xc]
            0x55c79226b873      83f80a         cmp eax, 0xa            ; 10
        ┌─< 0x55c79226b876      7e0e           jle 0x55c79226b886
        │   0x55c79226b878      488d3dd80100.  lea rdi, str.greater    ; 0x55c79226ba57 ; "greater"
        │   0x55c79226b87f      e88cfeffff     call sym.imp.puts
       ┌──< 0x55c79226b884      eb0c           jmp 0x55c79226b892
       │└─> 0x55c79226b886      488d3dd20100.  lea rdi, str.less       ; 0x55c79226ba5f ; "less"
[0x55c79226b83a]> dcu 0x55c79226b876
Continue until 0x55c79226b876 using 1 bpsize
7
hit breakpoint at: 0x55c79226b876
[0x55c79226b876]> dr eflags
0x00000293
[0x55c79226b876]> dr eflags=0x213
0x00000293 ->0x00000213
[0x55c79226b876]> dc
greater
(17193) Process exited with status=0x0

这里 eflags 从 0x00000293 更新为 0x00000213,因为

0x293&~(1<<7) = 0x213 

输入为 7 但输出为“更大”,因为未dr eflags=0x213设置 SF

同样在另一个方向,设置 SF

eflags |= (1 << 7)

对于较大的输入,它可用于转到较小的分支

[re] r2 -d test
Process with PID 23724 started...
= attach 23724 23724
bin.baddr 0x562ccba44000
Using 0x562ccba44000
asm.bits 64
[0x7f568eeaa090]> dcu sym.main
Continue until 0x562ccba4483a using 1 bpsize
hit breakpoint at: 0x562ccba4483a
[0x562ccba4483a]> pd20
            ;-- main:
            ;-- rax:
            ;-- rip:
            0x562ccba4483a      55             push rbp
            0x562ccba4483b      4889e5         mov rbp, rsp
            0x562ccba4483e      4883ec20       sub rsp, 0x20
            0x562ccba44842      897dec         mov dword [rbp - 0x14], edi
            0x562ccba44845      488975e0       mov qword [rbp - 0x20], rsi
            0x562ccba44849      64488b042528.  mov rax, qword fs:[0x28]
            0x562ccba44852      488945f8       mov qword [rbp - 8], rax
            0x562ccba44856      31c0           xor eax, eax
            0x562ccba44858      488d45f4       lea rax, [rbp - 0xc]
            0x562ccba4485c      4889c6         mov rsi, rax
            0x562ccba4485f      488d3dee0100.  lea rdi, [0x562ccba44a54] ; "%d"
            0x562ccba44866      b800000000     mov eax, 0
            0x562ccba4486b      e880feffff     call sym.imp.scanf
            0x562ccba44870      8b45f4         mov eax, dword [rbp - 0xc]
            0x562ccba44873      83f80a         cmp eax, 0xa            ; 10
        ┌─< 0x562ccba44876      7e0e           jle 0x562ccba44886
        │   0x562ccba44878      488d3dd80100.  lea rdi, str.greater    ; 0x562ccba44a57 ; "greater"
        │   0x562ccba4487f      e88cfeffff     call sym.imp.puts
       ┌──< 0x562ccba44884      eb0c           jmp 0x562ccba44892
       │└─> 0x562ccba44886      488d3dd20100.  lea rdi, str.less       ; 0x562ccba44a5f ; "less"
[0x562ccba4483a]> dcu 0x562ccba44876
Continue until 0x562ccba44876 using 1 bpsize
100
hit breakpoint at: 0x562ccba44876
[0x562ccba44876]> dr eflags
0x00000216
[0x562ccba44876]> "?vx eflags|(1 << 7)"
0x00000296
[0x562ccba44876]> dr eflags=0x296
0x00000216 ->0x00000296
[0x562ccba44876]> dc
less
(23724) Process exited with status=0x0

另外查看您的反汇编注释,您似乎正在分析二进制文件的主要功能。这里我们argc从 edi复制local_184h

|           0x55b3fd508a4b      89bd7cfeffff   mov dword [local_184h], edi       ; argc

因此,如果您以至少 1 个参数开始二进制文件,它应该可以工作。就像是

$ r2 -d binary arg1 

应该管用