Skip to content

Instantly share code, notes, and snippets.

View DavidBuchanan314's full-sized avatar
🌍
Hack the planet!

David Buchanan DavidBuchanan314

🌍
Hack the planet!
View GitHub Profile
@DavidBuchanan314
DavidBuchanan314 / demo.py
Last active December 6, 2024 18:21
magically import magic number constants (edit: moved to github https://github.com/DavidBuchanan314/magic-numbers (and pypi(!)))
from magic_numbers import FORTY_TWO, SIXTY_NINE, FOUR_HUNDRED_AND_TWENTY
from magic_numbers import ONE_THOUSAND_THREE_HUNDRED_AND_TWELVE
print(f"{FORTY_TWO = }")
print(f"{SIXTY_NINE = }")
print(f"{FOUR_HUNDRED_AND_TWENTY = }")
print(f"{ONE_THOUSAND_THREE_HUNDRED_AND_TWELVE = }")
# https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md
import re
import base64
PHC_STRING_RE = re.compile(r"""
\$(?P<id>[a-z0-9-]{1,32})
(\$v=(?P<version>[0-9]+))?
(\$(?P<params>[a-z0-9-]{1,32}=[a-zA-Z0-9/+.-=,]*))? # NOTE: full param parse happens later, this just checks at least one param exists
(
[
(try_except := (lambda fn, exception_callback:
type("mycontext", (__import__("contextlib").ContextDecorator,), {
"__enter__": lambda self: self,
"__exit__": lambda self, a, b, c: (a and exception_callback(a, b, c)) or True
})()(fn)()
)),
(throw := lambda e:
(_ for _ in ()).throw(e)
(
solve := lambda data: sum(
abs(a - b) for a, b in
zip(*map(sorted,zip(*(
map(int, line.split())
for line in data.split("\n")
))))
),
example := """\
@DavidBuchanan314
DavidBuchanan314 / arch-chroot-kindle.sh
Created November 23, 2024 19:24
arch-chroot from the arch-install-scripts package, hacked up to work from a kindle
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
shopt -s extglob
unshare=0
keepresolvconf=0
#!/hint/bash
# SPDX-License-Identifier: GPL-2.0-only
@DavidBuchanan314
DavidBuchanan314 / notes.md
Last active August 27, 2024 03:00
JNIC Reversing Notes https://jnic.dev/

I looked at a JAR file protected using JNIC, version jnic.dev v3.6.0. I haven't written a full-auto deobfuscater yet, but these notes should be useful for anyone reversing it.

The first layer is a LZMA2 compressed .dat file, from which a native library is extracted into a temp dir, and then loaded using System.load.

The sample I looked at had 4 different library versions (for different platforms/architectures), and the script I wrote to extract them looks like this:

import lzma

# from JNICLoader.java
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
KEY = bytes.fromhex("5c0e349a27dc46034c7b6744a378bd17")
IV = bytes.fromhex("a0b0924686447109f2d51dcddc93458a")
img = open("gz_a.bin", "rb")
img.seek(4)
length = int.from_bytes(img.read(4), "little")
img.seek(0x34)
offset = int.from_bytes(img.read(4), "little")
@DavidBuchanan314
DavidBuchanan314 / r1_apk_changelog.md
Last active November 24, 2024 06:08
Unofficial RabbitLauncher.apk changelog

Unofficial Rabbit R1 APK Changelog

Executive Summary

The APK is stored in the firmware system partition, and gets updated as a side-effect of OTA firmware updates. Thus, a certain OS version implies a particular APK version. The OS version numbers are more compact, so I'll use them to identify APK versions below.

v0.8.50 seems like a pre-prod version that accidentally got shipped on some early devices. Like all future versions, it sends the device's IMEI during account activation.

v0.8.67 is the "launch day" firmware. It sets the OS-Version and App-Version HTTP headers. It also sends the device's IMEI during authentication.

@DavidBuchanan314
DavidBuchanan314 / r1_notes.md
Last active November 24, 2024 06:08
Collecting my various Rabbit R1 RE notes in one place.