Created
April 23, 2025 20:11
-
-
Save Muqsit/07db65e1ab5802a35ceffde37c9fe7cf to your computer and use it in GitHub Desktop.
bedrock-skin-stealer.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "nbformat": 4, | |
| "nbformat_minor": 0, | |
| "metadata": { | |
| "colab": { | |
| "provenance": [], | |
| "authorship_tag": "ABX9TyOoxv8dkC1368O2mLMvq7Mf", | |
| "include_colab_link": true | |
| }, | |
| "kernelspec": { | |
| "name": "python3", | |
| "display_name": "Python 3" | |
| }, | |
| "language_info": { | |
| "name": "python" | |
| } | |
| }, | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "id": "view-in-github", | |
| "colab_type": "text" | |
| }, | |
| "source": [ | |
| "<a href=\"https://colab.research.google.com/gist/Muqsit/07db65e1ab5802a35ceffde37c9fe7cf/bedrock-skin-stealer.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# Install dependencies" | |
| ], | |
| "metadata": { | |
| "id": "TTkw-y0kOfNA" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "!pip install pygltflib" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "DibV85kHEcwv", | |
| "outputId": "2ada9e12-1756-4d20-c2ae-16fceff22f5f" | |
| }, | |
| "execution_count": 1, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Collecting pygltflib\n", | |
| " Downloading pygltflib-1.16.4-py3-none-any.whl.metadata (33 kB)\n", | |
| "Collecting dataclasses-json>=0.0.25 (from pygltflib)\n", | |
| " Downloading dataclasses_json-0.6.7-py3-none-any.whl.metadata (25 kB)\n", | |
| "Requirement already satisfied: deprecated in /usr/local/lib/python3.11/dist-packages (from pygltflib) (1.2.18)\n", | |
| "Collecting marshmallow<4.0.0,>=3.18.0 (from dataclasses-json>=0.0.25->pygltflib)\n", | |
| " Downloading marshmallow-3.26.1-py3-none-any.whl.metadata (7.3 kB)\n", | |
| "Collecting typing-inspect<1,>=0.4.0 (from dataclasses-json>=0.0.25->pygltflib)\n", | |
| " Downloading typing_inspect-0.9.0-py3-none-any.whl.metadata (1.5 kB)\n", | |
| "Requirement already satisfied: wrapt<2,>=1.10 in /usr/local/lib/python3.11/dist-packages (from deprecated->pygltflib) (1.17.2)\n", | |
| "Requirement already satisfied: packaging>=17.0 in /usr/local/lib/python3.11/dist-packages (from marshmallow<4.0.0,>=3.18.0->dataclasses-json>=0.0.25->pygltflib) (24.2)\n", | |
| "Collecting mypy-extensions>=0.3.0 (from typing-inspect<1,>=0.4.0->dataclasses-json>=0.0.25->pygltflib)\n", | |
| " Downloading mypy_extensions-1.1.0-py3-none-any.whl.metadata (1.1 kB)\n", | |
| "Requirement already satisfied: typing-extensions>=3.7.4 in /usr/local/lib/python3.11/dist-packages (from typing-inspect<1,>=0.4.0->dataclasses-json>=0.0.25->pygltflib) (4.13.2)\n", | |
| "Downloading pygltflib-1.16.4-py3-none-any.whl (27 kB)\n", | |
| "Downloading dataclasses_json-0.6.7-py3-none-any.whl (28 kB)\n", | |
| "Downloading marshmallow-3.26.1-py3-none-any.whl (50 kB)\n", | |
| "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.9/50.9 kB\u001b[0m \u001b[31m1.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
| "\u001b[?25hDownloading typing_inspect-0.9.0-py3-none-any.whl (8.8 kB)\n", | |
| "Downloading mypy_extensions-1.1.0-py3-none-any.whl (5.0 kB)\n", | |
| "Installing collected packages: mypy-extensions, marshmallow, typing-inspect, dataclasses-json, pygltflib\n", | |
| "Successfully installed dataclasses-json-0.6.7 marshmallow-3.26.1 mypy-extensions-1.1.0 pygltflib-1.16.4 typing-inspect-0.9.0\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# Download skin (.glb)" | |
| ], | |
| "metadata": { | |
| "id": "-2t_PkmKOhgZ" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 2, | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "0N6Xw6QFED1n", | |
| "outputId": "f578a925-86b6-4a99-899a-1d9697db58e9" | |
| }, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "--2025-04-23 20:06:20-- https://persona-secondary.franchise.minecraft-services.net/api/v1.0/profile/xuid/2535419200678464/image/modelbinary\n", | |
| "Resolving persona-secondary.franchise.minecraft-services.net (persona-secondary.franchise.minecraft-services.net)... 13.107.253.69, 2620:1ec:29:1::69\n", | |
| "Connecting to persona-secondary.franchise.minecraft-services.net (persona-secondary.franchise.minecraft-services.net)|13.107.253.69|:443... connected.\n", | |
| "HTTP request sent, awaiting response... 200 OK\n", | |
| "Length: 26512 (26K) [application/octet-stream]\n", | |
| "Saving to: ‘model.glb’\n", | |
| "\n", | |
| "model.glb 100%[===================>] 25.89K --.-KB/s in 0.004s \n", | |
| "\n", | |
| "2025-04-23 20:06:21 (6.58 MB/s) - ‘model.glb’ saved [26512/26512]\n", | |
| "\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "xuid = 2535419200678464\n", | |
| "!wget -O model.glb https://persona-secondary.franchise.minecraft-services.net/api/v1.0/profile/xuid/{xuid}/image/modelbinary" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# Extract standard minecraft .png from .glb" | |
| ], | |
| "metadata": { | |
| "id": "lAnNjbt4OmyH" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "from pygltflib import GLTF2\n", | |
| "\n", | |
| "gltf = GLTF2().load(\"model.glb\")\n", | |
| "image = gltf.images[0]\n", | |
| "bv = gltf.bufferViews[image.bufferView]\n", | |
| "with open(\"model.glb\", \"rb\") as f:\n", | |
| " f.read(4) # magic\n", | |
| " f.read(4) # version\n", | |
| " f.read(4) # length\n", | |
| " json_chunk_length = int.from_bytes(f.read(4), \"little\")\n", | |
| " f.read(4) # chunk type JSON\n", | |
| " f.read(json_chunk_length) # interesting metadata, but not useful for us\n", | |
| " bin_chunk_length = int.from_bytes(f.read(4), \"little\")\n", | |
| " f.read(4) # chunk type BIN\n", | |
| " f.read(bv.byteOffset)\n", | |
| " data = f.read(bv.byteLength)\n", | |
| "\n", | |
| "from PIL import Image\n", | |
| "import io\n", | |
| "image = Image.open(io.BytesIO(data))\n", | |
| "print(image.size)\n", | |
| "image" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 98 | |
| }, | |
| "id": "2MGKgLFWEJ8Q", | |
| "outputId": "e2194e4f-de7f-4e65-eb23-89ffcb9fae95" | |
| }, | |
| "execution_count": 3, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "(64, 64)\n" | |
| ] | |
| }, | |
| { | |
| "output_type": "execute_result", | |
| "data": { | |
| "text/plain": [ | |
| "<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=64x64>" | |
| ], | |
| "image/png": "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\n" | |
| }, | |
| "metadata": {}, | |
| "execution_count": 3 | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# Validate" | |
| ], | |
| "metadata": { | |
| "id": "aR7Tp7qrOr9K" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "%%writefile expected.base64\n", | |
| "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" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "RK5iQ5qKOBOD", | |
| "outputId": "458c7fb1-26fc-420c-d41e-132fa7fc21da" | |
| }, | |
| "execution_count": 4, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Writing expected.base64\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "import base64\n", | |
| "from io import BytesIO\n", | |
| "from PIL import ImageChops\n", | |
| "\n", | |
| "with open(\"expected.base64\", \"rb\") as f:\n", | |
| " true_data = f.read()\n", | |
| "\n", | |
| "truth = Image.open(BytesIO(base64.b64decode(true_data)))\n", | |
| "diff = ImageChops.difference(truth, image)\n", | |
| "print(\"Images are equal\" if diff.getbbox() is None else \"Images are not equal\")" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "7VAbfCKKONK_", | |
| "outputId": "16c64cbe-2d9e-41da-8e7c-2ec78bad783b" | |
| }, | |
| "execution_count": 13, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Images are equal\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "import matplotlib.pyplot as plt\n", | |
| "\n", | |
| "fig, axes = plt.subplots(1, 2, figsize=(8, 4))\n", | |
| "\n", | |
| "axes[0].imshow(truth, interpolation=\"nearest\")\n", | |
| "axes[0].set_title(\"Ground truth (%d x %d)\" % truth.size)\n", | |
| "axes[0].axis(\"off\")\n", | |
| "\n", | |
| "axes[1].imshow(image, interpolation=\"nearest\")\n", | |
| "axes[1].set_title(\"From mojang (%d x %d)\" % image.size)\n", | |
| "axes[1].axis(\"off\")\n", | |
| "\n", | |
| "plt.tight_layout()\n", | |
| "plt.show()" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 420 | |
| }, | |
| "id": "imP0QW8eQH01", | |
| "outputId": "8e4759e0-3e7a-44d3-ff27-6f5948f31fc1" | |
| }, | |
| "execution_count": 21, | |
| "outputs": [ | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "<Figure size 800x400 with 2 Axes>" | |
| ], | |
| "image/png": "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1atXTxMnTtT333/vVX/RM7/z589X9+7dlZycrLi4OHXu3Fkvv/yy1/wul0t33HGH1q9fr3bt2ikmJkZt27bVhg0bHN/rLl26KDY2Vs2bN9czzzzj7o0lef3113X27Fn16dPHYzxYx96iZs6cqSpVqmjz5s0e47feequio6O1a9cun88tKCjQ4sWL9bvf/U6XXnqpzp4969X3i9qyZYtefvllLVq0qNjtrrrqKr3//vuO//aoeISCMPHaa6+pRYsWSk1NDeh5Z8+e1dVXX62UlBTNnz9fQ4YMkTFGgwYN0uOPP65+/fpp4cKFatWqlaZNm6a77767THUOGzZMp06d0qOPPqphw4Zp1apVmj17tsc2Y8eO1aJFi9S3b1/9+c9/VlRUlAYOHFji3BdffLHS09MlnTtQvfjii3rxxRd1xRVXuLc5fvy4+vfvr44dO2rRokW68sor/a79iiuu0OTJkyVJ999/v3v+iy++2L1NRkaGhg4dqquuukoLFizQRRddpLS0NH3++efFzp2Xl6ft27frkksu8Xps8+bN6tq1q5YsWeIOSnXr1tWTTz7pONeDDz6oOnXq6LbbbvP7tcXFxWn16tXKyMjw+B7qxIkTlZOTo1WrVikiIsLn8zdt2iRJiomJUZcuXZSQkKD4+HjdcMMNjgfrjz76SKtXr9aiRYtKbIidO3fW1q1b/X4tALzl5OTou+++8/hzvoceekivv/66pk6dqjlz5ig6OlqrVq3SsGHDFBERoUcffVTjxo3TunXrdPnll3v9j3V+fr769++vhg0bat68eWrSpInuuOMOrVq1Sv369VOXLl00d+5cJSYm6uabb1ZmZqZfdf/1r3/V0qVLNWnSJE2ZMkX/93//p2HDhmn69OnasGGD7rnnHt16663617/+palTp3o8d9asWZo4caLq1aunBQsWaMiQIXrmmWfUt29f5eXlFbvfxYsXq1OnTkpPT9ecOXMUGRmp66+/Xq+//rrXtu+//74mTJigG264QfPmzdOZM2c0ZMgQHT9+3L3NJ598on79+un48eOaPXu2xowZo/T0dK1fv96v92Hr1q1KTk72+vpvMI+955s+fbo6duyoMWPG6NSpU5KkjRs3avny5ZoxY4Y6dOjg87lffPGFjhw5ovbt2+vWW29VQkKCEhIS1L59e73zzjte2+fn52vSpEkaO3asfv3rXxdbV+fOnWWMoUeEi5Cep4AxxpicnBwjyQwePNjrsezsbHPs2DH3n/NPL44aNcpIMvfee6/Hc9avX28kmYcffthjfOjQocblcpmMjAxjjDGZmZk+v6qjIl/1mTlzppFkbrnlFo/tfve735nk5GT333fu3GkkmQkTJnhsd+ONN5b560M9e/Y0kszTTz9dYr2FGjdubEaNGuX+e0lfH5JktmzZ4h7LysoyMTExZsqUKcXWnZGRYSSZJ554wmP8xIkTRpJJTk42VatWNY899phZu3at6devn+Nr2bVrl4mIiDAbN240xvzyvvv79aH77rvPVKlSxWzZssX9WhctWlTi8wYNGuSuc+TIkebll182Dz74oImMjDTdu3c3BQUF7m0LCgrMpZdeakaMGGGM+eVz5OsU9pw5c4wkc/ToUb9eA4BfFH59yOmPMca88847RpJp1qyZR3/Izc01KSkppl27dub06dPu8ddee81IMjNmzHCPFfaSOXPmuMeys7NNXFyccblc5u9//7t7/KuvvvLrWF54XKhVq5b5/vvv3eP33XefkWQ6dOhg8vLy3OMjRoww0dHR5syZM8aYc8fe6Oho07dvX4+vQj355JNGknn++ec96m/cuLHH/ot+FSc3N9e0a9fO9O7d22NckomOjnb3RWPOHYeLHs+vvfZaEx8fb7755hv32L59+0xkZKT736I4l19+uencubPXeDCPvUV9+umnJjo62owdO9ZkZ2eb+vXrmy5dunj8OzhZt26du8aWLVualStXmpUrV5qWLVua6Ohos2vXLo/tn3zySZOUlGSysrKMMabYrw8dOXLESDJz58716zUguDhTEAYKT/MW/dqJdO4rM7Vq1XL/KTyde77x48d7/P2NN95QRESE+7fihaZMmSJjjN58881S13r77bd7/L1Hjx46fvy4+zW88cYbkuS17zvvvLPU+zxfTEyMRo8eXS5zOWnTpo169Ojh/nutWrXUqlUr/fe//y32eYW/Ubrooos8xgu/KnT8+HGtWLFCU6dO1bBhw/T666+rTZs2evjhhz22nzx5svr376++ffuWqv5Zs2apbdu2GjVqlCZMmKCePXt6/Vs4Kayza9eu+stf/qIhQ4YoPT1dDz30kLZu3epxynnVqlX69NNPNXfuXL9qKnxPKmoFJaAyeuqpp/T22297/DnfqFGjFBcX5/77xx9/rKysLE2YMEGxsbHu8YEDB6p169aOvzEfO3as+7+rV6+uVq1aKSEhQcOGDXOPt2rVStWrVy/xmFjo+uuvV1JSkvvvhWfDb7rpJkVGRnqM5+bmur/atGnTJuXm5urOO+9UlSq//K/KuHHjVK1aNcf6z3f+e5Gdna2cnBz16NFD//nPf7y27dOnj5o3b+7+e/v27VWtWjX3a8zPz9emTZs0ePBg1atXz71dixYt1L9/f7/eh+PHj3v1Bym4x96i2rVrp9mzZ2vFihW6+uqr9d1332n16tUe/w5OCms8deqUNm/erLS0NKWlpWnTpk0yxmjevHker3PGjBl68MEHVatWrRJroj+EF0JBGChclcXpu+bPPPOM3n77bf3lL39xfG5kZKTXVf8HDhxQvXr1vFZ7KfyazIEDB0pda6NGjTz+XvgDnZ2d7Z67SpUqHgdY6VwjKQ/169dXdHR0uczlpOjrk869xsLXVxJz3jUb0i+NKSoqSkOHDnWPV6lSRcOHD9fhw4fdK0isXbtWW7du1YIFC0pbvqKjo/X8888rMzNTp06d0sqVK/06xVxY54gRIzzGb7zxRklyn9o9efKk7rvvPk2bNs3j+pbiFL4ngZzqBuDp0ksvVZ8+fTz+nK/oykSFx3mnY2/r1q29+kBsbKzX/8QlJSWpQYMGXj+7SUlJfh8Tix5TCwNC0eNH4fj5vcSp/ujoaDVr1qzEPvbaa6/pN7/5jWJjY1WjRg3VqlVLy5YtU05OTok1Sp7H/aysLJ0+fdpr1SBJjmO+FO0PUnCPvU6mTZumDh066KOPPtLMmTPVpk2bEp9TWONll13mse9GjRrp8ssv9/jqz/Tp01WjRg1NmjTJr3roD+GFJUnDQFJSkurWravPPvvM67HC36r4Wlc/JibG47cogfD1Q1jcRU6+vpfudLALhvN/++OPki7YKqq0ry85OVmSvBpljRo1FBsbq+rVq3vNnZKS4n5Oo0aNNG3aNF1//fWKjo52/3sXfu/30KFDys3N9fgtlS8bN26UJJ05c0b79u3z+p8FJ4Xz1q5d22eN0rmL93JzczV8+HB3jYUXkWdnZ2v//v2qV6+eR3ArfG7NmjVLrANA6QR6bCzK17GvrMf8YM1bnPfee0+DBg3SFVdcoaVLl6pu3bqKiorSypUrHS+Sroi+lpyc7BikgnnsdfLf//5X+/btk3TuAnJ/+KqxsM5PPvlEkrRv3z49++yzWrRokY4cOeLe5syZM8rLy9P+/ftVrVo11ahRw/0Y/SG8cKYgTAwcOFAZGRn66KOPyjxX48aNdeTIEffFRIW++uor9+PSL7/lL3rBWVnOJDRu3FgFBQX6+uuvPcb37Nnj1/NL+9uCiy66yOt15Obm6n//+1+5zF+SRo0aKS4uzuviuypVqqhjx446duyYcnNzPR4rPGgW/nbu0KFDWrNmjZo2ber+s3jxYknSJZdcogEDBpRYx+7du5Wenq7Ro0erU6dOGjt2rONvxorq3LmzJHmtSlK0xoMHDyo7O1tt27Z111j4das5c+aoadOm+uKLLzzmyMzMVM2aNf06lQygfBQe552OvXv27An7+934qj83N7fE+/X885//VGxsrDZu3KhbbrlF/fv39zqzEoiUlBTFxsYqIyPD6zGnMSetW7d2vDg7mMfeogoKCpSWlqZq1arp/vvv19/+9jetW7euxNp//etfKyoqyvG+OkeOHHHX+M0336igoECTJ0/26GPbtm3T3r171bRpU/diIoUK35PzF/xA6BAKwsSf/vQnxcfH65ZbbtHRo0e9Hg/kNxYDBgxQfn6+1+o2jz/+uFwul/s7kNWqVVPNmjW1ZcsWj+3KctvxwrmXLFniMV7SsmSFCm9yUvR/8EvSvHlzr9fx7LPPep0pKO38JYmKilKXLl308ccfez02fPhw5efne9zU7MyZM/rrX/+qNm3auH8L88orr3j9GT58uCTphRde0OOPP15sDXl5eUpLS1O9evW0ePFirVq1SkePHtVdd91VYv3XXXedYmJitHLlSo+bAK1YsULSuWXjpHPXPBSt8ZlnnpF0blnAV155xevMxI4dO9StW7cSawBQfrp06aKUlBQ9/fTT+vnnn93jb775pr788ku/VoQLpT59+ig6OlpLlizx6H/PPfeccnJyiq0/IiJCLpfL4/i/f/9+v1cKcpqvT58+Wr9+vcdvwDMyMvy+Rq9bt27Kzs72uhYjmMfeohYuXKitW7fq2Wef1UMPPaTu3btr/PjxJX6fPzExUQMGDNDWrVvdv1yUpC+//FJbt25119iuXTvHPta2bVs1atRIr7zyisaMGeMx944dO+RyuegRYYKvD4WJli1bas2aNRoxYoRatWrlvqOxMUaZmZlas2aNqlSp4njXwKKu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\n" | |
| }, | |
| "metadata": {} | |
| } | |
| ] | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment