Bläddra i källkod

fixed 2 Trade exploits

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@1001 54d463be-8e91-2dee-dedb-b68131a5f0ec
(no author) 20 år sedan
förälder
incheckning
6093c57132
2 ändrade filer med 91 tillägg och 75 borttagningar
  1. 3 0
      Changelog.txt
  2. 88 75
      src/map/trade.c

+ 3 - 0
Changelog.txt

@@ -1,5 +1,8 @@
 Date	Added
 Date	Added
 
 
+01/27
+	* Fixed TRADE exploits (it cures proxy hack / vending+trade hack) thanks to Freya [Lupus]
+
 01/26
 01/26
         * Added bug fix for a memory leak caused when a character logs out,
         * Added bug fix for a memory leak caused when a character logs out,
           by End_of_exam / jA 1108 [celest]
           by End_of_exam / jA 1108 [celest]

+ 88 - 75
src/map/trade.c

@@ -141,7 +141,8 @@ void trade_tradeok(struct map_session_data *sd)
 	int trade_i;
 	int trade_i;
 
 
 	nullpo_retv(sd);
 	nullpo_retv(sd);
-	
+
+	// check items
 	for(trade_i=0;trade_i<10;trade_i++) {
 	for(trade_i=0;trade_i<10;trade_i++) {
 		int idx = sd->deal_item_index[trade_i]-2;
 		int idx = sd->deal_item_index[trade_i]-2;
 		if(((idx >= 0) && (sd->deal_item_amount[trade_i]>sd->status.inventory[idx].amount)) || sd->deal_item_amount[trade_i]<0) {
 		if(((idx >= 0) && (sd->deal_item_amount[trade_i]>sd->status.inventory[idx].amount)) || sd->deal_item_amount[trade_i]<0) {
@@ -150,6 +151,12 @@ void trade_tradeok(struct map_session_data *sd)
 		}
 		}
 	
 	
 	}
 	}
+
+	// check zeny
+	if (sd->deal_zeny < 0 || sd->deal_zeny > MAX_ZENY || sd->deal_zeny > sd->status.zeny) { // check amount
+		trade_tradecancel(sd);
+		return;
+	}
 	
 	
 	if((target_sd = map_id2sd(sd->trade_partner)) != NULL){
 	if((target_sd = map_id2sd(sd->trade_partner)) != NULL){
 		sd->deal_locked=1;
 		sd->deal_locked=1;
@@ -204,94 +211,100 @@ void trade_tradecancel(struct map_session_data *sd)
  * Žæˆø‹–‘ø(trade‰Ÿ‚µ)
  * Žæˆø‹–‘ø(trade‰Ÿ‚µ)
  *------------------------------------------
  *------------------------------------------
  */
  */
-void trade_tradecommit(struct map_session_data *sd)
-{
+void trade_tradecommit(struct map_session_data *sd) {
 	struct map_session_data *target_sd;
 	struct map_session_data *target_sd;
 	int trade_i;
 	int trade_i;
+	int flag;
 
 
 	nullpo_retv(sd);
 	nullpo_retv(sd);
 
 
-	if((target_sd = map_id2sd(sd->trade_partner)) != NULL){
-		if( (sd->deal_locked >=1) && (target_sd->deal_locked >=1) ){ // both have pressed 'ok'
-			if(sd->deal_locked < 2) {sd->deal_locked=2;} // set locked to 2
-			if(target_sd->deal_locked==2) { // the other one pressed 'trade' too
-				for(trade_i=0; trade_i<10;trade_i++) {
-					if(sd->deal_item_amount[trade_i] != 0) {
-						int n=sd->deal_item_index[trade_i]-2;
-						int flag;
+	if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) {
+		if ((sd->deal_locked >= 1) && (target_sd->deal_locked >= 1)) { // both have pressed 'ok'
+			if (sd->deal_locked < 2) {sd->deal_locked = 2;} // set locked to 2
+			if (target_sd->deal_locked == 2) { // the other one pressed 'trade' too
+				// check zenys value against hackers
+				if (sd->deal_zeny >= 0 && sd->deal_zeny <= MAX_ZENY && sd->deal_zeny <= sd->status.zeny && // check amount
+				    (target_sd->status.zeny + sd->deal_zeny) <= MAX_ZENY && // fix positiv overflow
+				    target_sd->deal_zeny >= 0 && target_sd->deal_zeny <= MAX_ZENY && target_sd->deal_zeny <= target_sd->status.zeny && // check amount
+				    (sd->status.zeny + target_sd->deal_zeny) <= MAX_ZENY) { // fix positiv overflow
 
 
-						//Dupe Fix by mark
-						if (sd->status.inventory[n].amount < sd->deal_item_amount[trade_i])
-							sd->deal_item_amount[trade_i] = sd->status.inventory[n].amount;
-						//End Dupe Fix
+					// trade is accepted
+					for(trade_i = 0; trade_i < 10; trade_i++) {
+						if (sd->deal_item_amount[trade_i] != 0) {
+							int n = sd->deal_item_index[trade_i] - 2;
 
 
-						#ifndef TXT_ONLY
-						if(log_config.trade > 0)
-							log_trade(sd,target_sd,n,sd->deal_item_amount[trade_i]);
-						#endif //USE_SQL
+							if (sd->status.inventory[n].amount < sd->deal_item_amount[trade_i])
+								sd->deal_item_amount[trade_i] = sd->status.inventory[n].amount;
 
 
-						flag = pc_additem(target_sd,&sd->status.inventory[n],sd->deal_item_amount[trade_i]);
-						if(flag==0)
-						pc_delitem(sd,n,sd->deal_item_amount[trade_i],1);
-						else
-							clif_additem(sd,n,sd->deal_item_amount[trade_i],0);
-						sd->deal_item_index[trade_i] =0;
-						sd->deal_item_amount[trade_i]=0;
-					}
-					if(target_sd->deal_item_amount[trade_i] != 0) {
-						int n=target_sd->deal_item_index[trade_i]-2;
-						int flag;
+							#ifndef TXT_ONLY
+							if(log_config.trade > 0)
+								log_trade(sd,target_sd,n,sd->deal_item_amount[trade_i]);
+							#endif //USE_SQL
 
 
-						//Dupe Fix by mark
-						if (target_sd->status.inventory[n].amount < target_sd->deal_item_amount[trade_i])
-							target_sd->deal_item_amount[trade_i] = target_sd->status.inventory[n].amount;
-						//End Dupe Fix
+							flag = pc_additem(target_sd, &sd->status.inventory[n], sd->deal_item_amount[trade_i]);
+							if (flag == 0)
+								pc_delitem(sd, n, sd->deal_item_amount[trade_i], 1);
+							else
+								clif_additem(sd, n, sd->deal_item_amount[trade_i], 0);
+							sd->deal_item_index[trade_i] = 0;
+							sd->deal_item_amount[trade_i] = 0;
+						}
+						if (target_sd->deal_item_amount[trade_i] != 0) {
+							int n = target_sd->deal_item_index[trade_i] - 2;
 
 
-						#ifndef TXT_ONLY
-						if(log_config.trade > 0)
-							log_trade(target_sd,sd,n,target_sd->deal_item_amount[trade_i]);
-						#endif //USE_SQL
+							if (target_sd->status.inventory[n].amount < target_sd->deal_item_amount[trade_i])
+								target_sd->deal_item_amount[trade_i] = target_sd->status.inventory[n].amount;
+
+							#ifndef TXT_ONLY
+							if(log_config.trade > 0)
+								log_trade(target_sd,sd,n,target_sd->deal_item_amount[trade_i]);
+							#endif //USE_SQL
 
 
-						flag = pc_additem(sd,&target_sd->status.inventory[n],target_sd->deal_item_amount[trade_i]);
-						if(flag==0)
-						pc_delitem(target_sd,n,target_sd->deal_item_amount[trade_i],1);
-						else
-							clif_additem(target_sd,n,target_sd->deal_item_amount[trade_i],0);
-						target_sd->deal_item_index[trade_i] =0;
-						target_sd->deal_item_amount[trade_i]=0;
+							flag = pc_additem(sd, &target_sd->status.inventory[n], target_sd->deal_item_amount[trade_i]);
+							if (flag == 0)
+								pc_delitem(target_sd, n, target_sd->deal_item_amount[trade_i], 1);
+							else
+								clif_additem(target_sd, n, target_sd->deal_item_amount[trade_i], 0);
+							target_sd->deal_item_index[trade_i] = 0;
+							target_sd->deal_item_amount[trade_i] = 0;
+						}
 					}
 					}
-				}
-				if(sd->deal_zeny) {
+					if (sd->deal_zeny) {
+						#ifndef TXT_ONLY	
+						if (log_config.trade > 0 && log_config.zeny > 0)
+							log_zeny(sd, target_sd, sd->deal_zeny);
+						#endif //USE_SQL
+						sd->status.zeny -= sd->deal_zeny;
+						target_sd->status.zeny += sd->deal_zeny;
+					}
+					if (target_sd->deal_zeny) {
 					#ifndef TXT_ONLY	
 					#ifndef TXT_ONLY	
-					if (log_config.trade > 0 && log_config.zeny > 0)
-						log_zeny(sd, target_sd, sd->deal_zeny);
-					#endif //USE_SQL
-					sd->status.zeny -= sd->deal_zeny;
-					clif_updatestatus(sd,SP_ZENY);
-					target_sd->status.zeny += sd->deal_zeny;
-					clif_updatestatus(target_sd,SP_ZENY);
-					sd->deal_zeny=0;
-				}
-				if(target_sd->deal_zeny) {
-					#ifndef TXT_ONLY
-					if (log_config.trade > 0 && log_config.zeny > 0)
-						log_zeny(target_sd, sd, target_sd->deal_zeny);
-					#endif //USE_SQL
-					target_sd->status.zeny -= target_sd->deal_zeny;
-					clif_updatestatus(target_sd,SP_ZENY);
-					sd->status.zeny += target_sd->deal_zeny;
-					clif_updatestatus(sd,SP_ZENY);
-					target_sd->deal_zeny=0;
+						if (log_config.trade > 0 && log_config.zeny > 0)
+							log_zeny(target_sd, sd, sd->deal_zeny);
+						#endif //USE_SQL
+
+						target_sd->status.zeny -= target_sd->deal_zeny;
+						sd->status.zeny += target_sd->deal_zeny;
+					}
+					if (sd->deal_zeny || target_sd->deal_zeny) {
+						clif_updatestatus(sd, SP_ZENY);
+						sd->deal_zeny = 0;
+						clif_updatestatus(target_sd, SP_ZENY);
+						target_sd->deal_zeny = 0;
+					}
+					sd->deal_locked = 0;
+					sd->trade_partner = 0;
+					target_sd->deal_locked = 0;
+					target_sd->trade_partner = 0;
+					clif_tradecompleted(sd, 0);
+					clif_tradecompleted(target_sd, 0);
+					// save both player to avoid crash: they always have no advantage/disadvantage between the 2 players
+					chrif_save(sd); // do pc_makesavestatus and save storage too
+					chrif_save(target_sd); // do pc_makesavestatus and save storage too
+				// zeny value was modified!!!! hacker with packet modified
+				} else {
+					trade_tradecancel(sd);
 				}
 				}
-				sd->deal_locked =0;
-				sd->trade_partner=0;
-				target_sd->deal_locked=0;
-				target_sd->trade_partner=0;
-				clif_tradecompleted(sd,0);
-				clif_tradecompleted(target_sd,0);
-				// save both player to avoid crash: they always have no advantage/disadvantage between the 2 players [Yor]
-				chrif_save(sd); // do pc_makesavestatus and save storage too
-				chrif_save(target_sd); // do pc_makesavestatus and save storage too
 			}
 			}
 		}
 		}
 	}
 	}