function thumbnail_create()
{
extract(doSlash(gpsa(array('id', 'width', 'height'))));
global $txpcfg,$img_dir;
extract($txpcfg);
$id = assert_int(ps('id'));
// better checking of thumbnail dimensions
// don't try and use zeros
$rs = safe_row('*', 'txp_image', "id = $id");
if ($rs) {
extract($rs);
$width = (int) $width;
$height = (int) $height;
list($w, $h) = getimagesize(IMPATH.'/'.$id.$ext);
$w = (int) $w;
$h = (int) $h;
if ($width == 0 && $height == 0) {
image_edit(messenger('invalid_width_or_height', "($width)/($height)", ''), $id);
return;
} else {
if ($width == 0) {
$width = '';
}
if ($height == 0) {
$height = '';
}
}
$crop = gps('crop');
$t = new txp_thumb( $id );
$t->crop = ($crop == '1');
$t->hint = '0';
$t->width = $width / 100 * $w;
$t->height = $height / 100 * $h;
if ($t->write())
{
global $prefs;
$prefs['thumb_w'] = $width;
$prefs['thumb_h'] = $height;
$prefs['thumb_crop'] = $crop;
// hidden prefs
set_pref('thumb_w', $width, 'image', 2);
set_pref('thumb_h', $height, 'image', 2);
set_pref('thumb_crop', $crop, 'image', 2);
$message = gTxt('thumbnail_saved', array('{id}' => $id));
update_lastmod();
image_edit($message, $id);
}
else
{
$message = gTxt('thumbnail_not_saved', array('{id}' => $id));
image_edit($message, $id);
}
}
}
Hola
Parecido al artículo Detrás del SpywareBlaster… está vez voy a hablar de un programa bastante conocido llamado ERUNT, utilidad para realizar backups del registro de Windows. A diferencia del sistema de copias de seguridad del regedit, este programa guarda de forma binaria todo el registro de Windows .
La idea de este artículo comenzó debido a mi intención de añadir una función similar ofrecida en este programa a mi aplicación RegUnlocker, de modo tal de ofrecer un sistema de backups más veloz y completo, además de ser mucho más útil a la hora de errores de sistema.
En un principio debo reconocer que no tuve suerte al deducir como funcionaba la aplicación. Sinceramente siempre pensé que copiaba los archivos de la propia copia de seguridad de Windows, (C:\WINDOWS\repair) lo que no explicaría el lento proceso necesario para su copia, o que se las ingeniaba para copiar directamente los archivos de sistema de Windows de la carpeta C:\WINDOWS\System32, lo que era totalmente descabellado, ya que requeriría un método tipo DLL Injection lo que no va con este tipo de aplicaciones. Pero, ¿por qué llegue a pensar tal funcionamiento? Todo se debió a que ERUNT crea un backup de las entradas del registro más importantes, y las nombra exactamente igual a su equivalente en Windows, es decir a los siguientes archivos:
Luego, observando detenidamente los archivos creados, es fácil darse cuenta que no son iguales a los originales de Windows, lo que nos dice que esos archivos realmente salen de otro lado. Después de buscar en Google largo rato, no log´re encontrar ninguna solución concreta, así que procedí a fijarme que hace realmente la aplicación:
Lo que podemos ver en esa imagen es que la aplicación lo que hace es obtener el provilegio de acceso SeBackupName. Si investigan un poco en el msdn, podrán averiguar que este privilegio sirve para acceder a entradas del registro y archivos protegidos en modo de solo lectura, para poder ejecutar algunas funciones de backup. Además se hace una llamada a la función RegCreateKeyEx, que no solo sirve para crear claves en el registro, si no para obtener el HANDLE de la clave, (manipulador) de manera muy similar a la que trabaja la función CreateFile, la cual está destinada a archivos y directorios. Ahora, ¿por qué usa esa función en vez de RegOpenKey o RegCreateKey?
Para que vean más de cerca, en este caso se obtiene el HANDLE de la clave “HKEY_LOCAL_MACHINE\SYSTEM”, pero si prestan atención verán que el valor del parámetro Options es REG_OPTION_BACKUP_RESTORE. Este flag es muy importante durante el proceso si se desea tener total acceso de lectura al registro, lo cual es necesario para realizar el backup.
Por último, aquí es donde viene la parte más interesante para mí, donde aparece una función que desconocía de la api Win32:
Seguro les va a ser necesario agrandar la imagen, pero podrán observar que en el momento de hacerse una llamada a una función llamada RegSaveKeyEx, el programa Filemon detecta la creación del archivo de backup. ¡Bingo! Por fin encontramos la función que guarda el registro al estilo ERUNT :)
Ahora veamos como podemos hacer los pasos anteriores programaticamente. Para eso utilizaremos C++ y la directiva windows.h. En primer lugar lo que hacemos es obtener los privilegios SeBackupName. Para eso obtenemos el HANDLE de nuestro proceso, luego creamos una estructura TOKEN_PRIVILEGES con el flag SE_BACKUP_NAME, la añadimos a nuestro proceso, y por último liberamos todos los HANDLES que utilizamos:
BOOL GetPrivileges() //Get SeBackup Privileges
{
BOOL bReturn = FALSE;
HANDLE hToken;
TOKEN_PRIVILEGES NewPrivileges;if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
{
CloseHandle(hToken); return(FALSE);
}if(LookupPrivilegeValue(0, SE_BACKUP_NAME, &NewPrivileges.Privileges[0].Luid)) {
NewPrivileges.PrivilegeCount = 1; NewPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED
}
else { CloseHandle(hToken); return FALSE; }bReturn = AdjustTokenPrivileges(hToken, FALSE, &NewPrivileges, 0 ,0 ,0); CloseHandle(hToken);
return bReturn;
}
Creamos una función la cual reciba la entrada del registro a guardar y luego un nombre de archivo de salida y nos haga el backup automáticamente:
BOOL GetRegistryKey(HKEY RootKey, LPCSTR SubKey, LPCSTR FileName)
{ long lRval; HKEY hKey;DWORD Result;
Result = RegCreateKeyEx(RootKey, SubKey, 0, NULL, REG_OPTION_BACKUP_RESTORE, 0, NULL, &hKey, NULL);
if (Result!=ERROR_SUCCESS) { cout << “Couldn’t Open Registry Key” << endl; GetErrorMessage(Result); RegCloseKey(hKey); return FALSE; }
Result = RegSaveKey(hKey, FileName, 0); if (Result!=ERROR_SUCCESS) { cout << “Couldn’t save Registry Key” << endl; GetErrorMessage(Result); RegCloseKey(hKey); return FALSE; }
RegCloseKey(hKey); return TRUE;
}
Por último, teniendo ya estas dos funciones, lo único que hacemos es elegir que claves o subclaves queremos guardar, un juego de niños. Aquí les muestro un ejemplo de una función main:
#include <cstdlib>
#include <iostream>
#include <windows.h>
using namespace std;
BOOL GetPrivileges();
BOOL GetRegistryKey(HKEY RootKey, LPCSTR SubKey, LPCSTR FileName);
void GetErrorMessage(DWORD err);int main(int argc, char *argv[])
{ if (GetPrivileges()==TRUE) { cout << “Privileges got succesfully”<< endl; } else { return 1; }if(GetRegistryKey(HKEY_LOCAL_MACHINE, “SAM”, “SAM”)==TRUE) { cout << “Sam backuped succesfully”<< endl; }
if(GetRegistryKey(HKEY_LOCAL_MACHINE, “SECURITY”, “Security” )==TRUE) { cout << “Security backuped succesfully”<< endl; }
if(GetRegistryKey(HKEY_LOCAL_MACHINE, “SOFTWARE”, “Software”)==TRUE) { cout << “Software backuped succesfully”<< endl; }
if(GetRegistryKey(HKEY_LOCAL_MACHINE, “SYSTEM”, “System”)==TRUE) { cout << “System backuped succesfully”<< endl; }
cout << “Finished” <<endl;
system(“PAUSE”);
return EXIT_SUCCESS;
}
void GetErrorMessage(DWORD err)
{
TCHAR msg[256];FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, msg, 255, NULL);
cout << msg << endl;;
}
Conclusiones
Como ven no es nada difícil crear copias de seguridad mediante este método más allá de las ventajas que conlleva como la velocidad de creación y el tamaño de la copia. El único inconveniente es que la información se guarda en una especia de formato cifrado o binario por lo cual es imposible su edición, lo que lo vuelve inutilizable para ciertas tareas.
Saludos