MUGEN Cheap Wiki
Advertisement
Null Overflow - Sample No. 1

Crazy-Catastrophe: One of the first characters who could directly beat their enemies without even attacking them. Initial versions used this oversight to execute Parent Forgery.

Null Overflow, also known as 512 Overflow, is an oversight in M.U.G.E.N engine that allows for writing data to a character outside of the space it was intended to be written to.
Despite its common name, any State Controller can be used, not just the Null state controller.

Null is a State Controller that is usable in all the M.U.G.E.N Engine versions. It does absolutely nothing. The intent of this State Controller is to be used for debugging purposes, as it allows authors to temporarily disable other State Controllers during development, rather than delete them. Due to its lower weight by comparison to other controllers, another frequent use case is as a platform for variable assignment through the := operator.

Examples of the Null state controller being used for both purposes:

[StateDef -2]

[State Sample_Test] ;Main Purpose
Type     = Null ;EnvColor
Trigger1 = 1
Value    = 255,255,255
Time     = 1
IgnoreHitPause = 1

[State Sample_Test] ;Variable initialization
Type     = Null
Trigger1 = !IsHelper
Trigger1 = 1 || Var(20) := (25) || FVar(35) := (0.2750)
IgnoreHitPause = 1

Details[]

For the sake of the persistent field working as intended, all characters have 512 bytes allocated within their data structure. As a result, when a StateDef header is parsed, the engine performs a check to see if that particular StateDef has more than 512 State Controllers. If it does, the engine crashes with the usual error message: "State #### can only have a maximum of 512 state controllers." If it does not, all persistent bytes that correspond to these State Controllers are set to zero, and the rest of the header is read.

As a result, if a StateDef header is not parsed, the amount of State Controllers is never checked, and this boundary can be exceeded. This can be achieved in one of three ways:

  • By using a HitDef (user only) or a ReversalDef (either)'s PauseTime parameter to enter with positive HitPauseTime; this is referred to as "Frozen Overflow."
  • By using a HitDef or Projectile to execute a time-preserving throw (Ground.Type = None, P2StateNo = -1, P2GetP1State = 1) to enter with positive statetime; this is referred to as "Unfrozen Overflow."
  • By using the %n Bug or a similar exploit to temporarily activate the ESC key's processing handler by setting it to a non-zero value (0x004B6981 in WinMUGEN, 0x0052B97B in 1.0).

When called every frame through their normal methods, StateDefs -3, -2, and -1 never read their respective StateDef headers, nor are they tied to the persistent field in any way whatsoever. All character data after the 512th State Controller is treated in the exact same way a persistent byte is, and follows the standard persistent byte and State Controller execution rules. Namely, in the following order:

  1. If IgnoreHitPause = 1 is not specified, the State Controller will not be read and the below is ignored when the character has positive HitPauseTime.
  2. If its corresponding persistent byte is zero, the State Controller's triggers will be read to determine whether it will execute or not. If it will, directly before execution, the persistent byte will be set as it is defined, &255 (if Persistent = 0 is specified, it will set it to 1 instead).
  3. If the character did not branch out of the state through a ChangeState/SelfState/TagOut/TagIn/etc. and the State Controller does not have Persistent = 0, decrease the persistent byte by one. If the resulting byte is <0 (>127 if unsigned), set it to 0.

This operates on a byte-by-byte basis, meaning that most parameters, whether an integer or a float, take up 4 state controllers. As a result, it may be easier to imagine State Controllers in groups of 4. An example of this in action that will set Time to 234881024, Ctrl to 69, and InGuardDist flag to the ON state:

[StateDef 65535] ;WinMUGEN Only!
[State ] ;1: Persistent(1) | Clear ctrl for writing down below (time is automatically reset on entry)
type=CtrlSet
trigger1=1
value=0
ignorehitpause=1
[State ] ;2: Persistent(2)
type=Null
trigger1=1
;(3-511 omitted for brevity)
[State ] ;512: Persistent(512)
type=Null
trigger1=1
[State ] ;513: Time(1) | Set to 14*16777216 + 0*65536 + 0*256 + 0
type=Null
trigger1=1
[State ] ;513: Time(2)
type=Null
trigger1=1
[State ] ;514: Time(3)
type=Null
trigger1=1
[State ] ;515: Time(4)
type=Null
trigger1=1
ignorehitpause=1
persistent=15 ;(14+1)
[State ] ;516: StateType(1)
type=Null
trigger1=1
[State ] ;517: StateType(2)
type=Null
trigger1=1
[State ] ;518: StateType(3)
type=Null
trigger1=1
[State ] ;519: StateType(3)
type=Null
trigger1=1
[State ] ;520: MoveType(1)
type=Null
trigger1=1
[State ] ;521: MoveType(2)
type=Null
trigger1=1
[State ] ;522: MoveType(3)
type=Null
trigger1=1
[State ] ;523: MoveType(4)
type=Null
trigger1=1
[State ] ;524: Physics(1)
type=Null
trigger1=1
[State ] ;525: Physics(2)
type=Null
trigger1=1
[State ] ;526: Physics(3)
type=Null
trigger1=1
[State ] ;527: Physics(4)
type=Null
trigger1=1
[State ] ;528: Ctrl(1) | Set to 69
type=Null
trigger1=1
ignorehitpause=1
persistent=70 ;(69+1)
[State ] ;529: Ctrl(2)
type=Null
trigger1=1
[State ] ;530: Ctrl(3)
type=Null
trigger1=1
[State ] ;531: Ctrl(4)
type=Null
trigger1=1
[State ] ;532: GuardFlag(1)
type=Null
trigger1=1
ignorehitpause=1
persistent=0 ;1 if zero, unchanged otherwise

This is one of the first oversights that authors exploited to defeat opponents in a non-standard way, oftentimes by setting alive to 0 directly after forcing the opponent to acquire HitPauseTime during a throw. As it only behaves consistently in the context of the user's address space, throwing the opponent is necessary to exploit this in a stable manner. This oversight serves as the basis for common Nuke techniques such as Ultra-Instant Death (which is even widespread in even weaker cheap characters), PalNo Tampering, and Parent Change. Outside of the Nuke tier, this oversight has also seen use in primitive Null-tier edits for the purposes of Direct Death through extending the amount of State Controllers past the character's address space boundary, address acquisition through Parent Forgery, and even potentially ACE through repeated usage of the AfterImage bug.

Advertisement