Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Custom String pool

Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
Hi guys

Nothing very special, but here is a little hook to use a custom StringPool based on your own DLL, allowing edit of MS Strings without stredit. However, you should use STR to extract the strings of the version in first place.

It may be useful when you want to change a string in the client, but dont have a unpacked and runnable version of the game.


Code is very self explanatory.


Cheers,
 
Experienced Elementalist
Joined
Feb 10, 2008
Messages
249
Reaction score
161
could you post rest of the codes?

Just do this instead, the posted code is weird.

Code:
#define ZXString		char*

bool Hook_StringPool__GetString(bool enable)
{
	//Log(__FUNCTION__ " %i\r\n", enable);

	typedef ZXString*(__fastcall* StringPool__GetString_t)(void* ecx, void* edx, ZXString* result, unsigned int nIdx, char formal);

	static auto StringPool__GetString =
		reinterpret_cast<StringPool__GetString_t>(0x00746750); //v95

	StringPool__GetString_t Hook = [](void* ecx, void* edx, ZXString* result, unsigned int nIdx, char formal) -> ZXString*
	{
		auto ret = StringPool__GetString(ecx, edx, result, nIdx, formal);

		if (nIdx == 2722) //Ranking URL
		{
			strcpy(*ret, "http://rebirth.ms");
		}

		//Log("StringPool__GetString: %s\r\n", *result);
		return ret;
	};

	return SetHook(enable, reinterpret_cast<void**>(&StringPool__GetString), Hook);
}
 
Newbie Spellweaver
Joined
Feb 21, 2016
Messages
30
Reaction score
3
Just do this instead, the posted code is weird.

Code:
#define ZXString		char*

bool Hook_StringPool__GetString(bool enable)
{
	//Log(__FUNCTION__ " %i\r\n", enable);

	typedef ZXString*(__fastcall* StringPool__GetString_t)(void* ecx, void* edx, ZXString* result, unsigned int nIdx, char formal);

	static auto StringPool__GetString =
		reinterpret_cast<StringPool__GetString_t>(0x00746750); //v95

	StringPool__GetString_t Hook = [](void* ecx, void* edx, ZXString* result, unsigned int nIdx, char formal) -> ZXString*
	{
		auto ret = StringPool__GetString(ecx, edx, result, nIdx, formal);

		if (nIdx == 2722) //Ranking URL
		{
			strcpy(*ret, "http://rebirth.ms");
		}

		//Log("StringPool__GetString: %s\r\n", *result);
		return ret;
	};

	return SetHook(enable, reinterpret_cast<void**>(&StringPool__GetString), Hook);
}

Thx??????
 
Experienced Elementalist
Joined
Feb 10, 2008
Messages
249
Reaction score
161
is it ok to hook the function with detour?

yeah here

Code:
BOOL SetHook(BOOL bInstall, PVOID* ppvTarget, PVOID pvDetour)
{
	if (DetourTransactionBegin() != NO_ERROR)
		return FALSE;
	
	auto tid = GetCurrentThread();

	if (DetourUpdateThread(tid) == NO_ERROR)
	{
		auto func = bInstall ? DetourAttach : DetourDetach;

		if (func(ppvTarget, pvDetour) == NO_ERROR)
		{
			if (DetourTransactionCommit() == NO_ERROR)			
				return TRUE;			
		}
	}

	DetourTransactionAbort();
	return FALSE;
}

----------------------------------------------------------

You can also change StringPool entries without hooking by just changing the pointers of the char** StringPool::ms_aString but you gotta encode the new entry
 
Newbie Spellweaver
Joined
Jan 31, 2019
Messages
50
Reaction score
18
Apply to 083?

Both methods work for v83 - I use something similar to Darter's and it works perfectly (I recommend his method cuz you only need to change one function).

BTW stringpool edits like this work fine if you just want the client's functions to retrieve strings of your choosing, but if for some reason you write your own functions that call the Stringpool methods within them, you might run into some issues since ZXString objects are actually members of a larger class which IDA doesn't tell you about (you might find pseudocode like ZXString<char>* v2 = this; ZXString<char>::_Release(v2 - 0xC); which proves this).

You'd need proper handling of this unnamed class by looking at the memory layout of zxstrings (or just use char* and wchar_t* when possible).
 
Newbie Spellweaver
Joined
Sep 14, 2013
Messages
87
Reaction score
4
Hi guys

Nothing very special, but here is a little hook to use a custom StringPool based on your own DLL, allowing edit of MS Strings without stredit. However, you should use STR to extract the strings of the version in first place.

It may be useful when you want to change a string in the client, but dont have a unpacked and runnable version of the game.


Code is very self explanatory.


Cheers,

hey, how to compile this in C++.



Just do this instead, the posted code is weird.

Code:
#define ZXString        char*

bool Hook_StringPool__GetString(bool enable)
{
    //Log(__FUNCTION__ " %i\r\n", enable);

    typedef ZXString*(__fastcall* StringPool__GetString_t)(void* ecx, void* edx, ZXString* result, unsigned int nIdx, char formal);

    static auto StringPool__GetString =
        reinterpret_cast<StringPool__GetString_t>(0x00746750); //v95

    StringPool__GetString_t Hook = [](void* ecx, void* edx, ZXString* result, unsigned int nIdx, char formal) -> ZXString*
    {
        auto ret = StringPool__GetString(ecx, edx, result, nIdx, formal);

        if (nIdx == 2722) //Ranking URL
        {
            strcpy(*ret, "http://rebirth.ms");
        }

        //Log("StringPool__GetString: %s\r\n", *result);
        return ret;
    };

    return SetHook(enable, reinterpret_cast<void**>(&StringPool__GetString), Hook);
}
how to use your code my friend?
 
Newbie Spellweaver
Joined
Aug 8, 2018
Messages
58
Reaction score
41
suck a fat penis
 
Last edited:
Back
Top