Media Log



8월 1일자 열린 도시,

뚫리는 엔진시스템만 찾으시고 실행하시면 됩니다.


'-' 메이플스토리 8월1일 st/ct 메이플스토리 8월2일 st

no2

st.zip




메이플스토리 8월1일 st/ct 메이플스토리 8월2일 st/8월1일ct/st 8월2일ct/st 8월3일ct/st 뚫린ct 메이플 버그/모두의마블/결크/결제크랙/메이플/ct/st/버그/핵/추천인/x/공유/메이플버그/레어닉/닉네임/해병대/시신/5명/인양/제로/제로스킬트리/제로사냥터/빠른사냥터/크리아티스/헤카톤/ 메이플스토리 / 메이플 / 메이플 핵/ 메이플 파노딜 / 육성법 / 메이플 육성법 / 메이플 스킬 /메이플 스텟 / 메이플 /크리티컬 /메이플 크리티컬 / 물리공격 / 물공 / 돈핵 / 아란 / 모험가 / 신궁 / 레지스탕스/ 메카닉/ 베틀메이지 / 베메 /스텟 / 카이저 / 에반 / 메이플 데 / 미 /스공 /메이플스공 / 사냥터 / 메이플 사냥터 / 데몬 / 어벤져 / 플점 / 몹 정지 / 바패 / 스피넬 / crc / 메이플스토리 신의 아이 / 제로/ 레드 / 모험가 개편후 직업추천 / 서버추천 / 직업추천 / 개편 /모험가 / 사냥터 / 인소야 /제로 /다크나이트 스킬트리 / 엔진 /상인엔진/ st 패킷 /버그 / ct/ 자바의핫2슈 / 프리메이플 / 프메 /무료공유 / 공유/ 메이플 코드 / fa / 7월 17일 / 메이플 스토리 /서든어택 / 서든 핵/ 모션 제거 / 글월 / 칼속/ 총속 / 칼폭/ 관통 /흑룡 /흑사 / 수지 / 서든 어택핵 / 전월 / 우회법 / 엔진 우회 / 재밌는 짓/ 카스 / 카스핵/ 카스 월핵/ 카스 시나리오 핵 / 사용법 / 메이플 직업추천 / 제논 스킬트리/ 제논육성법 / 제논 스텟 / 비숍 스킬트리 /모험가 개편 / 팔라딘 / 팔라딘 스킬트리 / 메이플 마일리지 사용법 / 아이템 매니아 / 아이템 베이 / 7월19일 ST /7월19일 CT / 7월20일 ST / 7월20월 CT / 7월21일 ST / 7월21일 CT / 엔진사용법 / 상인엔진 / 메이플엔진 / 메이플ST / 메이플CT /메이플스토리ST / 메이플스토리CT / 메이플버그 / 메이플도시 / 메이플스토리도시 / 데미박메이플ct/메이플상인엔진 사용법/메이플 레몬엔진 ct/메이플엔진/메이플안믹힌엔진/메이플애플엔진/메이플애플엔진ct/1월17일자ct/12월23일자ct/12월24일자ct 안막힌ct/메이플ct/메이플스토리ct//메이플엔진/메이플 몹몰이ct/12월27일ct/1월19일ct/1월20일ct최신ct/메이플스토리/메이플 몹몰이핵/메이플 듀프/메이플노팅ct/메이플몰이 사냥터/메이플 듀프핵/ct/핵/버그/엔진/메이플애플ct/태상노군엔진/태상노군/3.0/멀티로더 아이스어택/메이플/메이플최신씨티 메이플페페킹무한소환/메이플ct/메이플몹몰이/메이플마박/ss마박/cs마박/무한공격/공속/메이플공속/ct/메이플핵/메이플핵버그/메이플버그/메이플미하일/메이플 버그 사용법/메이플안크터는법/메이플 트레이너/메이플레벨업버그/메이플 셧다운뚫기/셧다운/메이플 페페킹무한소환 사용법 /1214일/메이플사재기/메이플사제기/메이플장사하는법/메이플버그/메플버그/버그 / 7월26일도시/7월27일도시

  1. 홍빡 at 2014.08.08 20:56 [edit/del]

    wjdgusdhkd@naver.com 으로좀 보내주시면안될까요..ㅠ

    Reply

submit


HaCreator 1.7


2009. 11. 에 제작된 맵에디터 HaCreator 1.7 입니다.



HaCreator 1.7



HaCreator 1.7 Kor


뽀뽀

이 자료가 필요하시다면, 비밀댓글 또는 네이트온 문의

submit


HaCreator 1.5


2009. 8. 12. 에 제작된 맵에디터 HaCreator 1.5 입니다.




뽀뽀

이 자료가 필요하시다면, 비밀댓글 또는 네이트온 문의

submit

[1/5] 1.2.182 로그인창|   강의게시판
5/2012.12.27 21:09

USFM(www.maplestorylab.com)에 오신것을 환영합니다!

카페규칙에 어긋나는 게시글은 자동 삭제되며 관련 게시물 작성자는 제재될 수 있습니다.



 NateON:dbg_white@nate.com
 
 
<Opcodes.ini>
PING =12
PONG = 35
 
<LoginPacket.java>
 
    public static final Packet initializeConnection(final short mapleVersion, final byte[] sendIv, final byte[] recvIv) {
 final WritingPure w = new WritingPure();
        int ret = 0; 
        ret ^= (mapleVersion & 0x7FFF); 
        ret ^= (ServerConstants.check << 15); 
        ret ^= ((ServerConstants.subVersion & 0xFF) << 16); 
        String version = String.valueOf(ret);
        int packetsize = 13 + version.length();
 w.writeShort(packetsize);
 w.writeShort(291); //KMS Static
        w.writeMapleAsciiString(version);
 w.write(recvIv);
 w.write(sendIv);
 w.write(1); // 1 = KMS, 2 = KMST, 7 = MSEA, 8 = GlobalMS, 5 = Test Server
 return w.getPacket();
    }
이 작성자의 게시글|더보기
다크바이트_
자기소개가없습니다.
덧글 9개 new||조회수 106|5 추천하기

submit

174 하ol퍼 스킬 재접팅 Fix [완벽]|   강의게시판
3/2012.12.27 20:35

USFM(www.maplestorylab.com)에 오신것을 환영합니다!

카페규칙에 어긋나는 게시글은 자동 삭제되며 관련 게시물 작성자는 제재될 수 있습니다.



[Rain MS]

- 하이퍼 재접팅 해결방법 [모든하이퍼스킬]

  에반 10차 전직하고 난뒤 하이퍼스킬 찍으시 재접팅 걸리는점도 해결됨

  100~139 때 스킬마스터하면 재접팅걸리던점도 수정됨


먼저 Src\packet\creators << 이경로로 들어가 PacketProvider.java 이것을 열어줍니다 .

그런 다음 public static final void addSkillInfo 이것을 검색한뒤 

public static final void addSkillInfo 이거의 전체 내용을 

이렇게 바꿔줍니다 .


    public static final void addSkillInfo(final WritingRain w, final RainPlayer chr) {
        final Map<ISkill, SkillEntry> skills = chr.getSkills();
        final Map<ISkill, SkillEntry> skillscopy = new LinkedHashMap<ISkill, SkillEntry>(skills);
        for (Integer s : GameConstants.용사의의지()) {
            skillscopy.remove(SkillFactory.getSkill(s));
        }
        for (Integer s : GameConstants.getHiddenSkill()) {
            skillscopy.remove(SkillFactory.getSkill(s));
        }
        if(chr.getJob() == 112 || chr.getJob() == 122 || chr.getJob() == 132 || chr.getJob() == 212 || chr.getJob() == 222 || chr.getJob() == 232 || chr.getJob() == 2112 || chr.getJob() == 2217 || chr.getJob() == 2312 || chr.getJob() == 2412 || chr.getJob() == 5112 || chr.getJob() == 2712 || chr.getJob() == 6112 || chr.getJob() == 6512) {
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 1052)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 1053)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 1054)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 1055)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 1056)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 30)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 31)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 32)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 33)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 34)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 35)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 36)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 37)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 38)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 39)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 40)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 41)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 42)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 43)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 44)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 45)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 46)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 47)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 49)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 48)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 50)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 51)));
        skillscopy.remove(SkillFactory.getSkill((chr.getJob() * 10000 + 52)));
        }
if(chr.getJob() == 2218) {
        skillscopy.remove(SkillFactory.getSkill((22170030)));
        skillscopy.remove(SkillFactory.getSkill((22170031)));
        skillscopy.remove(SkillFactory.getSkill((22170032)));
        skillscopy.remove(SkillFactory.getSkill((22170033)));
        skillscopy.remove(SkillFactory.getSkill((22170034)));
        skillscopy.remove(SkillFactory.getSkill((22170035)));
        skillscopy.remove(SkillFactory.getSkill((22170036)));
        skillscopy.remove(SkillFactory.getSkill((22170037)));
        skillscopy.remove(SkillFactory.getSkill((22170038)));
        skillscopy.remove(SkillFactory.getSkill((22170039)));
        skillscopy.remove(SkillFactory.getSkill((22170040)));
        skillscopy.remove(SkillFactory.getSkill((22170041)));
        skillscopy.remove(SkillFactory.getSkill((22170042)));
        skillscopy.remove(SkillFactory.getSkill((22170043)));
        skillscopy.remove(SkillFactory.getSkill((22170044)));
        skillscopy.remove(SkillFactory.getSkill((22170045)));
        skillscopy.remove(SkillFactory.getSkill((22170046)));
        skillscopy.remove(SkillFactory.getSkill((22170047)));
        skillscopy.remove(SkillFactory.getSkill((22170048)));
        skillscopy.remove(SkillFactory.getSkill((22170049)));
        skillscopy.remove(SkillFactory.getSkill((22170050)));
        skillscopy.remove(SkillFactory.getSkill((22170051)));
        skillscopy.remove(SkillFactory.getSkill((22170052)));
        skillscopy.remove(SkillFactory.getSkill((22171052)));
        skillscopy.remove(SkillFactory.getSkill((22171053)));
        skillscopy.remove(SkillFactory.getSkill((22171054)));
        skillscopy.remove(SkillFactory.getSkill((22171055)));
        skillscopy.remove(SkillFactory.getSkill((22171056)));
}
w.writeShort(skillscopy.size());
for (final Entry<ISkill, SkillEntry> skill : skillscopy.entrySet()) {
            if (GameConstants.isProfessionSkill(skill.getKey().getId())) {
                w.writeInt(skill.getKey().getId());
                if (skill.getKey().getId() == chr.getProfession().getFirstProfessionSkill()) {
                    w.writeShort(chr.getProfession().getFirstProfessionExp());
                    w.write(0);
                    w.write(chr.getProfession().getFirstProfessionLevel());
                } else if (skill.getKey().getId() == chr.getProfession().getSecondProfessionSkill()) {
                    w.writeShort(chr.getProfession().getSecondProfessionExp());
                    w.write(0);
                    w.write(chr.getProfession().getSecondProfessionLevel());
                } else {
                    w.writeInt(2147483647);
                }
                w.writeLong(getTime(-1));
            } else {   

                w.writeInt(skill.getKey().getId());
                w.writeInt(skill.getValue().skillevel);
                w.writeLong(getTime(skill.getValue().expiration));
                if (skill.getKey().isFourthJob()) {
                    w.writeInt(skill.getValue().masterlevel);
                }   
            }
}
    }

그럼 하이퍼스킬 재접팅은 완료됩니다.

그런다음 이제 하이퍼스킬 포인트 유지 방법인데요 .

Src\handler\channel << 이경로로 들어가 InterServerHandler.java 이것을 열어봅니다.

그리고 안에보시면 

        for (Integer hiddenskill : GameConstants.getHiddenSkill()) {
            if (c.getPlayer().getMasterLevel(hiddenskill) > 0) {
                c.send(MainPacketCreator.updateSkill(hiddenskill, c.getPlayer().getOriginSkillLevel(hiddenskill), c.getPlayer().getMasterLevel(hiddenskill), -1));
            }
        }

이런게 있을꺼예요.

그럼 밑에다 

        if(c.getPlayer().getJob() == 112 || c.getPlayer().getJob() == 122 || c.getPlayer().getJob() == 132 || c.getPlayer().getJob() == 212 || c.getPlayer().getJob() == 222 || c.getPlayer().getJob() == 232 || c.getPlayer().getJob() == 2112 || c.getPlayer().getJob() == 2217 || c.getPlayer().getJob() == 2312 || c.getPlayer().getJob() == 2412 || c.getPlayer().getJob() == 5112 || c.getPlayer().getJob() == 2712 || c.getPlayer().getJob() == 6112 || c.getPlayer().getJob() == 6512) {
        for(int i = 30; i < 59; i++) {
        int hiddenskill = (c.getPlayer().getJob() * 10000 + i);
                c.send(MainPacketCreator.updateSkill(hiddenskill, c.getPlayer().getOriginSkillLevel(hiddenskill), c.getPlayer().getMasterLevel(hiddenskill), -1));
        }
                for(int i = 1052 ; i < 1057; i++) {
        int hiddenskill = (c.getPlayer().getJob() * 10000 + i);
                c.send(MainPacketCreator.updateSkill(hiddenskill, c.getPlayer().getOriginSkillLevel(hiddenskill), c.getPlayer().getMasterLevel(hiddenskill), -1));
        }
        }
if(c.getPlayer().getJob() == 2218) {
        for(int i = 22170030; i < 22170059; i++) {
        int hiddenskill = (i);
                c.send(MainPacketCreator.updateSkill(hiddenskill, c.getPlayer().getOriginSkillLevel(hiddenskill), c.getPlayer().getMasterLevel(hiddenskill), -1));
        }
                for(int i = 22171052 ; i < 22171057; i++) {
        int hiddenskill = (i);
                c.send(MainPacketCreator.updateSkill(hiddenskill, c.getPlayer().getOriginSkillLevel(hiddenskill), c.getPlayer().getMasterLevel(hiddenskill), -1));
        }
        }
        if (GameConstants.isKaiser(player.getJob())) {
            c.send(MainPacketCreator.giveMorphGauge(0));
        }

이걸 추가 해줍니다 .
 

그럼 이제 완벽하게 완료 .
수고하세요


submit

옵코드(핸들러)에 대해서 정확히 파헤쳐 봅시다.|   강의게시판
1/2012.12.26 01:28

My respectful teacher is LozeZIP

 

※스노우스니퍼를 중점적으로 설명

---------------------------------

 

옵코드(헤더) = 패킷의 맨 앞부분에 존재하는 4자리 16진수를 의미 (캐리의 설명= 패킷의 대가리)

 

 

13 00 23 01 06 00 31 39 36 37 35 33 C9 34 F0 59 C7 6C E5 44 01

위에 보이시는 패킷은 겟헬로우의 패킷입니다.

 

옵코드에 정의에 따라 분석해본다면 위 패킷의 옵코드는 무엇일까요?
바로 13 00 입니다.

 

--------------------------------------------------------

저 앞자리의 16진수 패킷 4개는 코딩 할 때 WriteShort(블라블라); 되거나 // 또는 Send/Recieve.properties 로 보내지게 됩니다.

 

(+추가내용) :

스노우스니퍼를 중심으로 보면 ToClient 와 ToSERVER이 있어요.

ToClient는 샌드 // ToServer 는 리시브입니다.

둘 중 어느 방법을 사용해도 좋으나, 다음에 버전업 할때 한눈에 알아보기 위해서는 프로펄타이즈에 저장하는것을 추천합니다!

 

※모든 팩은 보시면 샌드/리시브 프로펄타이즈는 존재합니다.

 

샌드나 리시브 프로펄타이즈를 열어 보시면 0x1F 라던지  0xFF11 이라던지 많이 존재했죠? 그 애매모한 숫자를 설명해드리겠습니다.

 

 

-----------------------------------------------------

 

13 00 23 01 06 00 31 39 36 37 35 33 C9 34 F0 59 C7 6C E5 44 01

아까 보신 겟헬로우 패킷입니다. 옵코드는 13 00 입니다. 

 

이 옵코드는 이렇게 처리해주시면 됩니다.

0x1300

 

앞의 0x를 제외한 뒤에 0은 항상 생략해주셔도 좋습니다. (하지만 108 에서 0를 빼서 18로 하면 값이 아얘달라지니깐 이건안되는겁니다)

 

생략결과 : 0x13

 

 

그렇다면 다른 것들을 예로 들어서 설명해볼까요?

00 13은 어떻게 바뀔까요?

바로 0x0013 입니다. 제가 0x를 제외한 뒤의 0들은 생략하라고 했습니다. 그러면 0x13이 되겠네요.

 

결론: 13 00 = 00 13

 

 

-----------------------------------------------------

 

좀 더 어려운 옵코드를 바꿔봅시다.

(#필자가 생각해낸것들입니다. 실제로 존재하지 않을 수 있습니다)

 

F1 01 =

F2 FF =

08 2F =

13 F3 =

 

영어가 들어있어도 어렵지 않습니다!! 배운대로 해봅시다.

일단 앞에 0x를 항상 쓰는건 이제 아시죠?

같이해볼까요?

F1 01 = 0xF101 (여기에 0은 생략할 수 없습니다)

F2 FF = 0xF2FF

08 2F = 0x082F

13 F3 = 0x13F3

 

여기까지가 기초적인 강의였습니다.

감사합니다.

프로젝터였습니다.

USFM(www.maplestorylab.com)에 오신것을 환영합니다!

카페규칙에 어긋나는 게시글은 자동 삭제되며 관련 게시물 작성자는 제재될 수 있습니다.



 


 

이 작성자의 게시글|더보기
alslwjd12님의 블로그
소총이당!!
덧글 11개 new||조회수 257|1 추천하기
  • 2012/12/26 01:30답글

    신고

    스노우랑 백호가 안되는데

    와이어 샤크같은거로는 어렵나요?

  • 2012/12/26 07:57답글

    신고

    와이어샤크는 메이플패킷이 복호화되지않아요.

  • 2012/12/26 08:38답글

    신고

    Saramic 와이어샤크 메이플패킷이 복호화되지않으면 멀로써야하는지?ㄷ

  • 2012/12/26 10:05답글

    신고

    OnGame 백호스니퍼나 스노우스니퍼쓰셔아죠

  • 2012/12/26 10:06답글

    신고

    Saramic 뭐 둘다같은거지만 ㅋ 안되면 저처럼 스니퍼 자작으로만드셔야함...
    64bit에서 스노우안돌아가는경우가있어서요

  • 2012/12/26 16:19답글

    신고


    혹시 getAuthSuccessRequest 건들줄아시나요?

  • 2012/12/26 17:31답글

    신고

    흠... 그러믄 옵코드를 딸수잇는건가요? 앞에잇는 13 00 이 옵코드엿으면 생략되어 13x0 이되엇으니 13 이 옵코드가되는건가요?

  • 0x13

  • 2012/12/27 15:55답글

    신고

    ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
    복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙복붙

  • 2012/12/27 18:35답글

    신고

    겟헬로우 딸려면 백호 써도되나요?

  • 2012/12/27 19:35답글

    신고

    출처 위드남기시죠

  1. at 2018.05.18 14:45 [edit/del]

    비밀댓글입니다

    Reply
  2. at 2018.05.18 14:47 [edit/del]

    비밀댓글입니다

    Reply

submit

버전업할때팁|   강의게시판
1/2012.12.26 01:26

USFM(www.maplestorylab.com)에 오신것을 환영합니다!

카페규칙에 어긋나는 게시글은 자동 삭제되며 관련 게시물 작성자는 제재될 수 있습니다.



 


버전업할때에 여러가지 팁을 드리죵 +_+

 

1. MSEA 에서 버전업을 하고 들어갈때, 게이트들어가면 C++ 오류나는건 무조건 getHello 오류에요~

2. 버전업할때는 상위버전과 하위버전의 패킷에 차이가 있을수 있는데, 예전 패킷메소드와 비교후에,

   차이점을 발견해서 찾아넣으셔야대용~

 

3. 딱봐도 이렇게 해야 자료형이 되겠구나 (ex: HP/MAXHp 는 9만이상되니 int 로 바뀜 / 빅뱅기준) 를 생각하면서찍으세요~

4. 옵코드수정은 기본중에 기본! 맨처음에 옵코드만 바꿔도되는 패킷이 있으니깐, 옵코드헤더만 먼저바꾸고해보세요.

5. 버전업할때는 혼자하면 재미없어요~ 못하는 친구라도 같이 댈꼬하는게 훨씬좋아요!

 

 

팁은 이정도로만쓸게욤 ㅎㅎㅎㅎ

이 작성자의 게시글|더보기
alslwjd12님의 블로그
소총이당!!
덧글 4개 new||조회수 216|1 추천하기

submit

패킷강의 (복호화실습)|   강의게시판
1/2012.12.26 01:25

USFM(www.maplestorylab.com)에 오신것을 환영합니다!

카페규칙에 어긋나는 게시글은 자동 삭제되며 관련 게시물 작성자는 제재될 수 있습니다.



 

> 패킷 정의

 

- 네트워크 작업에서 오가는 통신의 양을 보통 패킷이라고 합니다. 허나, 우리가 이 글에서 배우자 하는 패킷의 정의는 jpcap을 포함하여 자바어플리케이션을 이용한 네트워킹 기반의 패킷이라고 보면된다.

 

> 패킷은 어떨때 오고, 가는가?

 

- 딱히 상황은 정해져 있는게 아니다. 우리가 게임안에서 하는 모든 행동 하나하나가 패킷이 오고가는 상황이라고 보면된다. 깊히 말하자면 우리가 인터넷을 하는것 또한 패킷을 주고 받는다.

 

> 우리가 Decode 해야 할 패킷

 

- 우리가 복호화 시켜야될 패킷은 16진수(HEX)로 출력되는 패킷이다. 16진수는 0~16 즉 0 ~ F 까지 라고 보면된다.

 (0~9 까지는 일반 숫자로 기입하며 10부터는 0A, 0B, 0C… 이런식으로 기입한다.)

 

> 본격 적인 패킷 복호화

 

Step1) 먼저 패킷은 이미 복호화가(MaplePacketCreator.java) 되어 있는 패킷을 기반으로 ( 새로 추가된 패킷이 아니라면 ) 분석을 하는것이 좋다.

 

Step2) getServerlist( 겟헬로는 로그가 없으니 양해 바람 ) 부터 가볍게 분석을 해보자. 그전 각 패킷의 사이즈를 미리 용어를 통해 알아보자.

 write(byte*1) = 00 // 지정가능한 범위 : -128 ~ 127

 short(byte*2) = 00 00 // 지정가능한 범위 : -32768 ~ 32767

 int(byte*4) = 00 00 00 00 // 지정가능한 범위 : -2147483648 ~ 2147483647

 long(byte*8) = 00 00 00 00 00 00 00 00 // 지정가능한 범위 : -9223372036854775808 ~ 9223372036854775807

 

아래는 내가 가지고있는 getServerList 이다.

 



 

보면 어지럽다. 하지만 위의 각 단위별 사이즈를 보니 대충 사이즈가 짐작가려 하는것 같지만, 대체 뭔지도 모를거같은것들이 수두룩하다. 우리는 대부분 저런생각을 느끼고 패킷을 포기하곤 한다. 하지만 시간을 조금만 투자해서 한번을 이해하면 평생 써먹을 수 있다는것을 각인시켜두자.

 

아래는 Serverlist의 로그이다.

 

Received SERVERLIST [000A] (359) 
0A 00 00 06 00 53 63 61 6E 69 61 00 00 00 64 00 64 00 00 13 08 00 53 63 61 6E 69 61 2D 31 1F 05 00 00 00 00 00 08 00 53 63 61 6E 69 61 2D 32 EF 01 00 00 00 01 00 08 00 53 63 61 6E 69 61 2D 33 95 01 00 00 00 02 00 08 00 53 63 61 6E 69 61 2D 34 53 01 00 00 00 03 00 08 00 53 63 61 6E 69 61 2D 35 4C 01 00 00 00 04 00 08 00 53 63 61 6E 69 61 2D 36 99 01 00 00 00 05 00 08 00 53 63 61 6E 69 61 2D 37 61 01 00 00 00 06 00 08 00 53 63 61 6E 69 61 2D 38 58 01 00 00 00 07 00 08 00 53 63 61 6E 69 61 2D 39 5A 01 00 00 00 08 00 09 00 53 63 61 6E 69 61 2D 31 30 3E 01 00 00 00 09 00 09 00 53 63 61 6E 69 61 2D 31 31 83 01 00 00 00 0A 00 09 00 53 63 61 6E 69 61 2D 31 32 53 01 00 00 00 0B 00 09 00 53 63 61 6E 69 61 2D 31 33 71 01 00 00 00 0C 00 09 00 53 63 61 6E 69 61 2D 31 34 56 01 00 00 00 0D 00 09 00 53 63 61 6E 69 61 2D 31 35 56 01 00 00 00 0E 00 09 00 53 63 61 6E 69 61 2D 31 36 4C 01 00 00 00 0F 00 09 00 53 63 61 6E 69 61 2D 31 37 5A 01 00 00 00 10 00 09 00 53 63 61 6E 69 61 2D 31 38 62 01 00 00 00 11 00 09 00 53 63 61 6E 69 61 2D 31 39 7F 01 00 00 00 12 00 00 00 00 00 00 00
.....Scania...d.d.....Scania-1.........Scania-2?........Scania-3?........Scania-4S........Scania-5L........Scania-6?........Scania-7a........Scania-8X........Scania-9Z........Scania-10>........Scania-11?........Scania-12S........Scania-13q........Scania-14V........Scania-15V........Scania-16L........Scania-17Z........Scania-18b........Scania-19............

 

각 용어별 설명에 들어간다.

 

Received // 서버에서 패킷을 받았다.

SERVERLIST // 옵코드 이름이다. 하지만 이 이름은 패킷 스니퍼 안에 내장되 있는 이름이기 때문에 알아보기 쉽게 지정했다고 생각하자. 깊게 생각하면 머리아프다. 요즘버전에선 옵코드 이름은 전혀상관없다는점 유의하자.

[000A] // 옵코드 값이다. 보통 출력은 전부 4자릿수로 출력되는데 옆과 같은 경우 0x0A로 기입한다. 왠만한 초등학생 3학년의 수준이 아니면 000A 에서 0x0A로 바뀐거에 대한 차이점을 못찾을순 없을것이다. 대강 어떻게 쓰는지 때려 맞출 수 있다.

(359) // 패킷의 사이즈이다. 359byte가 뽑혔다.

 

 

0A 00 00 06 00 53 63 61 6E 69 61 00 00 00 64 00 64 00 00 13 08 00 53 63 61 6E 69 61 2D 31 1F 05 00 00 00 00 00 08 00 53 63 61 6E 69 61 2D 32 EF 01 00 00 00 01 00 08 00 53 63 61 6E 69 61 2D 33 95 01 00 00 00 02 00 08 00 53 63 61 6E 69 61 2D 34 53 01 00 00 00 03 00 08 00 53 63 61 6E 69 61 2D 35 4C 01 00 00 00 04 00 08 00 53 63 61 6E 69 61 2D 36 99 01 00 00 00 05 00 08 00 53 63 61 6E 69 61 2D 37 61 01 00 00 00 06 00 08 00 53 63 61 6E 69 61 2D 38 58 01 00 00 00 07 00 08 00 53 63 61 6E 69 61 2D 39 5A 01 00 00 00 08 00 09 00 53 63 61 6E 69 61 2D 31 30 3E 01 00 00 00 09 00 09 00 53 63 61 6E 69 61 2D 31 31 83 01 00 00 00 0A 00 09 00 53 63 61 6E 69 61 2D 31 32 53 01 00 00 00 0B 00 09 00 53 63 61 6E 69 61 2D 31 33 71 01 00 00 00 0C 00 09 00 53 63 61 6E 69 61 2D 31 34 56 01 00 00 00 0D 00 09 00 53 63 61 6E 69 61 2D 31 35 56 01 00 00 00 0E 00 09 00 53 63 61 6E 69 61 2D 31 36 4C 01 00 00 00 0F 00 09 00 53 63 61 6E 69 61 2D 31 37 5A 01 00 00 00 10 00 09 00 53 63 61 6E 69 61 2D 31 38 62 01 00 00 00 11 00 09 00 53 63 61 6E 69 61 2D 31 39 7F 01 00 00 00 12 00 00 00 00 00 00 00

위 구간은 16진수(HEX)로 인코딩된 로그이다. 이걸 다시 우리는 디코드를 하는것이다.

 

 

.....Scania...d.d.....Scania-1.........Scania-2?........Scania-3?........Scania-4S........Scania-5L........Scania-6?........Scania-7a........Scania-8X........Scania-9Z........Scania-10>........Scania-11?........Scania-12S........Scania-13q........Scania-14V........Scania-15V........Scania-16L........Scania-17Z........Scania-18b........Scania-19............

 

이건 위 로그에 대한 HEX to String 값이다. 몇몇은 알아볼 수 있게 뽑혔지만 나머지는 알 수 없는 값들이다. 이것이 같이 뽑혀 나오는 이유는 자세힌 모르지만, 개발자를 위한 작은 배려라고 봐도 된다.


우리가 필요한건 16진수로 인코딩된 로그를 기반으로 저 위 패킷에 짜맞춤 하는것이다. 다음 절차를 밟아보자.

 

Step3) 패킷 복호화

 



 

 

0A 00 // Opcode

00 // serverID

06 00 6E 53 63 61 69 61 // serverName 메이플아스키스트링 맨앞 06 00(6바이트 00 한개수치당 1 바이트) 6E 53 63 61 59 61 

00 // flag 깃발이다 이벤트 마크, N마크 ,H마크 등..

00 00 // 이벤트 메세지 이다. 메이플아스키 스트링은 값이 없어도 00 00 short크기를 반환한다.

64 // 64(10진수:100)값이다.

00  // 0값이다.

64 // 64(10진수:100)값이다.

00  // 0값이다.

00 // 0값이다.

13  // lastChannel 마지막 채널이 13이란건데 13은 10진수로 19이다. 즉 채널은 19개란소리.

 

/* for문이다. 위에 lastChannel 만큼 반복한다. 즉 19번을 반복한다. */

08 00 53 63 61 6E 69 61 2D 31 1F 05 00 00 00 00 00  // 1 채널

08 00 53 63 61 6E 69 61 2D 32 EF 01 00 00 00 01 00  // 2 ''

08 00 53 63 61 6E 69 61 2D 33 95 01 00 00 00 02 00  // 3 ''

08 00 53 63 61 6E 69 61 2D 34 53 01 00 00 00 03 00  // 4 

08 00 53 63 61 6E 69 61 2D 35 4C 01 00 00 00 04 00  // 5

08 00 53 63 61 6E 69 61 2D 36 99 01 00 00 00 05 00  // 6

08 00 53 63 61 6E 69 61 2D 37 61 01 00 00 00 06 00  // 7

08 00 53 63 61 6E 69 61 2D 38 58 01 00 00 00 07 00  // 8

08 00 53 63 61 6E 69 61 2D 39 5A 01 00 00 00 08 00  // 9

09 00 53 63 61 6E 69 61 2D 31 30 3E 01 00 00 00 09 00 // 10

09 00 53 63 61 6E 69 61 2D 31 31 83 01 00 00 00 0A 00 // 11

09 00 53 63 61 6E 69 61 2D 31 32 53 01 00 00 00 0B 00 // 12

09 00 53 63 61 6E 69 61 2D 31 33 71 01 00 00 00 0C 00 // 13

09 00 53 63 61 6E 69 61 2D 31 34 56 01 00 00 00 0D 00 // 14

09 00 53 63 61 6E 69 61 2D 31 35 56 01 00 00 00 0E 00  // 15

09 00 53 63 61 6E 69 61 2D 31 36 4C 01 00 00 00 0F 00  // 16

09 00 53 63 61 6E 69 61 2D 31 37 5A 01 00 00 00 10 00  // 17

09 00 53 63 61 6E 69 61 2D 31 38 62 01 00 00 00 11 00  // 18

09 00 53 63 61 6E 69 61 2D 31 39 7F 01 00 00 00 12 00  // 19

00 00 00 00 00 00  // byte 6개


 

위는 내가 분석한 getServerList이다.

 

바뀐 값은 딱 하나. 마지막 mplew.writeShort(0); 에서 mplew.write0(6); 으로 바뀌었다.

 

즉 아래와 같이 정리할수 있다.

 



 

 

이러면 분석은 끝났다. 완성후의 패킷은 아래와 같다.

 

 

 ○ 제로바이트만 연속일 경우.


 Ex) 00 00 00 // 이런식의 0크기의 바이트가 3개 일경우(즉 byte,short,int,long 처럼 갯수가 정해지지않은것)

 - > write0(3);


 Ex) 00 00 00 00 00 00 00 00 00 00 // 이런건 어떻게 하겠는가? 여러가지 방법이 있지만 많이쓰는 방법은 여러가지 이지만 내가 꼽은건 세 가지 이다.


 1. 첫 번째

 writeLong(0);

 writeShort(0);

 2. 두 번째

 write0(10);

 3. 세 번째

 writeShort(0);

 writeLong(0);

 

- 주의할점은 무조건 패킷은 저렇게 크기만 맞춰서 되는게 아니다. 패킷은 바뀌는 값이있다. 바뀌는값을 저렇게 크기만 맞출려고 대충대충 처리하다간 올바르게 동작하지 않는다. 그렇기 때문에, 두 세번 뽑아보고 그게 계속 바뀌지 않는다면 그때서 저런식으로 작성하자.

이 작성자의 게시글|더보기
alslwjd12님의 블로그
소총이당!!
덧글 16개||조회수 179|1 추천하기

submit

패킷강의 기초적인버프스탯을 하여보자|   강의게시판
1/2012.12.26 01:24

USFM(www.maplestorylab.com)에 오신것을 환영합니다!

카페규칙에 어긋나는 게시글은 자동 삭제되며 관련 게시물 작성자는 제재될 수 있습니다.

출처: 가베님
 
 
 
18 00 
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 08 00 00 00 00
/*for문 시작*/
01 00
5E 93 E6 00 
80 A9 03 00 
/*for문끝*/
00 00 00 2C 01 00
/*이부분까지가 로그분석본*/
00 00 00 00 00 00 00 00 //1
00 00 00 00 00 00 00 00 //2
00 00 00 00 00 00 00 00 //3
00 00 00 08 00 00 00 00 //4
/*이부분이 로그중에서 버프스탯에 해당하는 Long4개*/
여기서1~4순서대로잇는거고저걸버프스탯에적을때는맨위에것이1맨밑에가4이렇게순서대로적어줘야함(가끔 반대로된팩도 몇개있음)0인부분은무시하고버프스탯이있는부분만봐야해요00 00 00 08 00 00 00 00이렇게있잖아요버프스탯이00 00 00 08 00 00 00 00얘를오른쪽에서 왼쪽으로읽어요그러면마지막에있는 인트0뺴고00 00 00 08이남죠?이부분은마찬가지로오른쪽에서왼쪽으로읽으면버프스탯(80000000, 4)이것이나오는거죠
ㅇㅋ?대충 이정도면 간단한것들은 분석가능하실듯 
이 작성자의 게시글|더보기
alslwjd12님의 블로그
소총이당!!
덧글 5개||조회수 154|1 추천하기
  • 2012/12/26 01:25답글

    신고

    for 문이 while문이랑 비슷한거죠? 약간 다르면서도

  • 2012/12/26 14:23답글

    신고

    for문 while문 둘다 비슷합니다 while에 변형 do-while문도 있어요

  • loop 부분에서는 같습니다만. 다릅니다. while은 조건이 true가 될때까지 무한반복이고, for은 초기화 시점과 조건시점 그리고 카운터 부분이 있기때문에 좀더 세밀하고 조건이 복잡한 루프작업에 필요합니다.

    do-while은 그냥 쉽게 설명해드리자면; 조건이 맞지않아도 한번이상은 명령문 실행이 됩니다.


    약간 차이를 말씀드리기가 애매모호 하네요.

  • 2012/12/26 08:34답글

    신고

    2人, for 문이 while문이랑 비슷한거죠? 약간 다르면서도 ㅠㅠ



  • 2012/12/26 14:23답글

    신고

    for문 while문 둘다 비슷합니다 while에 변형 do-while문도 있어요

submit

1/2012.12.26 01:23

USFM(www.maplestorylab.com)에 오신것을 환영합니다!

카페규칙에 어긋나는 게시글은 자동 삭제되며 관련 게시물 작성자는 제재될 수 있습니다.

복습겸 올립니다

원본

00 00 00 C9 50 14 01 00 00 00 31 00 00 00 03 00 00 00 00 00 00 00 00 00 00 08 00 31 2A 2A 30 34 68 61 2A 00 00 01 01 01


분석본

00 00 << 헤더 [일명 옵코드 무조건 Short로 끊는다]
00 << wrtie 0
C9 50 14 01 << writeInt(client.getAccID()); [이렇게 덩어리로 되있는건 의미가 있음] (구현or연동) 
00 << wrtie 0
00 << wrtie 0
00 << wrtie 0
31 00 00 00 << writenInt 0x31 
03 00 00 00 << writenInt 0x3
00 00 00 00 << writenInt 0
00 00 << writeShort 0
00 << wrtie 0
08 00 31 2A 2A 30 34 68 61 2A 00 00 << writeMapleAsciiString / 활용 ex) writeMapleAsciiString("sAviOr");
01 << wrtie 1
01 << wrtie 1
01 << wrtie 1

모르는거 질문 많이해주세요 그래야 제실력이늠

하울님 질문! 

하울님이 쓰신것처럼 

00 00 00 C9 50 14 01 00 00 00 31 00 00 00 03 00 00 00 00 00 00 00 00 00 00 08 00 31 2A 2A 30 34 68 61 2A 00 00 01 01 01 

에서 어떤게 

write()이고 어떤게writeshort(), writeint(), writelong()인지 구분을 해요?? 

 

그리고write(HexTool.getByteArrayFromHexString는 

write(HexTool.getByteArrayFromHexString("00 00 00 C9 50 14 01 00 00 00 31 00 00 00 03 00 00 00 00 00 00 00 00 00 00 08 00 31 2A 2A 30 34 68 61 2A 00 00 01 01 01")); 이런식으로 쓰면되나요? 

 

마지막으로 writeMapleAsciiString가 이해가 안가내요..... 

질문을 한 번에 3개나 해서 죄송합니다 ㅎ.... 

 샤인2012/05/20 08:11답글신고 

일단 무조건앞에 2개는 헤더라고 하구요 00 00 

하지만 00다음에 c9나오죠 ? 0이 끝나는곳에서 끊어 주세요  

그럼  

00 00 

00 

c9 50 14 01 그리고 

00 

00 

00 

아그리고 패킷은 길이만 맞으면 작동한다고하네요  

 

2탄도 해드릴게욤 ㅎㅎㅎㅎ

이 작성자의 게시글|더보기
alslwjd12님의 블로그
소총이당!!
덧글 4개||조회수 171|1 추천하기

submit