Browse Source

* Hack protection from packet monkeys in clif_parse_NpcSelectMenu.

modified   Changelog-Trunk.txt
modified   src/map/clif.c
modified   src/map/map.h
modified   src/map/script.c



git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9261 54d463be-8e91-2dee-dedb-b68131a5f0ec
Lance 18 năm trước cách đây
mục cha
commit
22de482fce
4 tập tin đã thay đổi với 23 bổ sung5 xóa
  1. 1 0
      Changelog-Trunk.txt
  2. 9 2
      src/map/clif.c
  3. 1 1
      src/map/map.h
  4. 12 2
      src/map/script.c

+ 1 - 0
Changelog-Trunk.txt

@@ -4,6 +4,7 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2006/11/19
+	* Hack protection from packet monkeys in clif_parse_NpcSelectMenu. [Lance]
 	* Added 'cancel' button parsing in buildin_select menu system. Now scripts will continue
 	  to load if 'cancel' is pressed and 255 will be returned. [Lance]
 

+ 9 - 2
src/map/clif.c

@@ -10059,10 +10059,17 @@ void clif_parse_WeaponRefine(int fd, struct map_session_data *sd) {
  */
 void clif_parse_NpcSelectMenu(int fd,struct map_session_data *sd)
 {
+	unsigned char select;
 	RFIFOHEAD(fd);
 
-	sd->npc_menu=RFIFOB(fd,6);
-	npc_scriptcont(sd,RFIFOL(fd,2));
+	select = RFIFOB(fd,6);
+	if((select > sd->max_menu && select != 0xff) || !select){
+		ShowWarning("Hack on NPC Select Menu: %s (AID: %d)!\n",sd->status.name,sd->bl.id);
+		clif_GM_kick(sd,sd,0);
+	} else {
+		sd->npc_menu=select;
+		npc_scriptcont(sd,RFIFOL(fd,2));
+	}
 }
 
 /*==========================================

+ 1 - 1
src/map/map.h

@@ -627,7 +627,7 @@ struct map_session_data {
 	unsigned int client_tick;
 	int npc_id,areanpc_id,npc_shopid;
 	int npc_item_flag; //Marks the npc_id with which you can use items during interactions with said npc (see script command enable_itemuse)
-	int npc_menu;
+	int npc_menu, max_menu;
 	int npc_amount;
 	struct script_state *st;
 	char npc_str[256];

+ 12 - 2
src/map/script.c

@@ -4127,7 +4127,7 @@ int buildin_close2(struct script_state *st)
 int buildin_menu(struct script_state *st)
 {
 	char *buf;
-	int len,i;
+	int len,i, max = 1;
 	struct map_session_data *sd = script_rid2sd(st);
 
 	nullpo_retr(0, sd);
@@ -4154,6 +4154,11 @@ int buildin_menu(struct script_state *st)
 				strcat(buf,":");
 			}
 		}
+		for(i=0; (unsigned int)i < strlen(buf); i++){
+			if(buf[i] == ':')
+				max++;
+		}
+		sd->max_menu = max;
 		clif_scriptmenu(script_rid2sd(st),st->oid,buf);
 		aFree(buf);
 	} else if(sd->npc_menu==0xff){	// cansel
@@ -10278,7 +10283,7 @@ int buildin_jump_zero(struct script_state *st) {
 int buildin_select(struct script_state *st)
 {
 	char *buf;
-	int len,i;
+	int len,i,max = 1;
 	struct map_session_data *sd;
 
 	sd=script_rid2sd(st);
@@ -10296,6 +10301,11 @@ int buildin_select(struct script_state *st)
 			strcat(buf,st->stack->stack_data[i].u.str);
 			strcat(buf,":");
 		}
+		for(i=0; (unsigned int)i < strlen(buf); i++){
+			if(buf[i] == ':')
+				max++;
+		}
+		sd->max_menu = max;
 		clif_scriptmenu(script_rid2sd(st),st->oid,buf);
 		aFree(buf);
 	} /*else if(sd->npc_menu==0xff){	// Cancel will be parsed since this is select() [Lance]