Skip to content

Instantly share code, notes, and snippets.

@vetzki
Last active March 25, 2022 18:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vetzki/645e09c38221da4e6ddd45f4443c6261 to your computer and use it in GitHub Desktop.
Save vetzki/645e09c38221da4e6ddd45f4443c6261 to your computer and use it in GitHub Desktop.
hide hard disk from WiiU (and use with vWii)
#!/usr/bin/env python
"""
py_wiiu_hide_disk.py: hide hard disk from WiiU (and use with vWii)
Copyright (C) 2019 Vetter Michael
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
#
# this tools allow to change boot signature of hard disk to hide from WiiU (and use with vWii)
#
# thanks to https://code.google.com/archive/p/u-stealth/
#
# mbr = first 512 bytes
#
# last two bytes on bootable drives are usually 55 AA
# this tool changes either to 55AB (hidden) or to 55AA (shown)
import argparse
import os
import sys
import subprocess
# constants
STARTING_OFFSET=510 # second last byte of mbr (2 bytes are overwritten at offset 510 and 511)
HIDE_VAL=[0x55,0xab] # ["55","ab"] is also possible
SHOW_VAL=[0x55,0xaa]
def create_parser():
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--device",
help="device path (e.g. /dev/sdc)",
required=True
)
parser.add_argument("--hide",
help="hide drive",
action="store_const",
const=True
)
parser.add_argument("--unhide",
help="unhide drive",
action="store_const",
const=True
)
parser.add_argument("--skip-hwinfo",
help="skip hwinfo check",
action="store_const",
const=True
)
return(parser.parse_args())
def check_root():
if os.getuid() != 0:
print("please restart as root")
exit(1)
return
def check_answer(answer):
if answer != "y" and answer != "Y":
print("exiting")
exit()
def check_dev(dev):
# check for block device
if os.st.S_ISBLK(os.stat(dev).st_mode) is False:
answer = input("%s is not a block device. Are you sure this is the right path (y/Y)? " %(dev))
check_answer(answer)
# simple check if device path ends with number, which usually is a partiton
if dev[-1].isdigit():
answer = input("%s seems to be a partition. Are you sure you want to continue (y/Y)? " %(dev))
check_answer(answer)
def show_drive_info(dev):
try:
subprocess.run(["hwinfo","--short","--disk","--only",dev])
except FileNotFoundError:
# hwinfo not installed
print("hwinfo seems not installed")
finally:
answer = input(dev+" correct disk (y/Y)? ")
check_answer(answer)
def change_drive(dev, hexval, offset_dec):
try:
with open(dev,"r+b") as file:
for v in hexval:
if isinstance(v,str):
# convert to integer
v = int(v,16)
byteval = int.to_bytes(v,1,sys.byteorder)
file.seek(offset_dec)
file.write(byteval)
print("wrote {0:X} to offset {1:X} (decimal {2})".format(v,offset_dec,offset_dec))
offset_dec += 1
except Exception as e:
print("ERROR. something went wrong\n%s" %(str(e)))
exit(2)
def main(args):
check_root()
check_dev(args.device)
if args.skip_hwinfo is not True:
show_drive_info(args.device)
if args.hide and args.unhide:
print("use either --hide OR --unhide NOT both")
exit()
if args.hide:
change_drive(args.device,HIDE_VAL,STARTING_OFFSET)
print("drive %s hidden" %args.device)
elif args.unhide:
change_drive(args.device,SHOW_VAL,STARTING_OFFSET)
print("drive %s unhidden" %args.device)
if __name__ == "__main__":
main(create_parser())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment