refs #1226 finish and refactor RegistryLib
parent
1332b0b8bc
commit
7dccc621cb
|
@ -17,11 +17,18 @@ import SystemLib
|
||||||
import FileLib
|
import FileLib
|
||||||
|
|
||||||
# Función ficticia para lanzar chntpw con timeout de 5 s., evitando cuelgues del programa.
|
# Función ficticia para lanzar chntpw con timeout de 5 s., evitando cuelgues del programa.
|
||||||
def chntpw (file, input):
|
chntpw_exe = shutil.which ('drbl-chntpw') or shutil.which ('chntpw')
|
||||||
exe = shutil.which ('drbl-chntpw') or shutil.which ('chntpw')
|
def chntpw (hivefile, input_file):
|
||||||
|
return subprocess.run ([chntpw_exe, '-e', hivefile], timeout=5, input=open(input_file, 'r'), capture_output=True, text=True).stdout
|
||||||
return subprocess.run ([exe, '-e', file], timeout=5, input=input, capture_output=True, text=True).stdout
|
|
||||||
|
|
||||||
|
## en el codigo bash aparecen "${3%\\*}" y "${3##*\\}" varias veces
|
||||||
|
## ${3%\\*} es el "dirname" de una key del registro
|
||||||
|
## ${3##*\\} es el "basename"
|
||||||
|
def _split_k (k):
|
||||||
|
k_elems = k.split ('\\')
|
||||||
|
k_dirname = '\\'.join (k_elems[0:-1])
|
||||||
|
k_basename = k_elems[-1]
|
||||||
|
return k_dirname, k_basename
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
# ogAddRegistryKey path_mountpoint str_hive str_keyname
|
# ogAddRegistryKey path_mountpoint str_hive str_keyname
|
||||||
|
@ -36,18 +43,19 @@ def chntpw (file, input):
|
||||||
#@warning Requisitos: chntpw
|
#@warning Requisitos: chntpw
|
||||||
#@warning El sistema de archivos de Windows debe estar montada previamente.
|
#@warning El sistema de archivos de Windows debe estar montada previamente.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogAddRegistryKey(path_mountpoint, str_hive, str_key):
|
def ogAddRegistryKey (mntpt, hive, k):
|
||||||
# Variables locales.
|
hivefile = ogGetHivePath (mntpt, hive)
|
||||||
FILE = ogGetHivePath(path_mountpoint, str_hive)
|
if not hivefile: return
|
||||||
if not FILE:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Añadir nueva clave.
|
k_dirname, k_basename = _split_k (k)
|
||||||
chntpw(FILE, 'cd', str_key.rsplit('\\', 1)[0])
|
|
||||||
chntpw(FILE, 'nk', str_key.rsplit('\\', 1)[-1])
|
|
||||||
chntpw(FILE, 'q')
|
|
||||||
chntpw(FILE, 'y')
|
|
||||||
|
|
||||||
|
tmpfile = tempfile.TemporaryFile (prefix='chntpw-', mode='w')
|
||||||
|
with open (tmpfile, 'w') as f:
|
||||||
|
f.write (f'cd {k_dirname}\n')
|
||||||
|
f.write (f'nk {k_basename}\n')
|
||||||
|
f.write ('q\ny\n')
|
||||||
|
chntpw (hivefile, tmpfile)
|
||||||
|
os.remove (tmpfile)
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
# ogAddRegistryValue path_mountpoint str_hive str_valuename [str_valuetype]
|
# ogAddRegistryValue path_mountpoint str_hive str_valuename [str_valuetype]
|
||||||
|
@ -64,32 +72,29 @@ def ogAddRegistryKey(path_mountpoint, str_hive, str_key):
|
||||||
#@warning Requisitos: chntpw
|
#@warning Requisitos: chntpw
|
||||||
#@warning El sistema de archivos de Windows debe estar montada previamente.
|
#@warning El sistema de archivos de Windows debe estar montada previamente.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogAddRegistryValue(path_mountpoint, str_hive, str_key, str_valuename, str_valuetype=''):
|
#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1')
|
||||||
# Variables locales.
|
#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1', 'DWORD')
|
||||||
FILE = ogGetHivePath(path_mountpoint, str_hive)
|
def ogAddRegistryValue (mntpt, hive, k, vtype='STRING'):
|
||||||
if not FILE:
|
hivefile = ogGetHivePath (mntpt, hive)
|
||||||
return
|
if not hivefile: return
|
||||||
|
|
||||||
|
k_dirname, k_basename = _split_k (k)
|
||||||
|
|
||||||
# Determine the value type.
|
# Determine the value type.
|
||||||
if str_valuetype.upper() == 'STRING' or str_valuetype == '':
|
if 'STRING' == vtype.upper(): TYPE = 1
|
||||||
TYPE = 1
|
elif 'BINARY' == vtype.upper(): TYPE = 3
|
||||||
elif str_valuetype.upper() == 'BINARY':
|
elif 'DWORD' == vtype.upper(): TYPE = 4
|
||||||
TYPE = 3
|
|
||||||
elif str_valuetype.upper() == 'DWORD':
|
|
||||||
TYPE = 4
|
|
||||||
else:
|
else:
|
||||||
SystemLib.ogRaiseError(
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_OUTOFLIMIT, vtype)
|
||||||
"session",
|
|
||||||
ogGlobals.OG_ERR_OUTOFLIMIT,
|
|
||||||
f"Error: {str_valuetype}",
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Add the registry value.
|
tmpfile = tempfile.TemporaryFile (prefix='chntpw-', mode='w')
|
||||||
chntpw(FILE, 'cd', str_key.rsplit('\\', 1)[0])
|
with open (tmpfile, 'w') as f:
|
||||||
chntpw(FILE, 'nv', str_valuename.rsplit('\\', 1)[-1], TYPE)
|
f.write (f'cd {k_dirname}\n')
|
||||||
chntpw(FILE, 'q')
|
f.write (f'nv {TYPE} {k_basename}\n')
|
||||||
chntpw(FILE, 'y')
|
f.write ('q\ny\n')
|
||||||
|
chntpw (hivefile, tmpfile)
|
||||||
|
os.remove (tmpfile)
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
@ -106,14 +111,19 @@ def ogAddRegistryValue(path_mountpoint, str_hive, str_key, str_valuename, str_va
|
||||||
#@warning El sistema de archivos de Windows debe estar montada previamente.
|
#@warning El sistema de archivos de Windows debe estar montada previamente.
|
||||||
#@warning La clave debe estar vacía para poder ser borrada.
|
#@warning La clave debe estar vacía para poder ser borrada.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogDeleteRegistryKey(path_mountpoint, str_hive, str_key):
|
def ogDeleteRegistryKey (mntpt, hive, k):
|
||||||
# Variables locales.
|
hivefile = ogGetHivePath (mntpt, hive)
|
||||||
FILE = ogGetHivePath(path_mountpoint, str_hive)
|
if not hivefile: return
|
||||||
if not FILE:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Delete the registry key.
|
k_dirname, k_basename = _split_k (k)
|
||||||
subprocess.run(['chntpw', FILE], input=f"cd {str_key.rsplit('\\', 1)[0]}\ndk {str_key.rsplit('\\', 1)[-1]}\nq\ny\n".encode(), timeout=5)
|
|
||||||
|
tmpfile = tempfile.TemporaryFile (prefix='chntpw-', mode='w')
|
||||||
|
with open (tmpfile, 'w') as f:
|
||||||
|
f.write (f'cd {k_dirname}\n')
|
||||||
|
f.write (f'dk {k_basename}\n')
|
||||||
|
f.write ('q\ny\n')
|
||||||
|
chntpw (hivefile, tmpfile)
|
||||||
|
os.remove (tmpfile)
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
@ -129,17 +139,20 @@ def ogDeleteRegistryKey(path_mountpoint, str_hive, str_key):
|
||||||
#@warning Requisitos: chntpw
|
#@warning Requisitos: chntpw
|
||||||
#@warning El sistema de archivos de Windows debe estar montada previamente.
|
#@warning El sistema de archivos de Windows debe estar montada previamente.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogDeleteRegistryValue(path_mountpoint, str_hive, str_valuename):
|
#ogDeleteRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1')
|
||||||
# Variables locales.
|
def ogDeleteRegistryValue (mntpt, hive, k):
|
||||||
FILE = ogGetHivePath(path_mountpoint, str_hive)
|
hivefile = ogGetHivePath (mntpt, hive)
|
||||||
if not FILE:
|
if not hivefile: return
|
||||||
return
|
|
||||||
|
|
||||||
# Delete the registry value.
|
k_dirname, k_basename = _split_k (k)
|
||||||
chntpw(FILE, 'cd', str_valuename.rsplit('\\', 1)[0])
|
|
||||||
chntpw(FILE, 'dv', str_valuename.rsplit('\\', 1)[-1])
|
tmpfile = tempfile.TemporaryFile (prefix='chntpw-', mode='w')
|
||||||
chntpw(FILE, 'q')
|
with open(tmpfile, 'w') as f:
|
||||||
chntpw(FILE, 'y')
|
f.write (f'cd {k_dirname}\n')
|
||||||
|
f.write (f'dv {k_basename}\n')
|
||||||
|
f.write ('q\ny\n')
|
||||||
|
chntpw (hivefile, tmpfile)
|
||||||
|
os.remove(tmpfile)
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
@ -153,21 +166,20 @@ def ogDeleteRegistryValue(path_mountpoint, str_hive, str_valuename):
|
||||||
#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS, NombreDeUsuario }
|
#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS, NombreDeUsuario }
|
||||||
#@warning El sistema de archivos de Windows debe estar montada previamente.
|
#@warning El sistema de archivos de Windows debe estar montada previamente.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
#ogGetHivePath ('/mnt/sda1', 'SOFTWARE') => /mnt/sda1/WINDOWS/System32/config/SOFTWARE
|
|
||||||
#ogGetHivePath ('/mnt/sda1', 'user1') => /mnt/sda1/Users/user1/NTUSER.DAT
|
#ogGetHivePath ('/mnt/sda1', 'user1') => /mnt/sda1/Users/user1/NTUSER.DAT
|
||||||
def ogGetHivePath(path_mountpoint, str_hive):
|
def ogGetHivePath(mntpt, hive):
|
||||||
# Camino del fichero de registro de usuario o de sistema (de menor a mayor prioridad).
|
# Camino del fichero de registro de usuario o de sistema (de menor a mayor prioridad).
|
||||||
FILE = FileLib.ogGetPath(file=f"/{path_mountpoint}/Windows/System32/config/{str_hive}")
|
FILE = FileLib.ogGetPath(file=f"/{mntpt}/Windows/System32/config/{hive}")
|
||||||
if not FILE: FILE = FileLib.ogGetPath(file=f"/{path_mountpoint}/Users/{str_hive}/NTUSER.DAT")
|
if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/Users/{hive}/NTUSER.DAT")
|
||||||
if not FILE: FILE = FileLib.ogGetPath(file=f"/{path_mountpoint}/winnt/system32/config/{str_hive}")
|
if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/winnt/system32/config/{hive}")
|
||||||
if not FILE: FILE = FileLib.ogGetPath(file=f"/{path_mountpoint}/Documents and Settings/{str_hive}/NTUSER.DAT")
|
if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/Documents and Settings/{hive}/NTUSER.DAT")
|
||||||
if FILE and os.path.isfile(FILE):
|
if FILE and os.path.isfile(FILE):
|
||||||
return FILE
|
return FILE
|
||||||
else:
|
else:
|
||||||
SystemLib.ogRaiseError(
|
SystemLib.ogRaiseError(
|
||||||
[],
|
[],
|
||||||
ogGlobals.OG_ERR_NOTFOUND,
|
ogGlobals.OG_ERR_NOTFOUND,
|
||||||
f"{path_mountpoint} {str_hive}"
|
f"{mntpt} {hive}"
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -185,20 +197,20 @@ def ogGetHivePath(path_mountpoint, str_hive):
|
||||||
#@warning Requisitos: chntpw, awk
|
#@warning Requisitos: chntpw, awk
|
||||||
#@warning El sistema de archivos de Windows debe estar montado previamente.
|
#@warning El sistema de archivos de Windows debe estar montado previamente.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogGetRegistryValue(path_mountpoint, hive, k):
|
def ogGetRegistryValue (mntpt, hive, k):
|
||||||
FILE = ogGetHivePath(path_mountpoint, hive)
|
FILE = ogGetHivePath(mntpt, hive)
|
||||||
if not FILE: return
|
if not FILE: return
|
||||||
|
|
||||||
k_elems = k.split ('\\')
|
k_dirname, k_basename = _split_k (k)
|
||||||
k_dirname = '\\'.join (k_elems[0:-1])
|
|
||||||
k_basename = k_elems[-1]
|
|
||||||
|
|
||||||
input = '\n'.join ([
|
tmpfile = tempfile.TemporaryFile (prefix='chntpw-', mode='w')
|
||||||
f'cd {k_dirname}',
|
with open(tmpfile, 'w') as f:
|
||||||
f'cat {k_basename}',
|
f.write (f'cd {k_dirname}\n')
|
||||||
'q',
|
f.write (f'cat {k_basename}\n')
|
||||||
])
|
f.write ('q\n')
|
||||||
chntpw_out = chntpw (file, input)
|
|
||||||
|
chntpw_out = chntpw (hivefile, tmpfile)
|
||||||
|
os.remove (tmpfile)
|
||||||
lines = chntpw_out.splitlines()
|
lines = chntpw_out.splitlines()
|
||||||
if 2 != len (lines):
|
if 2 != len (lines):
|
||||||
return None
|
return None
|
||||||
|
@ -220,20 +232,26 @@ def ogGetRegistryValue(path_mountpoint, hive, k):
|
||||||
#@warning Requisitos: chntpw, awk
|
#@warning Requisitos: chntpw, awk
|
||||||
#@warning El sistema de archivos de Windows debe estar montado previamente.
|
#@warning El sistema de archivos de Windows debe estar montado previamente.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogListRegistryKeys(path_mountpoint, str_hive, str_key):
|
#ogListRegistryKeys ('/mnt/sda1', 'SOFTWARE', '\Microsoft\Windows\CurrentVersion')
|
||||||
# Variables locales.
|
def ogListRegistryKeys (mntpt, hive, k):
|
||||||
FILE = ogGetHivePath(path_mountpoint, str_hive)
|
FILE = ogGetHivePath(mntpt, hive)
|
||||||
if not FILE:
|
if not FILE: return
|
||||||
return
|
|
||||||
|
|
||||||
# Devolver la lista de claves de registro.
|
tmpfile = tempfile.TemporaryFile (prefix='chntpw-', mode='w')
|
||||||
chntpw_cmd = f'''
|
with open(tmpfile, 'w') as f:
|
||||||
chntpw "{FILE}" << EOT 2> /dev/null | awk 'BEGIN {{FS="[<>]"}} $1~/^ $/ {{print $2}}'
|
f.write (f'ls {k}\n')
|
||||||
ls {str_key}
|
f.write ('q\n')
|
||||||
q
|
chntpw_out = chntpw (hivefile, tmpfile)
|
||||||
EOT
|
os.remove (tmpfile)
|
||||||
'''
|
lines = chntpw_out.splitlines()
|
||||||
subprocess.run(chntpw_cmd, shell=True, timeout=5)
|
|
||||||
|
ret = []
|
||||||
|
for l in lines:
|
||||||
|
elems = re.split ('[<>]', l)
|
||||||
|
if len(elems) < 2: continue
|
||||||
|
if ' ' == elems[0]:
|
||||||
|
ret.append (elems[1])
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
@ -249,20 +267,27 @@ def ogListRegistryKeys(path_mountpoint, str_hive, str_key):
|
||||||
#@warning Requisitos: chntpw, awk
|
#@warning Requisitos: chntpw, awk
|
||||||
#@warning El sistema de archivos de Windows debe estar montado previamente.
|
#@warning El sistema de archivos de Windows debe estar montado previamente.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogListRegistryValues(path_mountpoint, str_hive, str_key):
|
#ogListRegistryValues ('/mnt/sda1', 'SOFTWARE', '\Microsoft\Windows\CurrentVersion')
|
||||||
# Variables locales.
|
def ogListRegistryValues (mntpt, hive, k):
|
||||||
FILE = ogGetHivePath(path_mountpoint, str_hive)
|
FILE = ogGetHivePath(mntpt, hive)
|
||||||
if not FILE:
|
if not FILE: return
|
||||||
return
|
|
||||||
|
tmpfile = tempfile.TemporaryFile (prefix='chntpw-', mode='w')
|
||||||
|
with open(tmpfile, 'w') as f:
|
||||||
|
f.write (f'ls {k}\n')
|
||||||
|
f.write ('q\n')
|
||||||
|
chntpw_out = chntpw (hivefile, tmpfile)
|
||||||
|
os.remove (tmpfile)
|
||||||
|
lines = chntpw_out.splitlines()
|
||||||
|
|
||||||
|
ret = []
|
||||||
|
for l in lines:
|
||||||
|
elems = re.split ('[<>]', l)
|
||||||
|
if len(elems) < 2: continue
|
||||||
|
if 'REG_' in elems[0]:
|
||||||
|
ret.append (elems[1])
|
||||||
|
return ret
|
||||||
|
|
||||||
# Devolver la lista de valores de registro.
|
|
||||||
chntpw_cmd = f'''
|
|
||||||
chntpw "{FILE}" << EOT 2> /dev/null | awk 'BEGIN {{FS="[<>]"}} $1~/REG_/ {{print $2}}'
|
|
||||||
ls {str_key}
|
|
||||||
q
|
|
||||||
EOT
|
|
||||||
'''
|
|
||||||
subprocess.run(chntpw_cmd, shell=True, timeout=5)
|
|
||||||
|
|
||||||
def _format_hex (hex_string):
|
def _format_hex (hex_string):
|
||||||
result = []
|
result = []
|
||||||
|
@ -304,11 +329,7 @@ def ogSetRegistryValue (mntpt, hive, k, v):
|
||||||
hivefile = ogGetHivePath (mntpt, hive)
|
hivefile = ogGetHivePath (mntpt, hive)
|
||||||
if not hivefile: return
|
if not hivefile: return
|
||||||
|
|
||||||
# ${3%\\*} es dirname
|
k_dirname, k_basename = _split_k (k)
|
||||||
# ${3##*\\} es basename
|
|
||||||
k_elems = k.split ('\\')
|
|
||||||
k_dirname = '\\'.join (k_elems[0:-1])
|
|
||||||
k_basename = k_elems[-1]
|
|
||||||
|
|
||||||
tmpfile = tempfile.TemporaryFile (prefix='chntpw-', mode='w')
|
tmpfile = tempfile.TemporaryFile (prefix='chntpw-', mode='w')
|
||||||
try:
|
try:
|
||||||
|
@ -316,8 +337,8 @@ def ogSetRegistryValue (mntpt, hive, k, v):
|
||||||
f.write (f"ls {k_dirname}\n")
|
f.write (f"ls {k_dirname}\n")
|
||||||
f.write ('q\n')
|
f.write ('q\n')
|
||||||
|
|
||||||
output = subprocess.run (['chntpw', hivefile], input=open(tmpfile, 'r'), capture_output=True, text=True).stdout
|
chntpw_out = chntpw (hivefile, tmpfile)
|
||||||
if re.search (f"BINARY.*<{k_basename}>", output):
|
if re.search (f"BINARY.*<{k_basename}>", chntpw_out):
|
||||||
## the entry in the registry is binary. Our input should be a sequence of bytes
|
## the entry in the registry is binary. Our input should be a sequence of bytes
|
||||||
|
|
||||||
if ' ' != v[-1]: v += ' ' ## the regex below requires a trailing space
|
if ' ' != v[-1]: v += ' ' ## the regex below requires a trailing space
|
||||||
|
@ -337,6 +358,6 @@ def ogSetRegistryValue (mntpt, hive, k, v):
|
||||||
f.write ('q\ny\n')
|
f.write ('q\ny\n')
|
||||||
|
|
||||||
# Aplicar cambios.
|
# Aplicar cambios.
|
||||||
subprocess.run (['chntpw', hivefile], input=open(tmpfile, 'r'))
|
chntpw (hivefile, tmpfile)
|
||||||
finally:
|
finally:
|
||||||
os.remove(tmpfile)
|
os.remove(tmpfile)
|
||||||
|
|
Loading…
Reference in New Issue