Jump to content

Recommended Posts

This hwid ban works in a quite simple way and I'm pretty sure that this isn't the best way to get HWID from a computer, but nonetheless it works :)

It was released a long time ago by someone on this forum, but that solution was awful. So I reimplemented it only in c++ without the need of an external exe and to add python code.

 

Client

 

File: packet.h

Find

typedef struct command_login3
{
    BYTE	header;
    char	name[ID_MAX_NUM + 1];
    char	pwd[PASS_MAX_NUM + 1];
    DWORD	adwClientKey[4];
} TPacketCGLogin3;

 

Replace with

typedef struct command_login3
{
    BYTE	header;
    char	name[ID_MAX_NUM + 1];
    char	pwd[PASS_MAX_NUM + 1];
    DWORD	adwClientKey[4];
	char	hwid[255]; // <-----
} TPacketCGLogin3;

 

File: AccountConnector.cpp

Find

TPacketCGLogin3 LoginPacket;
LoginPacket.header = HEADER_CG_LOGIN3;

strncpy(LoginPacket.name, m_strID.c_str(), ID_MAX_NUM);
strncpy(LoginPacket.pwd, m_strPassword.c_str(), PASS_MAX_NUM);
LoginPacket.name[ID_MAX_NUM] = '\0';
LoginPacket.pwd[PASS_MAX_NUM] = '\0';

Add under

HW_PROFILE_INFO hwProfileInfo;
GetCurrentHwProfile(&hwProfileInfo);
Tracef("hwid %s\n", hwProfileInfo.szHwProfileGuid);
strncpy(LoginPacket.hwid, hwProfileInfo.szHwProfileGuid, 254);

 

 

Server

 

 File: packet.h

Find

typedef struct command_login3
{
	BYTE	header;
	char	login[LOGIN_MAX_LEN + 1];
	char	passwd[PASSWD_MAX_LEN + 1];
	DWORD	adwClientKey[4];
} TPacketCGLogin3;

 

Replace with

typedef struct command_login3
{
	BYTE	header;
	char	login[LOGIN_MAX_LEN + 1];
	char	passwd[PASSWD_MAX_LEN + 1];
	DWORD	adwClientKey[4];
	char	hwid[255];
} TPacketCGLogin3;

 

File: input_auth.cpp

Find

 

	char login[LOGIN_MAX_LEN + 1];
	trim_and_lower(pinfo->login, login, sizeof(login));

	char passwd[PASSWD_MAX_LEN + 1];
	strlcpy(passwd, pinfo->passwd, sizeof(passwd));

 

add under 

	char hwid[255];
	strlcpy(hwid, pinfo->hwid, sizeof(hwid));

 

Find

	char szPasswd[PASSWD_MAX_LEN * 2 + 1];
	DBManager::instance().EscapeString(szPasswd, sizeof(szPasswd), passwd, strlen(passwd));

	char szLogin[LOGIN_MAX_LEN * 2 + 1];
	DBManager::instance().EscapeString(szLogin, sizeof(szLogin), login, strlen(login));

Add under

	char szHWID[255];
	DBManager::instance().EscapeString(szHWID, sizeof(szHWID), hwid, strlen(hwid));

// ENABLE_HWID_BAN
	// update client hwid
	// DBManager::instance().DirectQuery("UPDATE account.account SET hwid = '%s' WHERE login = '%s'", szHWID, szLogin);
	std::auto_ptr<SQLMsg> pUpdateMsg("UPDATE account.account SET hwid = '%s' WHERE login = '%s'", szHWID, szLogin);

	// check if client hwid is banned
	std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT * FROM account.hwid_ban WHERE hwid = '%s'", szHWID));

	if (pMsg->Get()->uiNumRows > 0)
	{
		LoginFailure(d, "BLOCK");
		printf("Account %s HWID ban - tried to login\n", szLogin);
		sys_log(0, "Account %s HWID ban - tried to login\n", szLogin);
		return;
	}
// end HWID BAN

 

 

Database

Add a new column called "hwid" (varchar 255) to table account.

Create a new table in the database "account" and call it hwid_ban. Inside this table put a column called "hwid".

 

 

Edited by Cappuccino
  • Love 2
  • Good 3
  • Think 1
Link to post

Hello.

 

I reckon important to always log datetimes of actions. The table you provide there could use an account ID field (so you can basically track the account that was HWID banned) and a datetime row (for verification purposes if ever needed). Maybe then limit the rows of that query to 1, since one single result is plenty enough for this verification to do its job.

This is considering you have a game management platform (adminpage) where you (or your teammates) can trigger these type of actions.

 

It's also important, the moment of the ban to update the state of the affected account to 'BLOCK' instead of simply adding its hwid into a table, or you might just end up having this player use other methods to enter the game under this (supposedly) locked account.

 

For the rest, you should probably only update the player's HWID once it reaches the handshake phase, because there is just no need to do so beforehand, especially when (during server launches or restarts) a lot of people tend to connect all at once.

 

These are only friendly advises that in my opinion are important to consider for this particular addition. But the content OP proposed is definitely a start!

 

Good share!

Edited by PACI
  • Metin2 Dev 1
  • Love 1
  • Good 2

when you return 0 and server doesn't boot:

unknown.png

Link to post
On 2/28/2021 at 11:25 PM, PACI said:

Hello.

 

I reckon important to always log datetimes of actions. The table you provide there could use an account ID field (so you can basically track the account that was HWID banned) and a datetime row (for verification purposes if ever needed). Maybe then limit the rows of that query to 1, since one single result is plenty enough for this verification to do its job.

This is considering you have a game management platform (adminpage) where you (or your teammates) can trigger these type of actions.

 

It's also important, the moment of the ban to update the state of the affected account to 'BLOCK' instead of simply adding its hwid into a table, or you might just end up having this player use other methods to enter the game under this (supposedly) locked account.

 

For the rest, you should probably only update the player's HWID once it reaches the handshake phase, because there is just no need to do so beforehand, especially when (during server launches or restarts) a lot of people tend to connect all at once.

 

These are only friendly advises that in my opinion are important to consider for this particular addition. But the content OP proposed is definitely a start!

 

Good share!

 

I know that it can be improved. I didn't put much effort in it and C++ isn't my cup of tea.

Everyone is free to take this code as a working base and improve it according to his needs :)

  • Metin2 Dev 1
Link to post
  • 2 weeks later...
  • VIP

Thanks for the release, I do not recommend using this solution, because it is very easy to create an HWID Spoofer that will allow you to change the HWID in the game's memory.

Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.