- inject_gta_city.py: Full GTA-style city with 20 buildings, roads, cars, street lights, traffic lights, trees, 15 human enemies with varied skin/clothing, and 10 COD weapons with visible gun models - inject_bg.py: Background injection using SendMessage/PostMessage Win32 API - inject_bg2.py: PostMessage approach targeting main window for WPF apps - inject_cod_final.py: Working COD game injection (7-step sequential) - cod_inject.py: Combined COD game builder with proper Studio launch - roblox-fps-p1-p6: Split Lua scripts for multi-part injection Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
104 lines
3.9 KiB
Python
104 lines
3.9 KiB
Python
"""
|
|
Background injection v2 - PostMessage to main window.
|
|
Roblox Studio uses WPF (no standard child controls).
|
|
We send keystrokes via PostMessage to the main window handle.
|
|
This works even when Studio is minimized or behind other windows.
|
|
"""
|
|
import ctypes, ctypes.wintypes, subprocess, time, sys, os
|
|
|
|
user32 = ctypes.windll.user32
|
|
WM_KEYDOWN = 0x0100
|
|
WM_KEYUP = 0x0101
|
|
WM_CHAR = 0x0102
|
|
WM_PASTE = 0x0302
|
|
|
|
def find_studio():
|
|
target = [None]
|
|
def cb(hwnd, _):
|
|
l = user32.GetWindowTextLengthW(hwnd)
|
|
if l > 0:
|
|
buf = ctypes.create_unicode_buffer(l + 1)
|
|
user32.GetWindowTextW(hwnd, buf, l + 1)
|
|
if "Roblox Studio" in buf.value:
|
|
target[0] = hwnd
|
|
return False
|
|
return True
|
|
WNDENUMPROC = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.wintypes.HWND, ctypes.wintypes.LPARAM)
|
|
user32.EnumWindows(WNDENUMPROC(cb), 0)
|
|
return target[0]
|
|
|
|
def post_key(hwnd, vk, shift=False, ctrl=False):
|
|
"""Send a key press/release via PostMessage to background window."""
|
|
if ctrl:
|
|
user32.PostMessageW(hwnd, WM_KEYDOWN, 0x11, 0)
|
|
if shift:
|
|
user32.PostMessageW(hwnd, WM_KEYDOWN, 0x10, 0)
|
|
# Key down
|
|
scan = ctypes.windll.user32.MapVirtualKeyW(vk, 0)
|
|
lparam_down = (scan << 16) | 1
|
|
user32.PostMessageW(hwnd, WM_KEYDOWN, vk, lparam_down)
|
|
time.sleep(0.01)
|
|
# Key up
|
|
lparam_up = (scan << 16) | 1 | (1 << 30) | (1 << 31)
|
|
user32.PostMessageW(hwnd, WM_KEYUP, vk, lparam_up)
|
|
time.sleep(0.01)
|
|
if ctrl:
|
|
user32.PostMessageW(hwnd, WM_KEYUP, 0x11, 0)
|
|
if shift:
|
|
user32.PostMessageW(hwnd, WM_KEYUP, 0x10, 0)
|
|
|
|
def paste_and_run(hwnd, code):
|
|
"""Copy code to clipboard, then send Ctrl+A, Ctrl+V, Enter via PostMessage."""
|
|
tmp = os.path.join(os.environ["TEMP"], "rbx.lua")
|
|
with open(tmp, "w", encoding="utf-8") as f:
|
|
f.write(code)
|
|
subprocess.run(["powershell", "-Command", f"Get-Content '{tmp}' -Raw | Set-Clipboard"],
|
|
capture_output=True, timeout=10)
|
|
time.sleep(0.3)
|
|
|
|
# Select all: Ctrl+A
|
|
user32.PostMessageW(hwnd, WM_KEYDOWN, 0x11, 0) # Ctrl down
|
|
time.sleep(0.02)
|
|
scan_a = user32.MapVirtualKeyW(0x41, 0)
|
|
user32.PostMessageW(hwnd, WM_KEYDOWN, 0x41, (scan_a << 16) | 1)
|
|
time.sleep(0.02)
|
|
user32.PostMessageW(hwnd, WM_KEYUP, 0x41, (scan_a << 16) | 1 | (1 << 30) | (1 << 31))
|
|
time.sleep(0.02)
|
|
user32.PostMessageW(hwnd, WM_KEYUP, 0x11, 0) # Ctrl up
|
|
time.sleep(0.1)
|
|
|
|
# Paste: Ctrl+V
|
|
user32.PostMessageW(hwnd, WM_KEYDOWN, 0x11, 0)
|
|
time.sleep(0.02)
|
|
scan_v = user32.MapVirtualKeyW(0x56, 0)
|
|
user32.PostMessageW(hwnd, WM_KEYDOWN, 0x56, (scan_v << 16) | 1)
|
|
time.sleep(0.02)
|
|
user32.PostMessageW(hwnd, WM_KEYUP, 0x56, (scan_v << 16) | 1 | (1 << 30) | (1 << 31))
|
|
time.sleep(0.02)
|
|
user32.PostMessageW(hwnd, WM_KEYUP, 0x11, 0)
|
|
time.sleep(0.8)
|
|
|
|
# Enter to execute
|
|
scan_enter = user32.MapVirtualKeyW(0x0D, 0)
|
|
user32.PostMessageW(hwnd, WM_KEYDOWN, 0x0D, (scan_enter << 16) | 1)
|
|
time.sleep(0.02)
|
|
user32.PostMessageW(hwnd, WM_KEYUP, 0x0D, (scan_enter << 16) | 1 | (1 << 30) | (1 << 31))
|
|
time.sleep(2)
|
|
|
|
# ═══════════════════════════════════════
|
|
hwnd = find_studio()
|
|
if not hwnd:
|
|
print("ERROR: Roblox Studio not found!")
|
|
sys.exit(1)
|
|
|
|
print(f"Studio: {hwnd}")
|
|
state = "minimized" if user32.IsIconic(hwnd) else ("background" if user32.GetForegroundWindow() != hwnd else "foreground")
|
|
print(f"Window state: {state}")
|
|
|
|
# Test with simple code
|
|
print("\nTest: sending print('BG_TEST_OK') via PostMessage...")
|
|
paste_and_run(hwnd, """print("BG_TEST_OK - BACKGROUND INJECTION WORKS!")""")
|
|
print("Sent! Check Studio Output window (F9) for the message.")
|
|
print("\nNOTE: If nothing appeared, the command bar needs focus first.")
|
|
print("Alternative: bring Studio to front briefly, inject, then let it go to background.")
|