From 031e274b8178896b8f847aad0701b5e2700c527f Mon Sep 17 00:00:00 2001
From: jooapa <jooa.akonpelto@gmail.com>
Date: Sat, 3 Feb 2024 23:14:10 +0200
Subject: [PATCH] Refactor decrypting logic and improve file handling, can
decrypt whole folders
---
README.md | 6 ++-
birdout.py | 141 +++++++++++++++++++++++++++++++++--------------------
2 files changed, 93 insertions(+), 54 deletions(-)
diff --git a/README.md b/README.md
index 3e2974b..0bb45fe 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
If you don't know how to install Angry Birds PC ports, [here](https://archive.org/details/angry-birds-pc) is a link to the Internet Archive page for the PC ports of Angry Birds.
-### Automatic Usage (only for decrypting)
+### Automatic decrypting
Firstly install [Python 3](https://www.python.org/downloads/).
@@ -15,6 +15,10 @@ or you can run it in the terminal with:
python birdout.py <file.lua> <file.lua> ...
+passing only a folder will decrypt all .lua files in the directory.
+
+ python birdout.py <directory>
+
Understandable, if you don't trust the .exe or the .jar file: openssl.exe. here is a virustotal scan: [virustotal](https://www.virustotal.com/gui/file/be0f086b9303fd52b6f5ec094c753c2b68f02559eb462f23929e72a6996eb1f8/detection/f-be0f086b9303fd52b6f5ec094c753c2b68f02559eb462f23929e72a6996eb1f8-1703249224)
and here scan for the unluac.jar: [virustotal](https://www.virustotal.com/gui/file/50f23c0b1cb85cc2bd07055ce782a918fdcb5d36d18d268b9606298d801bbb6e/detection/f-50f23c0b1cb85cc2bd07055ce782a918fdcb5d36d18d268b9606298d801bbb6e-1689512688)
diff --git a/birdout.py b/birdout.py
index 8494ded..94895a0 100644
--- a/birdout.py
+++ b/birdout.py
@@ -1,15 +1,49 @@
import os, sys, subprocess
import py7zr
-if len(sys.argv) == 0:
+files = sys.argv[1:]
+# counting the number of directories
+
+org_path = os.path.dirname(os.path.realpath(__file__))
+# get directory of first file
+path_to_go = os.path.dirname(files[0])
+
+if len(files) == 0:
print("Usage: birdout.py <file.lua> <file.lua> ...")
+ print("You can also pass a directory as an argument to decrypt all .lua files in it.")
sys.exit(1)
+
-for file in sys.argv[1:]:
+for file in files:
+ # if directory
+ if os.path.isdir(file):
+ # loop through all files in directory and if extension is .lua, add to list
+ for root, dirs, files in os.walk(file):
+ for file in files:
+ if file.endswith(".lua"):
+ file = os.path.join(root, file)
+ print("File: " + file)
+
if not os.path.isfile(file):
print("File not found: " + file)
- sys.exit(1)
+ # remove file from list
+ files.remove(file)
+
+if len(files) == 0:
+ print("No valid files found!")
+ sys.exit(1)
+
+# go to directory of first file
+os.chdir(path_to_go)
+# remove the path from files
+files = [os.path.basename(file) for file in files]
+
+print("\nAngry Birds Lua Decryptor, works on for decrypting Angry Birds Lua files.")
+print("For Encrypting Luad files back, Chech README.md")
+print("nöf nöf!")
+print("\nDecrypting files: " + str(files))
+
inp = input('''
CHOOSE Angry Birds Game:
1. Angry Birds
@@ -21,64 +55,65 @@
''')
if inp == '1': # Angry Birds
- hex = "55534361505170413454534E56784D49317639534B39554330795A75416E6232"
+ hex = "55534361505170413454534E56784D49317639534B39554330795A75416E6232"
elif inp == '2': # Angry Birds Rio
- hex = "55534361505170413454534E56784D49317639534B39554330795A75416E6232"
+ hex = "55534361505170413454534E56784D49317639534B39554330795A75416E6232"
elif inp == '3': # Angry Birds Seasons
- hex = "7A65506865737435666151755832533241707265403472654368417445765574"
+ hex = "7A65506865737435666151755832533241707265403472654368417445765574"
elif inp == '4': # Angry Birds Space
- hex = "526D67645A304A656E4C466757776B5976434C326C5361684662456846656334"
+ hex = "526D67645A304A656E4C466757776B5976434C326C5361684662456846656334"
elif inp == '5': # Angry Birds Star Wars
- hex = "416E3874336D6E38553673706951307A4848723361316C6F44725261336D7445"
+ hex = "416E3874336D6E38553673706951307A4848723361316C6F44725261336D7445"
elif inp == '6': # Angry Birds Star Wars II
- hex = "4230706D3354416C7A6B4E3967687A6F65324E697A456C6C50644E3068516E69"
-
+ hex = "4230706D3354416C7A6B4E3967687A6F65324E697A456C6C50644E3068516E69"
+else:
+ print("Invalid input! nöf nöf!")
+ sys.exit(1)
def extract_7z(archive_path, extract_path):
- with py7zr.SevenZipFile(archive_path, mode='r') as archive:
- archive.extractall(extract_path)
-
-def encrypt_file(hex, file, output_file):
- if os.path.isfile(file):
- # if windows
- if os.name == 'nt':
- print("Encrypting " + file + "...")
- subprocess.call(["bin/openssl.exe", "enc", "-aes-256-cbc", "-d", "-K", hex, "-iv", "0", "-in", file, "-out", output_file])
- extract_7z(output_file, extract_path)
- os.remove(output_file)
- os.remove(file)
- # run java -jar bin/unluac.jar out/<file> > out/<file>.lua
- subprocess.call(["java", "-jar", "bin/unluac.jar", "out/" + file], stdout=open("out/" + file + ".decypt", "w"))
- # move decrypted file to root
- os.rename("out/" + file + ".decypt", file)
- # remove out folder and its contents
- os.remove("out/" + file)
- os.rmdir("out")
-
- print("Done!")
- # if linux use wine
- elif os.name == 'posix':
- print("Encrypting " + file + "...")
- subprocess.call(["wine", "bin/openssl.exe", "enc", "-aes-256-cbc", "-d", "-K", hex, "-iv", "0", "-in", file, "-out", output_file])
- extract_7z(output_file, extract_path)
- os.remove(output_file)
- os.remove(file)
- # run java -jar bin/unluac.jar out/<file> > out/<file>.lua
- subprocess.call(["java", "-jar", "bin/unluac.jar", "out/" + file], stdout=open("out/" + file + ".decypt", "w"))
- # move decrypted file to root
- os.rename("out/" + file + ".decypt", file)
- # remove out folder and its contents
- os.remove("out/" + file)
- os.rmdir("out")
-
- print("Done!")
- else:
- print("File not found!")
-
-output_file = file + ".7z"
+ print("Extracting " + archive_path + "...")
+ try:
+ with py7zr.SevenZipFile(archive_path, mode='r') as archive:
+ archive.extractall(extract_path)
+ except py7zr.exceptions.Bad7zFile:
+ print("Error: Not a 7z archive! File might be corrupted somehow or it already has been decrypted.")
+ os.remove(archive_path)
+ sys.exit(1)
+
+def decrypt_file(hex, file):
+ print("Decrypting " + file + "...")
+ output_file = file + ".7z"
+
+ combined_path = os.path.join(org_path, "bin/openssl")
+ if os.name == 'nt':
+ decryption_result = subprocess.run([combined_path, "enc", "-aes-256-cbc", "-d", "-K", hex, "-iv", "0", "-in", file, "-out", output_file], capture_output=True)
+ elif os.name == 'posix':
+ decryption_result = subprocess.run(["wine", combined_path, "enc", "-aes-256-cbc", "-d", "-K", hex, "-iv", "0", "-in", file, "-out", output_file], capture_output=True)
+
+ if decryption_result.returncode != 0:
+ print("You might have entered the wrong game file or the file is corrupted. Decrypting failed! nöf nöf!")
+ os.remove(file + ".7z")
+ sys.exit(1)
+
+ extract_7z(output_file, extract_path)
+ os.remove(output_file)
+ os.remove(file)
+ # run java -jar bin/unluac.jar out/<file> > out/<file>.lua
+ combined_jar_path = os.path.join(org_path, "bin/unluac.jar")
+ # subprocess.call(["java", "-jar", "bin/unluac.jar", "out/" + file], stdout=open("out/" + file + ".decrypt", "w"))
+ subprocess.call(["java", "-jar", combined_jar_path, "out/" + file], stdout=open("out/" + file + ".decrypt", "w"))
+ # move decrypted file to root
+ os.rename("out/" + file + ".decrypt", file)
+ # remove out folder and its contents
+ os.remove("out/" + file)
+ os.rmdir("out")
+
+ print("Done!", file + " decrypted!")
+
extract_path = "out"
# for loop encrypts all files passed as arguments
-for file in sys.argv[1:]:
- encrypt_file(hex, file, output_file)
+for file in files:
+ decrypt_file(hex, file)
+print("nöf nöf!")