Whitespace, 67 bytes
This program requires a null byte to mark the end of input as Whitespace has no way to detect when stdin is empty. TheIf you're using the TIO version has been modifiedlink make sure not to use a newline asdelete the marker because that environment doesn't support null byteslast character in the input streamfield (looks like a space) as it's a null byte. If you do you'll need to append a null byte using your browsers console.
Explanation
(s - space, t - tab, n - newline)
sssn ; push 0 to use as the starting heap address
nsstn ; label 'read-loop'
sns ; dup
tnts ; getchar and store at address n
sns ; dup
ttt ; retrieve the character value we just read
ntsn ; jez 'output-loop' - if it was a null byte switch to output
ssstn ; push 1
tsss ; add - increment n
nsntn ; jmp 'read-loop'
nssn ; label 'output-loop'
ssstn ; push 1
tsst ; sub - decrement n
sns ; dup
ttt ; retrieve the character value at address n
tnss ; putchar - display the character
nsnn ; jmp 'output-loop'
Whitespace uses a stack and a heap for data storage. As I/O commands write to the heap naturally we store the string on the heap and keep the stack for our counter.
This program reads characters one at a time and stores them in order starting from heap address 0 counting up. Once the program reads a null byte it starts displaying characters starting from the previous heap address counting down. For the input hello\0
this populates the heap as [#0:h,#1:e,#2:l,#3:l,#4:o,#5:\0]
then outputs the characters at addresses #4,#3,#2,#1,#0
and we end up with olleh
.