• Unfortunately, we have experienced significant hard drive damage that requires urgent maintenance and rebuilding. The forum will be a state of read only until we install our new drives and rebuild all the configurations needed. Please follow our Facebook pagefor updates, or we will be back up shortly! (The forum could go offline at any given time due to the nature of the failed drives whilst awaiting the upgrades.)

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