1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-24 18:16:24 +01:00
2020-06-25 10:31:48 +10:00

986 lines
22 KiB
C++
Executable File

/*
Copyright 2012-2014 Michael Cohen <scudette@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/********************************************************************
This is a single binary memory imager for Windows.
Supported systems:
- Windows XPSP2 to Windows 8 inclusive, both 32 bit and 64 bit.
*********************************************************************/
#include "winpmem.h"
#include <stdio.h>
#include <time.h>
#ifndef min
#define min(x,y) ((x)<(y)?(x):(y))
#endif
int WinPmem::pad(uint64_t length)
{
uint64_t start = 0;
int result = 1;
ZeroMemory(buffer_, buffer_size_);
do
{
while (start < length) {
DWORD to_write = (DWORD)min(buffer_size_, length - start);
DWORD bytes_written;
if (!WriteFile(out_fd_, buffer_,
to_write, &bytes_written, NULL) ||
bytes_written != to_write) {
dprintf("[WINPMEM] Failed to write padding");
result = 0;
break;
};
out_offset += bytes_written;
start += bytes_written;
};
} while (0);
return result;
};
int WinPmem::copy_memory(uint64_t start, uint64_t end)
{
int result = 0;
LARGE_INTEGER large_start;
if (start > max_physical_memory_) {
return result;
};
// Clamp the region to the top of physical memory.
if (end > max_physical_memory_) {
end = max_physical_memory_;
};
do
{
while (start < end) {
DWORD to_write = (DWORD)min(buffer_size_, end - start);
DWORD bytes_read = 0;
DWORD bytes_written = 0;
large_start.QuadPart = start;
if (0xFFFFFFFF == SetFilePointerEx(
fd_, large_start, NULL, FILE_BEGIN)) {
dprintf("[WINPMEM] Failed to seek in the pmem device.");
break;
};
if (!ReadFile(fd_, buffer_, to_write, &bytes_read, NULL) ||
bytes_read != to_write) {
dprintf("[WINPMEM] Failed to Read memory.");
break;
};
if (!WriteFile(out_fd_, buffer_, bytes_read,
&bytes_written, NULL) ||
bytes_written != bytes_read) {
dprintf("[WINPMEM] Failed to write image file");
break;
};
out_offset += bytes_written;
start += to_write;
};
result = 1;
} while (0);
return result;
};
// Turn on write support in the driver.
int WinPmem::set_write_enabled(void)
{
UINT mode;
DWORD size;
if (!DeviceIoControl(fd_, PMEM_WRITE_ENABLE, &mode, 4, NULL, 0,
&size, NULL)) {
dprintf("[WINPMEM] Failed to set write mode. Maybe these drivers do not support this mode?");
return -1;
};
dprintf("[WINPMEM] Write mode enabled! Hope you know what you are doing.");
return 1;
};
void WinPmem::print_mode_(unsigned __int32 mode)
{
switch (mode) {
case PMEM_MODE_IOSPACE:
dprintf("[WINPMEM] MMMapIoSpace");
break;
case PMEM_MODE_PHYSICAL:
dprintf("[WINPMEM] \\\\.\\PhysicalMemory");
break;
case PMEM_MODE_PTE:
dprintf("[WINPMEM] PTE Remapping");
break;
case PMEM_MODE_PTE_PCI:
dprintf("[WINPMEM] PTE Remapping with PCI introspection");
break;
default:
dprintf("[WINPMEM] Unknown");
};
};
// Display information about the memory geometry.
void WinPmem::print_memory_info()
{
struct PmemMemoryInfo info;
DWORD size;
do
{
// Get the memory ranges.
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char*)&info, sizeof(info), &size, NULL))
{
dprintf("[WINPMEM] Failed to get memory geometry,");
break;
};
dprintf("[WINPMEM] CR3: 0x%010llX\n %d memory ranges:", info.CR3.QuadPart, info.NumberOfRuns);
max_physical_memory_ = 0;
for (int64_t i = 0; i < info.NumberOfRuns.QuadPart; i++)
{
dprintf("[WINPMEM] Start 0x%08llX - Length 0x%08llX", info.Run[i].start, info.Run[i].length);
max_physical_memory_ = info.Run[i].start + info.Run[i].length;
};
// When using the pci introspection we dont know the maximum physical memory,
// we therefore make a guess based on the total ram in the system.
dprintf("[WINPMEM] Acquisition mode ");
print_mode_(mode_);
if (mode_ == PMEM_MODE_PTE_PCI)
{
ULONGLONG installed_memory = 0;
MEMORYSTATUSEX statusx;
statusx.dwLength = sizeof(statusx);
if (GlobalMemoryStatusEx(&statusx))
{
max_physical_memory_ = (size_t)(statusx.ullTotalPhys * 3 / 2);
dprintf("[WINPMEM] Max physical memory guessed at 0x%08llX", max_physical_memory_);
}
else
{
dprintf("[WINPMEM] Unable to guess max physical memory. Just Ctrl-C when done.");
};
};
} while (0);
};
int WinPmem::set_acquisition_mode(unsigned __int32 mode)
{
DWORD size;
if (mode == PMEM_MODE_AUTO)
{
mode = default_mode_;
}
// Set the acquisition mode.
if (!DeviceIoControl(fd_, PMEM_CTRL_IOCTRL, &mode, 4, NULL, 0, &size, NULL))
{
dprintf("[WINPMEM] Failed to set acquisition mode %lu ", mode);
print_mode_(mode);
return -1;
};
mode_ = mode;
return 1;
};
int WinPmem::create_output_file(TCHAR *output_filename)
{
int status = 1;
do
{
// The special file name of - means we should use stdout.
if (!_tcscmp(output_filename, TEXT("-")))
{
out_fd_ = GetStdHandle(STD_OUTPUT_HANDLE);
break;
}
// Create the output file.
out_fd_ = CreateFile(output_filename,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (out_fd_ == INVALID_HANDLE_VALUE) {
dprintf("[WINPMEM] Unable to create output file.");
status = -1;
break;
};
} while (0);
return status;
}
int WinPmem::write_coredump()
{
// Somewhere to store the info from the driver;
struct PmemMemoryInfo info;
DWORD size;
int status = -1;
do
{
if (out_fd_ == INVALID_HANDLE_VALUE)
{
dprintf("[WINPMEM] Must open an output file first.");
break;
};
RtlZeroMemory(&info, sizeof(info));
// Get the memory ranges.
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char*)&info,
sizeof(info), &size, NULL)) {
dprintf("[WINPMEM] Failed to get memory geometry,");
break;
};
dprintf("[WINPMEM] Will write an elf coredump.");
print_memory_info();
if (!write_coredump_header_(&info)) {
break;
};
for (int64_t i = 0; i < info.NumberOfRuns.QuadPart; i++)
{
copy_memory((size_t)info.Run[i].start, (size_t)(info.Run[i].start + info.Run[i].length));
};
// Remember where we wrote the last metadata header.
last_header_offset_ = out_offset;
if (!WriteFile(out_fd_, metadata_, metadata_len_, &metadata_len_, NULL))
{
dprintf("[WINPMEM] Can not write metadata.");
}
out_offset += metadata_len_;
if (pagefile_path_)
{
write_page_file();
};
} while (0);
if (out_fd_ != NULL && out_fd_ != INVALID_HANDLE_VALUE)
{
CloseHandle(out_fd_);
}
out_fd_ = INVALID_HANDLE_VALUE;
return status;
};
void WinPmem::CreateChildProcess(TCHAR *command, HANDLE stdout_wr)
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bSuccess = FALSE;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdInput = NULL;
siStartInfo.hStdOutput = stdout_wr;
siStartInfo.hStdError = stdout_wr;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
dprintf("[WINPMEM] Launching %s", command);
// Create the child process.
bSuccess = CreateProcess(NULL,
command, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
// If an error occurs, exit the application.
if (!bSuccess) {
dprintf("[WINPMEM] Unable to launch process.");
return;
}
// Close handles to the child process and its primary thread.
// Some applications might keep these handles to monitor the status
// of the child process, for example.
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
CloseHandle(stdout_wr);
}
// Copy the pagefile to the current place in the output file.
void WinPmem::write_page_file()
{
unsigned __int64 pagefile_offset = out_offset;
TCHAR path[MAX_PATH + 1];
TCHAR filename[MAX_PATH + 1];
do
{
if (!GetTempPath(MAX_PATH, path))
{
dprintf("[WINPMEM] Unable to determine temporary path.");
break;
}
// filename is now the random path.
GetTempFileName(path, L"fls", 0, filename);
dprintf("[WINPMEM] Extracting fcat to %s", filename);
if (extract_file_(WINPMEM_FCAT_EXECUTABLE, filename) < 0)
{
break;
};
SECURITY_ATTRIBUTES saAttr;
HANDLE stdout_rd = NULL;
HANDLE stdout_wr = NULL;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if (!CreatePipe(&stdout_rd, &stdout_wr, &saAttr, 0))
{
dprintf("[WINPMEM] StdoutRd CreatePipe");
break;
};
// Ensure the read handle to the pipe for STDOUT is not inherited.
SetHandleInformation(stdout_rd, HANDLE_FLAG_INHERIT, 0);
WCHAR command_line[1000];
swprintf(command_line, 1000, L"%s %s \\\\.\\%s", filename, &pagefile_path_[3], pagefile_path_);
CreateChildProcess(command_line, stdout_wr);
dprintf("[WINPMEM] Preparing to read pagefile.");
int running = 1;
while (running)
{
DWORD bytes_read = buffer_size_;
DWORD bytes_written = 0;
if (!ReadFile(stdout_rd, buffer_, bytes_read, &bytes_read, NULL))
{
break;
};
if (!WriteFile(out_fd_, buffer_, bytes_read, &bytes_written, NULL) ||
bytes_written != bytes_read) {
dprintf("[WINPMEM] Failed to write image file");
running = 0;
break;
};
out_offset += bytes_written;
};
} while (0);
// Write another metadata header.
{
char metadata[1000];
_snprintf_s(metadata, sizeof(metadata), _TRUNCATE,
"# PMEM\n"
"---\n"
"PreviousHeader: %#llx\n"
"PagefileOffset: %#llx\n"
"PagefileSize: %#llx\n"
"...\n",
last_header_offset_,
pagefile_offset,
out_offset - pagefile_offset
);
DWORD metadata_len = (DWORD)strlen(metadata);
DWORD bytes_written = 0;
if (!WriteFile(out_fd_, metadata, metadata_len, &bytes_written, NULL) || bytes_written != metadata_len)
{
dprintf("[WINPMEM] Failed to write image file");
};
out_offset += bytes_written;
};
DeleteFile(filename);
};
int WinPmem::write_raw_image()
{
// Somewhere to store the info from the driver;
struct PmemMemoryInfo info;
DWORD size;
int status = -1;
do
{
if (out_fd_ == INVALID_HANDLE_VALUE)
{
dprintf("[WINPMEM] Must open an output file first.");
break;
};
RtlZeroMemory(&info, sizeof(info));
// Get the memory ranges.
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char*)&info,
sizeof(info), &size, NULL)) {
dprintf("[WINPMEM] Failed to get memory geometry,");
break;
};
dprintf("[WINPMEM] Will generate a RAW image");
print_memory_info();
int64_t offset = 0;
int failed = 0;
for (int64_t i = 0; i < info.NumberOfRuns.QuadPart; i++)
{
if (info.Run[i].start > offset)
{
dprintf("[WINPMEM] Padding from 0x%08llX to 0x%08llX", offset, info.Run[i].start);
if (!pad((size_t)(info.Run[i].start - offset)))
{
failed = 1;
break;
}
};
copy_memory((size_t)info.Run[i].start, (size_t)(info.Run[i].start + info.Run[i].length));
offset = info.Run[i].start + info.Run[i].length;
};
if (!failed)
{
// All is well.
status = 1;
}
} while (0);
if (out_fd_ != NULL && out_fd_ != INVALID_HANDLE_VALUE)
{
CloseHandle(out_fd_);
}
out_fd_ = INVALID_HANDLE_VALUE;
return status;
};
WinPmem::WinPmem()
: fd_(INVALID_HANDLE_VALUE),
buffer_size_(1024 * 1024),
buffer_(NULL),
service_name(PMEM_SERVICE_NAME),
max_physical_memory_(0),
mode_(PMEM_MODE_AUTO),
default_mode_(PMEM_MODE_AUTO),
metadata_(NULL),
metadata_len_(0),
driver_filename_(NULL),
driver_is_tempfile_(false),
out_offset(0),
pagefile_path_(NULL)
{
buffer_ = new char[buffer_size_];
}
WinPmem::~WinPmem()
{
if (fd_ != INVALID_HANDLE_VALUE)
{
CloseHandle(fd_);
};
if (buffer_)
{
delete[] buffer_;
}
if (driver_filename_ && driver_is_tempfile_)
{
free(driver_filename_);
}
}
int WinPmem::extract_file_(__int64 resource_id, TCHAR *filename)
{
int result = -1;
// Locate the driver resource in the .EXE file.
HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(resource_id), L"FILE");
do
{
if (hRes == NULL)
{
dprintf("[WINPMEM] Could not locate driver resource.");
break;
}
HGLOBAL hResLoad = LoadResource(NULL, hRes);
if (hResLoad == NULL)
{
dprintf("[WINPMEM] Could not load driver resource.");
break;
}
VOID* lpResLock = LockResource(hResLoad);
if (lpResLock == NULL)
{
dprintf("[WINPMEM] Could not lock driver resource.");
break;
}
DWORD size = SizeofResource(NULL, hRes);
// Now open the filename and write the driver image on it.
HANDLE out_fd = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (out_fd == INVALID_HANDLE_VALUE)
{
dprintf("[WINPMEM] Can not create temporary file.");
break;
};
if (!WriteFile(out_fd, lpResLock, size, &size, NULL))
{
dprintf("[WINPMEM] Can not write to temporary file.");
break;
}
result = 1;
} while (0);
if (out_fd_ != NULL && out_fd_ != INVALID_HANDLE_VALUE)
{
CloseHandle(out_fd_);
}
return result;
};
void WinPmem::set_driver_filename(TCHAR *driver_filename)
{
DWORD res;
if (driver_filename_)
{
free(driver_filename_);
driver_filename_ = NULL;
};
if (driver_filename)
{
driver_filename_ = (TCHAR *)malloc(MAX_PATH * sizeof(TCHAR));
if (driver_filename_)
{
res = GetFullPathName(driver_filename, MAX_PATH, driver_filename_, NULL);
};
};
}
void WinPmem::set_pagefile_path(TCHAR *path)
{
DWORD res;
if (pagefile_path_)
{
free(pagefile_path_);
pagefile_path_ = NULL;
};
if (path)
{
pagefile_path_ = (TCHAR *)malloc(MAX_PATH * sizeof(TCHAR));
if (pagefile_path_)
{
res = GetFullPathName(path, MAX_PATH, pagefile_path_, NULL);
};
// Split at the drive letter. C:\pagefile.sys
pagefile_path_[2] = 0;
};
};
int WinPmem::install_driver()
{
SC_HANDLE scm, service;
int status = -1;
do
{
// Try to load the driver from the resource section.
if (extract_driver() < 0)
{
break;
}
uninstall_driver();
scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (!scm)
{
dprintf("[WINPMEM] Can not open SCM. Are you administrator?\n");
break;
}
service = CreateService(scm,
service_name,
service_name,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
driver_filename_,
NULL,
NULL,
NULL,
NULL,
NULL);
if (GetLastError() == ERROR_SERVICE_EXISTS) {
service = OpenService(scm, service_name, SERVICE_ALL_ACCESS);
}
if (!service)
{
break;
};
if (!StartService(service, 0, NULL))
{
if (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING)
{
dprintf("[WINPMEM] Error: StartService(), Cannot start the driver.\n");
break;
}
}
dprintf("[WINPMEM] Loaded Driver %s.\n", driver_filename_);
fd_ = CreateFile(TEXT("\\\\.\\") TEXT(PMEM_DEVICE_NAME),
// Write is needed for IOCTL.
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fd_ == INVALID_HANDLE_VALUE) {
dprintf("[WINPMEM] Can not open raw device.");
break;
};
status = 1;
} while (0);
if (service != NULL)
{
CloseServiceHandle(service);
}
if (scm != NULL)
{
CloseServiceHandle(scm);
}
// Only remove the driver file if it was a temporary file.
if (driver_is_tempfile_)
{
dprintf("[WINPMEM] Deleting %S", driver_filename_);
DeleteFile(driver_filename_);
};
return status;
}
int WinPmem::uninstall_driver()
{
SC_HANDLE scm, service;
SERVICE_STATUS ServiceStatus;
scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (!scm) return 0;
service = OpenService(scm, service_name, SERVICE_ALL_ACCESS);
if (service)
{
ControlService(service, SERVICE_CONTROL_STOP, &ServiceStatus);
DeleteService(service);
CloseServiceHandle(service);
dprintf("[WINPMEM] Driver Unloaded.");
return 1;
};
return 0;
}
/* Create a YAML file describing the image encoded into a null terminated
string. Caller will own the memory.
*/
char *store_metadata_(struct PmemMemoryInfo *info)
{
SYSTEM_INFO sys_info;
char *arch = NULL;
// Get basic architecture information (Note that we always write ELF64 core
// dumps - even on 32 bit platforms).
ZeroMemory(&sys_info, sizeof(sys_info));
GetNativeSystemInfo(&sys_info);
switch (sys_info.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_AMD64:
arch = "AMD64";
break;
case PROCESSOR_ARCHITECTURE_INTEL:
arch = "I386";
break;
default:
arch = "Unknown";
}
char *buffer = (char *)malloc(1000);
_snprintf_s(buffer, 1000, _TRUNCATE,
// A YAML File describing metadata about this image.
"# PMEM\n"
"---\n" // The start of the YAML file.
"acquisition_tool: 'WinPMEM " PMEM_VERSION "'\n"
"CR3: %#llx\n"
"NtBuildNumber: %#llx\n"
"NtBuildNumberAddr: %#llx\n"
"KernBase: %#llx\n"
"Arch: %s\n"
"...\n", // This is the end of a YAML file.
info->CR3.QuadPart,
info->NtBuildNumber.QuadPart,
info->NtBuildNumberAddr.QuadPart,
info->KernBase.QuadPart,
arch
);
return buffer;
};
// WinPmem64 - A 64 bit implementation of the imager.
__int64 WinPmem::write_coredump_header_(struct PmemMemoryInfo *info)
{
Elf64_Ehdr header;
DWORD header_size;
Elf64_Phdr pheader;
int i;
if (!metadata_) {
metadata_ = store_metadata_(info);
if (!metadata_) return 0;
metadata_len_ = (DWORD)strlen(metadata_);
};
// Where we start writing data.
uint64 file_offset = (
sizeof(Elf64_Ehdr) +
// One Phdr for each run and one for the metadata.
(info->NumberOfRuns.QuadPart + 1) * sizeof(Elf64_Phdr));
// All values that are unset will be zero
RtlZeroMemory(&header, sizeof(Elf64_Ehdr));
// We create a 64 bit core dump file with one section
// for each physical memory segment.
header.ident[0] = ELFMAG0;
header.ident[1] = ELFMAG1;
header.ident[2] = ELFMAG2;
header.ident[3] = ELFMAG3;
header.ident[4] = ELFCLASS64;
header.ident[5] = ELFDATA2LSB;
header.ident[6] = EV_CURRENT;
header.type = ET_CORE;
header.machine = EM_X86_64;
header.version = EV_CURRENT;
header.phoff = sizeof(Elf64_Ehdr);
header.ehsize = sizeof(Elf64_Ehdr);
header.phentsize = sizeof(Elf64_Phdr);
// One more header for the metadata.
header.phnum = (uint32)info->NumberOfRuns.QuadPart + 1;
header.shentsize = sizeof(Elf64_Shdr);
header.shnum = 0;
header_size = sizeof(header);
if (!WriteFile(out_fd_, &header, header_size, &header_size, NULL))
{
dprintf("[WINPMEM] Failed to write header");
return 0;
};
out_offset += header_size;
for (i = 0; i < info->NumberOfRuns.QuadPart; i++) {
PHYSICAL_MEMORY_RANGE range = info->Run[i];
RtlZeroMemory(&pheader, sizeof(Elf64_Phdr));
pheader.type = PT_LOAD;
pheader.paddr = range.start;
pheader.memsz = range.length;
pheader.align = PAGE_SIZE;
pheader.flags = PF_R;
pheader.off = file_offset;
pheader.filesz = range.length;
// Move the file offset by the size of this run.
file_offset += range.length;
header_size = sizeof(pheader);
if (!WriteFile(out_fd_, &pheader, header_size, &header_size, NULL)) {
dprintf("[WINPMEM] Failed to write header");
return 0;
};
out_offset += header_size;
};
// Add a header for the metadata so it can be easily found in the file.
RtlZeroMemory(&pheader, sizeof(Elf64_Phdr));
pheader.type = PT_PMEM_METADATA;
// The metadata section will be written at the end of the
pheader.off = file_offset;
pheader.filesz = metadata_len_;
header_size = sizeof(pheader);
if (!WriteFile(out_fd_, &pheader, header_size, &header_size, NULL)) {
dprintf("[WINPMEM] Failed to write header");
return 0;
};
out_offset += header_size;
return 1;
};
int WinPmem::extract_driver(TCHAR *driver_filename)
{
set_driver_filename(driver_filename);
return extract_driver();
};
int WinPmem64::extract_driver()
{
// 64 bit drivers use PTE acquisition by default.
default_mode_ = PMEM_MODE_PTE;
if (!driver_filename_) {
TCHAR path[MAX_PATH + 1];
TCHAR filename[MAX_PATH + 1];
// Gets the temp path env string (no guarantee it's a valid path).
if (!GetTempPath(MAX_PATH, path)) {
dprintf("[WINPMEM] Unable to determine temporary path.");
return -1;
}
GetTempFileName(path, service_name, 0, filename);
set_driver_filename(filename);
driver_is_tempfile_ = true;
};
dprintf("[WINPMEM] Extracting driver to %S", driver_filename_);
return extract_file_(WINPMEM_64BIT_DRIVER, driver_filename_);
}
int WinPmem32::extract_driver()
{
// 32 bit acquisition defaults to physical device.
default_mode_ = PMEM_MODE_PHYSICAL;
if (!driver_filename_)
{
TCHAR path[MAX_PATH + 1];
TCHAR filename[MAX_PATH + 1];
// Gets the temp path env string (no guarantee it's a valid path).
if (!GetTempPath(MAX_PATH, path)) {
dprintf("[WINPMEM] Unable to determine temporary path.");
return -1;
}
GetTempFileName(path, service_name, 0, filename);
set_driver_filename(filename);
driver_is_tempfile_ = true;
};
dprintf("[WINPMEM] Extracting driver to %S", driver_filename_);
return extract_file_(WINPMEM_32BIT_DRIVER, driver_filename_);
}