ReClass.NET icon indicating copy to clipboard operation
ReClass.NET copied to clipboard

[REQUEST] Disable first Class node to be parent class

Open dudztroyer opened this issue 6 years ago • 4 comments

Just as the title.

Reason: some compilers treat the parent class differently memory-wise when compiling, so you get different real offsets within different ways.

I'm using RPM externally, it should get it right.

Proof: devenv_2019-03-10_07-22-01

and on ReClass ReClass NET_2019-03-10_07-23-44

The Structure is the same but somehow my compiler if fucking out because of the parent class.

PS: not sure if it is the compiler or something else, tho

dudztroyer avatar Mar 10 '19 10:03 dudztroyer

The title doesn't match your problem. Your class is strange aligned.

SEntity_Info_Basic::m_Position and SEntity_Info_Basic::m_Destination start at offsets where offset%4 != 0. That doesn't look right. SEntity_Info::m_iMovingSpeed has an odd offset too.

If you check the offsets in your code, you will see that offsetof(SEntity_Info, m_iMovingSpeed) is not 0x2C but 0x30 because the compiler adds padding. If you are sure you reversed the correct offsets you can force your compiler to skip alignment with #pragma pack(1).

//#pragma pack(1)

class SActor
{
public:
	char pad_0000[72]; //0x0000
}; //Size: 0x0048

class SEntity_Alive_Name
{
public:
	char pad_0000[96]; //0x0000
}; //Size: 0x0060

class SPosition_2bytes
{
public:
	char pad_0000[4]; //0x0000
}; //Size: 0x0004

class SEntity_Info_Basic
{
public:
	char pad_0000[34]; //0x0000
	class SPosition_2bytes m_Position; //0x0022
	class SPosition_2bytes m_Destination; //0x0026
	char pad_002A[2]; //0x002A
}; //Size: 0x002C

class SEntity_Info : public SEntity_Info_Basic
{
public:
	char pad_002C[2]; //0x002C
	uint32_t m_iMovingSpeed; //0x002E
}; //Size: 0x0032

class SEntity_Player : public SActor
{
public:
	class SEntity_Alive_Name m_Name; //0x0048
	char pad_00A8[8]; //0x00A8
	class SEntity_Info m_Info; //0x00B0
	char pad_0102[44]; //0x0102
}; //Size: 0x012E

int main()
{
	auto x = offsetof(SEntity_Player, m_Info); //B0
	x = offsetof(SEntity_Info_Basic, m_Position); //22
	x = offsetof(SEntity_Info_Basic, m_Destination); //26
	x = offsetof(SEntity_Info_Basic, pad_002A); //2A
	x = offsetof(SEntity_Info, pad_002C); //2C
	x = offsetof(SEntity_Info, m_iMovingSpeed); //30
}

Uncomment the pragma line and try again. See here for more informations: https://docs.microsoft.com/en-us/cpp/preprocessor/pack?view=vs-2017 ReClass.NET doesn't have problems here, your class just looks strange.

KN4CK3R avatar Mar 10 '19 11:03 KN4CK3R

Well, I've reversed the variables correctly. The only thing is that I arbitrarely decided to start the class where m_shUID is and end it after m_Destination (4 bytes long). Since the SEntity_Info_Basic have everywhere on other classes, I made a small prototype to reproduce it along the others.

Should I add some padding to fit addy%4=0 after m_Destination? Or should I use the skip alignment?

I didn't go deep into compiler yet so I might be skipping some knowledge on this hand.

dudztroyer avatar Mar 10 '19 11:03 dudztroyer

Misaligned classes are more performance expensive than aligned classes so I highly doubt the original code uses misaligned classes. The cpu loads memory from even offsets in 4 byte (x86) or 8 byte (x64) chunks. If m_Position is not aligned it must load two chunks and copy parts from both to build the objects memory. But if you are sure your classes are correct you are forced to use pack(1) to get the same layout as the target.

KN4CK3R avatar Mar 10 '19 11:03 KN4CK3R

Well, I'll try to reverse the surroundings to get the correct view of it. This game uses a lot of char and short, so they can actually be misaligned. Still it could be an array of short and I didnt get the beginning of it.

If anything else, i'll use pack and all good.

The request for the title is still an need.

Thanks for your time :)

dudztroyer avatar Mar 10 '19 11:03 dudztroyer