""" Launch Remcos with SSL_CERT_FILE + apply IAT patches. Run WHILE server_only.py is running in another terminal. """ import ctypes, ctypes.wintypes as wt, struct, subprocess, os, sys, time PROCESS_ALL_ACCESS = 0x1F0FFF PAGE_EXECUTE_READWRITE = 0x40 MEM_COMMIT, MEM_RESERVE = 0x1000, 0x2000 UNPACK_ADDR, UNPACK_SIG = 0x8EEED8, b'\x55\x8b\xec\x6a' kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) OpenProcess = kernel32.OpenProcess; OpenProcess.restype = wt.HANDLE ReadProcessMemory = kernel32.ReadProcessMemory; ReadProcessMemory.restype = wt.BOOL WriteProcessMemory = kernel32.WriteProcessMemory; WriteProcessMemory.restype = wt.BOOL VirtualAllocEx = kernel32.VirtualAllocEx; VirtualAllocEx.restype = wt.LPVOID VirtualProtectEx = kernel32.VirtualProtectEx; VirtualProtectEx.restype = wt.BOOL CloseHandle = kernel32.CloseHandle def read_mem(h, addr, sz): buf = ctypes.create_string_buffer(sz); n = ctypes.c_size_t(0) return buf.raw[:n.value] if ReadProcessMemory(h, addr, buf, sz, ctypes.byref(n)) else None def write_mem(h, addr, data): old = wt.DWORD(0) VirtualProtectEx(h, addr, len(data), PAGE_EXECUTE_READWRITE, ctypes.byref(old)) n = ctypes.c_size_t(0); buf = ctypes.create_string_buffer(data) ok = WriteProcessMemory(h, addr, buf, len(data), ctypes.byref(n)) VirtualProtectEx(h, addr, len(data), old.value, ctypes.byref(old)) return ok and n.value == len(data) def main(): d = os.path.dirname(os.path.abspath(__file__)) exe = os.path.join(d, "Remcos v7.2.2 Pro.exe") # Set SSL env ca = os.path.join(d, "certs", "ca_bundle.pem") if os.path.exists(ca): os.environ["SSL_CERT_FILE"] = ca os.environ["SSL_CERT_DIR"] = os.path.join(d, "certs") print(f"[+] SSL_CERT_FILE={ca}") # Kill old subprocess.run(['taskkill', '/F', '/IM', 'Remcos v7.2.2 Pro.exe'], capture_output=True) time.sleep(1) # Launch proc = subprocess.Popen([exe], cwd=d) pid = proc.pid; print(f"[+] PID {pid}") h = None for _ in range(30): h = OpenProcess(PROCESS_ALL_ACCESS, False, pid) if h: break time.sleep(0.1) if not h: print("[-] Can't open"); return # Wait unpack print("[*] Waiting for unpack...") t0 = time.time() while time.time() - t0 < 45: if proc.poll() is not None: print("[-] Exited early"); CloseHandle(h); return if read_mem(h, UNPACK_ADDR, 4) == UNPACK_SIG: break time.sleep(0.05) else: print("[-] Timeout"); CloseHandle(h); return print(f"[+] Unpacked {time.time()-t0:.1f}s"); time.sleep(0.2) # Stubs page = VirtualAllocEx(h, None, 4096, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE) stub = bytearray(32) stub[0x00] = 0xC3 # ret stub[0x04:0x07] = b'\xC2\x04\x00' # ret 4 stub[0x08:0x10] = b'\xB8\x01\x00\x00\x00\xC2\x18\x00' # CryptVerify -> TRUE write_mem(h, page, bytes(stub)) # Exit hooks for addr, off, name in [(0x9DF18C,0,"Halt"),(0x4C36428,4,"PostQuitMessage"), (0xA1007C,4,"ExitProcess1"),(0x4C36590,4,"ExitProcess2"),(0x4C36AE8,4,"ExitProcess3")]: write_mem(h, addr, struct.pack('