Not a member yet? Register for your free account!

You last visited: Today at 05:23

  • Please register to post and access all features, it's quick, easy and FREE!

 

[TSRO] edxTsroMod - A complete Loader example

This is a discussion on [TSRO] edxTsroMod - A complete Loader example within the Foreign SRO Hacks, Bots, Cheats & Exploits forum part of the Foreign SRO - Discussions / Questions category; This is going to be my last project I'm releasing for TSRO. It's simply a loader that will do all ...

Closed Thread
 
Thread Tools
Old   #1
 
Join Date: Aug 2008
Posts: 526
Received Thanks: 3,177
[TSRO] edxTsroMod - A complete Loader example

This is going to be my last project I'm releasing for TSRO.

It's simply a loader that will do all of the things my release does. It's just a practical application of what my Silkroad Development Series guides show, except with specific Silkroad patches.

Make sure to keep a 1.201 TSRO client so you can refer back to it in the future for updates as I won't be updating this. You can also use the other guides to add in your own custom console commands and output. Likewise, if you are a developer, you can integrate in my new and have a nice dev tool for TSRO.

Just as a reminder, the Loader's configuration file is stored in: "%appdata%\edxLabs\edxTsroMod\edxTsroMod.ini". So if you change the paths of the DLL and it no longer works, you need to clear the path to the DLL inside that file or just delete it and rechoose your locations.

Included is the source and a precompiled binary in the attached file. I have tested it out for a while on TSRO while playing a new character and it seems to work just fine.



Here's the relevant source code files for easy reference if you don't want to downlod anything. You can grab Common.h/Common.cpp from as well.

DLL.cpp
Code:
// This project based on my Silkroad development series guides:
// http://www.elitepvpers.com/forum/sro-guides-templates/271405-guide-silkroad-development-series.html

#include <windows.h>
#include "../common/common.h"

// Global instance handle to this DLL
HMODULE gInstance = NULL;

// Function prototype
void UserOnInject();

// Main DLL entry point
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReason, LPVOID lpReserved)
{
	UNREFERENCED_PARAMETER(lpReserved);
	if(ulReason == DLL_PROCESS_ATTACH)
	{
		gInstance = hModule;
		// Do not notify this DLL of thread based events
		DisableThreadLibraryCalls(hModule);
	}
	return TRUE;
}

// This is the main function that is called when the DLL is injected into the process
extern "C" __declspec(dllexport) void OnInject(DWORD address, LPDWORD bytes)
{
	// Restore the original bytes at the OEP
	DWORD wrote = 0;
	WriteProcessMemory(GetCurrentProcess(), UlongToPtr(address), bytes, 6, &wrote);

	// Call our user function to keep this function clean
	UserOnInject();
}

//-------------------------------------------------------------------------

// Function we use to obtain the global settings object (needs updating each patch)
FARPROC GetGlobalSettingsFunc = (FARPROC)0x4631D0; 

DWORD codecave_EnglishPatch_ReturnAddress = 0;
__declspec(naked) void codecave_EnglishPatch()
{
	__asm pop codecave_EnglishPatch_ReturnAddress
	__asm pushad
	__asm call GetGlobalSettingsFunc 
	__asm MOV DWORD PTR DS:[EAX + 0x160], 2 // Taiwan
	__asm popad
	__asm CMP DWORD PTR DS:[0xD3DF4C], 0 // original code, needs updating each client patch
	__asm push codecave_EnglishPatch_ReturnAddress
	__asm ret
}

//-------------------------------------------------------------------------

// Function we use to obtain the global settings object (needs updating each patch)
FARPROC AppendBytesFunc = (FARPROC)0x413D80;

LPBYTE pMac;
void Multiclient()
{
	*((LPDWORD)(pMac + 2)) = GetTickCount();
}

DWORD codecave_Multiclient_ReturnAddress = 0;
__declspec(naked) void codecave_Multiclient()
{
	__asm pop codecave_Multiclient_ReturnAddress
	__asm mov pMac, eax
	__asm pushad
	Multiclient();
	__asm popad
	__asm call AppendBytesFunc // Original code
	__asm push codecave_Multiclient_ReturnAddress
	__asm ret
}

//-------------------------------------------------------------------------

// The function where we place all our logic
void UserOnInject()
{
	// Create a debugging console
	//edx::CreateConsole("SilkroadFramework Debugging Console");

//-------------------------------------------------------------------------

	// Mutex for the launcher, no patches required to start Silkroad now
	CreateMutexA(0, 0, "Silkroad Online Launcher");
	CreateMutexA(0, 0, "Ready");

//-------------------------------------------------------------------------

	// Mutex patch - multi-client 1, easy, above launcher check
	//006D5DE0  |. /75 47         JNZ SHORT [edx]sro.006D5E29
	//006D5DE0     /EB 47         JMP SHORT [edx]sro.006D5E29
	BYTE patch0[] = {0xEB, 0x47};
	edx::WriteBytes(0x6D5DE0, patch0, 2);

	// MAC patch - multi-client 2, more tricky, above
	// 004363C1  |> \BF 1074C900   MOV EDI,sro_clie.00C97410                ;  ASCII "DownloadServer"
	// and below:
	// 0043629A  |> \BF 0474C900   MOV EDI,sro_clie.00C97404                ;  ASCII "AgentServer"
	/*0043636A  |.  6A 06         PUSH 6 <-- size of bytes
	0043636C  |.  8D4424 48     LEA EAX,DWORD PTR SS:[ESP+48]
	00436370  |.  50            PUSH EAX <- buffer to write
	00436371  |.  8BCF          MOV ECX,EDI
	00436373  |.  E8 08DAFDFF   CALL <sro_clie.AppendBytes>  <- function we want to call (we codecave on it)
	*/
	edx::CreateCodeCave(0x436373, 5, codecave_Multiclient);

	// Bind patch - multi-client 3
	/*006E7987  |.  E8 D4192C00   CALL sro_clie.009A9360 ; <-- NOP
	006E798C  |.  85C0          TEST EAX,EAX ; <-- NOP
	006E798E  |.  75 6B         JNZ SHORT sro_clie.006E79FB ; <-- Force JMP
	006E7990  |.  53            PUSH EBX                                 ; /Style
	006E7991  |.  68 C061C500   PUSH sro_clie.00C561C0                   ; |Title = "Silkroad"
	006E7996  |.  68 A061C500   PUSH sro_clie.00C561A0                   ; |Text = "실크로드가 이미 실행 중 입니다."
	006E799B  |.  53            PUSH EBX                                 ; |hOwner
	006E799C  |.  FF15 B433C100 CALL NEAR DWORD PTR DS:[<&USER32.Message>; \MessageBoxA*/
	BYTE patch5[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xEB, 0x6B};
	edx::WriteBytes(0x6E7987, patch5, 9);

//-------------------------------------------------------------------------

	// English patch - force English - see my post here:
	// http://www.elitepvpers.com/forum/sro-guides-templates/277221-guide-how-patch-any-client-into-english-client.html
	//006EA5B9   . /75 16         JNZ SHORT [edx]sro.006EA5D1
	BYTE patch2[] = {0x90, 0x90};
	edx::WriteBytes(0x6EA5B9, patch2, 2);

	// English patch - Stop non-English
	//006EA539   . /75 1D         JNZ SHORT [edx]sro.006EA558
	BYTE patch3[] = {0xEB, 0x1D};
	edx::WriteBytes(0x6EA539, patch3, 2);

	// English patch - Fake foreign flag
	//006D5EC1  |.  833D 4CDFD300 00   CMP DWORD PTR DS:[D3DF4C],0
	edx::CreateCodeCave(0x6D5EC1, 7, codecave_EnglishPatch);

//-------------------------------------------------------------------------

	// Zoom hack - see my post here:
	// http://www.elitepvpers.com/forum/sro-ask-experts/298072-help-infinite-zoom.html#post2731209
	//0063B206   . /7A 08         JPE SHORT sro_clie.0063B210
	BYTE patch4[] = {0xEB, 0x08};
	edx::WriteBytes(0x63B206, patch4, 2);

//-------------------------------------------------------------------------

	// Swear filter - just find all 3 UIIT_MSG_CHATWND_MESSAGE_FILTER and patch JEs before them
	// Skip the one that is a different layout.
	//004C712C   . /74 43         JE SHORT sro_clie.004C7171
	//004FF166   . /74 44         JE SHORT sro_clie.004FF1AC
	//0066DD4B  |. /74 43         JE SHORT sro_clie.0066DD90
	BYTE patch6[] = {0xEB};
	edx::WriteBytes(0x4C712C, patch6, 1);
	edx::WriteBytes(0x4FF166, patch6, 1);
	edx::WriteBytes(0x66DD4B, patch6, 1);

//-------------------------------------------------------------------------

	// Nude patch - try binary search: 8B 84 EE 1C 01 00 00 3B 44 24 14
	// NOP the check.
	//008CA74B  |. /75 1A         JNZ SHORT sro_clie.008CA767
	BYTE patch7[] = {0x90, 0x90};
	edx::WriteBytes(0x8CA74B, patch7, 2);
}
Loader.cpp
Code:
#include <windows.h>
#include <string>
#include <sstream>
#include "../common/common.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	// Let's get rid of any extra warnings we don't need
	UNREFERENCED_PARAMETER(hInstance);
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	UNREFERENCED_PARAMETER(nCmdShow);

	STARTUPINFOA si = {0};
	PROCESS_INFORMATION pi = {0};

	std::string pathToClient;
	std::string pathToDll;
	edx::ConfigFile cf;
	bool bExists = false;
	std::stringstream ini;

	// Try to load the configuration file
	ini << edx::GetWriteableDirectory("edxTsroMod") << "edxTsroMod.ini";
	cf.Open(ini.str(), false, bExists);
	if(bExists)
	{
		pathToClient = cf.Read("client");
		pathToDll = cf.Read("dll");
	}
	if(bExists == false || pathToClient.empty() || pathToDll.empty())
	{
		// Choose the injection DLL if required
		if(pathToDll.empty())
		{
			edx::FileChooser fc;
			fc.AddFilter("Dynamic-link library", "*.dll");
			fc.SetInitialDirectory(edx::GetAbsoluteDirectoryPath().c_str());
			fc.SetDialogTitle("Please choose the DLL to inject...");
			if(fc.ShowChooseFile(true) == false)
			{
				MessageBoxA(0, "The DLL selection process was canceled. The program will now exit.", "Fatal Error", MB_ICONERROR);
				return 0;
			}
			pathToDll = fc.GetSelectedFilePath();
			cf.Write("dll", pathToDll);
		}

		// Choose the game client if required
		if(pathToClient.empty())
		{
			edx::FileChooser fc;
			fc.SetDefaultFileName("sro_client.exe");
			fc.AddFilter("Executable Files", "*.exe");
			fc.SetDialogTitle("Please choose your \"sro_client.exe\" executable...");
			if(fc.ShowChooseFile(true) == false)
			{
				MessageBoxA(0, "The client selection process was canceled. The program will now exit.", "Fatal Error", MB_ICONERROR);
				return 0;
			}
			std::string title = fc.GetSelectedFileTitle();
			if(title.find("sro_client") == std::string::npos)
			{
				std::stringstream ss;
				ss << "You selected the file \"" << fc.GetSelectedFileName() << "\". Are you sure this is your \"sro_client.exe\" file?\n\nIf this file is not your \"sro_client.exe\" file, please choose No to exit the loader and try again. Otherwise please choose Yes to continue.";
				int result = MessageBoxA(0, ss.str().c_str(), "Unexpected file name detected", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
				if(result == IDNO)
				{
					return 0;
				}
			}
			pathToClient = fc.GetSelectedFilePath();
			cf.Write("client", pathToClient);
		}

		// We have to restart the application now since the GetOpenFileName function messes up the working directories.
		// Unfortunately on Vista/Win7, the old method of storing the previous working directory and reseting it
		// doesn't seem to work anymore.
		MessageBoxA(0, "The directory changes have been saved. Please relaunch the program now.", "Application restart required", MB_ICONINFORMATION);
		return 0;
	}

	// Since we want to use a few functions
	WSADATA wsaData = {0};
	WSAStartup(MAKEWORD(2, 2), &wsaData);

	bool bConnected = false;

	// Figure out which login server we should use. This is what Silkroad.exe pretty much does
	// in figuring out which last parameter to send to the client.
	std::stringstream args;
	args << "0 /12 0 ";
	for(int x = 1; x <= 3; ++x)
	{
		std::stringstream ss;
		if(x == 1 || x == 2)
		{
			ss << "gw" << x << ".sro.com.tw";
		}
		else
		{
			ss << "login.sro.com.tw";
		}
		if(edx::CanGetHostFromAddress(ss.str()))
		{
			SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
			hostent * host = edx::GetHost(ss.str().c_str());
			if(host)
			{
				sockaddr_in svr = {0};
				svr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
				svr.sin_family = AF_INET;
				svr.sin_port = htons(15779);
				if(connect(s, (struct sockaddr*)&svr, sizeof(svr)) == 0)
				{
					bConnected = true;
					args << (x - 1);
					break;
				}
			}
			closesocket(s);
		}
	}

	if(bConnected == false)
	{
		WSACleanup();
		MessageBoxA(0, "The address to the Silkroad servers could not be resolved. There are two causes for this error:\n\n1. The Silkroad servers are actually down and you will have to wait until they are up again.\n\n2.Your computer cannot obtain the address of the Silkroad servers. Please visit http://www.joymax.com/silkroad first and try launching the Loader again.\n\nIf that fails, try running Silkroad.exe and see if you get the Start button. If you get a Start button, try running the Loader again until it works. If you do not get a Start button, then there is an issue on your system preventing you from obtaining the addresses.", "Fatal Error", MB_ICONERROR);
		return 0;
	}
	WSACleanup();

	// Launch the client in a suspended state so we can patch it
	std::string workingDir = pathToClient.substr(0, 1 + pathToClient.find_last_of("\\/"));
	bool result = edx::CreateSuspendedProcess(pathToClient, args.str(), si, pi);
	if(result == false)
	{
		MessageBoxA(0, "Could not start \"sro_client.exe\".", "Fatal Error", MB_ICONERROR);
		return 0;
	}

	// Inject the DLL so we can have some fun
	result = (FALSE != edx::InjectDLL(pi.hProcess, pathToDll.c_str(), "OnInject", static_cast<DWORD>(edx::GetEntryPoint(pathToClient.c_str())), false));
	if(result == false)
	{
		TerminateThread(pi.hThread, 0);
		MessageBoxA(0, "Could not inject into the Silkroad client process.", "Fatal Error", MB_ICONERROR);
		return 0;
	}

	// Finally resume the client.
	ResumeThread(pi.hThread);
	ResumeThread(pi.hProcess);

	// All done!
	return 0;
}
You can use these same concepts for any Silkroad version really. All you have to do is change the patches and codecaves to work for those versions. This is for anyone who wants to be able to always have an up to date loader to use after a client patch and not have to rely on anyone else for one.

Enjoy!
Attached Files
File Type: zip edxTsroMod.zip (32.9 KB, 1366 views)

__________________

pushedx is offline  
Thanks
20 Users
Old   #2
 
Join Date: Mar 2008
Posts: 1,563
Received Thanks: 354
#Approved
Julian2008 is offline  
Thanks
3 Users
Old   #3
 
Join Date: Aug 2008
Posts: 526
Received Thanks: 3,177
Ok, so I kinda lied about this being my last project for TSRO. Anyways, I will be writing an updated version soon that makes use of auto-updating features so you should not have to manually update this yourself. I might not get around to it this week, but it will come soon. I don't expect TSRO gets another client update so soon, but if they do this week, I'll post an updated version.

First though, I am rewriting all my network code once again for a new series of projects to replace older projects. Overtime I have found new ways to implement old tasks, so I want to have a good solid code base for future projects so the quality of releases far exceeds the previous tools I've released.
pushedx is offline  
Thanks
3 Users
Old   #4
 
Join Date: Mar 2007
Posts: 4,276
Received Thanks: 2,984
Great choice ,Drew!

#Sticky.

__________________

InvincibleNoOB is offline  
Thanks
1 User
Old   #5
 
Join Date: Aug 2008
Posts: 526
Received Thanks: 3,177
Even though TSRO just got a a new client for the 1.205 update, all of the addresses are the same shown here. No updates are needed yet!
pushedx is offline  
Thanks
2 Users
Old   #6
 
Join Date: Mar 2008
Posts: 3,938
Received Thanks: 2,073
Quote:
Originally Posted by pushedx View Post
Even though TSRO just got a a new client for the 1.205 update, all of the addresses are the same shown here. No updates are needed yet!
Thanks Drew. I just saw the update, are you still going to work on the loader?
theoneofgod is offline  
Thanks
1 User
Old   #7
 
Join Date: Aug 2008
Posts: 526
Received Thanks: 3,177
Quote:
Originally Posted by theoneofgod View Post
Thanks Drew. I just saw the update, are you still going to work on the loader?
Yes, for a little over the past week, I was working on getting three new guides done but now that they are done and posted (the last one finished yesterday), I can now move back to this project. I hope to get an update done early this weekend before another inspection hits.
pushedx is offline  
Thanks
1 User
Old   #8
 
Join Date: Aug 2008
Posts: 526
Received Thanks: 3,177
Sorry for the back to back posts, but I think I'm going to take a little more time on this loader this weekend.

Instead of making a TSRO specific loader framework, I'm going to make one for all SROs. One loader that should work on VSRO, KSRO, TSRO, CSRO, and ISRO (unpacked).

My plan is to modify the loader to use my updated PK2 api to pull the connection information from DivisionInfo.txt so it can start the client correctly. The user would just specify their SRO directory in that case. A simple profile system would be used to let the user choose which SRO version to launch. That should take care of the generic loader.

For the DLL, I'll go through and find common binary search patterns for the sigs for all the different versions. I have them all downloaded now and should be able to test them all. I don't think there should be any problems since all of the clients are pretty similar. I might have to keep the DLL pretty simple in this case though but I'll see about adding more advanced patches later (like /min for example).

I think a project like this would be more worthwhile for SRO rather than trying to make different loader versions for each Silkroad. So, I'll be working on updating the loader tomorrow, the DLL the next day, but I'm not sure if I can get it all done before inspection hits. I'll try though!

Eventually, I'll get my edxSilkroadProxy full version done and can integrate that into the DLL so people can easily inject packets or modify them. I'd like try out integrating Lua into my framework to start a new level of easier development, but I am getting ahead of myself right now, that will come 'soon' hopefully, but is quite a bit of work.

[Edit] Some images of early work! This is all data driven, straight from the Media.pk2 of the folder you choose. Yes, I know the GUI looks like ****, but I'll work on that later.



pushedx is offline  
Thanks
1 User
Old   #9
 
Join Date: Aug 2008
Posts: 526
Received Thanks: 3,177
Request close and unstick of this thread. I am posting a new thread of a different project that will be much better.
pushedx is offline  
Thanks
1 User
Closed Thread

Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
need tsro bot or new loader bbxnvjnx Foreign SRO Hacks, Bots, Cheats & Exploits 8 09/08/2009 05:41
Tsro Loader Problem stueber741 Foreign SRO - Discussions / Questions 6 09/08/2009 00:57
Tsro loader olympis Foreign SRO - Discussions / Questions 11 09/04/2009 08:42
[TSRO] / [Pserver] LOADER saiyansrule Foreign SRO Hacks, Bots, Cheats & Exploits 92 09/03/2009 19:43



All times are GMT +1. The time now is 05:23.


Powered by vBulletin®
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.