Giter Club home page Giter Club logo

wdpassport-utils's Introduction

WD My Passport Drive Hardware Encryption Utility for Linux

A Linux command-line utility to lock, unlock, and manage the hardware encryption functionality of Western Digital My Passport external drives. Written in Python 3.

WD My Passport drives support hardware encryption. New drives arrive in a passwordless state --- they can be used without locking or unlocking. After a password is set, drives become locked when they are unplugged and must be unlocked when they are plugged in to mount the volume and see its content.

This utlity can:

  • Show drive status.
  • Set and change the drive's password.
  • Unlock an encrypted drive, given the password.
  • Reset the drive in case of a lost password.

Passwords given on the command line are converted into binary password data in a mechanism intended to be compatible with WD's unlock software that is used in Microsoft Windows.

This tool was originally written by 0-duke in 2015 based on reverse engineering research by DanLukes and an implementation by DanLukes and KenMacD. crypto-universe converted this project and the underlying SCSI interface library py_sg to Python 3. JoshData updated the library to work with the latest WD My Passport device.

Installing

You'll need the Python 3 development headers to install this tool. On Ubuntu 22.04 LTS run:

sudo apt install python3 python3-dev python3-pip git

Install py3_sg via pip

sudo python3 -m pip install py3_sg

On other Linux distributions you may need a different command.

You must use sudo in this command. Usually that's a bad idea when running pip but we need to be root to access the devices. Then use pip to install the source code in this repository:

sudo pip install git+https://github.com/0-duke/wdpassport-utils

Usage

Run script as root or as a user that has permission to manage the device.

When used without any arguments, the status of the drive is shown:

$ sudo wdpassport-utils.py 
[sudo] password for user: 
Device: /dev/sdc
Security status: Unlocked
Encryption type: Unknown (0x31)

There are few options:

-u, --unlock          Unlock

Unlock a locked drive. You will be asked to enter the unlock password. If everything is fine device will be unlocked. (To lock a drive, unplug it.)

-m, --mount           Enable mount point for an unlocked device

After unlock, your operating system may still think that your device is a strange thing attached to its USB port and doesn't know how to manage it. This option forces the operating system to rescan the device and handle it as a normal external USB harddrive. This flag can be combined with -u.

-c, --change_passwd   Set, change, or remove password protection

Set a password on a new drive, change the password, or remove the password (so that it does not need to be unlocked to use). To remove a password, leave the new password empty.

-e, --erase           Erase/reset device

Erase (reset) the drive. This will remove the internal key associated to you password and all your data will be unaccessible. You will also lose your partition table and you will need to create a new one (you can use fdisk and mkfs or other utilities to prepare and format the drive).

-d DEVICE, --device DEVICE  Device path (ex. /dev/sdb). Optional.

This tool will try to auto-detect the device path of your WD My Passport device. If you have more than one device, or if auto-detection fails, you can manually specify the device path, e.g. as /dev/sdb.

-h, --help            show this help message and exit

Lists all possible arguments.

Disclaimer

Use the tool and any of the information contained in this repository at your own risk. The tool was developed without any official documenation from Western Digital on how to manage the drive using its raw SCSI interface. We accept no responsibility.

wdpassport-utils's People

Contributors

0-duke avatar joshdata avatar magikid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wdpassport-utils's Issues

Scsi or USB?

Hi guys,
this is probably a very stupid question, but I'm confused ;-) Your project uses a SCSI driver to communicate with the WD disk, so does this mean it NOT work with USB3 drives? I'm asking this because I'm intending to buy such a USB disk for my Linux box and I'm trying to find out which software helps me with the disk encryption on the Linux side. Any clarification is very much appreciated.
Ralph

Issue in installing due to "py_sg"

It seems like we should use "py3_sg".
The step was working in my previous Os version. But i face issue when i installed latest "Ubuntu 22.04.1 LTS"

deprecation warnings

After updating fedora to version 32 I had to install py_sg again.
Now it works again but there is this warning in console:

$ wdpassport-utils.py -u
/usr/local/bin/wdpassport-utils.py:131: DeprecationWarning: PY_SSIZE_T_CLEAN will be required for '#' formats
data = py_sg.read_as_bin_str(dev, _scsi_pack_cdb(cdb), BLOCK_SIZE)
[wdpassport] password for /dev/sdb:
/usr/local/bin/wdpassport-utils.py:89: DeprecationWarning: PY_SSIZE_T_CLEAN will be required for '#' formats
data = py_sg.read_as_bin_str(dev, _scsi_pack_cdb(cdb), BLOCK_SIZE)
/usr/local/bin/wdpassport-utils.py:230: DeprecationWarning: PY_SSIZE_T_CLEAN will be required for '#' formats
py_sg.write(dev, _scsi_pack_cdb(cdb), _scsi_pack_cdb(pw_block) + pwd_hashed)

Python 3.8.6

Update

Can you update the script for nowadays use? I'm new on python and I fixed some old-syntax errors that python complained about your script, but furthermore there's a problem with importing py-sg, I think it's because of version change on python 2.7 - 3. Besides, It cannot load (import) py-sg.

How to find HDD /dev/...

I've been spending the last 15 minutes trying to workaround my password encrypted My Passport on my Ubuntu Laptop and I can't find the discriminating letters of my HDD. I couldn't find anything on fdisk either and it's just showing up the virtual disc for the Windows unlocker. What do I do? Thanks.

Some How-To tips

Duke,
There is no way to contact you that I can find. Please list some contact info.

I am not a very experienced Linux user, so I got the script to work eventually by following these steps:

  1. I had to install py_sg by Googling for its online posting, grabbing the install file, and running the install file with -install option.
    https://pypi.python.org/pypi/py_sg/

  2. Users be aware that right-clicking of script file and choosing "Save link as..." DOES NOT download the actual file! You have to first view the script file, then click "Raw" button, and THEN downloading plaintext script contents to a file from the browser. This github behavior is a little stupid in my opinion. Otherwise you will download a file with script's filename but HTML code inside!!! (Check the contents of script file with any text editor).

  3. Always use sudo with this command in the Terminal: Every time you run the script you have to type in
    sudo ./wdpassport-utils.py (any commands here)
    and enter your password.

  4. The auto-detect option probably works for Passport drives only. It does not work for WD My Drive. In this case you have to use the -d or --device flag IN FRONT OF EVERY COMMAND YOU TYPE IN.
    So for example, if autodetect does not work and you want to unlock, after you figure out the path to your drive, enter
    sudo ./wdpassport-utils.py -d /dev/sde -u
    First enter your username password, then you will be prompted for drive's password.
    Of course for you "sde" will probably be something else.

  5. Error when hard drive is in power save mode:
    If the HD is currently in power save mode, the following extensive but non-intuitive error is shown:
    "Traceback (most recent call last):
    File "./wdpassport-utils.py", line 428, in
    main(sys.argv[1:])
    File "./wdpassport-utils.py", line 412, in main
    unlock()
    File "./wdpassport-utils.py", line 199, in unlock
    iteration,salt,hint = read_handy_store_block1()
    File "./wdpassport-utils.py", line 142, in read_handy_store_block1
    sector_data = read_handy_store(1)
    File "./wdpassport-utils.py", line 94, in read_handy_store
    data = py_sg.read(dev, _scsi_pack_cdb(cdb), BLOCK_SIZE)
    py_sg.SCSIError: (1, 0, 8, 'p\x00\x02\x00\x00\x00\x00\n\x00\x00\x00\x00\x04\x01\x00\x00\x00\x00')
    "
    AFTER the error is shown, the hard drive starts coming out of Power Save mode. Then, the utility has to be re-run with the password again to be able to unlock the HD.

Confirmed works! Thanks!
http://www.MKRD.info/

Error when hard drive is in power save mode

Hello,
If the HD is currently in power save mode, the following extensive but non-intuitive error is shown:
"Traceback (most recent call last):
File "./wdpassport-utils.py", line 428, in
main(sys.argv[1:])
File "./wdpassport-utils.py", line 412, in main
unlock()
File "./wdpassport-utils.py", line 199, in unlock
iteration,salt,hint = read_handy_store_block1()
File "./wdpassport-utils.py", line 142, in read_handy_store_block1
sector_data = read_handy_store(1)
File "./wdpassport-utils.py", line 94, in read_handy_store
data = py_sg.read(dev, _scsi_pack_cdb(cdb), BLOCK_SIZE)
py_sg.SCSIError: (1, 0, 8, 'p\x00\x02\x00\x00\x00\x00\n\x00\x00\x00\x00\x04\x01\x00\x00\x00\x00')
"
AFTER the error is shown, the hard drive starts coming out of Power Save mode. Then, the utility has to be re-run with the password again to be able to unlock the HD.

It would be nice if the HD was pinged (or say a random read request was requested) or some other method was used to bring it out of Power Save mode before utility tries to unlock the HD.

lock?

err how do i lock the drive when finished?

Secure_erase vulnerability

First thing first. Nice write-up of WD VSCs in python.

The danger is in function "secure_erase" where you miss a crucial point, correctly stated in the work of Dan Lukes you refer to:
https://github.com/KenMacD/wdpassport-utils/blob/master/wdutils.c

Bug: For security, you really should supply pseudo random data from the host. Dan Lukes uses arc4random, which WD SW for MAC also uses (was fixed spring 2014). You provide no data from the host.

So:

  1. uncomment lines 303 and 306: #pw_block[3] = 0x01
  2. append pwblen pseudo random bytes to pw_block before sending "erase" CDB

Setting pw_block[3] = 0x00, like you do by default, tells the drive to exclude key material from your host machine, using only on-device HW PRNG as source for the new key (DEK). This is very bad. These on-device HW PRNGs have issues, depending on model. Setting pw_block[3] = 0x01 mixes host machine bytes with on-device HW PRNG bytes, improving security, given you use a proper host random source.

Have a look at this paper for details:
https://eprint.iacr.org/2015/1002.pdf (Table 4 at page 6).
Also have a look at slide 33 here for a figure of the "erase" VSC (depending on model):
http://hardwear.io/wp-content/uploads/2015/10/got-HW-crypto-slides_hardwear_gunnar-christian.pdf

-gradoisageek-

Any chance here?

I came across wdpassport-utils and I was looking for some intel.

I came across a device today that doesn't mount.
The heads on this device are working perfectly.
PCB voltage is fine and everything working as it should.

As far as I know this devices have an MCU encrypted and module responsible for data encryption (Module190).
Since this PCB is locked I cannot access Service Area or read the rom.
When I try to clone the drive the image is full of 00's (because the hdd buffer is not capable of reaching the original ROM).

I was wondering if you know any other command or really can point me towards the right direction so I can do some RE on this device. This is sad because I'm used to work with data recovery and firmware repair tools, but none have added support for this drive.

Thank you very much for your time

importing py_sg error

my pip3 list shows the py_sg package as present but when im running the command im getting error as you need to install py_sg package

WD Passport 5TB - failed to set password - py_sg.SCSIError: (0, 3, 0, '')

Dear Developer,
I was successfull with setting password at my previous 2TB and 4TB WD Passports.
I just bought a 5TB new WD Passport and did the same way but I had an error and now the drive has a blocking problem... could you help, please? I did the following:
$ sudo wdpassport-utils.py --device /dev/sdg -c
Changing password for /dev/sdg...
New password:
New password (again):
[0, 1, 68, 87, 0, 0, 0, 0, 232, 3, 0, 0, 78, 83, 71, 69, 87, 81, 48, 75, 0, 0, 0, 0, 119, 100, 112, 97, 115, 115, 112, 111, 114, 116, 45, 117, 116, 105, 108, 115, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52]
Traceback (most recent call last):
File "/usr/local/bin/wdpassport-utils.py", line 457, in
main(sys.argv[1:])
File "/usr/local/bin/wdpassport-utils.py", line 443, in main
change_password()
File "/usr/local/bin/wdpassport-utils.py", line 287, in change_password
write_handy_store_block1(*hash_parameters)
File "/usr/local/bin/wdpassport-utils.py", line 177, in write_handy_store_block1
write_handy_store(1, bytes(sector_data))
File "/usr/local/bin/wdpassport-utils.py", line 99, in write_handy_store
py_sg.write(dev, _scsi_pack_cdb(cdb), data)
py_sg.SCSIError: (0, 3, 0, '')

Now when I try to unlock the drive I get the error:

$ sudo wdpassport-utils.py --device /dev/sdg -u
[!] Something wrong opening /dev/sdg

I have the same error when I re-try to set the password:
$ sudo wdpassport-utils.py --device /dev/sdg -c
[!] Something wrong opening /dev/sdg

Additionally, the drive disappears from the drive list...

Thank you in advance for your feedback/help and best regards, Piotr.

Support for internal hard-drives?

Hello!

I purchased a surveillance hard-drive (WDC WD10PURZ-85U8XY0) for my NVR kit and I am stuck: it is locked, cannot be formatted nor detected by the NVR kit. Furthermore, it is an internal hard-drive and I do not have access to Windows to run the official WD software.

I am on Linux Mint (Cinnamon) so I tried to make Wine work with WD Security/Disk Utility software but it fails trying to install some .NET stuff.

Trying a different approach, I found your code. It is by far the closest I have been to a solution but the script simply tells me that:

[!] No Western Digital Passport device found.

Is there a way to modify this script so it can unlock an internal hard-drive?

Thanks in advance!

Program exits with "[!] Wrong HSB1 signature" error

Hello, i am very interested in to can use this program to enable or disable password on WD MyPassport disks.
I am testing it with the following drive:
Model: WD10JMVW-11AJGS2
Encryption chip: JMS569
Processor: 9446-NDB2

When I run the program with option -c, I leave old password in blank, then I type new password, then program exists with the following error:
[!] Wrong HSB1 signature.
The result is that password is not set.
Please, try to find the origin of the problem out, and let me know if I can provide some useful debug information.
I am testing it in Linux Mint 17.3 (with Ubuntu 14.04 base) and I run sucessfully the needed installation:
sudo apt-get install python-pip python-dev lsscsi
sudo pip install py_sg

No issue here, just a tip.

Great work thank you 0-duke, seriously, I was counting the wasted seconds every time i start the VM just to unlock this WD.

i copied the wdpassport-utils.py to /usr/bin
and made an .sh with the following commands:

sudo wdpassport-utils.py -u
sudo wdpassport-utils.py -m

now i just run it from the desktop and it asks for the passwords and auto-mount.

Thanks again!

Python3 version does not recognize my drive

Similar to #14
I have a device here that can be read (but not more more) at https://github.com/0-duke/wdpassport-utils/tree/0a251b2a3a647513c430efab7a1bb3a18fedd642:

sudo python2 ./wdpassport-utils.py -d /dev/sda -s
WD Passport Ultra linux utility v0.1 by duke
[*] Device state
	Security status: No keys
	Encryption type: unknown

but cannot be read with the python3 version:

 sudo ./wdpassport-utils.py -d /dev/sda 
[!] No Western Digital Passport device found.

The drive came here without a label for repair and doesn't have a standard SATA adapter (micro usb is soldered directly to the PCB (sigh...)). All I can currently say about it is that it is from Western Digital, and Not For Resale (P/N WD10TMVV)

Question: Installation in a venv using pipx

sudo is required for installation as mentioned in the Readme. Is it possible to install it in a venv using pipx (which automatically installs in a venv) with sudo?

Not sure, but isolating in venv may provide some safety.

Erasing the drive or removing the password throws an error

Hey there,
I've just found a wd usb drive in a cupboard and I wanted to resurrect it. The HDD just went to tech heaven, dying when I tried to format it, but the control board is still alive, and still has a password set. I know the password and I can unlock the device, but I cannot remove the password permanently (I can set it, but it refuses to accept an empty password), nor erase the disk (along with the password). I always get an error.
Any idea what's going on?
Thanks!

Edit: I just realized that my drive is a mybook studio - is that just not supported? Could you add support for that? Interestingly, unlocking works flawlessly

Edit 2: Set up a whole vm for the stupid software and not even that is able to change the password. At this point I feel like these devices are plagued by planned obsolescence. If the drive dies you can never remove the password

Edit 3: After talking to a support rep about removing the password, I was told to use the "WD security" software instead of "WD discovery". The latter showed pretty much the same problems that your software shows (able to change the password, but not remove it), so I assume that your software just uses an older revision of the protocol?

Error on Synology NAS DSM 6.2 "No library named udev"

Trying to setup wdpassport-utils.py on Synology DS411+ii NAS with DSM DSM 6.2.2-24922 Update 4 Installed all the required packages according to the instructions.

Everything looks good so far, but when I try to use wdpassport-utils.py, I get the following error:

sudo wdpassport-utils.py

Traceback (most recent call last):
File "/opt/bin/wdpassport-utils.py", line 457, in
main(sys.argv[1:])
File "/opt/bin/wdpassport-utils.py", line 395, in main
context = pyudev.Context()
File "/opt/lib/python3.6/site-packages/pyudev/core.py", line 61, in init
self._libudev = load_ctypes_library('udev', SIGNATURES, ERROR_CHECKERS)
File "/opt/lib/python3.6/site-packages/pyudev/_ctypeslib/utils.py", line 55, in load_ctypes_library
raise ImportError('No library named %s' % name)
ImportError: No library named udev
Exception ignored in: <bound method Context.del of <pyudev.core.Context object at 0xe1bae8>>
Traceback (most recent call last):
File "/opt/lib/python3.6/site-packages/pyudev/core.py", line 65, in del
self._libudev.udev_unref(self)
AttributeError: 'Context' object has no attribute '_libudev'

Any ideas?

Version 0.2 Detailed Installation Procedure

Folks,
Lots of devs are skimpy on detailed procedure and all prerequisites (mostly because they have all the prerequisites on their machine from a long ago), so here are ALL prerequisites and installation steps:

sudo apt install python3-dev
Python 3 is a prerequisite for this software.

sudo apt install python3-pip
Addresses error:
pip3: command not found

sudo apt install git
Addresses error:
No such file or directory: 'git'

sudo apt-get install python3-setuptools
Addresses error:
No module named 'setuptools'

pip3 install --user git+https://github.com/crypto-universe/py_sg
Addresses error:
You need to install the "py_sg" module.

Unfortunately, version 0.2 does not work with WD MyBook that has worked with version 0.1 so until we find out what is going on, keep using version 0.1...

/dev/disk/by-id/ links not accepted

If I use -d /dev/sdb everything works fine, but the tool does not accept '/dev/disk/by-id/' links.
[!] No Western Digital Passport device found.
Please add /dev/disk/by-id/ links support.

Version 0.2 does not work with WD MyBook that works with v0.1

@0-duke,
RE: Some How-To tips #6
It is nice to hear from you! I just assumed (from years of inactivity) that you are gone for good.
I have just installed version 0.2. Unfortunately, it does not work with a WD MyBook that has worked fine with version 0.1 of this software.

Version 0.1 autodetect never worked, so I always forced it as:
sudo ./wdpassport-utils.py -d /dev/sdc -u

Version 0.2 does not want to see me whether I force it or not. I tried both:
sudo wdpassport-utils.py -d /dev/sdc -u
and
sudo wdpassport-utils.py -u
In both cases I get the same message:
[!] No Western Digital Passport device found.

I am using WD MyBook USB 3.0 version. Part number is WDBBGB0060HBK-NA

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.