Open trueToastedCode opened 1 year ago
It tries to execute x86-64 chromium although its on ARM64
$ file /home/anonymous/.local/share/undetected_chromedriver/2fd8036c81a1359c_chromedriver /home/anonymous/.local/share/undetected_chromedriver/2fd8036c81a1359c_chromedriver: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=5334671b5a2412bfdfe18309fb12af91c933542d, stripped
OK so the problem is, that the google archive does actually only provide x86-64 Linux Chromedriver. The solution is to download a custom one and patch it so it doesn't get detected.
uname -r
> for me 6.0.0-kali3-arm64
chromedriver_...
from https://github.com/electron/electron/releases and extract the chromedriver
nano patch.py
and write the following (its the current chromedriver patching script copy-pasted from this library) and execute it
#!/usr/bin/python
import io
import re
import random
import string
executable_path = './chromedriver'
def random_cdc(): cdc = random.choices(string.asciilowercase, k=26) cdc[-6:-4] = map(str.upper, cdc[-6:-4]) cdc[2] = cdc[0] cdc[3] = "" return "".join(cdc).encode()
def patch_binary(): """ Patches the ChromeDriver binary :return: False on failure, binary name on success """ linect = 0 replacement = random_cdc() with io.open(executablepath, "r+b") as fh: for line in iter(lambda: fh.readline(), b""): if b"cdc" in line: fh.seek(-len(line), 1) newline = re.sub(b"cdc_.{22}", replacement, line) fh.write(newline) linect += 1 return linect
if name == 'main': patch_binary()
5. `chromedriver` is patched now so we can proceed with the library where we just have to define a custom chromedriver... for example
import undetected_chromedriver as uc driver_executable_path = './chromedrive' driver = uc.Chrome(driver_executable_path=driver_executable_path) driver.get("https://www.google.com")
It would be nice if this library would support the chromedriver from electron for Arm64. This platform is actually used by quite a lot of people ... e.g. me who is using a M1 chip with Linux virtual machine or people using a raspberry pi.
I had a similar situation (issue 1109) running on an old pi. Is is possible to set environment variables or a config file that the default parameters when the class is invoked? In my case I am using another project and have to modify that code passing in my executable path and version.
OK so the problem is, that the google archive does actually only provide x86-64 Linux Chromedriver. The solution is to download a custom one and patch it so it doesn't get detected.
uname -r
> for me6.0.0-kali3-arm64
- Download a fitting
chromedriver_...
from https://github.com/electron/electron/releases and extract thechromedriver
nano patch.py
and write the following (its the current chromedriver patching script copy-pasted from this library) and execute it#!/usr/bin/python import io import re import random import string executable_path = './chromedriver' def random_cdc(): cdc = random.choices(string.ascii_lowercase, k=26) cdc[-6:-4] = map(str.upper, cdc[-6:-4]) cdc[2] = cdc[0] cdc[3] = "_" return "".join(cdc).encode() def patch_binary(): """ Patches the ChromeDriver binary :return: False on failure, binary name on success """ linect = 0 replacement = random_cdc() with io.open(executable_path, "r+b") as fh: for line in iter(lambda: fh.readline(), b""): if b"cdc_" in line: fh.seek(-len(line), 1) newline = re.sub(b"cdc_.{22}", replacement, line) fh.write(newline) linect += 1 return linect if __name__ == '__main__': patch_binary()
chromedriver
is patched now so we can proceed with the library where we just have to define a custom chromedriver... for exampleimport undetected_chromedriver as uc driver_executable_path = './chromedrive' driver = uc.Chrome(driver_executable_path=driver_executable_path) driver.get("https://www.google.com")
It would be nice if this library would support the chromedriver from electron for Arm64. This platform is actually used by quite a lot of people ... e.g. me who is using a M1 chip with Linux virtual machine or people using a raspberry pi.
Necessary till this day, here is an update for the latest version:
#!/usr/bin/python
import logging
import time
import re
import io
executable_path = './chromedriver'
def patch_exe():
start = time.perf_counter()
logging.info("patching driver executable %s" % executable_path)
with io.open(executable_path, "r+b") as fh:
content = fh.read()
# match_injected_codeblock = re.search(rb"{window.*;}", content)
match_injected_codeblock = re.search(rb"\{window\.cdc.*?;\}", content)
if match_injected_codeblock:
target_bytes = match_injected_codeblock[0]
new_target_bytes = (
b'{console.log("undetected chromedriver 1337!")}'.ljust(
len(target_bytes), b" "
)
)
new_content = content.replace(target_bytes, new_target_bytes)
if new_content == content:
logging.warning(
"something went wrong patching the driver binary. could not find injection code block"
)
else:
logging.debug(
"found block:\n%s\nreplacing with:\n%s"
% (target_bytes, new_target_bytes)
)
fh.seek(0)
fh.write(new_content)
logging.debug(
"patching took us {:.2f} seconds".format(time.perf_counter() - start)
)
if __name__ == '__main__':
logging.basicConfig(
format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
datefmt='%Y/%d/%m %H:%M:%S',
level=logging.DEBUG,
handlers=[logging.StreamHandler()]
)
patch_exe()
OK so the problem is, that the google archive does actually only provide x86-64 Linux Chromedriver. The solution is to download a custom one and patch it so it doesn't get detected.
uname -r
> for me6.0.0-kali3-arm64
- Download a fitting
chromedriver_...
from https://github.com/electron/electron/releases and extract thechromedriver
nano patch.py
and write the following (its the current chromedriver patching script copy-pasted from this library) and execute it#!/usr/bin/python import io import re import random import string executable_path = './chromedriver' def random_cdc(): cdc = random.choices(string.ascii_lowercase, k=26) cdc[-6:-4] = map(str.upper, cdc[-6:-4]) cdc[2] = cdc[0] cdc[3] = "_" return "".join(cdc).encode() def patch_binary(): """ Patches the ChromeDriver binary :return: False on failure, binary name on success """ linect = 0 replacement = random_cdc() with io.open(executable_path, "r+b") as fh: for line in iter(lambda: fh.readline(), b""): if b"cdc_" in line: fh.seek(-len(line), 1) newline = re.sub(b"cdc_.{22}", replacement, line) fh.write(newline) linect += 1 return linect if __name__ == '__main__': patch_binary()
chromedriver
is patched now so we can proceed with the library where we just have to define a custom chromedriver... for exampleimport undetected_chromedriver as uc driver_executable_path = './chromedrive' driver = uc.Chrome(driver_executable_path=driver_executable_path) driver.get("https://www.google.com")
It would be nice if this library would support the chromedriver from electron for Arm64. This platform is actually used by quite a lot of people ... e.g. me who is using a M1 chip with Linux virtual machine or people using a raspberry pi.
Necessary till this day, here is an update for the latest version:
#!/usr/bin/python import logging import time import re import io executable_path = './chromedriver' def patch_exe(): start = time.perf_counter() logging.info("patching driver executable %s" % executable_path) with io.open(executable_path, "r+b") as fh: content = fh.read() # match_injected_codeblock = re.search(rb"{window.*;}", content) match_injected_codeblock = re.search(rb"\{window\.cdc.*?;\}", content) if match_injected_codeblock: target_bytes = match_injected_codeblock[0] new_target_bytes = ( b'{console.log("undetected chromedriver 1337!")}'.ljust( len(target_bytes), b" " ) ) new_content = content.replace(target_bytes, new_target_bytes) if new_content == content: logging.warning( "something went wrong patching the driver binary. could not find injection code block" ) else: logging.debug( "found block:\n%s\nreplacing with:\n%s" % (target_bytes, new_target_bytes) ) fh.seek(0) fh.write(new_content) logging.debug( "patching took us {:.2f} seconds".format(time.perf_counter() - start) ) if __name__ == '__main__': logging.basicConfig( format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', datefmt='%Y/%d/%m %H:%M:%S', level=logging.DEBUG, handlers=[logging.StreamHandler()] ) patch_exe()
Tried replicating this solution for an M1 Mac (UC 3.5.5) with the following:
import time
import re
import io
from undetected_chromedriver import Chrome
executable_path = "/Users/philipjoss/Downloads/chromedriver-mac-arm64/chromedriver"
def patch_exe():
start = time.perf_counter()
logging.info("patching driver executable %s" % executable_path)
with io.open(executable_path, "r+b") as fh:
content = fh.read()
# match_injected_codeblock = re.search(rb"{window.*;}", content)
match_injected_codeblock = re.search(rb"\{window\.cdc.*?;\}", content)
if match_injected_codeblock:
target_bytes = match_injected_codeblock[0]
new_target_bytes = (
b'{console.log("undetected chromedriver 1337!")}'.ljust(
len(target_bytes), b" "
)
)
new_content = content.replace(target_bytes, new_target_bytes)
if new_content == content:
logging.warning(
"something went wrong patching the driver binary. could not find injection code block"
)
else:
logging.debug(
"found block:\n%s\nreplacing with:\n%s"
% (target_bytes, new_target_bytes)
)
fh.seek(0)
fh.write(new_content)
logging.debug(
"patching took us {:.2f} seconds".format(time.perf_counter() - start)
)
if __name__ == "__main__":
patch_exe()
driver = Chrome(driver_executable_path=executable_path)
driver.get("https://www.google.com")
patch_exe
runs fine and it updates chromedriver however when the script tries to create the driver an error box pops up:
And then the line errors with:
Exception has occurred: WebDriverException
Message: Can not connect to the Service /Users/philipjoss/Downloads/chromedriver-mac-arm64/chromedriver
File "/Users/philipjoss/GitHub/polgara_v2/uc_arm64.py", line 43, in <module>
driver = Chrome(driver_executable_path=executable_path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
selenium.common.exceptions.WebDriverException: Message: Can not connect to the Service /Users/philipjoss/Downloads/chromedriver-mac-arm64/chromedriver
Any ideas on what might be going wrong?
Platform is Debian on ARM64 (using Apple Silicon VM)