1、ICEWR讲解Ke制作ICE-WR的perl与ke入门!Kore第一讲: Kore运行与编译 by ICE-WRKore是用perl来编写,目前WIN32系统比较流行的是ActivePerl,网站自行XX,而如果你需要把Kore编译为exe执行文件,那你需要安装Perl PDK,里面有perlapp用来把.pl文件转为.exe文件已经安装了ActivePerl和perl PDK了,但为什么还不能运行Kore.pl呢?请打开Kore.pl,你会看到类似这样的语句:use Time:HiRes qw(time usleep);use IO:Socket;use语句用作调用模块,而你没有这些模块那就
2、当然运行不了咯,PDK里包含一个叫VPM(Visual Package Manager)的模块管理软件,运行后会出现一个搜索网页,在搜索栏输入Time:HiRes和IO:Socket就会从网上把模块搜索出来并安装到你的电脑里,只要把模块都装好,那你就可以运行Kore.pl了如何把.pl文件转为.exe文件呢?这里需要用PDK里的perlapp,在这里用KE的编译来举例:perlapp -xclude -icon KoreEasy.ico KoreEasy.pl-xclude 编译时不包含perl58.dll文件,这样会让编译出来的程序小点,但别的机器要运行时需要复制perl58.dll-ico
3、n 这个是指定图标文件ActivePerl下载地址自行XXPerl PDK下载地址自行XXKore第二讲: Kore与Perl by ICE-WRKore是用perl语言来编写的,perl是一种简单而强大的脚本语言,.pl的文件就是perl脚本,需要解释器来运行,例如:Windows平台下的Active Perl。要想了解Kore,不需要对perl非常精通,当你第一次看Kore.pl时估计会非常头痛,一些语句甚至无法理解,大部分都是一些匹配模式,例如: foreach () next if (/#/); s/rn/g; s/s+/ /g; s/s+$/g; args = split /s/,
4、$_; Kore第三讲: Kore的程序结构 by ICE-WRKore的程序执行流程如下:1)程序初始化:调用模块,初始化变量2)读入数据文件3)建立控制台指令输入连接及与服务器连接4)执行主程序,主程序是个循环,只要没有接收到quit指令就一直执行,包括如下功能: a)执行控制台指令 b)分析接收到的封包,转化为Kore里的游戏信息,如HP/SP等 c)根据信息执行AI d)检查连接情况5)接收到quit指令后结束连接和程序Kore原版有8000行代码,但实际上主程序只有20行代码!了解主程序你就能知道整个运作原理了,以下位主程序代码的解释:while ($quit != 1) #当不是$
5、quit = 1时,一直执行以下程序,假如你在Kore里输入quit,那就会退出Kore啦 usleep($configsleepTime); #usleep就是要睡眠多少微秒,作用是等待封包接收及减低CPU占用率 if (dataWaiting($input_socket) #$input_socket用来读取控制台指令,如果有指令输入,则执行以下代码 $input_socket-recv($input, $MAX_READ); #从$input_socket读取数据并储存在$input,例如我们输入i指令,那$input就等于i parseInput($input); #parseInpu
6、t是个子程序,用来执行控制台指令 elsif (dataWaiting($remote_socket) #$remote_socket用来接收封包,加入服务器发送了封包过来,则执行以下代码 $remote_socket-recv($new, $MAX_READ); #从$remote_socket读取服务器发送过来的数据,$MAX_READ是用来限制一次读入的数据量 $msg .= $new; #由于服务器每次发送的封包不一定是完整的数据,所以Kore会把封包连接起来并储存在$msg $msg_length = length($msg); #这里是计算解释封包前的长度 while ($msg
7、ne ) #当有封包数据时,一直执行下面的代码 $msg = parseMsg($msg); #parseMsg是封包解释子程序,负责把封包转换为各种数据,例如HP/SP等,运行时读取$msg,运行后把已经解释完毕的封包去掉,并返回给$msg,这个过程就是,读完一段就删除一段 last if ($msg_length = length($msg); #因为封包解释子程序是解释完一段就删除一段的,所以这里比较解释前和解释后的$msg长度,来判断是否仍然有未解释的封包,假如解释前和解释后的$msg长度一样,那就代表已经没有要解释的封包,终止执行这个封包解释循环 $msg_length = leng
8、th($msg); #记录下解释后的封包长度,用作下一次比较 #上面的循环是用作接收指令和解释封包,执行后会运行以下子程序“AI” $ai_cmdQue_shift = 0; #$ai_cmdQue是用作远程控制(聊天指令控制) do AI(%$ai_cmdQue$ai_cmdQue_shift) if ($conState = 5 & timeOut(%$timeoutai) & $remote_socket & $remote_socket-connected(); #$conState 5代表已经完成登陆过程,并开始游戏;因为进入游戏后会收到大量信息,所以等待timeout.txt里AI
9、指定的秒数后才执行AI;后面两个判断是代表连接正常 undef %$ai_cmdQue$ai_cmdQue_shift+; $ai_cmdQue- if ($ai_cmdQue 0); #以上两句是用作执行远程控制 while ($ai_cmdQue 0); checkConnection(); #管理数据通讯连接状况的子程序,例如:登陆和断线等功能Kore第四讲: RO封包简要说明 by ICE-WRRO客户端与服务器间通过TCP协议连接,并互相传递信息,封包内容类似B0 00 05 00 E0 10 00 00#00b0 w lRO的封包头包含2个字节,数值从0064到01FF,上面的封包
10、头为00B0,每种封包分别代表不同类型的信息。RO封包有2种,一种是固定长度,一种是非固定长度,类型和各封包长度在ragexe.exe里记录,KARASU把RAGEXE.EXE破解后翻译出全部封包长度。例如00B0是固定长度8字节,但如果一个封包并不是固定长度,那服务器需要告知RO客户端封包的长度,对非固定长度的封包,在封包的第三和第四个字节用来表示封包长度把类似“B0 00 05 00 E0 10 00 00”这种16进制形式的代码转换为数值,在perl里通常用substr和unpack函数从封包里转换为具体数值(perl函数请参考Kore第二讲里的perl教学文件)例如Kore的封包分析子
11、程序里对B0 00 05 00 E0 10 00 00的解释执行如下: elsif ($switch eq 00B0) #$switch在Kore里代表封包头,当封包头为00B0时执行下面代码 $type = unpack(S1,substr($msg, 2, 2); #这里代表截取封包里05 00并翻译为无符号短整数,赋值给$type,这时$type = 5 $val = unpack(L1,substr($msg, 4, 4); #截取E0 10 00 00并翻译为无符号长整数,赋值给$val,这时$val = 4320 if ($type = 0) print Something1: $
12、valn if $configdebug; elsif ($type = 3) print Something2: $valn if $configdebug; elsif ($type = 5) #当$type等于5时执行 $chars$configcharhp = $val; #把$val赋值给$chars$configcharhp print Hp: $valn if ($configdebug = 2); .以上的封包分析后,这个封包的内容就是告知客户端当前人物HP = 4320Kore第五讲: 封包分析子程序运作详解 by ICE-WR 从前面的介绍我们知道当收到RO服务器封包时,会
13、执行子程序parseMsg()来进行封包分析,那parseMsg()是怎么运作的呢?首先从Kore主程序结构里得知,Kore采用阻塞的方式进行封包接收,就是每隔一段时间收一次,这个循环时间大概是AI执行时间加上config.txt里sleepTime的微妙数。收回来的封包会放在$msg里,然后把$msg交给parseMsg()来进行分析,parseMsg()的执行过程如下:1)取$msg前两个字节,解释为封包头2)根据封包头来选择分析代码3)把分析了的封包信息删除,并把还没分析的返回给主程序主程序根据$msg在执行parseMsg()分析前和分析后的长度是否相等,来判断是否还需要进行分析,假如
14、分析前与分析后长度一样,代表分析完毕,假如不等,则继续循环(请参照第三节内容)目前封包信息已知头信息均为006401FF,另外还有一个种只包含ACCOUNT ID,以下为KE内的分析代码,采用MODKORE的计算方式在主程序阶段执行了$msg = parseMsg($msg);后,运行以下代码sub parseMsg my $msg = shift; #my为定义局部变量,shift为传递第一个子程序参数,并删除参数,perl里的子程序参数都以数组形式传递,这里是把主程序里的$msg引用到子程序中 my $msg_size; #定义局部变量$msg_size,看字面解释就很清楚:“封包长度”
15、if (length($msg) = 4 & substr($msg,0,4) ne $accountID & $conState = 4 & $lastswitch ne $switch & length($msg) = unpack(S1, substr($msg, 0, 2) decrypt($msg, $msg); #这里是执行封包解密,有些服务器是封包加密形式的,对CRO没用 $switch = uc(unpack(H2, substr($msg, 1, 1) . uc(unpack(H2, substr($msg, 0, 1); #封包解密后从新计算封包头,对CRO没用 if ($
16、lastswitch eq $switch & length($msg) $lastMsgLength) $errorCount+; else $errorCount = 0; if ($errorCount 3) dumpData($msg); $errorCount = 0; $msg_size = length($msg); print 封包解释错误: $last_know_switch $switch ($msg_size)n; #以上是效验封包完整性,假如一个封包经过三次接收都还没被分析,会被认为是封包错误,把已经接收到的封包全部去掉。造成封包错误的主要原因是封包长度错误,例如00B
17、0长度8,假如我设置了00B0为长度6,经过一次封包解释后,删除了前面6个字节,得到后面的封包头为00 00,不在006401FF这个范围,那就不能进行分析,Kore必须丢弃这些这些封包才能确保封包分析能继续执行下去。 $lastswitch = $switch; #计算前记录下上一次分析前的封包头(用作完整性判断) if (substr($msg,0,4) ne $accountID | ($conState != 2 & $conState != 4) #RO封包里有个特殊的封包只返回Account ID,假如不是这个封包则进行下面的封包长度计算,$rpackets$switch代表从rp
18、ackets.txt里读取出来的封包长度,例如$rpackets00B0 = 8。$switch范围为006401FF,超出这个范围的封包头肯定代表封包接收有问题! if ($rpackets$switch eq -) #这种封包会把整个封包截取出来分析(实际上RO并没有这这种封包,只是在KARASU未解析出全部封包长度前,所遗留下来的问题- -b) $msg_size = length($msg); elsif ($rpackets$switch eq 0) #判断是否非固定长度类封包,封包头为前2字节,封包长度保存在封包的第3-4字节里 if (length($msg) 4) return $msg; #由于这种封包前4位分别记录封包头和封包长度,所以小于4字节时代表封包还没接收完整,因此返回到主程序 $msg_size = unpack(S1, substr($msg, 2, 2); #这里是从第34字节里计算出封包长度 if (length($msg) 1) #判断是否固定长度封包 if (length($msg) = $msg_size) ? substr($msg, $msg_size, length($msg) - $msg_size) : ; return $msg;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1