3 ms·
I see where I was off by one byte (14 instead of 13) but that still doesn't explain things. The code doesn't load edx with 13 but instead loads it with 0x08048
by abbeyj 13y ago
I see where I was off by one byte (14 instead of 13) but that still doesn't explain things. The code doesn't load edx with 13 but instead loads it with 0x080480B1. If you wanted to fetch a byte from that address and load it into edx you'd need to use something like "movzx edx, byte ptr [0x080480B1]" but the code on the page just does "mov edx, 0x080480B1". In fact when you run this the code actually prints out not just "Hello, World\n" but also prints out the 0x0D length byte and then the entire rest of the page (all 0x00). Of course these aren't visible in a terminal.
I'm guessing the kernel tries to keep printing but it can't since the next page isn't mapped so it just gives up.
- deleted 13y ago[deleted]
- adestefan 13y agoI agree. This is definitely a bug. The correct instruction is 8b 15 B1800408 or a MOV EDX, [0x080480B1]. I hope I got my register number correct on that. The movzx/movsx is only needed when you're doing something like movzx EAX, BX. That way you're sure the CPU does what you expect when moving from a smaller register to a larger one. Man do I hate x86.
- arh68 13y agoYeah, you're right. The syscall does ask for a size_t. It now looks correct. The whole length-after-the-string part is edited out, and the value is indeed placed as immediate (as the syscall wants). Now the binary ends with "hello, world\n" and 14 is inserted directly (b9 a4 80 04 08, ba 0d 00 00 00).