Code Block
#include "stdafx.h"
#include <Windows.h>
#include <msi.h>
// typedefs
typedef BOOL (WINAPI* pGetFileSizeEx)(HANDLE, PLARGE_INTEGER);
///////////////////////////////////////////////////////////////////////
// Utility function to display the string representation of a Win32 error code.
///////////////////////////////////////////////////////////////////////
void ShowLastError(DWORD err)
{
LPTSTR buf;
if (::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
err,
0,
(LPTSTR) &buf,
0,
NULL) == 0)
{
}
else
{
printf("%d: %s\n", err, buf);
::LocalFree(buf);
}
}
///////////////////////////////////////////////////////////////////////
// Use this function to grant the current process the specified privilege.
// This code is copied from Microsoft's website (http://msdn2.microsoft.com/en-us/library/Aa387705.aspx)
///////////////////////////////////////////////////////////////////////
HRESULT ModifyPrivilege(
IN LPCTSTR szPrivilege,
IN BOOL fEnable)
{
HRESULT hr = S_OK;
TOKEN_PRIVILEGES NewState;
LUID luid;
HANDLE hToken = NULL;
// Open the process token for this process.
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken ))
{
printf("Failed OpenProcessToken\n");
return ERROR_FUNCTION_FAILED;
}
// Get the local unique ID for the privilege.
if ( !LookupPrivilegeValue( NULL,
szPrivilege,
&luid ))
{
CloseHandle( hToken );
printf("Failed LookupPrivilegeValue\n");
return ERROR_FUNCTION_FAILED;
}
// Assign values to the TOKEN_PRIVILEGE structure.
NewState.PrivilegeCount = 1;
NewState.Privileges[0].Luid = luid;
NewState.Privileges[0].Attributes = (fEnable SE_PRIVILEGE_ENABLED : 0);
// Adjust the token privilege.
if (!AdjustTokenPrivileges(hToken,
FALSE,
&NewState,
0,
NULL,
NULL))
{
printf("Failed AdjustTokenPrivileges\n");
hr = ERROR_FUNCTION_FAILED;
}
// Close the handle.
::CloseHandle(hToken);
return hr;
}
///////////////////////////////////////////////////////////////////////
// Main function
///////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
// Acquire the SE_BACKUP_NAME privilege
HRESULT hr = ModifyPrivilege(SE_BACKUP_NAME, TRUE);
if (!SUCCEEDED(hr))
printf("Failed to modify privilege.\n");
else
printf("Successfully modified privilege.\n");
LPTSTR szFile[] = {
"C:\\Documents and Settings\\<USER>\\Local Settings\\Application Data\\Microsoft\\Windows\\UsrClass.dat",
// Registry files
"C:\\WINDOWS\\system32\\config\\SAM",
"C:\\WINDOWS\\system32\\config\\Software",
"C:\\WINDOWS\\system32\\config\\System",
"C:\\WINDOWS\\system32\\config\\Security",
"C:\\WINDOWS\\system32\\config\\Default",
"C:\\WINDOWS\\system32\\config\\UserDiff",
"C:\\Documents and Settings\\<USER>\\NTUser.dat",
};
// Load the kernel32 library
HMODULE hLib = ::LoadLibrary("kernel32");
// Get the address of GetFileSizeEx. I had to do this since my MSVC wouldn't recognize GetFileSizeEx
pGetFileSizeEx pf = (pGetFileSizeEx) GetProcAddress(hLib, "GetFileSizeEx");
printf("GetFileSizeEx's address: 0x%0x\n", pf);
for (int i = 0; i < 8; i++)
{
// Open the file
HANDLE hFile = ::CreateFile(
szFile[i], //
READ_CONTROL | ACCESS_SYSTEM_SECURITY, //
FILE_SHARE_READ, // share for reading
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_FLAG_BACKUP_SEMANTICS, // open the file for backup. you will need this flag.
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
{
ShowLastError(GetLastError());
}
else
{
if (hLib && pf)
{
// Now let us get the file's size.
LARGE_INTEGER size;
if ( pf(hFile, &size) )
{
printf("Size: %d\n", size.QuadPart);
}
else
{
printf("Failed to retrieve file's size.\n");
}
}
else
{
printf("Kernel32 could not be loaded.\n");
ShowLastError(GetLastError());
}
// We now read the file's contents.
const DWORD dwBytesToRead = 32768;
DWORD dwBytesRead = 0;
BYTE buf[dwBytesToRead];
LPVOID lpContext = NULL;
if ( BackupRead(hFile, buf, dwBytesToRead, &dwBytesRead, FALSE, TRUE, &lpContext) )
{
printf("Able to read %s!\n", szFile[i]);
for (int i = 0; i < dwBytesRead; i++)
putc(buf[i], stdout);
}
else
{
ShowLastError(GetLastError());
}
// Close handle
::CloseHandle(hFile);
}
}
if (hLib)
::FreeLibrary(hLib);
return 0;
}