fix for linux find_elements: SyntaxError: missing ) after argument list

This commit is contained in:
UltrafunkAmsterdam 2023-02-05 18:37:28 +01:00
parent 8baa77352f
commit 305803ca95
2 changed files with 348 additions and 326 deletions

View File

@ -101,6 +101,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
session_id = None
debug = False
def __init__(
self ,
options = None ,
@ -458,10 +459,12 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
if options.headless:
self._configure_headless()
def _configure_headless( self ):
orig_get = self.get
logger.info( "setting properties for headless" )
def get_wrapped( *args , **kwargs ):
if self.execute_script( "return navigator.webdriver" ):
logger.info( "patch navigator.webdriver" )
@ -470,18 +473,18 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
{
"source": """
Object.defineProperty(window, 'navigator', {
Object.defineProperty(window, "navigator", {
Object.defineProperty(window, "navigator", {
value: new Proxy(navigator, {
has: (target, key) => (key === 'webdriver' ? false : key in target),
has: (target, key) => (key === "webdriver" ? false : key in target),
get: (target, key) =>
key === 'webdriver' ?
false :
typeof target[key] === 'function' ?
target[key].bind(target) :
target[key]
})
key === "webdriver"
? false
: typeof target[key] === "function"
? target[key].bind(target)
: target[key],
}),
});
"""
} ,
)
@ -598,8 +601,10 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
)
return orig_get( *args , **kwargs )
self.get = get_wrapped
# def _get_cdc_props(self):
# return self.execute_script(
# """
@ -634,6 +639,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
# self._hook_remove_cdc_props()
return super().get( url )
def add_cdp_listener( self , event_name , callback ):
if (
self.reactor
@ -644,15 +650,18 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
return self.reactor.handlers
return False
def clear_cdp_listeners( self ):
if self.reactor and isinstance( self.reactor , Reactor ):
self.reactor.handlers.clear()
def window_new( self ):
self.execute(
selenium.webdriver.remote.command.Command.NEW_WINDOW , { "type": "window" }
)
def tab_new( self , url: str ):
"""
this opens a url in a new tab.
@ -672,6 +681,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
cdp = CDP( self.options )
cdp.tab_new( url )
def reconnect( self , timeout = 0.1 ):
try:
self.service.stop()
@ -688,6 +698,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
except Exception as e:
logger.debug( e )
def start_session( self , capabilities = None , browser_profile = None ):
if not capabilities:
capabilities = self.options.to_capabilities()
@ -696,6 +707,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
)
# super(Chrome, self).start_session(capabilities, browser_profile)
def quit( self ):
try:
self.service.process.kill()
@ -736,6 +748,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
# this must come last, otherwise it will throw 'in use' errors
self.patcher = None
def __getattribute__( self , item ):
if not super().__getattribute__( "debug" ):
return super().__getattribute__( item )
@ -744,7 +757,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
original = super().__getattribute__( item )
if inspect.ismethod( original ) and not inspect.isclass( original ):
def newfunc( *args , **kwargs ):
logger.debug(
"calling %s with args %s and kwargs %s\n"
@ -752,24 +764,30 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
)
return original( *args , **kwargs )
return newfunc
return original
def __enter__( self ):
return self
def __exit__( self , exc_type , exc_val , exc_tb ):
self.service.stop()
time.sleep( self._delay )
self.service.start()
self.start_session()
def __hash__( self ):
return hash( self.options.debugger_address )
def __dir__( self ):
return object.__dir__( self )
def __del__( self ):
try:
self.service.process.kill()
@ -777,6 +795,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
pass
self.quit()
@classmethod
def _ensure_close( cls , self ):
# needs to be a classmethod so finalize can find the reference

View File

@ -217,46 +217,49 @@ class Patcher(object):
def is_binary_patched(self, executable_path=None):
executable_path = executable_path or self.executable_path
try:
with io.open(executable_path, "rb") as fh:
return fh.read().find(b"undetected chromedriver") != -1
except FileNotFoundError:
return False
def patch_exe(self):
start = time.perf_counter()
logger.info("patching driver executable %s" % self.executable_path)
with io.open(self.executable_path, "r+b") as fh:
content = fh.read()
match_injected_codeblock = re.search(rb"{window.*;}", 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:
logger.warning(
"something went wrong patching the driver binary. could not find injection code block"
)
else:
logger.debug(
"found block:\n%s\nreplacing with:\n%s"
% (target_bytes, new_target_bytes)
)
fh.seek(0)
fh.write(new_content)
#content = fh.read()
#match_injected_codeblock = re.search(rb"{window.*;}", 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:
# logger.warning(
# "something went wrong patching the driver binary. could not find injection code block"
# )
# else:
# logger.debug(
# "found block:\n%s\nreplacing with:\n%s"
# % (target_bytes, new_target_bytes)
# )
# fh.seek(0)
# fh.write(new_content)
# we just keep the cdc variables as they can't be injected anyways so no harm
# keeping for reference
# fh.seek(0)
# for line in iter( lambda: fh.readline() , b"" ):
# if b'cdc_' in line:
# fh.seek( -len( line ) , 1 )
# new_line = re.sub( b"cdc_.{22}_" , self.gen_random_cdc() , line )
# logger.debug( 'replaced %s\n\twith:%s' % (line , new_line) )
# fh.write( new_line )
else:
logger.info("%s seems already patched ?!?!" % self.executable_path)
for line in iter( lambda: fh.readline() , b"" ):
if b'cdc_' in line:
fh.seek( -len( line ) , 1 )
new_line = re.sub( b"cdc_.{22}_" , self.gen_random_cdc() , line )
logger.debug( 'replaced %s\n\twith:%s' % (line , new_line) )
fh.write( new_line )
# else:
# logger.info("%s seems already patched ?!?!" % self.executable_path)
logger.debug(
"patching took us {:.2f} seconds".format(time.perf_counter() - start)
)