- Status
- Offline
- Joined
- Mar 3, 2026
- Messages
- 598
- Reaction score
- 7
Anyone currently digging into the xLua garbage in Maple Story World? I've been trying to pin down the player's X-coordinate in Land of the Wind, but the register shuffling is a nightmare. This isn't your standard static offset; we're dealing with a VM-based dispatch here.
The Reversing Problem
I found the write instruction where the coordinate vector is updated:
The issue is R9. It's volatile as hell. Depending on where you break, R9 is either a function pointer, a scrap register, or the actual coordinate struct. The game seems to be using an xLua implementation, meaning we're likely looking at a bridge between the C++ engine and the Lua stack.
Assembly Breakdown
Looking at the dump, the address isn't coming from a single
or static pointer. It’s being passed around through various jumps and calls:
Technical Troubleshooting
If you're trying to find where R9 gets its "coordinate address" identity, you need to back-trace RAX after the call to
. This function is almost certainly a getter for the entity's position component. In these modern "classic" remakes, the engine often keeps the physics and the visual representation in two different places, synced through these xLua wrappers.
Prevention and Ethics
Has anyone mapped out the r11 / r15 base structures yet? It looks like R15+20 is the head for the entity list, but the offsets are still shifting. Drop your crash logs or IDA pseudo-code below if you've got a cleaner way to resolve the local player base.
The Reversing Problem
I found the write instruction where the coordinate vector is updated:
Code:
movups xmmword ptr ds:[r9], xmm0
The issue is R9. It's volatile as hell. Depending on where you break, R9 is either a function pointer, a scrap register, or the actual coordinate struct. The game seems to be using an xLua implementation, meaning we're likely looking at a bridge between the C++ engine and the Lua stack.
Assembly Breakdown
Looking at the dump, the address isn't coming from a single
Code:
LEA
- Initial setup:
— here it looks like a function call preparation.Code:
mov r9, qword ptr ds:[rdi+B0] - The pivot:
occurs after a series of bitwise shifts (Code:
mov r9, r12,Code:SHR) which usually screams "array index calculation" or "table lookup" in Lua objects.Code:SHL - The source: In the final block, R9 is set by
immediately after a call to a Lua management function (Code:
mov r9, rax).Code:xlua.7FFB6DA98D20
Code:
// ... snippets from the trace
mov r14,qword ptr ds:[r15+20]
mov r10,qword ptr ss:[rbp+188]
mov r11,qword ptr ss:[rbp+190]
mov eax,edi
shr eax,6
movzx ebx,al
// ... coordinate resolution logic ...
movups xmm0,xmmword ptr ds:[rax]
mov r10,qword ptr ss:[rbp+188]
mov r11,qword ptr ss:[rbp+190]
movups xmmword ptr ds:[r9],xmm0
Technical Troubleshooting
If you're trying to find where R9 gets its "coordinate address" identity, you need to back-trace RAX after the call to
Code:
xlua.7FFB6DA98D20
Prevention and Ethics
- Don't hook the
directly without checking the calling context, or you'll crash every time an NPC moves.Code:
MOVUPS - Disable Secure Boot to ensure your debugger doesn't get stripped of handles by the AC.
- Watch out for the Subtick-like updates; Land of the Wind has some weird latency interpolation.
Has anyone mapped out the r11 / r15 base structures yet? It looks like R15+20 is the head for the entity list, but the offsets are still shifting. Drop your crash logs or IDA pseudo-code below if you've got a cleaner way to resolve the local player base.