The Substitute drain move not missing is a minor battle glitch in English Pokémon Red, Blue, and Yellow, where HP draining moves don't miss against a substitute, even though they do in Pokémon Red, Green, and Pokémon Blue (Japanese) as well as in Pokémon Yellow (Japanese). It is considered a glitch in the English versions, because the disassembly shows that the games do contain the piece of code to make HP draining moves miss against a substitute, but it ceases to work due to the fix for the Swift miss glitch.
Furthermore, this glitch makes it possible to "drain HP" from a substitute. However, due to a quirk with the Generation I substitute mechanics, the drain effect will not happen if the draining move breaks the substitute. This is due to a separate check that removes the secondary effect of damaging moves only when the move breaks a substitute.
How to perform
When a Pokémon has a substitute and the opposing Pokémon uses an HP-draining move (including Absorb, Mega Drain, Leech Life, and Dream Eater), the move may hit.
Note that this glitch does not exist in any of the Japanese games.
Source : Pokéred, Pokéyellow
ld a, [de] ; [de] contains the effect of the move
cp a, SWIFT_EFFECT
ret z ; If the move is Swift, bypass the accuracy check altogether
call CheckTargetSubstitute ; * Does the opponent have a substitute?
jr z, .checkForDigOrFlyStatus ; * If not, skip the two checks below
cp a, DRAIN_HP_EFFECT
jp z, .moveMissed ; Draining moves should miss unconditionally against substitutes
cp a, DREAM_EATER_EFFECT
jp z, .moveMissed ; Same for Dream Eater
In the Japanese versions, the two lines marked with "*" are above
ld a, [de] instead. As a result, they skip all three checks shown here, causing the Swift miss glitch.
In the English versions, those lines are moved down, fixing the Swift miss glitch. However, the function CheckTargetSubstitute overwrites register
a with either 0 or 1, so the two checks below will always fail, making drain moves able to hit substitutes.