# Tcl, 286 bytes #

    proc f {o i l} {seek $o 0
    set s [string repeat $i $l]
    puts -nonewline $o $s
    flush $o
    seek $o 0
    return [string equal [read $o $l] $s]}
    set n [open $argv r+]
    fconfigure $n -translation binary
    seek $n 0 end
    set m [tell $n]
    while {![f $n "\0" $m]} {}
    while {![f $n "\xff" $m]} {}
Not really optimized that well. I tried what I could, but I don't know that much about Tcl.

Save as "f.tcl" and run on Unix with `tclsh f.tcl "your filename"`. Make sure there's exactly one argument! I tested this on a plain file, but it should work on a device file as well.

Setting variables and indexing is more involved in Tcl, so I decided to put the common code between the passes into a function. Then I call it first with "\0", and repeat while it fails to verify. I do the same thing with "\xff".

I flushed after writes; it might not be necessary. `fconfigure -translation binary -buffering none` is longer.

-2 bytes by removing quotes around `r+`.