Edit 2: Well I’ll be damned. An extremely knowledgeable and kind stranger just reverse-engineered the whole thing and poured it into a python script. And it’s only Monday. See comments for the script.


Edit: Oh wow, this community is already on fire. Thanks for your advice everybody, I didn’t even think of intercepting the downloads in transit! Brilliant.

I will try to see how far I can get there, but that does sound much easier than rummaging around in iOS. Thank you all :)


Hello,

I’m trying to get the downloaded audio out of an iOS app, but I struggle because the information I can find is mostly rather old, needs some additional software I need to pay for, etc. The content is downloaded post installing the app, so simply accessing the IPA doesn’t help.

I have this app called naturespace (see naturespace.org), it’s an app that has really good recordings of rain, thunderstorms, etc. In my opinion those recordings are far better than anything I’ve heard so far.

Now, I did pay for the content, but the app hasn’t been updated for years now, and there’s also been no new content for years as well. I wrote to the owners but didn’t get any response. I guess you could consider it abandoned at this point.

Since I fear that anytime soon the app stops working, I’d like to save that content.

I’m a bit tech savvy, I can work with CLI and such, but I’m not a professional coder or hacker, any help is appreciated.

  • @HiDefMusic@feddit.uk
    link
    fedilink
    English
    6
    edit-2
    2 years ago

    Interesting, looks like they might be using a completely different file format for iOS versus Android. In any case, I’ve knocked up a script which will extract the track.ogg file from any pack of your choosing. Pasting directly here to see if it works (haven’t tried sharing code on Lemmy).

    You can browse available packs using the below URL. If you want to find out a pack name, just copy the banner image URL for it and you’ll see the “com.whatever” name in the URL itself.

    http://www.naturespace.com/android/v3/store/?live=true&udid=0

    Code:

    import sys
    import requests
    import hashlib
    import io
    import zipfile
    
    ns_baseurl = "https://s3.amazonaws.com/naturespace/kindle_catalog/"
    
    # Encryption key
    key = b'DE2#We@(# sffsFSHfssfhsSFHSs_+&Gaa s,W.Z./lSFGSDF! NOWG!fjasdflasdkfjSADFKJASdflskgj fdkaG8HS42dncuFFSe=-56a'
    
    def decryptNS(content):
    	x = 1025
    	y = 0
    	dec = bytearray()
    	for i in range(x,len(content)):
    		if ((i+1024) % 1024) != 0:
    			dec += bytes([content[i] ^ key[y % len(key)]])
    			y = y+1
    
    	return dec
    
    if __name__ == '__main__':
    	if len(sys.argv) < 2:
    		print("Please provide a pack/module name (e.g. 'com.HolographicAudioTheater.Naturespace.TheImaginarium')")
    		sys.exit(0)
    
    	pack = sys.argv[1]
    	json_url = ns_baseurl + pack + "/data.json"
    	size = requests.get(json_url).json()["packageSize"]
    	print(size)
    
    	hashval = hashlib.sha1((pack + "8DvJx25sXwNwq2p" + size).encode()).hexdigest()
    	dlurl = ns_baseurl + pack + "/" + hashval + "/" + pack + ".nzp"
    	print(dlurl)
    
    	content = decryptNS(requests.get(dlurl).content)
    	"""
    	with open(pack + ".zip", "wb") as f:
    		f.write(content)
    	"""
    	zipf = io.BytesIO(content)
    	zipfile = zipfile.ZipFile(zipf, 'r')
    	track_nsp = zipfile.read('track.nsp')
    
    	track_ogg = decryptNS(track_nsp)
    	with open(pack + "_track.ogg", "wb") as f:
    		f.write(track_ogg)
    
    • @quandoquando@slrpnk.netOP
      link
      fedilink
      English
      32 years ago

      :O Wow.

      That is just simply amazing. Can confirm it works.

      The file names are always the same, prefix and the sounds name, e.g. if the sound is called “The Electric Forest” it’s com.HolographicAudioTheater.Naturespace.TheElectricForest.

      I guess I could write a scraper and parse the whole collection.

      Well, thank you kind stranger on the internet.