Cappuccino 43 Posted February 28, 2021 Share Posted February 28, 2021 (edited) 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 February 28, 2021 by Cappuccino 2 1 3 4 Link to comment Share on other sites More sharing options...
Developer PACI 929 Posted February 28, 2021 Developer Share Posted February 28, 2021 (edited) 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 February 28, 2021 by PACI 1 2 1 when you return 0 and server doesn't boot: Link to comment Share on other sites More sharing options...
Cappuccino 43 Posted March 3, 2021 Author Share Posted March 3, 2021 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 1 Link to comment Share on other sites More sharing options...
takbardzo 21 Posted March 6, 2021 Share Posted March 6, 2021 (edited) if someone wants to expand upon this and wants to create a better hwid banning system, there is a bunch of useful info: https://www.unknowncheats.me/forum/anti-cheat-bypass/333662-methods-retrieving-unique-identifiers-hwids-pc.html/ Edited March 6, 2021 by takbardzo 8 1 2 1 Link to comment Share on other sites More sharing options...
Active Member Helia01 2153 Posted March 16, 2021 Active Member Share Posted March 16, 2021 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 comment Share on other sites More sharing options...
gutaadelin22 1 Posted May 28, 2023 Share Posted May 28, 2023 (edited) y have err compile pliz help me https://metin2.download/picture/hGujxdOin03DVKZH05ZAL7REJ5CzIuG6/.png Edited May 28, 2023 by Metin2 Dev International Core X - External 2 Internal 1 Link to comment Share on other sites More sharing options...
cacaa 0 Posted April 7 Share Posted April 7 On 5/28/2023 at 11:36 AM, gutaadelin22 said: y have err compile pliz help me https://metin2.download/picture/hGujxdOin03DVKZH05ZAL7REJ5CzIuG6/.png Same... Link to comment Share on other sites More sharing options...
Premium WeedHex 636 Posted April 7 Premium Share Posted April 7 DirectQuery Link to comment Share on other sites More sharing options...
cacaa 0 Posted April 8 Share Posted April 8 I have use unique_ptr and i fix that issue. Link to comment Share on other sites More sharing options...
Recommended Posts