Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Azerothcore] Object:SetInt32Value crashes the server when given a non-int value #435

Closed
gabrilend opened this issue Jun 9, 2023 · 4 comments

Comments

@gabrilend
Copy link

Here's a sample script:

local function InitialLogin(event, player)
    player:SetInt32Value(0, math.random())
    player:SendBroadcastMessage(player:GetInt32Value(0))
end

local PLAYER_EVENT_ON_LOGIN = 3
RegisterPlayerEvent(PLAYER_EVENT_ON_LOGIN, InitialLogin)

If you change math.random() to an integer it works, but since math.random() gives a number between 0 and 1 (as in, not an integer) it crashes first the WoW client, then if you try to log back in it crashes the worldserver. Here are the error messages:

First, it crashes the WoW client with this error:
https://i.imgur.com/XbAnsXy.png (picture version)

This application has encountered a critical error:

ERROR #132 (0x85100084) Fatal Exception
Program: Z:\home\ritz\games\azeroth-core\wotlk-client\Wow.exe
Exception: 0xC0000005(ACCESS_VIOLATION) at 0023:0040CD58

The instruction at "0x0040CD58" referenced memory at "0x1C219331".
The memory could not be "read".

Press OK to terminate the application.

[okay sure fine whatever]

Then when you try and log in again it again it crashes the server for good and displays this error message:

AC> HandleSetActiveMoverOpcode: incorrect mover guid: mover is GUID Full: 0x0000000000000001 Type: Player Low: 1 and should be GUID Full: 0x0000000000000000 Type: None Low: 0
#----------------------------------------------------------------------#

>> ASSERTION FAILED

# Location '/home/ritz/games/azeroth-core/azerothcore/src/server/game/Entities/Unit/Unit.cpp:15658'
# Function 'RemoveFromWorld'
# Condition 'GetGUID()'

# Debug info: 'MapID: 530 X: 10315.7 Y: -6223.41 Z: 27.3775 O: 1.32636
GUID Full: 0x0000000000000000 Type: None Low: 0 Entry 0
Name: Test
AliveState: true UnitMovementFlags: 0 ExtraUnitMovementFlags: 0 Class: 2'

#----------------------------------------------------------------------#
Segmentation fault
/home/ritz

Obviously putting a non-int into an int function is unexpected and undesired behavior, dare I say it user error, but it might be useful to catch those kinds of exceptions for debugging purposes.

I'm using Azerothcore on Void Linux if it matters.

@Rochet2
Copy link
Member

Rochet2 commented Jun 9, 2023

I somewhat doubt this is eluna related really.
The issue is not that you pass in 0.5 for example.
The values get rounded by static_cast into the correct type before use.
math.random() would produces a value that is below 1, so it is rounded down to 0.

The issue is that you try to use invalid addresses and values with the function that the core and client does not support.

Based on this https://github.com/azerothcore/azerothcore-wotlk/blob/6b846df6a36e4ce72e9c26313d14aae70bad33e5/src/server/game/Entities/Object/Updates/UpdateFields.h#L25
it looks like you are setting the player's guid to 0. The core assumes there is no player with guid 0 (and probably guids shouldnt change on the fly anyways as that would violate assumptions). The client on the other hand probably has similar assumptions. And thus the code you use will crash client and core.

@gabrilend
Copy link
Author

gabrilend commented Jun 9, 2023

Interesting. I'm not sure how I'm changing the player's GUID - I didn't even know that was possible, that seems like a read-only kinda variable to me!

According to this: https://www.azerothcore.org/pages/eluna/Object/SetInt32Value.html

the first parameter to Object:SetInt32Value() should be the index. I was assuming this was the index of a data structure stored on the object, and that you could store arbitrary integer values in it keyed to the index. I might be misunderstanding how SetInt32Value() works though.

EDIT: The only script active currently is the example script shown above.

@Rochet2
Copy link
Member

Rochet2 commented Jun 9, 2023

Adding the reply here for completeness:

The function is core side low level function for setting data on entity objects like player and item etc. The server sends the data almost as-is to client.

If you check the link I posted above, you can see the indexes of different fields.
You can then set a value for that field.
You can for example try to mess around with levels by using this index https://github.com/azerothcore/azerothcore-wotlk/blob/6b846df6a36e4ce72e9c26313d14aae70bad33e5/src/server/game/Entities/Object/Updates/UpdateFields.h#L114
and value being whatever level you want. It is sent to all clients as is and everyone would see your level to be what you set.

Its a bit of a treasure trove of fun things to try and do. For example once I tried that you can set the entry of a player to an elite NPC's entry using this field https://github.com/azerothcore/azerothcore-wotlk/blob/6b846df6a36e4ce72e9c26313d14aae70bad33e5/src/server/game/Entities/Object/Updates/UpdateFields.h#LL27C13-L27C13
and then players would see an elite frame around the player.
You can also make yourself sparkle as if you were lootable by setting the correct flags for example.

@gabrilend
Copy link
Author

Interesting! This is some neat functionality. I definitely misunderstood the function, and should have been using something like this:
https://github.com/ElunaLuaEngine/Eluna/blob/master/extensions/ObjectVariables.ext
instead. Thanks for the clarification, closing issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants