WinDbg, 87 71 bytes
db$t0 L1;.for(r$t1=@$t0;@$p;r$t1=@$t1+1){db$t1 L1};da$t0 L(@$t1-@$t0)/2
-16 bytes by not inserting NULL, instead passing length to da
Input is passed in via an address in psuedo-register $t0
. For example:
eza 2000000 "abcdedcba" * Write string "abcdedcba" into memory at 0x02000000
r $t0 = 33554432 * Set $t0 = 0x02000000
* Edit: Something got messed up in my WinDB session, of course r $t0 = 2000000 should work
* not that crazy 33554432.
It works by replacing the right of middle char (or right-middle if the string has even length) with a null and then prints the string from the original starting memory address.
db $t0 L1; * Set $p = memory-at($t0)
.for (r $t1 = @$t0; @$p; r $t1 = @$t1 + 1) * Set $t1 = $t0 and increment until $p == 0
{
db $t1 L1 * Set $p = memory-at($t1)
};
da $t0 L(@$t1-@$t0)/2 * Print half the string
Output:
0:000> eza 2000000 "abcdeedcba"
0:000> r $t0 = 33554432
0:000> db$t0 L1;.for(r$t1=@$t0;@$p;r$t1=@$t1+1){db$t1 L1};da$t0 L(@$t1-@$t0)/2
02000000 61 a
02000000 61 a
02000001 62 b
02000002 63 c
02000003 64 d
02000004 65 e
02000005 65 e
02000006 64 d
02000007 63 c
02000008 62 b
02000009 61 a
0200000a 00 .
02000000 "abcde"