Let me first explain why your script is not working for you.
Basically, the problem you encounter is a result of a common misconception about copyin(). It is intended to be used to copy content of userspace memory into a scratch buffer so that it can be accessed directly from within kernel space (where the DTrace core executes). That said, it is often interpreted as somehow being equivalent to malloc() whereas in reality it actually works like alloca() instead. So, what you are seeing is basically the artefact of the scratch buffer being overwritten with other data. And unfortunately, that is perfectly legal.
The content of the scratch buffer pointed to by self->addr in your script is only valid for as long as the specific probe enabling is executing (it is clause-local). So, your clauses to print out the actual bytes in the buffer are looking at a buffer that is for all intends and purposes no longer reserved, and therefore you are looking at it after other data was written to the scratch space.
So... in order for this to work, you should do things a bit different. Rather than trying to get a copy of the buffer in one clause, and then read from it in following clauses, you can simply collect the buffer address in the entry read:entry clause, get the number of bytes read in the first read:return clause, and then for every clause in which you print 4 bytes do the following (example for bytes 4-7):
/execname == "foobar" && self->nbytes > 4/
this->addr = (char *)copyin((uintptr_t)self->bufferaddr + 4, 4);
printf(" 4- 7: %02x %02x %02x %02x\n", this->addr, this->addr, this->addr, this->addr);
So basically, for every clause that print 4 bytes you copyin those bytes, and then print them out.