Reply 20 of 47, by superfury
ff8: sp0 base for the original IRQ0 handler to return to the never returning code
ff6: IRET ss
ff4: IRET sp
ff2: IRET flags
ff0: IRET cs
fee: IRET ip (base frame for IRQ0)
fec: 0h
fea: Dh
fe8: call IP=cc6h
fe6: ???
fe4: ???
fe2: ???
fe0: ???
fde: gs
ffc: fs
fda: ds
fd8: es
fd6: 0h
fd2: eax=1Ch
fce: ecx=0
fca: edx=Ah
fc6: ebx=0
fc2: esp=FD6h
fbe: ebp=3EB4
fba: esi=2127h
fb6: edi=2174h
fb4: [ds:63E]=fb4h (check against 75h happened here)
fb2: IRET flags=3202h
fb0: bx=B3h
fae: cx=2h
fac: 3h
faa: 0h
fa8: 1h
fa6: dx=417h
fa4: ax=26BCh
fa2: ip=3D64h
fa0: bp=FB4 <- bp
f9e: si <- sp
At 0020:000036d2, CX becomes the calling segment(417h), DX becomes the calling offset(3D64h)?
AX becomes the user stack. Then it compares some parameter(FAA=0h), which matches, so it doesn't jump.
It then pops SI(seems sane).
ff8: sp0 base for the original IRQ0 handler to return to the never returning code
ff6: IRET ss
ff4: IRET sp
ff2: IRET flags
ff0: IRET cs
fee: IRET ip (base frame for IRQ0)
fec: 0h
fea: Dh
fe8: call IP=cc6h
fe6: ???
fe4: ???
fe2: ???
fe0: ???
fde: gs
ffc: fs
fda: ds
fd8: es
fd6: 0h
fd2: eax=1Ch
fce: ecx=0
fca: edx=Ah
fc6: ebx=0
fc2: esp=FD6h
fbe: ebp=3EB4
fba: esi=2127h
fb6: edi=2174h
fb4: [ds:63E]=fb4h (check against 75h happened here)
fb2: IRET flags=3202h
fb0: bx=B3h
fae: cx=2h
fac: 3h
faa: 0h
fa8: 1h
fa6: dx=417h
fa4: ax=26BCh
fa2: ip=3D64h
fa0: bp=FB4 <- bp <- sp
But then it moves SI into SP? Although this has the same effect as POP SP in this case? But it leaves EBP(FA0) intact, even though SP>BP at that moment? That's kind of strange behaviour?
ff8: sp0 base for the original IRQ0 handler to return to the never returning code
ff6: IRET ss
ff4: IRET sp
ff2: IRET flags
ff0: IRET cs
fee: IRET ip (base frame for IRQ0)
fec: 0h
fea: Dh
fe8: call IP=cc6h
fe6: ???
fe4: ???
fe2: ???
fe0: ???
fde: gs
ffc: fs
fda: ds
fd8: es
fd6: 0h
fd2: eax=1Ch
fce: ecx=0
fca: edx=Ah
fc6: ebx=0
fc2: esp=FD6h
fbe: ebp=3EB4
fba: esi=2127h
fb6: edi=2174h
fb4: [ds:63E]=fb4h (check against 75h happened here) <- sp
fb2: IRET flags=3202h
fb0: bx=B3h
fae: cx=2h
fac: 3h
faa: 0h
fa8: 1h
fa6: dx=417h
fa4: ax=26BCh
fa2: ip=3D64h
fa0: bp=FB4 <- bp
It then pushes 0h 7 times, destroying the return segment? This seems very strange?
So the weird kind of code starts at 0020:000036e1, with the mov sp,si instruction?
Edit: OK. So the kernel stack isn't directly affected by the overwrites. The kernel stack still contains the original values of the originally interrupted thread/application.
So, SP is moved to SI, which is the originating stack pointer. So the top of stack is moved back to the previous stack frame at FB4, then new data overwrites it:
ff8: sp0 base for the original IRQ0 handler to return to the never returning code
ff6: IRET ss
ff4: IRET sp
ff2: IRET flags
ff0: IRET cs
fee: IRET ip (base frame for IRQ0)
fec: 0h
fea: Dh
fe8: call IP=cc6h
fe6: ???
fe4: ???
fe2: ???
fe0: ???
fde: gs
ffc: fs
fda: ds
fd8: es
fd6: 0h
fd2: eax=1Ch
fce: ecx=0
fca: edx=Ah
fc6: ebx=0
fc2: esp=FD6h
fbe: ebp=3EB4
fba: esi=2127h
fb6: edi=2174h
fb4: [ds:63E]=fb4h (check against 75h happened here)
fb2: 0
fb0: 0
fae: 0
fac: 0
faa: 0
fa8: 0
fa6: 0
fa4: ip=36F4h *done by call 0000131c at 0020:000036f1*
fa2: ip=3D64h
fa0: bp=FB4 <- bp
f9e: ???
f9c: ???
f9a: ???
f98: ??? <- sp
It then pushes DS and 98h.
ff8: sp0 base for the original IRQ0 handler to return to the never returning code
ff6: IRET ss
ff4: IRET sp
ff2: IRET flags
ff0: IRET cs
fee: IRET ip (base frame for IRQ0)
fec: 0h
fea: Dh
fe8: call IP=cc6h
fe6: ???
fe4: ???
fe2: ???
fe0: ???
fde: gs
ffc: fs
fda: ds
fd8: es
fd6: 0h
fd2: eax=1Ch
fce: ecx=0
fca: edx=Ah
fc6: ebx=0
fc2: esp=FD6h
fbe: ebp=3EB4
fba: esi=2127h
fb6: edi=2174h
fb4: [ds:63E]=fb4h (check against 75h happened here)
fb2: 0
fb0: 0
fae: 0
fac: 0
faa: 0
fa8: 0
fa6: 0
fa4: ip=36F4h *done by call 0000131c at 0020:000036f1*
fa2: ip=3D64h
fa0: bp=FB4 <- bp
f9e: ???
f9c: ???
f9a: ???
f98: ???
f96: ds=18h
f94: 98h <- sp
It pops DS again for the 98h selector to be loaded. And push ES.
ff8: sp0 base for the original IRQ0 handler to return to the never returning code
ff6: IRET ss
ff4: IRET sp
ff2: IRET flags
ff0: IRET cs
fee: IRET ip (base frame for IRQ0)
fec: 0h
fea: Dh
fe8: call IP=cc6h
fe6: ???
fe4: ???
fe2: ???
fe0: ???
fde: gs
ffc: fs
fda: ds
fd8: es
fd6: 0h
fd2: eax=1Ch
fce: ecx=0
fca: edx=Ah
fc6: ebx=0
fc2: esp=FD6h
fbe: ebp=3EB4
fba: esi=2127h
fb6: edi=2174h
fb4: [ds:63E]=fb4h (check against 75h happened here)
fb2: 0
fb0: 0
fae: 0
fac: 0
faa: 0
fa8: 0
fa6: 0
fa4: ip=36F4h *done by call 0000131c at 0020:000036f1*
fa2: ip=3D64h
fa0: bp=FB4 <- bp
f9e: ???
f9c: ???
f9a: ???
f98: ???
f96: ds=18h
f94: es=5Bh <- sp
It then pushes 0h and finds bit 2 of DS:[401] being set.
ff8: sp0 base for the original IRQ0 handler to return to the never returning code
ff6: IRET ss
ff4: IRET sp
ff2: IRET flags
ff0: IRET cs
fee: IRET ip (base frame for IRQ0)
fec: 0h
fea: Dh
fe8: call IP=cc6h
fe6: ???
fe4: ???
fe2: ???
fe0: ???
fde: gs
ffc: fs
fda: ds
fd8: es
fd6: 0h
fd2: eax=1Ch
fce: ecx=0
fca: edx=Ah
fc6: ebx=0
fc2: esp=FD6h
fbe: ebp=3EB4
fba: esi=2127h
fb6: edi=2174h
fb4: [ds:63E]=fb4h (check against 75h happened here)
fb2: 0
fb0: 0
fae: 0
fac: 0
faa: 0
fa8: 0
fa6: 0
fa4: ip=36F4h *done by call 0000131c at 0020:000036f1*
fa2: ip=3D64h
fa0: bp=FB4 <- bp
f9e: ???
f9c: ???
f9a: ???
f98: ???
f96: ds=18h
f94: es=5Bh
f92: 0h <- sp
Said action pushes all registers again, at 0020:0000132F.
Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io