Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Need Help about client ivRecv ivSend

Newbie Spellweaver
Joined
Dec 1, 2016
Messages
15
Reaction score
0
Hello Everyone i need some help about client. can we get ivRecv, ivSend on client? i see this thread V118.3 real localhost (No Redirector) and i use this localhost but it don't work after login.

I think it have problem with ivRecv and ivSend Because dc after click login or send any packet to client..

Thank you! ^_^
 
Newbie Spellweaver
Joined
Dec 1, 2016
Messages
15
Reaction score
0
Code:
final byte ivRecv[] = new byte[]{(byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255)};        final byte ivSend[] = new byte[]{(byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255)};


        final MapleClient client = new MapleClient(
                new MapleAESOFB(ivSend, (short) (0xFFFF - ServerConstants.MAPLE_VERSION)), // Sent Cypher
                new MapleAESOFB(ivRecv, ServerConstants.MAPLE_VERSION), // Recv Cypher
                session);
        client.setChannel(channel);


        MaplePacketDecoder.DecoderState decoderState = new MaplePacketDecoder.DecoderState();
        session.setAttribute(MaplePacketDecoder.DECODER_STATE_KEY, decoderState);


        session.write(LoginPacket.getHello(ServerConstants.MAPLE_VERSION, ivSend, ivRecv));
        session.setAttribute(MapleClient.CLIENT_KEY, client);

Code:
public static byte[] getHello(final short mapleVersion, final byte[] sendIv, final byte[] recvIv) {        final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(15 + ServerConstants.MAPLE_PATCH.length());


        mplew.writeShort(13 + ServerConstants.MAPLE_PATCH.length()); // length of the packet
        mplew.writeShort(mapleVersion);
        mplew.writeMapleAsciiString(ServerConstants.MAPLE_PATCH);
        mplew.write(recvIv);
        mplew.write(sendIv);
        mplew.write(8); // 7 = MSEA, 8 = GlobalMS, 5 = Test Server


        return mplew.getPacket();
    }

It work on redirector, but I want to try it on Localhost because it can edit text in client ^_^
ps. I'm using this source http://forum.ragezone.com/f427/v118-deviousms-973076/

Thank you Fraysa!
 
Upvote 0
Newbie Spellweaver
Joined
Dec 1, 2016
Messages
15
Reaction score
0
SendPacketOpcode.java
Code:
/*This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc> 
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>


This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License version 3
as published by the Free Software Foundation. You may not use, modify
or distribute this program under any other version of the
GNU Affero General Public License.


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 Affero General Public License for more details.


You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package handling;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;


public enum SendPacketOpcode implements WritableIntValueHolder {
    // GENERAL


    PING,
    // LOGIN
    LOGIN_STATUS,
    LOGIN_SECOND,
    PIN_OPERATION,
    SECONDPW_ERROR,
    SERVERLIST,
    SERVERSTATUS,
    SERVER_IP,
    CHARLIST,
    CHAR_NAME_RESPONSE,
    ADD_NEW_CHAR_ENTRY,
    DELETE_CHAR_RESPONSE,
    CHANNEL_SELECTED,
    ALL_CHARLIST,
    RSA_KEY,
    ENABLE_RECOMMENDED,
    SEND_RECOMMENDED,
    LOGIN_WELCOME,
    CHANGE_NAME_CHECK,
    CHANGE_NAME_RESPONSE,
    GACHAPON_STAMPS,
    EQUIP_STOLEN_SKILL,
    UPDATE_CARD_DECK,
    UPDATE_STOLEN_SKILLS,
    SKILL_SWIPE_WINDOW,
    FREE_CASH_ITEM,
    ONE_A_DAY,
    // CHANNEL
    CHANGE_CHANNEL, SHOW_TITLE,
    UPDATE_STATS,
    CS_CHARGE_CASH,
    FAME_RESPONSE,
    OWL_RESULT,
    USE_CASH_PET_FOOD,
    WEDDING_GIFT,
    UPDATE_SKILLS,
    YOUR_INFORMATION,
    CARD_DROPS,
    PINKBEAN_CHOCO,
    MULUNG_DOJO_RANKING,
    AUTO_CC_MSG,
    ALIEN_SOCKET_CREATOR,
    MULUNG_MESSAGE,
    SHOW_FUSION_EFFECT,
    UPDATE_IMP_TIME,
    FIND_FRIEND,
    BOMB_LIE_DETECTOR,
    REPORT_RESPONSE,
    REPORT_TIME,
    RANDOM_MESOBAG_SUCCESS,
    BUFF_ZONE_EFFECT,
    TIME_BOMB_ATTACK,
    REISSUE_MEDAL,
    RANDOM_MESOBAG_FAILURE,
    POTION_BONUS,
    DISABLE_NPC,
    REPORT_STATUS,
    SHOW_FIREWORKS_EFFECT,
    SHOW_MAGNIFYING_EFFECT,
    SHOW_NEBULITE_EFFECT,
    SHEEP_RANCH_INFO,
    SHEEP_RANCH_CLOTHES,
    AP_RESET,
    ARIANT_SCOREBOARD,
    ARIANT_SCORE_UPDATE,
    BOAT_MOVE,
    BOAT_STATE,
    WITCH_TOWER,
    PYRAMID_KILL_COUNT,
    PVP_DAMAGED,
    ANDROID_UPDATE,
    SHOW_PQ_REWARD,
    PVP_DETAILS,
    NETT_PYRAMID,
    EXPAND_CHARACTER_SLOTS,
    WARP_TO_MAP,
    SERVERMESSAGE,
    ECHO_MESSAGE,
    AVATAR_MEGA,
    SPAWN_NPC,
    REMOVE_NPC,
    SPAWN_NPC_REQUEST_CONTROLLER,
    SPAWN_MONSTER,
    SPAWN_MONSTER_CONTROL,
    MOVE_MONSTER_RESPONSE,
    CHATTEXT,
    SHOW_STATUS_INFO,
    SHOW_MESO_GAIN,
    SHOW_QUEST_COMPLETION,
    WHISPER,
    SPAWN_PLAYER,
    ANNOUNCE_PLAYER_SHOP,
    SHOW_SCROLL_EFFECT,
    SHOW_ITEM_GAIN_INCHAT,
    CURRENT_MAP_WARP,
    KILL_MONSTER,
    DROP_ITEM_FROM_MAPOBJECT,
    FACIAL_EXPRESSION,
    MOVE_PLAYER,
    MOVE_MONSTER,
    CLOSE_RANGE_ATTACK,
    RANGED_ATTACK,
    MAGIC_ATTACK,
    ENERGY_ATTACK,
    OPEN_NPC_SHOP,
    CONFIRM_SHOP_TRANSACTION,
    OPEN_STORAGE,
    INVENTORY_OPERATION,
    REMOVE_PLAYER_FROM_MAP,
    REMOVE_ITEM_FROM_MAP,
    UPDATE_CHAR_LOOK,
    SHOW_FOREIGN_EFFECT,
    GIVE_FOREIGN_BUFF,
    CANCEL_FOREIGN_BUFF,
    DAMAGE_PLAYER,
    CHAR_INFO,
    UPDATE_QUEST_INFO,
    GIVE_BUFF,
    CANCEL_BUFF,
    PLAYER_INTERACTION,
    UPDATE_CHAR_BOX,
    NPC_TALK,
    KEYMAP,
    SHOW_MONSTER_HP,
    PARTY_OPERATION,
    UPDATE_PARTYMEMBER_HP,
    MULTICHAT,
    APPLY_MONSTER_STATUS,
    CANCEL_MONSTER_STATUS,
    CLOCK,
    SPAWN_PORTAL,
    SPAWN_DOOR,
    REMOVE_DOOR,
    SPAWN_SUMMON,
    REMOVE_SUMMON,
    SUMMON_ATTACK,
    MOVE_SUMMON,
    SPAWN_MIST,
    REMOVE_MIST,
    DAMAGE_SUMMON,
    DAMAGE_MONSTER,
    BUDDYLIST,
    SHOW_ITEM_EFFECT,
    SHOW_CHAIR,
    CANCEL_CHAIR,
    SKILL_EFFECT,
    CANCEL_SKILL_EFFECT,
    BOSS_ENV,
    REACTOR_SPAWN,
    REACTOR_HIT,
    REACTOR_DESTROY,
    MAP_EFFECT,
    GUILD_OPERATION,
    ALLIANCE_OPERATION,
    BBS_OPERATION,
    FAMILY,
    EARN_TITLE_MSG,
    SHOW_MAGNET,
    MERCH_ITEM_MSG,
    MERCH_ITEM_STORE,
    MESSENGER,
    NPC_ACTION,
    SPAWN_PET,
    MOVE_PET,
    PET_CHAT,
    PET_COMMAND,
    PET_NAMECHANGE,
    PET_AUTO_HP,
    PET_AUTO_MP,
    PET_UPDATE,
    COOLDOWN,
    PLAYER_HINT,
    SUMMON_HINT,
    SUMMON_HINT_MSG,
    CYGNUS_INTRO_DISABLE_UI,
    CYGNUS_INTRO_LOCK,
    USE_SKILL_BOOK,
    SHOW_EQUIP_EFFECT,
    SKILL_MACRO,
    CS_OPEN,
    CS_UPDATE,
    CS_OPERATION,
    MTS_OPEN,
    PLAYER_NPC,
    SHOW_NOTES,
    SUMMON_SKILL,
    ARIANT_PQ_START,
    CATCH_MONSTER,
    CATCH_MOB,
    ENGLISH_QUIZ,
    BOAT_EFFECT,
    CHALKBOARD,
    RENAME_FAMILIAR,
    DUEY,
    TROCK_LOCATIONS,
    MONSTER_CARNIVAL_START,
    MONSTER_CARNIVAL_OBTAINED_CP,
    MONSTER_CARNIVAL_PARTY_CP,
    MONSTER_CARNIVAL_SUMMON,
    MONSTER_CARNIVAL_DIED,
    SPAWN_HIRED_MERCHANT,
    UPDATE_HIRED_MERCHANT,
    SEND_TITLE_BOX,
    DESTROY_HIRED_MERCHANT,
    UPDATE_MOUNT,
    EXP_BONUS,
    VICIOUS_HAMMER,
    FISHING_BOARD_UPDATE,
    FISHING_CAUGHT,
    OX_QUIZ,
    ROLL_SNOWBALL,
    HIT_SNOWBALL,
    SNOWBALL_MESSAGE,
    LEFT_KNOCK_BACK,
    FINISH_SORT,
    FINISH_GATHER,
    SEND_PEDIGREE,
    OPEN_FAMILY,
    FAMILY_MESSAGE,
    FAMILY_INVITE,
    FAMILY_JUNIOR,
    SENIOR_MESSAGE,
    REP_INCREASE,
    FAMILY_LOGGEDIN,
    FAMILY_BUFF,
    FAMILY_USE_REQUEST,
    YELLOW_CHAT,
    PIGMI_REWARD,
    GM_EFFECT,
    HIT_COCONUT,
    COCONUT_SCORE,
    LEVEL_UPDATE,
    MARRIAGE_UPDATE,
    JOB_UPDATE,
    HORNTAIL_SHRINE,
    STOP_CLOCK,
    MESOBAG_SUCCESS,
    MESOBAG_FAILURE,
    SERVER_BLOCKED,
    DRAGON_MOVE,
    DRAGON_REMOVE,
    DRAGON_SPAWN,
    ARAN_COMBO,
    TOP_MSG,
    TEMP_STATS,
    TEMP_STATS_RESET,
    OPEN_UI,
    OPEN_UI_OPTION,
    PYRAMID_UPDATE,
    PYRAMID_RESULT,
    SESSION_VALUE,
    GET_MTS_TOKENS,
    MTS_OPERATION,
    SHOW_POTENTIAL_EFFECT,
    SHOW_POTENTIAL_RESET,
    CHAOS_ZAKUM_SHRINE,
    CHAOS_HORNTAIL_SHRINE,
    GAME_POLL_QUESTION,
    GAME_POLL_REPLY,
    GMEVENT_INSTRUCTIONS,
    BOAT_EFF,
    OWL_OF_MINERVA,
    XMAS_SURPRISE,
    CASH_SONG,
    INVENTORY_GROW,
    FOLLOW_REQUEST,
    FOLLOW_EFFECT,
    FOLLOW_MOVE,
    FOLLOW_MSG,
    TALK_MONSTER,
    REMOVE_TALK_MONSTER,
    MONSTER_PROPERTIES,
    MOVE_PLATFORM,
    MOVE_ENV,
    UPDATE_ENV,
    ENGAGE_REQUEST,
    PARTY_VALUE,
    MAP_VALUE,
    ENGAGE_RESULT,
    UPDATE_JAGUAR,
    EXPEDITION_OPERATION,
    LOGIN_AUTH,
    TESLA_TRIANGLE,
    MECH_PORTAL,
    MECH_DOOR_SPAWN,
    MECH_DOOR_REMOVE,
    PET_FLAG_CHANGE,
    PAMS_SONG,
    PLAYER_DAMAGED,
    SP_RESET,
    REPORT,
    ULTIMATE_EXPLORER,
    GM_POLICE,
    PAM_SONG,
    CS_USE,
    DRAGON_BLINK,
    HARVESTED,
    SHOW_HARVEST,
    GAME_MESSAGE,
    ITEM_POT,
    SPAWN_EXTRACTOR,
    REMOVE_EXTRACTOR,
    CRAFT_COMPLETE,
    CRAFT_EFFECT,
    HARVEST_MESSAGE,
    OPEN_BAG,
    BUFF_BAR,
    MID_MSG,
    NPC_SCRIPTABLE,
    SHOP_DISCOUNT,
    GET_CARD,
    CARD_SET,
    BOOK_STATS,
    ANDROID_SPAWN,
    ANDROID_MOVE,
    ANDROID_EMOTION,
    ANDROID_REMOVE,
    ANDROID_DEACTIVATED,
    PENDANT_SLOT,
    BOOK_INFO,
    PARTY_SEARCH,
    MEMBER_SEARCH,
    ARAN_COMBO_RECHARGE,
    R_MESOBAG_SUCCESS, //TODO use this
    R_MESOBAG_FAILURE, //TODO use this
    LOAD_GUILD_NAME,
    LOAD_GUILD_ICON,
    SPOUSE_CHAT, //TODO confirm
    MAP_BLOCKED, //TODO use this
    RESET_SCREEN, //TODO use this
    CHANGE_BACKGROUND, //TODO use this
    VISITOR,
    UPDATE_GENDER,
    REGISTER_FAMILIAR,
    SPAWN_FAMILIAR,
    MOVE_FAMILIAR,
    ATTACK_FAMILIAR,
    UPDATE_FAMILIAR,
    TOUCH_FAMILIAR,
    SIDEKICK_OPERATION,
    RESET_MINIMAP, //TODO use this
    ACHIEVEMENT_RATIO,
    CREATE_ULTIMATE,
    PROFESSION_INFO,
    QUICK_SLOT,
    BOOSTER_FAMILIAR,
    BOOSTER_PACK,
    FAMILIAR_INFO,
    PVP_INFO,
    PVP_SCOREBOARD,
    PVP_RESULT,
    PVP_ENABLED,
    PVP_MODE,
    PVP_TYPE,
    PVP_TEAM,
    PVP_SCORE,
    PVP_KILLED,
    PVP_SUMMON,
    PVP_ATTACK,
    PVP_POINTS,
    PVP_HP,
    PVP_MIST,
    PVP_ICEKNIGHT,
    PVP_COOL,
    PVP_ICEGAGE,
    PVP_TRANSFORM,
    LOAD_TEAM,
    CAPTURE_FLAGS,
    CAPTURE_POSITION,
    CAPTURE_RESET,
    CLEAR_MID_MSG,
    PUBLIC_NPC,
    PVP_BLOCKED,
    PLAY_MOVIE,
    DIRECTION_INFO,
    DIRECTION_STATUS,
    GAIN_FORCE,
    CYGNUS_INTRO_ENABLE_UI,
    MONSTER_CARNIVAL_LEAVE,
    MONSTER_CARNIVAL_STATS,
    MONSTER_CARNIVAL_RESULT,
    MONSTER_CARNIVAL_RANKING,
    MOB_TO_MOB_DAMAGE,
    SKILL_EFFECT_MOB,
    ITEM_EFFECT_MOB,
    CYGNUS_ATTACK,
    SPECIAL_CREATION,
    MONSTER_RESIST,
    PET_EXCEPTION_LIST,
    RPS_GAME, AZWAN_FAME, PART_TIME_JOB, MAGIC_WHEEL;
    private short code = -2;


    @Override
    public void setValue(short code) {
        this.code = code;
    }


    @Override
    public short getValue() {
        //System.out.println("Packet to send: " + this.name() + " Value: " + this.code + "\r\nCaller: " + Thread.currentThread().getStackTrace()[2]);
        return code;
    }


    public static Properties getDefaultProperties() throws FileNotFoundException, IOException {
        Properties props = new Properties();
        FileInputStream fileInputStream = new FileInputStream("send.properties");
        props.load(fileInputStream);
        fileInputStream.close();
        return props;
    }


    static {
        reloadValues();
    }


    public static String getOpcodeName(int value) {
        for (SendPacketOpcode opcode : SendPacketOpcode.values()) {
            if (opcode.getValue() == value) {
                return opcode.name();
            }
        }
        return "UNKNOWN";
    }


    public static final void reloadValues() {
        try {
            ExternalCodeTableGetter.populateValues(getDefaultProperties(), values());
        } catch (IOException e) {
            throw new RuntimeException("Failed to load sendops", e);
        }
    }
}

MaplePacketDecoder.java
Code:
/*    This file is part of the OdinMS Maple Story Server
    Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc> 
                       Matthias Butz <matze@odinms.de>
                       Jan Christian Meyer <vimes@odinms.de>


    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
    as published by the Free Software Foundation. You may not use, modify
    or distribute this program under any other version of the
    GNU Affero General Public License.


    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 Affero General Public License for more details.


    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package handling.mina;


import client.MapleClient;
import tools.MapleAESOFB;
import tools.MapleCustomEncryption;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;


import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;


public class MaplePacketDecoder extends CumulativeProtocolDecoder {


    public static final String DECODER_STATE_KEY = MaplePacketDecoder.class.getName() + ".STATE";


    public static class DecoderState {


    public int packetlength = -1;
    }


    @Override
    protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
    final DecoderState decoderState = (DecoderState) session.getAttribute(DECODER_STATE_KEY);


/*    if (decoderState == null) {
        decoderState = new DecoderState();
        session.setAttribute(DECODER_STATE_KEY, decoderState);
    }*/
    final MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);


    if (decoderState.packetlength == -1) {
        if (in.remaining() >= 4) {
        final int packetHeader = in.getInt();
        if (!client.getReceiveCrypto().checkPacket(packetHeader)) {
            session.close(true);
            return false;
        }
        decoderState.packetlength = MapleAESOFB.getPacketLength(packetHeader);
        } else {
        return false;
        }
    }
    if (in.remaining() >= decoderState.packetlength) {
        final byte decryptedPacket[] = new byte[decoderState.packetlength];
        in.get(decryptedPacket, 0, decoderState.packetlength);
        decoderState.packetlength = -1;


        client.getReceiveCrypto().crypt(decryptedPacket);
        MapleCustomEncryption.decryptData(decryptedPacket);
        out.write(decryptedPacket);
        return true;
    }
    return false;
    }
}

MaplePacketEncode.java
Code:
/*    This file is part of the OdinMS Maple Story Server
    Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc> 
                       Matthias Butz <matze@odinms.de>
                       Jan Christian Meyer <vimes@odinms.de>


    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
    as published by the Free Software Foundation. You may not use, modify
    or distribute this program under any other version of the
    GNU Affero General Public License.


    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 Affero General Public License for more details.


    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package handling.mina;


import client.MapleClient;


import tools.MapleAESOFB;
import tools.MapleCustomEncryption;


import java.util.concurrent.locks.Lock;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;




import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;


public class MaplePacketEncoder implements ProtocolEncoder {


    @Override
    public void encode(final IoSession session, final Object message, final ProtocolEncoderOutput out) throws Exception {
    final MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);


    if (client != null) {
        final MapleAESOFB send_crypto = client.getSendCrypto();


        final byte[] inputInitialPacket = ((byte[]) message);
        final byte[] unencrypted = new byte[inputInitialPacket.length];
        System.arraycopy(inputInitialPacket, 0, unencrypted, 0, inputInitialPacket.length); // Copy the input > "unencrypted"
        final byte[] ret = new byte[unencrypted.length + 4]; // Create new bytes with length = "unencrypted" + 4


        final Lock mutex = client.getLock();
        mutex.lock();
        try {
        final byte[] header = send_crypto.getPacketHeader(unencrypted.length);
        MapleCustomEncryption.encryptData(unencrypted); // Encrypting Data
        send_crypto.crypt(unencrypted); // Crypt it with IV
        System.arraycopy(header, 0, ret, 0, 4); // Copy the header > "Ret", first 4 bytes
        } finally {
        mutex.unlock();
        }
        System.arraycopy(unencrypted, 0, ret, 4, unencrypted.length); // Copy the unencrypted > "ret"
        out.write(IoBuffer.wrap(ret));
    } else { // no client object created yet, send unencrypted (hello)
        out.write(IoBuffer.wrap(((byte[]) message)));
    }
    }


    @Override
    public void dispose(IoSession session) throws Exception {
    // nothing to do
    }
}

MapleAESOFB.java
Code:
/*This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc> 
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>


This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License version 3
as published by the Free Software Foundation. You may not use, modify
or distribute this program under any other version of the
GNU Affero General Public License.


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 Affero General Public License for more details.


You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package tools;


import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;


import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;


/**
 * Provides a class for encrypting MapleStory packets with AES OFB encryption.
 *
 * @author Frz
 * @[I][B][URL="http://forum.ragezone.com/members/316612.html"]Version[/URL][/B][/I] 1.0
 * @[I][B][URL="http://forum.ragezone.com/members/302236.html"]Sin[/URL][/B][/I]ce Revision 320
 */
public class MapleAESOFB {


    private byte iv[];
    private Cipher cipher;
    private short mapleVersion;
    
    //private final static SecretKeySpec skey = new SecretKeySpec(new byte[]{(byte) 0x5A, 0x00, 0x00, 0x00, (byte) 0x22, 0x00, 0x00, 0x00, (byte) 0xFB, 0x00, 0x00, 0x00, (byte) 0xD1, 0x00, 0x00, 0x00, (byte) 0x8F, 0x00, 0x00, 0x00, (byte) 0x93, 0x00, 0x00, 0x00, (byte) 0xCD, 0x00, 0x00, 0x00, (byte) 0xE6, 0x00, 0x00, 0x00}, "AES");
    private final static SecretKeySpec skey = new SecretKeySpec(new byte[]{0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, (byte) 0xB4, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00}, "AES");
    // KMS
//    {0x13, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00}
    /* VANA */
    private static final byte[] funnyBytes = new byte[]{(byte) 0xEC, (byte) 0x3F, (byte) 0x77, (byte) 0xA4, (byte) 0x45, (byte) 0xD0, (byte) 0x71, (byte) 0xBF, (byte) 0xB7, (byte) 0x98, (byte) 0x20, (byte) 0xFC,
        (byte) 0x4B, (byte) 0xE9, (byte) 0xB3, (byte) 0xE1, (byte) 0x5C, (byte) 0x22, (byte) 0xF7, (byte) 0x0C, (byte) 0x44, (byte) 0x1B, (byte) 0x81, (byte) 0xBD, (byte) 0x63, (byte) 0x8D, (byte) 0xD4, (byte) 0xC3,
        (byte) 0xF2, (byte) 0x10, (byte) 0x19, (byte) 0xE0, (byte) 0xFB, (byte) 0xA1, (byte) 0x6E, (byte) 0x66, (byte) 0xEA, (byte) 0xAE, (byte) 0xD6, (byte) 0xCE, (byte) 0x06, (byte) 0x18, (byte) 0x4E, (byte) 0xEB,
        (byte) 0x78, (byte) 0x95, (byte) 0xDB, (byte) 0xBA, (byte) 0xB6, (byte) 0x42, (byte) 0x7A, (byte) 0x2A, (byte) 0x83, (byte) 0x0B, (byte) 0x54, (byte) 0x67, (byte) 0x6D, (byte) 0xE8, (byte) 0x65, (byte) 0xE7,
        (byte) 0x2F, (byte) 0x07, (byte) 0xF3, (byte) 0xAA, (byte) 0x27, (byte) 0x7B, (byte) 0x85, (byte) 0xB0, (byte) 0x26, (byte) 0xFD, (byte) 0x8B, (byte) 0xA9, (byte) 0xFA, (byte) 0xBE, (byte) 0xA8, (byte) 0xD7,
        (byte) 0xCB, (byte) 0xCC, (byte) 0x92, (byte) 0xDA, (byte) 0xF9, (byte) 0x93, (byte) 0x60, (byte) 0x2D, (byte) 0xDD, (byte) 0xD2, (byte) 0xA2, (byte) 0x9B, (byte) 0x39, (byte) 0x5F, (byte) 0x82, (byte) 0x21,
        (byte) 0x4C, (byte) 0x69, (byte) 0xF8, (byte) 0x31, (byte) 0x87, (byte) 0xEE, (byte) 0x8E, (byte) 0xAD, (byte) 0x8C, (byte) 0x6A, (byte) 0xBC, (byte) 0xB5, (byte) 0x6B, (byte) 0x59, (byte) 0x13, (byte) 0xF1,
        (byte) 0x04, (byte) 0x00, (byte) 0xF6, (byte) 0x5A, (byte) 0x35, (byte) 0x79, (byte) 0x48, (byte) 0x8F, (byte) 0x15, (byte) 0xCD, (byte) 0x97, (byte) 0x57, (byte) 0x12, (byte) 0x3E, (byte) 0x37, (byte) 0xFF,
        (byte) 0x9D, (byte) 0x4F, (byte) 0x51, (byte) 0xF5, (byte) 0xA3, (byte) 0x70, (byte) 0xBB, (byte) 0x14, (byte) 0x75, (byte) 0xC2, (byte) 0xB8, (byte) 0x72, (byte) 0xC0, (byte) 0xED, (byte) 0x7D, (byte) 0x68,
        (byte) 0xC9, (byte) 0x2E, (byte) 0x0D, (byte) 0x62, (byte) 0x46, (byte) 0x17, (byte) 0x11, (byte) 0x4D, (byte) 0x6C, (byte) 0xC4, (byte) 0x7E, (byte) 0x53, (byte) 0xC1, (byte) 0x25, (byte) 0xC7, (byte) 0x9A,
        (byte) 0x1C, (byte) 0x88, (byte) 0x58, (byte) 0x2C, (byte) 0x89, (byte) 0xDC, (byte) 0x02, (byte) 0x64, (byte) 0x40, (byte) 0x01, (byte) 0x5D, (byte) 0x38, (byte) 0xA5, (byte) 0xE2, (byte) 0xAF, (byte) 0x55,
        (byte) 0xD5, (byte) 0xEF, (byte) 0x1A, (byte) 0x7C, (byte) 0xA7, (byte) 0x5B, (byte) 0xA6, (byte) 0x6F, (byte) 0x86, (byte) 0x9F, (byte) 0x73, (byte) 0xE6, (byte) 0x0A, (byte) 0xDE, (byte) 0x2B, (byte) 0x99,
        (byte) 0x4A, (byte) 0x47, (byte) 0x9C, (byte) 0xDF, (byte) 0x09, (byte) 0x76, (byte) 0x9E, (byte) 0x30, (byte) 0x0E, (byte) 0xE4, (byte) 0xB2, (byte) 0x94, (byte) 0xA0, (byte) 0x3B, (byte) 0x34, (byte) 0x1D,
        (byte) 0x28, (byte) 0x0F, (byte) 0x36, (byte) 0xE3, (byte) 0x23, (byte) 0xB4, (byte) 0x03, (byte) 0xD8, (byte) 0x90, (byte) 0xC8, (byte) 0x3C, (byte) 0xFE, (byte) 0x5E, (byte) 0x32, (byte) 0x24, (byte) 0x50,
        (byte) 0x1F, (byte) 0x3A, (byte) 0x43, (byte) 0x8A, (byte) 0x96, (byte) 0x41, (byte) 0x74, (byte) 0xAC, (byte) 0x52, (byte) 0x33, (byte) 0xF0, (byte) 0xD9, (byte) 0x29, (byte) 0x80, (byte) 0xB1, (byte) 0x16,
        (byte) 0xD3, (byte) 0xAB, (byte) 0x91, (byte) 0xB9, (byte) 0x84, (byte) 0x7F, (byte) 0x61, (byte) 0x1E, (byte) 0xCF, (byte) 0xC5, (byte) 0xD1, (byte) 0x56, (byte) 0x3D, (byte) 0xCA, (byte) 0xF4, (byte) 0x05,
        (byte) 0xC6, (byte) 0xE5, (byte) 0x08, (byte) 0x49};


    /* ORIGINAL
    private static final byte[] funnyBytes2 = new byte[] { (byte) 0xEC, 0x3F, 0x77, (byte) 0xA4, 0x45, (byte) 0xD0,
    0x71, (byte) 0xBF, (byte) 0xB7, (byte) 0x98, 0x20, (byte) 0xFC, 0x4B, (byte) 0xE9, (byte) 0xB3, (byte) 0xE1,
    0x5C, 0x22, (byte) 0xF7, 0x0C, 0x44, 0x1B, (byte) 0x81, (byte) 0xBD, 0x63, (byte) 0x8D, (byte) 0xD4,
    (byte) 0xC3, (byte) 0xF2, 0x10, 0x19, (byte) 0xE0, (byte) 0xFB, (byte) 0xA1, 0x6E, 0x66, (byte) 0xEA,
    (byte) 0xAE, (byte) 0xD6, (byte) 0xCE, 0x06, 0x18, 0x4E, (byte) 0xEB, 0x78, (byte) 0x95, (byte) 0xDB,
    (byte) 0xBA, (byte) 0xB6, 0x42, 0x7A, 0x2A, (byte) 0x83, 0x0B, 0x54, 0x67, 0x6D, (byte) 0xE8, 0x65,
    (byte) 0xE7, 0x2F, 0x07, (byte) 0xF3, (byte) 0xAA, 0x27, 0x7B, (byte) 0x85, (byte) 0xB0, 0x26, (byte) 0xFD,
    (byte) 0x8B, (byte) 0xA9, (byte) 0xFA, (byte) 0xBE, (byte) 0xA8, (byte) 0xD7, (byte) 0xCB, (byte) 0xCC,
    (byte) 0x92, (byte) 0xDA, (byte) 0xF9, (byte) 0x93, 0x60, 0x2D, (byte) 0xDD, (byte) 0xD2, (byte) 0xA2,
    (byte) 0x9B, 0x39, 0x5F, (byte) 0x82, 0x21, 0x4C, 0x69, (byte) 0xF8, 0x31, (byte) 0x87, (byte) 0xEE,
    (byte) 0x8E, (byte) 0xAD, (byte) 0x8C, 0x6A, (byte) 0xBC, (byte) 0xB5, 0x6B, 0x59, 0x13, (byte) 0xF1, 0x04,
    0x00, (byte) 0xF6, 0x5A, 0x35, 0x79, 0x48, (byte) 0x8F, 0x15, (byte) 0xCD, (byte) 0x97, 0x57, 0x12, 0x3E, 0x37,
    (byte) 0xFF, (byte) 0x9D, 0x4F, 0x51, (byte) 0xF5, (byte) 0xA3, 0x70, (byte) 0xBB, 0x14, 0x75, (byte) 0xC2,
    (byte) 0xB8, 0x72, (byte) 0xC0, (byte) 0xED, 0x7D, 0x68, (byte) 0xC9, 0x2E, 0x0D, 0x62, 0x46, 0x17, 0x11, 0x4D,
    0x6C, (byte) 0xC4, 0x7E, 0x53, (byte) 0xC1, 0x25, (byte) 0xC7, (byte) 0x9A, 0x1C, (byte) 0x88, 0x58, 0x2C,
    (byte) 0x89, (byte) 0xDC, 0x02, 0x64, 0x40, 0x01, 0x5D, 0x38, (byte) 0xA5, (byte) 0xE2, (byte) 0xAF, 0x55,
    (byte) 0xD5, (byte) 0xEF, 0x1A, 0x7C, (byte) 0xA7, 0x5B, (byte) 0xA6, 0x6F, (byte) 0x86, (byte) 0x9F, 0x73,
    (byte) 0xE6, 0x0A, (byte) 0xDE, 0x2B, (byte) 0x99, 0x4A, 0x47, (byte) 0x9C, (byte) 0xDF, 0x09, 0x76,
    (byte) 0x9E, 0x30, 0x0E, (byte) 0xE4, (byte) 0xB2, (byte) 0x94, (byte) 0xA0, 0x3B, 0x34, 0x1D, 0x28, 0x0F,
    0x36, (byte) 0xE3, 0x23, (byte) 0xB4, 0x03, (byte) 0xD8, (byte) 0x90, (byte) 0xC8, 0x3C, (byte) 0xFE, 0x5E,
    0x32, 0x24, 0x50, 0x1F, 0x3A, 0x43, (byte) 0x8A, (byte) 0x96, 0x41, 0x74, (byte) 0xAC, 0x52, 0x33, (byte) 0xF0,
    (byte) 0xD9, 0x29, (byte) 0x80, (byte) 0xB1, 0x16, (byte) 0xD3, (byte) 0xAB, (byte) 0x91, (byte) 0xB9,
    (byte) 0x84, 0x7F, 0x61, 0x1E, (byte) 0xCF, (byte) 0xC5, (byte) 0xD1, 0x56, 0x3D, (byte) 0xCA, (byte) 0xF4,
    0x05, (byte) 0xC6, (byte) 0xE5, 0x08, 0x49, 0x4F, 0x64, 0x69, 0x6E, 0x4D, 0x53, 0x7E, 0x46, 0x72, 0x7A };*/
    private static byte[] rammyByte = new byte[]{(byte) 0xEC, (byte) 0x3F, (byte) 0x77, (byte) 0xA4, (byte) 0x45, (byte) 0xD0, (byte) 0x71, (byte) 0xBF, (byte) 0xB7, (byte) 0x98, (byte) 0x20, (byte) 0xFC,
        (byte) 0x4B, (byte) 0xE9, (byte) 0xB3, (byte) 0xE1, (byte) 0x5C, (byte) 0x22, (byte) 0xF7, (byte) 0x0C, (byte) 0x44, (byte) 0x1B, (byte) 0x81, (byte) 0xBD, (byte) 0x63, (byte) 0x8D, (byte) 0xD4, (byte) 0xC3,
        (byte) 0xF2, (byte) 0x10, (byte) 0x19, (byte) 0xE0, (byte) 0xFB, (byte) 0xA1, (byte) 0x6E, (byte) 0x66, (byte) 0xEA, (byte) 0xAE, (byte) 0xD6, (byte) 0xCE, (byte) 0x06, (byte) 0x18, (byte) 0x4E, (byte) 0xEB,
        (byte) 0x78, (byte) 0x95, (byte) 0xDB, (byte) 0xBA, (byte) 0xB6, (byte) 0x42, (byte) 0x7A, (byte) 0x2A, (byte) 0x83, (byte) 0x0B, (byte) 0x54, (byte) 0x67, (byte) 0x6D, (byte) 0xE8, (byte) 0x65, (byte) 0xE7,
        (byte) 0x2F, (byte) 0x07, (byte) 0xF3, (byte) 0xAA, (byte) 0x27, (byte) 0x7B, (byte) 0x85, (byte) 0xB0, (byte) 0x26, (byte) 0xFD, (byte) 0x8B, (byte) 0xA9, (byte) 0xFA, (byte) 0xBE, (byte) 0xA8, (byte) 0xD7,
        (byte) 0xCB, (byte) 0xCC, (byte) 0x92, (byte) 0xDA, (byte) 0xF9, (byte) 0x93, (byte) 0x60, (byte) 0x2D, (byte) 0xDD, (byte) 0xD2, (byte) 0xA2, (byte) 0x9B, (byte) 0x39, (byte) 0x5F, (byte) 0x82, (byte) 0x21,
        (byte) 0x4C, (byte) 0x69, (byte) 0xF8, (byte) 0x31, (byte) 0x87, (byte) 0xEE, (byte) 0x8E, (byte) 0xAD, (byte) 0x8C, (byte) 0x6A, (byte) 0xBC, (byte) 0xB5, (byte) 0x6B, (byte) 0x59, (byte) 0x13, (byte) 0xF1,
        (byte) 0x04, (byte) 0x00, (byte) 0xF6, (byte) 0x5A, (byte) 0x35, (byte) 0x79, (byte) 0x48, (byte) 0x8F, (byte) 0x15, (byte) 0xCD, (byte) 0x97, (byte) 0x57, (byte) 0x12, (byte) 0x3E, (byte) 0x37, (byte) 0xFF,
        (byte) 0x9D, (byte) 0x4F, (byte) 0x51, (byte) 0xF5, (byte) 0xA3, (byte) 0x70, (byte) 0xBB, (byte) 0x14, (byte) 0x75, (byte) 0xC2, (byte) 0xB8, (byte) 0x72, (byte) 0xC0, (byte) 0xED, (byte) 0x7D, (byte) 0x68,
        (byte) 0xC9, (byte) 0x2E, (byte) 0x0D, (byte) 0x62, (byte) 0x46, (byte) 0x17, (byte) 0x11, (byte) 0x4D, (byte) 0x6C, (byte) 0xC4, (byte) 0x7E, (byte) 0x53, (byte) 0xC1, (byte) 0x25, (byte) 0xC7, (byte) 0x9A,
        (byte) 0x1C, (byte) 0x88, (byte) 0x58, (byte) 0x2C, (byte) 0x89, (byte) 0xDC, (byte) 0x02, (byte) 0x64, (byte) 0x40, (byte) 0x01, (byte) 0x5D, (byte) 0x38, (byte) 0xA5, (byte) 0xE2, (byte) 0xAF, (byte) 0x55,
        (byte) 0xD5, (byte) 0xEF, (byte) 0x1A, (byte) 0x7C, (byte) 0xA7, (byte) 0x5B, (byte) 0xA6, (byte) 0x6F, (byte) 0x86, (byte) 0x9F, (byte) 0x73, (byte) 0xE6, (byte) 0x0A, (byte) 0xDE, (byte) 0x2B, (byte) 0x99,
        (byte) 0x4A, (byte) 0x47, (byte) 0x9C, (byte) 0xDF, (byte) 0x09, (byte) 0x76, (byte) 0x9E, (byte) 0x30, (byte) 0x0E, (byte) 0xE4, (byte) 0xB2, (byte) 0x94, (byte) 0xA0, (byte) 0x3B, (byte) 0x34, (byte) 0x1D,
        (byte) 0x28, (byte) 0x0F, (byte) 0x36, (byte) 0xE3, (byte) 0x23, (byte) 0xB4, (byte) 0x03, (byte) 0xD8, (byte) 0x90, (byte) 0xC8, (byte) 0x3C, (byte) 0xFE, (byte) 0x5E, (byte) 0x32, (byte) 0x24, (byte) 0x50,
        (byte) 0x1F, (byte) 0x3A, (byte) 0x43, (byte) 0x8A, (byte) 0x96, (byte) 0x41, (byte) 0x74, (byte) 0xAC, (byte) 0x52, (byte) 0x33, (byte) 0xF0, (byte) 0xD9, (byte) 0x29, (byte) 0x80, (byte) 0xB1, (byte) 0x16,
        (byte) 0xD3, (byte) 0xAB, (byte) 0x91, (byte) 0xB9, (byte) 0x84, (byte) 0x7F, (byte) 0x61, (byte) 0x1E, (byte) 0xCF, (byte) 0xC5, (byte) 0xD1, (byte) 0x56, (byte) 0x3D, (byte) 0xCA, (byte) 0xF4, (byte) 0x05,
        (byte) 0xC6, (byte) 0xE5, (byte) 0x08, (byte) 0x49};


    /**
     * Class constructor - Creates an instance of the MapleStory encryption
     * cipher.
     *
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m key The 256 bit AES key to use.
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m iv The 4-byte IV to use.
     */
    public MapleAESOFB(byte iv[], short mapleVersion) {
        try {
            cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, skey);
        } catch (NoSuchAlgorithmException e) {
            System.err.println("ERROR" + e);
        } catch (NoSuchPaddingException e) {
            System.err.println("ERROR" + e);
        } catch (InvalidKeyException e) {
            System.err.println("Error initalizing the encryption cipher.  Make sure you're using the Unlimited Strength cryptography jar files.");
        }


        this.setIv(iv);
        this.mapleVersion = (short) (((mapleVersion >> 8) & 0xFF) | ((mapleVersion << 8) & 0xFF00));
    }


    /**
     * Sets the IV of this instance.
     *
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m iv The new IV.
     */
    private void setIv(byte[] iv) {
        this.iv = iv;
    }


    /**
     * For debugging/testing purposes only.
     *
     * @[I][B][URL="http://forum.ragezone.com/members/850422.html"]return[/URL][/B][/I] The IV.
     */
    public byte[] getIv() {
        return this.iv;
    }


    /**
     * Encrypts <code>data</code> and generates a new IV.
     *
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m data The bytes to encrypt.
     * @[I][B][URL="http://forum.ragezone.com/members/850422.html"]return[/URL][/B][/I] The encrypted bytes.
     */
    public byte[] crypt(byte[] data) {
        int remaining = data.length;
        int llength = 0x5B0;
        int start = 0;


        try {
            while (remaining > 0) {
                byte[] myIv = BitTools.multiplyBytes(this.iv, 4, 4);
                if (remaining < llength) {
                    llength = remaining;
                }
                for (int x = start; x < (start + llength); x++) {
                    if ((x - start) % myIv.length == 0) {
                        byte[] newIv = cipher.doFinal(myIv);
                        System.arraycopy(newIv, 0, myIv, 0, myIv.length);
                        // System.out
                        // .println("Iv is now " + HexTool.toString(this.iv));


                    }
                    data[x] ^= myIv[(x - start) % myIv.length];
                }
                start += llength;
                remaining -= llength;
                llength = 0x5B4;
            }
            updateIv();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return data;
    }


    /**
     * Generates a new IV.
     */
    private void updateIv() {
        this.iv = getNewIv(this.iv);
    }


    /**
     * Generates a packet header for a packet that is <code>length</code>
     * long.
     *
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m length How long the packet that this header is for is.
     * @[I][B][URL="http://forum.ragezone.com/members/850422.html"]return[/URL][/B][/I] The header.
     */
    public byte[] getPacketHeader(int length) {
        int iiv = (((iv[3]) & 0xFF) | ((iv[2] << 8) & 0xFF00)) ^ mapleVersion;
        int mlength = (((length << 8) & 0xFF00) | (length >>> 8)) ^ iiv;


        return new byte[]{(byte) ((iiv >>> 8) & 0xFF), (byte) (iiv & 0xFF), (byte) ((mlength >>> 8) & 0xFF), (byte) (mlength & 0xFF)};
    }


    /**
     * Gets the packet length from a header.
     *
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m packetHeader The header as an integer.
     * @[I][B][URL="http://forum.ragezone.com/members/850422.html"]return[/URL][/B][/I] The length of the packet.
     */
    public static int getPacketLength(int packetHeader) {
        int packetLength = ((packetHeader >>> 16) ^ (packetHeader & 0xFFFF));
        packetLength = ((packetLength << 8) & 0xFF00) | ((packetLength >>> 8) & 0xFF); // fix endianness
        return packetLength;
    }


    /**
     * Check the packet to make sure it has a header.
     *
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m packet The packet to check.
     * @[I][B][URL="http://forum.ragezone.com/members/850422.html"]return[/URL][/B][/I] <code>True</code> if the packet has a correct header,
     *         <code>false</code> otherwise.
     */
    public boolean checkPacket(byte[] packet) {
        return ((((packet[0] ^ iv[2]) & 0xFF) == ((mapleVersion >> 8) & 0xFF)) && (((packet[1] ^ iv[3]) & 0xFF) == (mapleVersion & 0xFF)));
    }


    /**
     * Check the header for validity.
     *
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m packetHeader The packet header to check.
     * @[I][B][URL="http://forum.ragezone.com/members/850422.html"]return[/URL][/B][/I] <code>True</code> if the header is correct, <code>false</code>
     *         otherwise.
     */
    public boolean checkPacket(int packetHeader) {
        return checkPacket(new byte[]{(byte) ((packetHeader >> 24) & 0xFF), (byte) ((packetHeader >> 16) & 0xFF)});
    }


    /**
     * Gets a new IV from <code>oldIv</code>
     *
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m oldIv The old IV to get a new IV from.
     * @[I][B][URL="http://forum.ragezone.com/members/850422.html"]return[/URL][/B][/I] The new IV.
     */
    public static byte[] getNewIv(byte oldIv[]) {
        byte[] in = {(byte) 0xf2, 0x53, (byte) 0x50, (byte) 0xc6}; // magic
        // ;)
        for (int x = 0; x < 4; x++) {
            funnyShit(oldIv[x], in);
            // System.out.println(HexTool.toString(in));
        }
        return in;
    }


    /**
     * Returns the IV of this instance as a string.
     */
    @Override
    public String toString() {
        return "IV: " + HexTool.toString(this.iv);
    }


    /**
     * Does funny stuff. <code>this.OldIV</code> must not equal
     * <code>in</code> Modifies <code>in</code> and returns it for
     * convenience.
     *
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m inputByte The byte to apply the funny stuff to.
     * @[I][B][URL="http://forum.ragezone.com/members/2000183830.html"]para[/URL][/B][/I]m in Something needed for all this to occur.
     * @[I][B][URL="http://forum.ragezone.com/members/850422.html"]return[/URL][/B][/I] The modified version of <code>in</code>.
     */
    public static final void funnyShit(byte inputByte, byte[] in) {
        byte elina = in[1];
        byte anna = inputByte;
        byte moritz = funnyBytes[(int) elina & 0xFF];
        moritz -= inputByte;
        in[0] += moritz;
        moritz = in[2];
        moritz ^= funnyBytes[(int) anna & 0xFF];
        elina -= (int) moritz & 0xFF;
        in[1] = elina;
        elina = in[3];
        moritz = elina;
        elina -= (int) in[0] & 0xFF;
        moritz = funnyBytes[(int) moritz & 0xFF];
        moritz += inputByte;
        moritz ^= in[2];
        in[2] = moritz;
        elina += (int) funnyBytes[(int) anna & 0xFF] & 0xFF;
        in[3] = elina;


        int merry = ((int) in[0]) & 0xFF;
        merry |= (in[1] << 8) & 0xFF00;
        merry |= (in[2] << 16) & 0xFF0000;
        merry |= (in[3] << 24) & 0xFF000000;
        int ret_value = merry >>> 0x1d;
        merry <<= 3;
        ret_value |= merry;


        in[0] = (byte) (ret_value & 0xFF);
        in[1] = (byte) ((ret_value >> 8) & 0xFF);
        in[2] = (byte) ((ret_value >> 16) & 0xFF);
        in[3] = (byte) ((ret_value >> 24) & 0xFF);
    }
}

Code:
public static final byte[] getAuthSuccessRequest(final MapleClient client) {        final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();


        mplew.writeShort(SendPacketOpcode.LOGIN_STATUS.getValue()); // 0x00
        mplew.writeZeroBytes(6); // 00 00 00 00 00 00
        mplew.writeInt(client.getAccID()); // 8E 02 00 00
        mplew.write(0); // 00
        mplew.write(0); // 00  
        mplew.writeShort(0); // 00 00  
        mplew.write(0); // 00
        mplew.write(11); // 0B
        mplew.write(0); // 00
        mplew.writeMapleAsciiString(client.getAccountName()); // 61 65 72 6F 64 79 6E 61 6D 69 6B
        mplew.writeLong(2); // 02 00 00 00 00 00 00 00
        mplew.writeLong(0); // 00 00 00 00 00 00 00 00
        mplew.writeInt(0); // 00 00 00 00
        mplew.writeShort(0); // 00 00
        mplew.write(1); // 01 
        mplew.write(1); // 01
        mplew.write(1); // 01
        mplew.write(1); // 01
        mplew.writeLong(0); // 00 00 00 00 00 00 00 00
        mplew.write(0); // 00


        return mplew.getPacket();
    }

This is packet log.
Code:
Received data :14 00 08 76 00 03 00
...v...
Received data :
36 00
6.
Received data :
15 00 05 00 61 64 6D 69 6E 09 00 31 32 33 34 35 36 37 38 39 6A FF B9 EE 34 00 36 30 42 32 31 41 30 44 2D 43 42 35 42 2D 44 39 31 31 2D 38 34 38 35 2D 46 34 36 44 30 34 37 31 38 34 42 37 5F 4D 54 37 30 31 35 30 33 38 35 30 34 35 39 34 28 00 34 31 34 62 33 30 33 32 33 35 33 31 33 37 33 30 33 38 33 32 33 30 33 30 33 38 33 34 33 30 32 64 33 30 33 30 33 37 33 33 00 00 00 00 02 00 00 00 00 00 00 00
....admin..123456789jÿ¹î4.60B21A0D-CB5B-D911-8485-F46D047184B7_MT7015038504594(.414b303235313730383230303834302d30303733............
Packet to be sent:
00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 0B 00 05 00 61 64 6D 69 6E 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00
.....................admin...................................
After Click login I'm DC.
And when I try to send Ping to Client but it's Alway DC.
 
Upvote 0
Newbie Spellweaver
Joined
Dec 1, 2016
Messages
15
Reaction score
0
It working fine on redirector, but when i use edolasms localhost it's dc after click login.
 
Upvote 0
Back
Top