4 ms·
The SIGSEGVs you are seeing are caused by these instructions: 0x8048199 <_start+299> add cl, 0x2 0x804819c <_start+302> jp 0x80481a3 <_s
by fortyonepercent 4y ago
The SIGSEGVs you are seeing are caused by these instructions:
0x8048199 <_start+299> add cl, 0x2
0x804819c <_start+302> jp 0x80481a3 <_start+309>
At this point, ECX has a value based on the initial value of your stack pointer ESP. With ASLR enabled, this is randomized by the ELF loader. The parity flag (PF) is set if the number of bits in the least significant byte of the arithmetic result (which is just CL) is even, and cleared if odd. This ends up clear about 50% of the time, so the branch isn't taken and execution continues here, which because EAX is 1 (from the previous syscall return value), is an invalid access, causing SIGSEGV:
0x804819e <_start+304> pblendw xmm2, XMMWORD PTR [eax+0x4eb3909], 0xd9
You should be able to reliably reproduce this in GDB by providing additional arguments to your program, which will adjust the initial value of ESP as they are placed on the stack. For example, this worked to always hit the SIGSEGV on my system:
gdb -ex r --args ./gibberish 1 2 3 4 5 6 7
There's another potential issue here, in that these instructions assume that the most significant bit is set in ESP, which EBP has been derived from (via ECX):
0x8048127 <_start+185> neg ebp
0x8048129 <_start+187> jns 0x804812d <_start+191>
This isn't always the case. For instance, if running your binary under QEMU's user-mode emulation, the stack is likely to be placed in the lower end of the address space, so that branch isn't taken and you will get a SIGSEGV here:
0x804812b <_start+189> cmovb edx, DWORD PTR [eax-0x72dbfbe0]
- phoreverpheebs 4y agothank you! you are wonderful for this <3 idk why but the stack being in the lower end of the address space doesn't feel right. nevertheless this is an amazing explanation and thank you for taking the time <3