5
votes

I am trying to modify a string which is stored in memory by changing a byte in it. I'm using movb to this but for some reason, the byte at the given memory location is not changing.

On gdb debugger:

14 movb %al, (%r10) # next instr
(gdb) print /d $al
$4 = 0
(gdb) print /c *$r10
$5 = 47 '/'
(gdb) s
16 mov $59, %rax
(gdb) print /c *$r10
$6 = 47 '/'

The code is just:

.globl _start
.text

_start:
        call chamaexecve
        variaveis:
            .asciz "/bin/bashABBBBCCCC"


    chamaexecve: 

        pop %r10
        xor %rax, %rax
        movb %al, (%r10) # problem happening here

        mov $59, %rax
        mov %rsi, %rdi
        mov $0, %rsi
        mov $0, %rdx

        syscall

And it is being compiled with as -gstabs -o shellf.o shellf.s - ld -N -z execstack -o shellf shellf.o

Edit To be sure I wasn't making any mistake I deleted the executable and recompiled. The error persists. Another thing I noticed is that if I add a line movb $'r', %al before moving %al to memory, so the 'r' is normally printed on memory but for some reason it is not working with the $0 value.

I'm running this on a Linux Mint 18.1 "Serena" rolling release, gnu assembler 2.26.1. Here is a print using x/i $rip to show the current instruction:

enter image description here

Edit2: After changing break to tbreak and s to si, I saw it changing from '/' to '\000' finally. So what could be the problem after all s/break/gdb getting messed up?

(gdb) tb 14
Temporary breakpoint 1 at 0x4000cd: file shellf.s, line 14.
(gdb) run
Starting program: /home/fabio/criação/nasm-tutorial/shellf

Temporary breakpoint 1, chamaexecve () at shellf.s:14
14 movb %al, (%r10)
(gdb) si
16 mov $59, %rax
(gdb) print /c *$rsi
Cannot access memory at address 0x0
(gdb) print /c *$r10
$1 = 0 '\000'
(gdb)

1
Are you sure you are running the binary you just compiled? Works fine here, as it should. +1 for using a debugger though :) Also check actual instruction with x/i $rip in case debug info is mismatched.Jester
@NickApperson because of the call+pop trick (which is of course not needed in 64 bit, but that's a different matter).Jester
He used the s command (single step) which relies on debug info being correct so I'd be happier to see si being used and the output of x/i $rip which he also claims is fine. Furthermore, writing something else than a zero is reported to work, I can't think of any reason why writing a zero should then fail.Jester
I think what is happening is that GDB is getting messed up with self modifying code. Rather than use break 14 what if you make it a temporary break with tbreak 14.Michael Petch
Given that these seems to work in some environments (Debian Jessie) and not in others (your environment and Ubuntu 16.04) you might want to address this issue with the GDB bug tracking system. See this link to make a report: gnu.org/software/gdb/bugs . I can only guess that a GDB bug and/or the Linux environment you are running in is somehow interfering with proper operation. It is possible it may be expected behavior (and they have a work around) or they find it to be a bug. I was able to confirm this behaviour on Ubuntu 16.04 which Linux Mint 18.1 is based on.Michael Petch

1 Answers

0
votes

The .text section of a program is read only, if you would like to modify the string you'll want to place it in the .data section.