Cats Guard Source

Iniciado por Swarlog, Jun 25, 2025, 09:17 PM

Tema anterior - Siguiente tema

Swarlog

### Eclipse Workspace Patch 1.0
#P L2jFrozenInterlude
Index: gameserver/head-src/com/l2jfrozen/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/gameserver/model/actor/instance/L2PcInstance.java (revision 986)
+++ gameserver/head-src/com/l2jfrozen/gameserver/model/actor/instance/L2PcInstance.java (working copy)
@@ -1500,6 +1500,9 @@
/** The _is stored. */
private boolean _isStored = false;

+
+ private String _hwid;
+
/**
* Skill casting information (used to queue when several skills are cast in a short time) *.
*/
@@ -1644,6 +1647,24 @@
return _accountName;
}

+ /**
+ * Gets the hwid
+ *
+ * @return the hwid
+ */
+ public String getHWid()
+ {
+ if (getClient() == null)
+ return _hwid;
+ _hwid = getClient().getHWid();
+ return _hwid;
+ }
+
+ public String getLastHwId()
+ {
+ return this._hwid;
+ }
+
/**
* Gets the account chars.
*
Index: gameserver/head-src/com/l2jfrozen/protection/LameHandler.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/protection/LameHandler.java (revision 0)
+++ gameserver/head-src/com/l2jfrozen/protection/LameHandler.java (revision 0)
@@ -0,0 +1,15 @@
+package com.l2jfrozen.protection;
+
+import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;
+
+public class LameHandler
+{
+ public void runCommand(L2PcInstance admin, String[] params)
+ {
+ }
+
+ public String[] getCommandList()
+ {
+ return null;
+ }
+}
\ No newline at end of file
Index: gameserver/head-src/com/l2jfrozen/gameserver/network/clientpackets/GameGuardReply.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/gameserver/network/clientpackets/GameGuardReply.java (revision 986)
+++ gameserver/head-src/com/l2jfrozen/gameserver/network/clientpackets/GameGuardReply.java (working copy)
@@ -14,50 +14,44 @@
*/
package com.l2jfrozen.gameserver.network.clientpackets;

-import java.util.logging.Logger;
-
-import com.l2jfrozen.Config;
-import com.l2jfrozen.crypt.nProtect;
+import com.l2jfrozen.gameserver.network.L2GameClient;
+import com.l2jfrozen.protection.CatsGuard;
+import java.nio.ByteBuffer;

-/**
- * @author zabbix Lets drink to code!
- * Unknown Packet: ca 0000: 45 00 01 00 1e 37 a2 f5 00 00 00 00 00 00 00 00
- * E....7..........
- */
public class GameGuardReply extends L2GameClientPacket
{
- private int[] _reply = new int[4];
- private static final Logger _log = Logger.getLogger(GameGuardReply.class.getName());
+ private static final String _C__CA_GAMEGUARDREPLY = "[C] CA GameGuardReply";
+ private int[] _reply;

- @Override
- protected void readImpl()
- {
- _reply[0] = readD();
- _reply[1] = readD();
- _reply[2] = readD();
- _reply[3] = readD();
- }
+ public GameGuardReply()
+ {
+ this._reply = new int[4];
+ }

- @Override
- protected void runImpl()
- {
- //TODO: clean nProtect System
- if (!nProtect.getInstance().checkGameGuardRepy(getClient(), _reply))
- return;
-
- //L2jFrozen cannot be reached with GameGuard: L2Net notification --> Close Client connection
- if(Config.GAMEGUARD_L2NET_CHECK){
- getClient().closeNow();
- _log.warning("Player with account name "+getClient().accountName +" kicked to use L2Net ");
- return;
- }
-
- getClient().setGameGuardOk(true);
- }
+ protected void readImpl()
+ {
+ if ((CatsGuard.getInstance().isEnabled()) && (((L2GameClient)getClient()).getHWid() == null))
+ {
+ this._reply[0] = readD();
+ this._reply[1] = readD();
+ this._reply[2] = readD();
+ this._reply[3] = readD();
+ }
+ else
+ {
+ byte[] b = new byte[this._buf.remaining()];
+ readB(b);
+ }
+ }

- @Override
- public String getType()
- {
- return "[C] CA GameGuardReply";
- }
+ protected void runImpl()
+ {
+ if (CatsGuard.getInstance().isEnabled())
+ CatsGuard.getInstance().initSession((L2GameClient)getClient(), this._reply);
+ }
+
+ public String getType()
+ {
+ return "[C] CA GameGuardReply";
+ }
}
\ No newline at end of file
Index: gameserver/head-src/com/l2jfrozen/gameserver/network/GameCrypt.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/gameserver/network/GameCrypt.java (revision 986)
+++ gameserver/head-src/com/l2jfrozen/gameserver/network/GameCrypt.java (working copy)
@@ -1,87 +1,94 @@
-/*
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later
- * version. This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details. You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
package com.l2jfrozen.gameserver.network;

-/**
- * @author L2JFrozen
- */
public class GameCrypt
{
- private final byte[] _inKey = new byte[16];
- private final byte[] _outKey = new byte[16];
- private boolean _isEnabled;
+ private final byte[] _inKey = new byte[16];
+ private final byte[] _outKey = new byte[16];
+ private boolean _isEnabled;
+ private com.lameguard.crypt.GameCrypt _lameCrypt;
+ public static boolean _ISLAME;
+
+ public GameCrypt()
+ {
+ if (_ISLAME)
+ this._lameCrypt = new com.lameguard.crypt.GameCrypt();
+ }

- public static void decrypt(final byte[] raw, final int offset, final int size, final GameCrypt gcrypt)
- {
- if(!gcrypt._isEnabled)
- return;
+ public void setKey(byte[] key)
+ {
+ System.arraycopy(key, 0, this._inKey, 0, 16);
+ System.arraycopy(key, 0, this._outKey, 0, 16);
+ }

- int temp = 0;
+ public void decrypt(byte[] raw, int offset, int size)
+ {
+ if (_ISLAME)
+ {
+ this._lameCrypt.decrypt(raw, offset, size);
+ return;
+ }

- for(int i = 0; i < size; i++)
- {
- final int temp2 = raw[offset + i] & 0xFF;
+ if (!this._isEnabled) {
+ return;
+ }
+ int temp = 0;

- raw[offset + i] = (byte) (temp2 ^ gcrypt._inKey[i & 15] ^ temp);
- temp = temp2;
- }
+ for (int i = 0; i < size; i++)
+ {
+ int temp2 = raw[(offset + i)] & 0xFF;

- int old = gcrypt._inKey[8] & 0xff;
- old |= gcrypt._inKey[9] << 8 & 0xff00;
- old |= gcrypt._inKey[10] << 0x10 & 0xff0000;
- old |= gcrypt._inKey[11] << 0x18 & 0xff000000;
+ raw[(offset + i)] = ((byte)(temp2 ^ this._inKey[(i & 0xF)] ^ temp));
+ temp = temp2;
+ }

- old += size;
+ int old = this._inKey[8] & 0xFF;
+ old |= this._inKey[9] << 8 & 0xFF00;
+ old |= this._inKey[10] << 16 & 0xFF0000;
+ old |= this._inKey[11] << 24 & 0xFF000000;

- gcrypt._inKey[8] = (byte) (old & 0xff);
- gcrypt._inKey[9] = (byte) (old >> 0x08 & 0xff);
- gcrypt._inKey[10] = (byte) (old >> 0x10 & 0xff);
- gcrypt._inKey[11] = (byte) (old >> 0x18 & 0xff);
- }
+ old += size;

- public static void encrypt(final byte[] raw, final int offset, final int size, final GameCrypt gcrypt)
- {
- if(!gcrypt._isEnabled)
- {
- gcrypt._isEnabled = true;
- return;
- }
+ this._inKey[8] = ((byte)(old & 0xFF));
+ this._inKey[9] = ((byte)(old >> 8 & 0xFF));
+ this._inKey[10] = ((byte)(old >> 16 & 0xFF));
+ this._inKey[11] = ((byte)(old >> 24 & 0xFF));
+ }

- int temp = 0;
+ public void encrypt(byte[] raw, int offset, int size)
+ {
+ if (_ISLAME)
+ {
+ this._lameCrypt.encrypt(raw, offset, size);
+ return;
+ }

- for(int i = 0; i < size; i++)
- {
- final int temp2 = raw[offset + i] & 0xFF;
+ if (!this._isEnabled)
+ {
+ this._isEnabled = true;
+ return;
+ }

- temp = temp2 ^ gcrypt._outKey[i & 15] ^ temp;
- raw[offset + i] = (byte) temp;
- }
+ int temp = 0;

- int old = gcrypt._outKey[8] & 0xff;
+ for (int i = 0; i < size; i++)
+ {
+ int temp2 = raw[(offset + i)] & 0xFF;

- old |= gcrypt._outKey[9] << 8 & 0xff00;
- old |= gcrypt._outKey[10] << 0x10 & 0xff0000;
- old |= gcrypt._outKey[11] << 0x18 & 0xff000000;
+ temp = temp2 ^ this._outKey[(i & 0xF)] ^ temp;
+ raw[(offset + i)] = ((byte)temp);
+ }

- old += size;
+ int old = this._outKey[8] & 0xFF;

- gcrypt._outKey[8] = (byte) (old & 0xff);
- gcrypt._outKey[9] = (byte) (old >> 0x08 & 0xff);
- gcrypt._outKey[10] = (byte) (old >> 0x10 & 0xff);
- gcrypt._outKey[11] = (byte) (old >> 0x18 & 0xff);
- }
+ old |= this._outKey[9] << 8 & 0xFF00;
+ old |= this._outKey[10] << 16 & 0xFF0000;
+ old |= this._outKey[11] << 24 & 0xFF000000;

- public static void setKey(final byte[] key, final GameCrypt gcrypt)
- {
- System.arraycopy(key, 0, gcrypt._inKey, 0, 16);
- System.arraycopy(key, 0, gcrypt._outKey, 0, 16);
- }
-}
+ old += size;
+
+ this._outKey[8] = ((byte)(old & 0xFF));
+ this._outKey[9] = ((byte)(old >> 8 & 0xFF));
+ this._outKey[10] = ((byte)(old >> 16 & 0xFF));
+ this._outKey[11] = ((byte)(old >> 24 & 0xFF));
+ }
+}
\ No newline at end of file
Index: gameserver/head-src/com/l2jfrozen/protection/CRC16.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/protection/CRC16.java (revision 0)
+++ gameserver/head-src/com/l2jfrozen/protection/CRC16.java (revision 0)
@@ -0,0 +1,15 @@
+package com.l2jfrozen.protection;
+
+public class CRC16
+{
+ private static int[] table = { 0, 49345, 49537, 320, 49921, 960, 640, 49729, 50689, 1728, 1920, 51009, 1280, 50625, 50305, 1088, 52225, 3264, 3456, 52545, 3840, 53185, 52865, 3648, 2560, 51905, 52097, 2880, 51457, 2496, 2176, 51265, 55297, 6336, 6528, 55617, 6912, 56257, 55937, 6720, 7680, 57025, 57217, 8000, 56577, 7616, 7296, 56385, 5120, 54465, 54657, 5440, 55041, 6080, 5760, 54849, 53761, 4800, 4992, 54081, 4352, 53697, 53377, 4160, 61441, 12480, 12672, 61761, 13056, 62401, 62081, 12864, 13824, 63169, 63361, 14144, 62721, 13760, 13440, 62529, 15360, 64705, 64897, 15680, 65281, 16320, 16000, 65089, 64001, 15040, 15232, 64321, 14592, 63937, 63617, 14400, 10240, 59585, 59777, 10560, 60161, 11200, 10880, 59969, 60929, 11968, 12160, 61249, 11520, 60865, 60545, 11328, 58369, 9408, 9600, 58689, 9984, 59329, 59009, 9792, 8704, 58049, 58241, 9024, 57601, 8640, 8320, 57409, 40961, 24768, 24960, 41281, 25344, 41921, 41601, 25152, 26112, 42689, 42881, 26432, 42241, 26048, 25728, 42049, 27648, 44225, 44417, 27968, 44801, 28608, 28288, 44609, 43521, 27328, 27520, 43841, 26880, 43457, 43137, 26688, 30720, 47297, 47489, 31040, 47873, 31680, 31360, 47681, 48641, 32448, 32640, 48961, 32000, 48577, 48257, 31808, 46081, 29888, 30080, 46401, 30464, 47041, 46721, 30272, 29184, 45761, 45953, 29504, 45313, 29120, 28800, 45121, 20480, 37057, 37249, 20800, 37633, 21440, 21120, 37441, 38401, 22208, 22400, 38721, 21760, 38337, 38017, 21568, 39937, 23744, 23936, 40257, 24320, 40897, 40577, 24128, 23040, 39617, 39809, 23360, 39169, 22976, 22656, 38977, 34817, 18624, 18816, 35137, 19200, 35777, 35457, 19008, 19968, 36545, 36737, 20288, 36097, 19904, 19584, 35905, 17408, 33985, 34177, 17728, 34561, 18368, 18048, 34369, 33281, 17088, 17280, 33601, 16640, 33217, 32897, 16448 };
+
+ public static int calc(byte[] bytes) {
+ int crc = 0;
+ for (byte b : bytes)
+ {
+ crc = crc >> 8 & 0xFF ^ table[((crc ^ b) & 0xFF)];
+ }
+ return crc;
+ }
+}
\ No newline at end of file
Index: gameserver/head-src/com/l2jfrozen/gameserver/network/L2GameClient.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/gameserver/network/L2GameClient.java (revision 986)
+++ gameserver/head-src/com/l2jfrozen/gameserver/network/L2GameClient.java (working copy)
@@ -66,6 +66,8 @@
import com.l2jfrozen.util.CloseUtil;
import com.l2jfrozen.util.database.L2DatabaseFactory;

+import com.l2jfrozen.protection.CatsGuard;
+
/**
* @author L2JFrozen dev
*/
@@ -109,7 +111,10 @@
private ClientStats _stats;

// Crypt
- public GameCrypt crypt;
+ public GameCrypt _crypt;
+
+ private String _hwid = null;
+ public IExReader _reader;

// Flood protection
public long packetsNextSendTick = 0;
@@ -132,7 +137,7 @@
super(con);
state = GameClientState.CONNECTED;
_connectionstartTime = System.currentTimeMillis();
- crypt = new GameCrypt();
+ _crypt = new GameCrypt();
_stats = new ClientStats();
_packetQueue = new ArrayBlockingQueue<ReceivablePacket<L2GameClient>>(com.l2jfrozen.netcore.Config.getInstance().CLIENT_PACKET_QUEUE_SIZE);

@@ -150,7 +155,7 @@
public byte[] enableCrypt()
{
byte[] key = BlowFishKeygen.getRandomKey();
- GameCrypt.setKey(key, crypt);
+ _crypt.setKey(key);
return key;
}

@@ -182,30 +187,31 @@
public boolean decrypt(ByteBuffer buf, int size)
{
_closenow = false;
- GameCrypt.decrypt(buf.array(), buf.position(), size, crypt);
- return true;
+ _crypt.decrypt(buf.array(), buf.position(), size);
+ return true;
}

@Override
public boolean encrypt(final ByteBuffer buf, final int size)
{
- GameCrypt.encrypt(buf.array(), buf.position(), size, crypt);
- buf.position(buf.position() + size);
- return true;
+ _crypt.encrypt(buf.array(), buf.position(), size);
+ buf.position(buf.position() + size);
+ return true;
}

public L2PcInstance getActiveChar()
{
return activeChar;
}
-
+
public void setActiveChar(L2PcInstance pActiveChar)
{
- activeChar = pActiveChar;
- if(activeChar != null)
- {
- L2World.getInstance().storeObject(getActiveChar());
- }
+ activeChar = pActiveChar;
+ if ((_reader != null) && (activeChar != null))
+ {
+ _reader.checkChar(activeChar);
+ L2World.getInstance().storeObject(getActiveChar());
+ }
}

public ReentrantLock getActiveCharLock()
@@ -226,6 +232,8 @@
public void setAccountName(String pAccountName)
{
accountName = pAccountName;
+ if (_reader == null)
+ CatsGuard.getInstance().initSession(this);
}

public String getAccountName()
@@ -741,6 +749,8 @@
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
}
+ if (this._reader != null)
+ CatsGuard.getInstance().doneSession(this);
}

/**
@@ -1212,7 +1222,23 @@
}
}

- /**
+ public void setHWID(String hwid)
+ {
+ this._hwid = hwid;
+ }
+
+ public String getHWid()
+ {
+ return this._hwid;
+ }
+
+ public static abstract interface IExReader
+ {
+ public abstract int read(ByteBuffer paramByteBuffer);
+ public abstract void checkChar(L2PcInstance paramL2PcInstance);
+ }
+
+ /**
* @return the _forcedToClose
*/
public boolean is_forcedToClose()
Index: gameserver/head-src/com/l2jfrozen/gameserver/network/BlowFishKeygen.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/gameserver/network/BlowFishKeygen.java (revision 986)
+++ gameserver/head-src/com/l2jfrozen/gameserver/network/BlowFishKeygen.java (working copy)
@@ -19,52 +19,36 @@

import com.l2jfrozen.util.random.Rnd;

-/**
- * Blowfish keygen for GameServer client connections
- *
- * @author KenM
- */
public class BlowFishKeygen
{
- private static final int CRYPT_KEYS_SIZE = 20;
- private static final byte[][] CRYPT_KEYS = new byte[CRYPT_KEYS_SIZE][16];
+ private static final int CRYPT_KEYS_SIZE = 20;
+ private static final byte[][] CRYPT_KEYS = new byte[20][16];
+ public static boolean _ISLAME;

- static
- {
- // init the GS encryption keys on class load
+ public static byte[] getRandomKey()
+ {
+ if (_ISLAME)
+ return com.lameguard.crypt.BlowFishKeygen.getRandomKey();
+ return CRYPT_KEYS[Rnd.get(20)];
+ }

- for(int i = 0; i < CRYPT_KEYS_SIZE; i++)
- {
- // randomize the 8 first bytes
- for(int j = 0; j < CRYPT_KEYS[i].length; j++)
- {
- CRYPT_KEYS[i][j] = (byte) Rnd.get(255);
- }
+ static
+ {
+ for (int i = 0; i < 20; i++)
+ {
+ for (int j = 0; j < CRYPT_KEYS[i].length; j++)
+ {
+ CRYPT_KEYS[i][j] = ((byte)Rnd.get(255));
+ }

- // the last 8 bytes are static
- CRYPT_KEYS[i][8] = (byte) 0xc8;
- CRYPT_KEYS[i][9] = (byte) 0x27;
- CRYPT_KEYS[i][10] = (byte) 0x93;
- CRYPT_KEYS[i][11] = (byte) 0x01;
- CRYPT_KEYS[i][12] = (byte) 0xa1;
- CRYPT_KEYS[i][13] = (byte) 0x6c;
- CRYPT_KEYS[i][14] = (byte) 0x31;
- CRYPT_KEYS[i][15] = (byte) 0x97;
- }
- }
-
- // block instantiation
- private BlowFishKeygen()
- {}
-
- /**
- * Returns a key from this keygen pool, the logical ownership is retained by this keygen.<BR>
- * Thus when getting a key with interests other then read-only a copy must be performed.<BR>
- *
- * @return A key from this keygen pool.
- */
- public static byte[] getRandomKey()
- {
- return CRYPT_KEYS[Rnd.get(CRYPT_KEYS_SIZE)];
- }
-}
+ CRYPT_KEYS[i][8] = -56;
+ CRYPT_KEYS[i][9] = 39;
+ CRYPT_KEYS[i][10] = -109;
+ CRYPT_KEYS[i][11] = 1;
+ CRYPT_KEYS[i][12] = -95;
+ CRYPT_KEYS[i][13] = 108;
+ CRYPT_KEYS[i][14] = 49;
+ CRYPT_KEYS[i][15] = -105;
+ }
+ }
+}
\ No newline at end of file
Index: gameserver/head-src/com/l2jfrozen/protection/RC4.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/protection/RC4.java (revision 0)
+++ gameserver/head-src/com/l2jfrozen/protection/RC4.java (revision 0)
@@ -0,0 +1,96 @@
+package com.l2jfrozen.protection;
+
+public class RC4
+{
+ private byte[] state = new byte[256];
+ private int x;
+ private int y;
+ private byte[] _key;
+ private boolean _block = false;
+
+ public RC4(String key, boolean block)
+ throws NullPointerException
+ {
+ this(key.getBytes(), block);
+ }
+
+ public RC4(byte[] key, boolean block)
+ throws NullPointerException
+ {
+ this._key = key;
+ this._block = block;
+ setKey();
+ }
+
+ private void setKey()
+ {
+ for (int i = 0; i < 256; i++)
+ {
+ this.state[i] = ((byte)i);
+ }
+
+ this.x = 0;
+ this.y = 0;
+
+ int index1 = 0;
+ int index2 = 0;
+
+ if ((this._key == null) || (this._key.length == 0))
+ {
+ throw new NullPointerException();
+ }
+ for (int i = 0; i < 256; i++)
+ {
+ index2 = (this._key[index1] & 0xFF) + (this.state[i] & 0xFF) + index2 & 0xFF;
+
+ byte tmp = this.state[i];
+ this.state[i] = this.state[index2];
+ this.state[index2] = tmp;
+
+ index1 = (index1 + 1) % this._key.length;
+ }
+ }
+
+ public byte[] rc4(String data)
+ {
+ if ((data == null) || (data.length() == 0))
+ {
+ return null;
+ }
+ return rc4(data.getBytes());
+ }
+
+ public byte[] rc4(byte[] buf)
+ {
+ if (buf == null)
+ {
+ return null;
+ }
+
+ byte[] result = new byte[buf.length];
+
+ for (int i = 0; i < buf.length; i++)
+ {
+ this.x = (this.x + 1 & 0xFF);
+ this.y = ((this.state[this.x] & 0xFF) + this.y & 0xFF);
+
+ byte tmp = this.state[this.x];
+ this.state[this.x] = this.state[this.y];
+ this.state[this.y] = tmp;
+
+ int xorIndex = (this.state[this.x] & 0xFF) + (this.state[this.y] & 0xFF) & 0xFF;
+ result[i] = ((byte)((buf[i] ^ this.state[xorIndex]) & 0xFF));
+ }
+ if (this._block)
+ {
+ this.x = 0;
+ this.y = 0;
+ }
+ else if ((this.x > 5000) || (this.y > 5000))
+ {
+ this.x = 0; this.y = 0;
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
Index: gameserver/head-src/com/l2jfrozen/gameserver/GameServer.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/gameserver/GameServer.java (revision 986)
+++ gameserver/head-src/com/l2jfrozen/gameserver/GameServer.java (working copy)
@@ -146,10 +146,12 @@
import com.l2jfrozen.netcore.SelectorConfig;
import com.l2jfrozen.netcore.SelectorThread;
import com.l2jfrozen.status.Status;
+import com.l2jfrozen.protection.CatsGuard;
import com.l2jfrozen.util.IPv4Filter;
import com.l2jfrozen.util.Memory;
import com.l2jfrozen.util.Util;
import com.l2jfrozen.util.database.L2DatabaseFactory;
+import com.lameguard.LameGuard;

public class GameServer
{
@@ -161,7 +163,7 @@

public static final Calendar dateTimeServerStarted = Calendar.getInstance();

- public static void main(String[] args) throws Exception
+ public static void main(String[] args) throws Throwable
{
ServerType.serverMode = ServerType.MODE_GAMESERVER;

@@ -221,10 +223,26 @@
CrestCache.getInstance();
L2ScriptEngineManager.getInstance();

- nProtect.getInstance();
- if (nProtect.isEnabled())
- _log.info("nProtect System Enabled");
-
+ CatsGuard.getInstance();
+ if (!CatsGuard.getInstance().isEnabled()) {
+ try
+ {
+ Class clazz = Class.forName("com.lameguard.LameGuard");
+ if (clazz != null)
+ {
+ File f = new File("./lameguard/lameguard.properties");
+ if (f.exists())
+ {
+ Util.printSection("LameGuard");
+
+ LameGuard.main(new String[] { "ru.catssoftware.protection.LameStub" });
+ }
+ }
+ }
+ catch (Exception ignored)
+ {
+ }
+ }
Util.printSection("World");
L2World.getInstance();
MapRegionTable.getInstance();
Index: gameserver/head-src/com/l2jfrozen/protection/CatsGuard.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/protection/CatsGuard.java (revision 0)
+++ gameserver/head-src/com/l2jfrozen/protection/CatsGuard.java (revision 0)
@@ -0,0 +1,298 @@
+package com.l2jfrozen.protection;
+
+import com.l2jfrozen.L2Properties;
+import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jfrozen.gameserver.model.entity.Announcements;
+import com.l2jfrozen.gameserver.network.L2GameClient;
+import com.l2jfrozen.gameserver.network.L2GameClient.IExReader;
+import com.l2jfrozen.gameserver.network.serverpackets.GameGuardQuery;
+import com.l2jfrozen.gameserver.network.serverpackets.LeaveWorld;
+import com.l2jfrozen.gameserver.thread.LoginServerThread;
+import com.l2jfrozen.util.Util;
+import com.l2jfrozen.util.database.L2DatabaseFactory;
+import java.nio.ByteBuffer;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+import javolution.util.FastList;
+import javolution.util.FastMap;
+
+public class CatsGuard
+{
+ private static Logger _log = Logger.getLogger("CatsGuard");
+ private static CatsGuard _instance;
+ private Map<String, Integer> _connections;
+ private List<String> _premium = new FastList();
+ private List<String> _bannedhwid;
+ private static boolean ENABLED = true;
+ private static int _SERVER_KEY = 7958915;
+ private int MAX_SESSIONS;
+ private int MAX_PREMIUM_SESSIONS;
+ private String LOG_OPTION;
+ private boolean ANNOUNCE_HACK;
+ private String ON_HACK_ATTEMP;
+ private boolean ALLOW_GM_FROM_BANNED_HWID;
+ private boolean LOG_SESSIONS;
+
+ public static CatsGuard getInstance()
+ {
+ if (_instance == null)
+ _instance = new CatsGuard();
+ return _instance;
+ }
+
+ private CatsGuard()
+ {
+ Util.printSection("CatsGuard");
+ try
+ {
+ if (_SERVER_KEY == 0)
+ return;
+ L2Properties p = new L2Properties("./config/protected/catsguard.properties");
+ ENABLED = (Boolean.parseBoolean(p.getProperty("Enabled", "true"))) && (ENABLED);
+ if (!ENABLED)
+ {
+ _log.info("CatsGuard: disabled");
+ return;
+ } else {
+ _log.info("CatsGuard: enabled!");
+ }
+ this.LOG_OPTION = p.getProperty("LogOption", "NOSPS HACK");
+ this.MAX_SESSIONS = Integer.parseInt(p.getProperty("MaxSessionsFromHWID", "-1"));
+ this.MAX_PREMIUM_SESSIONS = Integer.parseInt(p.getProperty("MaxSessionsForPremium", "-1"));
+ this.ANNOUNCE_HACK = Boolean.parseBoolean(p.getProperty("AnnounceHackAttempt", "true"));
+ this.ON_HACK_ATTEMP = p.getProperty("OnHackAttempt", "kick");
+ this.ALLOW_GM_FROM_BANNED_HWID = Boolean.parseBoolean(p.getProperty("AllowGMFromBannedHWID", "false"));
+ this._connections = new FastMap().setShared(true);
+ this.LOG_SESSIONS = Boolean.parseBoolean(p.getProperty("LogSessions", "false"));
+ this._bannedhwid = new FastList();
+ Connection con = L2DatabaseFactory.getInstance().getConnection(false);
+ PreparedStatement stm = con.prepareStatement("select * from banned_hwid");
+ try
+ {
+ ResultSet rs = stm.executeQuery();
+ while (rs.next())
+ this._bannedhwid.add(rs.getString(1));
+ rs.close();
+ }
+ catch (Exception e)
+ {
+ if (e.getClass().getSimpleName().equals("MySQLSyntaxErrorException"))
+ {
+ stm.close();
+ stm = con.prepareStatement("create table `banned_hwid` (`hwid` varchar(64) not null primary key)");
+ stm.execute();
+ }
+ }
+ stm.close();
+ con.close();
+ _log.info("CatsGuard: Loaded " + this._bannedhwid.size() + " banned hwid(s)");
+ _log.info("CatsGuard: Ready");
+ }
+ catch (Exception e)
+ {
+ _log.warning("CatsGuard: Error while loading ./config/protected/catsguard.properties");
+ ENABLED = false;
+ }
+ }
+
+ public boolean isEnabled()
+ {
+ return ENABLED;
+ }
+
+ public void ban(L2PcInstance player)
+ {
+ ban(player.getHWid());
+ }
+
+ public void ban(String hwid)
+ {
+ if (!ENABLED)
+ return;
+ synchronized (this._bannedhwid)
+ {
+ if (this._bannedhwid.contains(hwid))
+ return;
+ this._bannedhwid.add(hwid);
+ try
+ {
+ Connection con = L2DatabaseFactory.getInstance().getConnection(false);
+ PreparedStatement stm = con.prepareStatement("insert into banned_hwid values(?)");
+ stm.setString(1, hwid);
+ stm.execute();
+ stm.close();
+ con.close();
+ }
+ catch (SQLException e)
+ {
+ _log.warning("CatsGuard: Unable to store banned hwid");
+ }
+ }
+ }
+
+ private void illegalAction(L2GameClient cl, String reason)
+ {
+ if ((cl.getActiveChar() != null) && (this.ANNOUNCE_HACK))
+ Announcements.getInstance().announceToAll("Player " + cl.getActiveChar().getName() + " used illegal software!");
+ if ((this.ON_HACK_ATTEMP.equals("hwidban")) && (cl.getHWid() != null))
+ ban(cl.getHWid());
+ else if ((this.ON_HACK_ATTEMP.equals("jail")) && (cl.getActiveChar() != null))
+ cl.getActiveChar().isInJail();
+ else if ((this.ON_HACK_ATTEMP.equals("ban")) && (cl.getActiveChar() != null))
+ LoginServerThread.getInstance().sendAccessLevel(cl.getAccountName(), -100);
+ _log.info("CatsGuard: Client " + cl + " use illegal software and will " + this.ON_HACK_ATTEMP + "ed. Reason: " + reason);
+ cl.close(new LeaveWorld());
+ }
+
+ public void initSession(L2GameClient cl)
+ {
+ if (!ENABLED)
+ return;
+ cl.sendPacket(GameGuardQuery.STATIC_PACKET);
+ cl._reader = new CatsGuardReader(cl);
+ }
+
+ public void doneSession(L2GameClient cl)
+ {
+ if (!ENABLED)
+ return;
+ if (cl.getHWid() != null)
+ {
+ this._premium.remove(cl.getHWid());
+ if (this._connections.containsKey(cl.getHWid()))
+ {
+ int nwnd = ((Integer)this._connections.get(cl.getHWid())).intValue();
+ if (nwnd == 0)
+ this._connections.remove(cl.getHWid());
+ else
+ this._connections.put(cl.getHWid(), Integer.valueOf(--nwnd));
+ }
+ }
+ cl._reader = null;
+ }
+
+ public void initSession(L2GameClient cl, int[] data)
+ {
+ if (!ENABLED)
+ return;
+ if (data[0] != _SERVER_KEY)
+ {
+ if (this.LOG_OPTION.contains("NOPROTECT"))
+ _log.info("CatsGuard: Client " + cl + " try to log with no CatsGuard");
+ cl.close(new LeaveWorld());
+ return;
+ }
+ String hwid = String.format("%x", new Object[] { Integer.valueOf(data[3]) });
+ if (cl._reader == null)
+ {
+ if (this.LOG_OPTION.contains("HACK"))
+ _log.info("CatsGuard: Client " + cl + " has no pre-authed state");
+ cl.close(new LeaveWorld());
+ return;
+ }
+ if (this._bannedhwid.contains(hwid))
+ {
+ ((CatsGuardReader)cl._reader)._checkChar = true;
+ }
+ if (!this._connections.containsKey(hwid))
+ this._connections.put(hwid, Integer.valueOf(0));
+ int nwindow = ((Integer)this._connections.get(hwid)).intValue();
+ int max = this.MAX_SESSIONS;
+ if (this._premium.contains(hwid))
+ max = this.MAX_PREMIUM_SESSIONS;
+ if (max > 0) { nwindow++; if (nwindow > max)
+ {
+ if (this.LOG_OPTION.contains("SESSIONS"))
+ _log.info("CatsGuard: To many sessions from hwid " + hwid);
+ cl.close(new LeaveWorld());
+ return;
+ } }
+ if (!this._premium.contains(hwid))
+ this._premium.add(hwid);
+ this._connections.put(hwid, Integer.valueOf(nwindow));
+ cl.setHWID(hwid);
+ ((CatsGuardReader)cl._reader).setKey(data);
+ if (this.LOG_SESSIONS)
+ _log.info("Client " + cl.getAccountName() + " connected with hwid " + cl.getHWid());
+ }
+
+ private class CatsGuardReader
+ implements L2GameClient.IExReader
+ {
+ private RC4 _crypt;
+ private L2GameClient _client;
+ private int _prevcode = 0;
+ private byte[] buffer = new byte[4];
+ private int _state;
+ private boolean _checkChar;
+
+ private CatsGuardReader(L2GameClient cl)
+ {
+ this._state = 0;
+ this._client = cl;
+ }
+
+ private void setKey(int[] data)
+ {
+ String key = "";
+ for (int i = 0; i < 10; i++)
+ key = key + String.format("%X%X", new Object[] { Integer.valueOf(data[1]), Integer.valueOf(CatsGuard._SERVER_KEY) });
+ this._crypt = new RC4(key, false);
+ this._state = 1;
+ }
+
+ public int read(ByteBuffer buf)
+ {
+ int opcode = 0;
+ if (this._state == 0)
+ {
+ opcode = buf.get() & 0xFF;
+ if (opcode != 202)
+ {
+ CatsGuard.this.illegalAction(this._client, "Invalid opcode on pre-auth state");
+ return 0;
+ }
+
+ }
+ else if (buf.remaining() < 4) {
+ CatsGuard.this.illegalAction(this._client, "Invalid block size on authed state");
+ }
+ else {
+ buf.get(this.buffer);
+ opcode = decryptPacket(this.buffer) & 0xFF;
+ }
+
+ return opcode;
+ }
+
+ private int decryptPacket(byte[] packet)
+ {
+ packet = this._crypt.rc4(packet);
+ int crc = CRC16.calc(new byte[] { (byte)(this._prevcode & 0xFF), packet[1] });
+ int read_crc = (packet[3] & 0xFF) << 8 & 0xFF00 | packet[2] & 0xFF;
+ if (crc != read_crc)
+ {
+ CatsGuard.this.illegalAction(this._client, "CRC error");
+ return 0;
+ }
+ this._prevcode = (packet[1] & 0xFF);
+ return this._prevcode;
+ }
+
+ public void checkChar(L2PcInstance cha)
+ {
+ if ((!this._checkChar) || (cha == null))
+ return;
+ if (CatsGuard.this.ALLOW_GM_FROM_BANNED_HWID)
+ return;
+ if (CatsGuard.this.LOG_OPTION.contains("BANNED"))
+ CatsGuard._log.info("CatsGuard: Client " + cha.getClient() + " try to log with banned hwid");
+ cha.closeNetConnection();
+ }
+ }
+}
\ No newline at end of file
Index: gameserver/config/protected/catsguard.properties
===================================================================
--- gameserver/config/protected/catsguard.properties (revision 0)
+++ gameserver/config/protected/catsguard.properties (revision 0)
@@ -0,0 +1,30 @@
+# Enable Protection (need client patch)
+Enabled = True
+
+# Log
+# NOPROTECT - Login without client patch
+# HACK - Hacking attempt
+# SESSIONS - Enter players to world
+LogOption = NOPROTECT HACK SESSIONS
+
+# Maximum sessions from one HWID
+MaxSessionsFromHWID = 1
+
+#
+MaxSessionsForPremium=-1
+
+# Announce to all world hacker name
+AnnounceHackAttempt = false
+
+# then hack attempt
+# kick - kick player
+# jail - move player to jail
+# ban - ban player
+# hwidban - ban with hwid
+OnHackAttempt = kick
+
+# Allow GM from banned HWID pc
+AllowGMFromBannedHWID=false
+
+# Log players in enter world
+LogSessions= true
Index: gameserver/head-src/com/l2jfrozen/gameserver/network/serverpackets/GameGuardQuery.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/gameserver/network/serverpackets/GameGuardQuery.java (revision 986)
+++ gameserver/head-src/com/l2jfrozen/gameserver/network/serverpackets/GameGuardQuery.java (working copy)
@@ -18,39 +18,25 @@
*/
package com.l2jfrozen.gameserver.network.serverpackets;

-import com.l2jfrozen.crypt.nProtect;
+import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jfrozen.gameserver.network.L2GameClient;

-/**
- * @author zabbix Lets drink to code!
- */
public class GameGuardQuery extends L2GameServerPacket
{
- private static final String _S__F9_GAMEGUARDQUERY = "[S] F9 GameGuardQuery";
+ private static final String _S__F9_GAMEGUARDQUERY = "[S] F9 GameGuardQuery";
+ public static final GameGuardQuery STATIC_PACKET = new GameGuardQuery();

- public GameGuardQuery()
- {
+ public void runImpl(L2GameClient client, L2PcInstance activeChar)
+ {
+ }

- }
+ public void writeImpl()
+ {
+ writeC(249);
+ }

- @Override
- public void runImpl()
- {
- // Lets make user as gg-unauthorized
- // We will set him as ggOK after reply fromclient
- // or kick
- getClient().setGameGuardOk(false);
- }
-
- @Override
- public void writeImpl()
- {
- writeC(0xf9);
- nProtect.getInstance().sendGameGuardQuery(this);
- }
-
- @Override
- public String getType()
- {
- return _S__F9_GAMEGUARDQUERY;
- }
-}
+ public String getType()
+ {
+ return "[S] F9 GameGuardQuery";
+ }
+}
\ No newline at end of file
Index: gameserver/head-src/com/l2jfrozen/protection/LameStub.java
===================================================================
--- gameserver/head-src/com/l2jfrozen/protection/LameStub.java (revision 0)
+++ gameserver/head-src/com/l2jfrozen/protection/LameStub.java (revision 0)
@@ -0,0 +1,12 @@
+package com.l2jfrozen.protection;
+
+public class LameStub
+{
+ public static boolean ISLAME = false;
+
+ public static void main(String[] args) {
+ com.l2jfrozen.gameserver.network.BlowFishKeygen._ISLAME = true;
+ com.l2jfrozen.gameserver.network.GameCrypt._ISLAME = true;
+ ISLAME = true;
+ }
+}
\ No newline at end of file

Descargas:

http://www.mediafire.com/file/gl5lzlv1bba4pfi/CatsGuard.7z

Otras fuentes:

https://github.com/HityZ/server/commit/0463b5f61a21bfba6d0eb9b40fddee5fa83ed7c3