Ir al contenido



Foto

Mover claves del registro recursivamente [MULTILENGUAJE]


  • Por favor identifícate para responder
2 respuestas en este tema

#1 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.733 mensajes
  • LocationMadrid - España

Escrito 12 abril 2018 - 01:30

Con fines de esconder claves o realizar un BackUp de una clave guardándola dentro del registro, pensé en escribir un código para copiar una clave, sus valores y sus subclaves, en otra zona del registro de Windows.
 
Aparentemente no debería ser complicado copiar claves del registro arrastrando todos sus valores y subclaves, para eso M$ dispone de las API RegCopyTree y SHCopyKey. El problema es que estas API tienen restricciones de copia. No quedando contento con las pruebas que realicé y para generalizar la solución al problema he escrito una función recursiva que copia una clave a otro lugar.
 
Primero crea la subclave de destino, luego enumera y copia los valores, y finalmente, copia las subclaves, En este último punto la función se vuelve recursiva para repetir las acciones fasta la última rama del árbol.
 


delphi
  1. function RegCopyKey(SrcKey, TrgKey: HKEY; TrgSubKeyName: PAnsiChar): integer;
  2. var
  3. SrcSubKey: HKEY;
  4. TrgSubKey: HKEY;
  5. ValIndex: integer;
  6. KeyIndex: integer;
  7.  
  8. ValName: array [0..MAX_PATH] of AnsiChar;
  9. KeyName: array [0..MAX_PATH] of AnsiChar;
  10. Size: DWORD;
  11. ValType: DWORD;
  12. BuffSize: DWORD;
  13. Buff: PBYTE;
  14. begin
  15. ValIndex:= 0;
  16. KeyIndex:= 0;
  17.  
  18.   Result:= 2;
  19.   if (SrcKey = 0) or (TrgKey = 0) then exit;
  20.  
  21. // Creando La Clave Destino
  22. Result:= RegCreateKeyEx(TrgKey, TrgSubKeyName, 0, nil, REG_OPTION_NON_VOLATILE,
  23. KEY_ALL_ACCESS, nil, TrgSubKey, nil);
  24. if Result = ERROR_SUCCESS then
  25. begin
  26. Size:= sizeof(ValName);
  27.  
  28. // Copio valores
  29. while ERROR_NO_MORE_ITEMS <> RegEnumValue(SrcKey, ValIndex, ValName, Size, nil, @ValType, nil, @BuffSize) do
  30. begin
  31. Buff:= VirtualAlloc(nil, BuffSize, MEM_COMMIT, PAGE_READWRITE);
  32. RegSetValueEx(TrgSubKey, ValName, 0, ValType, Buff, BuffSize);
  33. VirtualFree(Buff, 0, MEM_RELEASE);
  34. Size:= sizeof(ValName);
  35. inc(ValIndex);
  36. end;
  37. // Copio Claves recursivamente
  38. Size:= sizeof(KeyName);
  39. while ERROR_NO_MORE_ITEMS <> RegEnumKeyEx(SrcKey, KeyIndex, KeyName, Size, nil, nil, nil, nil) do
  40. begin
  41. if RegOpenKeyEx(SrcKey, KeyName, 0, KEY_ALL_ACCESS, SrcSubKey) = ERROR_SUCCESS then
  42. begin
  43. if 0 = lstrcmpi(@KeyName[0], @TrgSubKeyName[0]) then continue;
  44. if ERROR_SUCCESS <> RegCopyKey(SrcSubKey, TrgSubKey, KeyName) then break;
  45. RegCloseKey(SrcSubKey);
  46. end;
  47. Size:= sizeof(KeyName);
  48. inc(KeyIndex);
  49. end;
  50.  
  51. RegCloseKey(TrgSubKey);
  52. end;
  53. end;

Un ejemplo de uso que copia HKEY_CLASSES_ROOT\batfile\shell en  HKEY_CLASSES_ROOT\batfile\bkShell


delphi
  1. var
  2. SrcKey, TrgKey: HKEY;
  3. begin
  4. RegOpenKeyEx(HKEY_CLASSES_ROOT, 'batfile\shell', 0, KEY_READ, SrcKey);
  5. RegOpenKeyEx(HKEY_CLASSES_ROOT, 'batfile', 0, KEY_READ, TrgKey);
  6. RegCopyKey(SrcKey, TrgKey, 'bkShell');
  7. RegCloseKey(SrcKey);
  8. RegCloseKey(TrgKey);
  9. end;

Añadiendo el borrado de la clave original, tenemos el código listo para mover claves:


delphi
  1. type
  2.  
  3. function RegDeleteTree(KeyScr: HKEY; lpSubKey: LPCTSTR): integer; stdcall; external 'Advapi32.dll' name 'RegDeleteTreeA';
  4.  
  5.  
  6. ..................
  7.  
  8. var
  9. SrcKey, TrgKey: HKEY;
  10. begin
  11. RegOpenKeyEx(HKEY_CLASSES_ROOT, 'batfile\shell\runas', 0, KEY_READ, SrcKey);
  12. RegOpenKeyEx(HKEY_CLASSES_ROOT, 'batfile', 0, KEY_READ, TrgKey);
  13. RegCopyKey(SrcKey, TrgKey, 'bkRunAs');
  14. RegCloseKey(SrcKey);
  15. RegCloseKey(TrgKey);
  16. RegDeleteTree(HKEY_CLASSES_ROOT, 'batfile\shell\runas');
  17. end;

Saludos.


  • 0

#2 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.733 mensajes
  • LocationMadrid - España

Escrito 12 abril 2018 - 01:33

Como no podía ser de otra manera, publico el código en C/C++


cpp
  1. LONG RegCopyKey(HKEY SrcKey, HKEY TrgKey, char* TrgSubKeyName)
  2. {
  3. HKEY SrcSubKey;
  4. HKEY TrgSubKey;
  5. int ValIndex = 0;
  6. int KeyIndex = 0;
  7. char ValName[MAX_PATH+1];
  8. char KeyName[MAX_PATH+1];
  9. DWORD Size;
  10. DWORD ValType;
  11. DWORD BuffSize;
  12. PBYTE Buff;
  13. LONG Error;
  14.  
  15. if(SrcKey == 0 || TrgKey == 0) return 2;
  16.  
  17. // Creo Clave destino
  18. Error = RegCreateKeyEx(TrgKey, TrgSubKeyName, NULL, NULL, REG_OPTION_NON_VOLATILE,
  19. KEY_ALL_ACCESS, NULL, &TrgSubKey, 0);
  20.  
  21. if(Error == ERROR_SUCCESS){
  22. // Copio valores
  23. Size = sizeof(ValName);
  24. while(ERROR_NO_MORE_ITEMS != RegEnumValue(SrcKey, ValIndex++, ValName, &Size, NULL, &ValType, NULL, &BuffSize)){
  25. Size = sizeof(ValName);
  26. Buff = (PBYTE)VirtualAlloc(0, BuffSize, MEM_COMMIT, PAGE_READWRITE);
  27. RegSetValueEx(TrgSubKey, ValName, NULL, ValType, Buff, BuffSize);
  28. VirtualFree(Buff, 0, MEM_RELEASE);
  29. }
  30. // Copio Claves recursivamente
  31. Size = sizeof(KeyName);
  32. while(ERROR_NO_MORE_ITEMS != RegEnumKeyEx(SrcKey, KeyIndex++, KeyName, &Size, 0, 0, 0, 0)){
  33. Size = sizeof(KeyName);
  34. if(RegOpenKeyEx(SrcKey, KeyName, NULL, KEY_ALL_ACCESS, &SrcSubKey) == ERROR_SUCCESS){
  35. if(!strnicmp(KeyName, TrgSubKeyName, strlen(KeyName))) continue;
  36. if(ERROR_SUCCESS != RegCopyKey(SrcSubKey, TrgSubKey, KeyName)) break;
  37. RegCloseKey(SrcSubKey);
  38. }
  39. }
  40.  
  41. RegCloseKey(TrgSubKey);
  42. }
  43. return Error;
  44. }

Dado que el código es similar al escrito en delphi, los ejemplos de uso también lo son.

 

 

Saludos.


  • 1

#3 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.744 mensajes
  • LocationMéxico

Escrito 12 abril 2018 - 02:08


Muy interesante solución amigo escafandra, sobre todo para gente como yo que gustamos de borrar llaves del registro :D :D :D

Saludos
  • 0