Skip to content

Commit 51c25dd

Browse files
committed
Updating files for the future addition of the kitsune_handler.py file.
1 parent d418c6b commit 51c25dd

5 files changed

Lines changed: 195 additions & 207 deletions

File tree

config_handler.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
11
def modify_config_file(config_path, setting, new_value):
2-
"""Modifies a setting in the BlueStacks configuration file.
3-
4-
Args:
5-
config_path: The full path to the bluestacks.conf file.
6-
setting: The name of the setting to modify (e.g., "bst.feature.rooting").
7-
new_value: The new value for the setting (e.g., "1" or "0").
8-
"""
2+
"""Modifies a setting in bluestacks.conf."""
3+
changed = False
94
try:
105
with open(config_path, "r") as f:
116
lines = f.readlines()
127

138
with open(config_path, "w") as f:
149
for line in lines:
15-
if line.startswith(setting + "="):
10+
if line.startswith(f"{setting}="):
1611
f.write(f"{setting}=\"{new_value}\"\n")
12+
changed = True
1713
else:
1814
f.write(line)
15+
16+
if changed:
17+
print(f"Successfully updated '{setting}' to '{new_value}' in {config_path}")
18+
else:
19+
print(f"No changes made for '{setting}' in {config_path}")
1920
except FileNotFoundError:
20-
print(f"Error: Configuration file not found at {config_path}")
21+
print(f"Error: File not found at {config_path}")
2122
except Exception as e:
22-
print(f"Error modifying configuration file: {e}")
23+
print(f"Error modifying configuration: {e}")
24+
2325

2426
def is_root_enabled(config_path, instance_name):
25-
"""Checks if root access is enabled for a specific instance in the configuration file."""
27+
"""Checks if root access is enabled for a specific instance."""
2628
try:
2729
with open(config_path, "r") as f:
2830
for line in f:
2931
if line.startswith(f"bst.instance.{instance_name}.enable_root_access="):
3032
return line.strip().endswith("=\"1\"")
31-
return False # Default to False if the setting is not found
33+
return False
3234
except FileNotFoundError:
33-
print(f"Error: Configuration file not found at {config_path}")
35+
print(f"Error: File not found at {config_path}")
3436
return False
3537
except Exception as e:
36-
print(f"Error reading configuration file: {e}")
38+
print(f"Error reading configuration: {e}")
3739
return False

instance_handler.py

Lines changed: 37 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,64 @@
11
import os
2-
import glob # Import the glob module
2+
import glob
33

44
def modify_instance_files(instance_path, file_names, new_type):
5-
"""Modifies the type of specified files within an instance's .bstk files.
6-
7-
Directly replaces "Readonly" and "Normal" strings to toggle R/W status.
8-
9-
Args:
10-
instance_path: The path to the instance directory (e.g., ...\Engine\Rvc64).
11-
file_names: A list of file names to modify (e.g., ["fastboot.vdi", "Root.vhd"]).
12-
new_type: The new type to set (e.g., "Normal" or "Readonly").
13-
"""
5+
"""Modifies file types in .bstk files to toggle R/W status, and logs changes in detail."""
146
bstk_files = ["Android.bstk.in"]
7+
instance_bstk = glob.glob(os.path.join(instance_path, "*.bstk"))
158

16-
# Find the instance-specific .bstk file
17-
instance_bstk_files = glob.glob(os.path.join(instance_path, "*.bstk"))
18-
if instance_bstk_files:
19-
bstk_files.append(os.path.basename(instance_bstk_files[0]))
20-
else:
21-
print(f"Error: No instance-specific .bstk file found in {instance_path}")
9+
if not instance_bstk:
10+
print(f"Error: No .bstk file found in {instance_path}")
2211
return
2312

24-
for bstk_file_name in bstk_files:
25-
bstk_file_path = os.path.join(instance_path, bstk_file_name)
13+
bstk_files.append(os.path.basename(instance_bstk[0]))
14+
15+
for bstk_file in bstk_files:
16+
bstk_path = os.path.join(instance_path, bstk_file)
17+
changed_entries = [] # Store (filename, old_value, new_value)
2618

2719
try:
28-
with open(bstk_file_path, "r") as file:
29-
content = file.readlines()
20+
with open(bstk_path, "r") as f:
21+
content = f.readlines()
3022

31-
modified = False
32-
with open(bstk_file_path, "w") as file:
23+
with open(bstk_path, "w") as f:
3324
for line in content:
34-
# Check if any of the file_names are in the current line
35-
if any(file_name in line for file_name in file_names):
36-
# Replace "Readonly" or "Normal" with the new_type
25+
# Check if any target file_name is mentioned in this line
26+
matched_file_name = next((fn for fn in file_names if fn in line), None)
27+
if matched_file_name:
3728
if "Readonly" in line:
29+
old_value = "Readonly"
3830
line = line.replace("Readonly", new_type)
39-
modified = True
31+
changed_entries.append((matched_file_name, old_value, new_type))
4032
elif "Normal" in line:
33+
old_value = "Normal"
4134
line = line.replace("Normal", new_type)
42-
modified = True
43-
file.write(line)
35+
changed_entries.append((matched_file_name, old_value, new_type))
36+
f.write(line)
4437

45-
if modified:
46-
print(f"Modified file: {bstk_file_path}")
38+
if changed_entries:
39+
for (file_name, old_val, new_val) in changed_entries:
40+
print(f"Successfully updated '{file_name}' from '{old_val}' to '{new_val}' in {bstk_path}")
4741
else:
48-
print(f"No changes made to file: {bstk_file_path}")
42+
print(f"No changes made in {bstk_path}")
4943

5044
except FileNotFoundError:
51-
print(f"Error: Instance file not found at {bstk_file_path}")
45+
print(f"Error: File not found at {bstk_path}")
5246
except Exception as e:
53-
print(f"Error modifying instance file: {e}")
54-
55-
def is_instance_readonly(instance_path):
56-
"""Checks if the instance files are set to Readonly.
57-
58-
Args:
59-
instance_path: The path to the instance directory.
60-
61-
Returns:
62-
True if any line in the instance files contains "Readonly", False otherwise.
63-
"""
64-
for bstk_file_name in ["Android.bstk.in", f"{os.path.basename(instance_path)}.bstk"]:
65-
bstk_file_path = os.path.join(instance_path, bstk_file_name)
47+
print(f"Error modifying file: {e}")
6648

49+
def is_instance_readonly(instance_path):
50+
"""Checks if instance files are set to 'Readonly'."""
51+
for bstk_file in ["Android.bstk.in", f"{os.path.basename(instance_path)}.bstk"]:
52+
bstk_path = os.path.join(instance_path, bstk_file)
6753
try:
68-
with open(bstk_file_path, "r") as file:
69-
for line in file:
54+
with open(bstk_path, "r") as f:
55+
for line in f:
7056
if "Readonly" in line:
71-
return True # Found "Readonly" in a line
72-
return False # Did not find "Readonly" in any line
57+
return True
58+
return False
7359
except FileNotFoundError:
74-
print(f"Error: Instance file not found at {bstk_file_path}")
60+
print(f"Error: File not found at {bstk_path}")
7561
return False
7662
except Exception as e:
77-
print(f"Error reading instance file: {e}")
63+
print(f"Error reading file: {e}")
7864
return False

kitsune_handler.py

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,78 @@
1+
import os
12
import subprocess
23
import time
4+
import requests # Requires: pip install requests
35

4-
def install_and_configure_kitsune(apk_path, instance_name):
5-
"""Attempts to install Kitsune Mask and perform the initial configuration.
6-
HIGHLY CONCEPTUAL - Requires significant research and adaptation.
6+
def download_latest_kitsune_apk(download_url, save_path="kitsune_mask_latest.apk"):
7+
"""Downloads the latest Kitsune Mask APK to the specified path."""
8+
try:
9+
print("Downloading Kitsune Mask APK...")
10+
response = requests.get(download_url, stream=True)
11+
response.raise_for_status()
12+
with open(save_path, "wb") as f:
13+
for chunk in response.iter_content(chunk_size=8192):
14+
if chunk:
15+
f.write(chunk)
16+
print(f"Download complete: {save_path}")
17+
return save_path
18+
except Exception as e:
19+
print(f"Error downloading Kitsune Mask APK: {e}")
20+
return None
721

8-
Args:
9-
apk_path: Path to the Kitsune Mask APK.
10-
instance_name: The name of the BlueStacks instance.
22+
def toggle_adb_on_instance(instance_name):
23+
"""
24+
Enables or toggles ADB on the specified BlueStacks instance.
25+
Placeholder function: Replace with actual commands or APIs that
26+
enable ADB on the given instance.
1127
"""
1228
try:
13-
# 1. Install the APK using ADB
14-
adb_command = f"adb -s {instance_name} install {apk_path}"
15-
subprocess.run(adb_command, shell=True, check=True)
16-
17-
# 2. Launch Kitsune Mask (you need to find the correct package and activity name)
18-
adb_command = f"adb -s {instance_name} shell monkey -p com.example.kitsune 1" # Replace com.example.kitsune
19-
subprocess.run(adb_command, shell=True, check=True)
20-
21-
time.sleep(5) # Wait for the app to launch
22-
23-
# 3. Simulate UI interactions using ADB shell input (VERY brittle)
24-
# You'll need to use 'adb shell input tap X Y' commands, where X and Y
25-
# are coordinates on the screen. These coordinates will be VERY specific to
26-
# the device/resolution and will likely break easily.
27-
#
28-
# This sequence is EXTREMELY hypothetical and needs to be replaced with real
29-
# coordinates captured from a running emulator.
30-
adb_command = f"adb -s {instance_name} shell input tap 100 200" # Tap "Install" (example)
31-
subprocess.run(adb_command, shell=True, check=True)
29+
# Example placeholder command:
30+
# Some setups might allow something like:
31+
# subprocess.run(["HD-Adb", "shell"], check=True)
32+
# or "HD-ConfigHttpProxy.exe adb on" (depending on your BlueStacks version)
33+
# The following is just a conceptual echo command:
34+
print(f"Toggling ADB on instance: {instance_name} (placeholder)")
35+
# Actual logic needed here...
36+
except Exception as e:
37+
print(f"Error toggling ADB on {instance_name}: {e}")
38+
39+
def install_and_configure_kitsune(apk_path, instance_name):
40+
"""Attempts to install Kitsune Mask and perform initial configuration."""
41+
try:
42+
# 1. Install APK
43+
print("Installing Kitsune Mask...")
44+
install_cmd = f"adb -s {instance_name} install {apk_path}"
45+
subprocess.run(install_cmd, shell=True, check=True)
46+
47+
# 2. Launch Kitsune Mask (placeholder package name)
48+
print("Launching Kitsune Mask...")
49+
launch_cmd = f"adb -s {instance_name} shell monkey -p com.example.kitsune 1"
50+
subprocess.run(launch_cmd, shell=True, check=True)
51+
time.sleep(5)
52+
53+
# 3. Simulate UI actions (very approximate)
54+
print("Performing UI actions in Kitsune Mask...")
55+
tap_install = f"adb -s {instance_name} shell input tap 100 200"
56+
subprocess.run(tap_install, shell=True, check=True)
3257
time.sleep(2)
33-
adb_command = f"adb -s {instance_name} shell input tap 300 400" # Tap "Direct Install to System" (example)
34-
subprocess.run(adb_command, shell=True, check=True)
35-
time.sleep(10) # Wait for installation
58+
tap_direct_install = f"adb -s {instance_name} shell input tap 300 400"
59+
subprocess.run(tap_direct_install, shell=True, check=True)
60+
time.sleep(10)
3661

62+
print("Kitsune Mask configuration steps attempted.")
3763
except Exception as e:
38-
print(f"Error automating Kitsune Mask: {e}")
64+
print(f"Error automating Kitsune Mask: {e}")
65+
66+
if __name__ == "__main__":
67+
# Example usage (replace URL and instance_name with real values)
68+
# 1. Download the APK
69+
url = "https://example.com/kitsune_mask_latest.apk" # Placeholder URL
70+
apk_path = download_latest_kitsune_apk(url)
71+
72+
if apk_path:
73+
# 2. Toggle/Enable ADB on the desired instance
74+
instance_name = "emulator-5554" # Example device name
75+
toggle_adb_on_instance(instance_name)
76+
77+
# 3. Install and configure Kitsune Mask
78+
install_and_configure_kitsune(apk_path, instance_name)

0 commit comments

Comments
 (0)