C++ - How to specify offset of MBR? - c++

I have been able to modify such that the MBR is overwritten with 0 values. However, is it possible to make it such that I only overwrite the last 2 bytes (55h AAh) of the MBR (Boot Signature) to become 00h 00h ?
My code is:
char dataWrite[3] = "\x00\x00";
// Create file of physical drive
HANDLE MasterBootRecord = CreateFile("\\\\.\\PhysicalDrive0"
, GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE
, NULL, OPEN_EXISTING, NULL, NULL);
// Set file pointer
DWORD dwPtr1 = SetFilePointer(MasterBootRecord, 510, NULL, NULL);
if (dwPtr1 == INVALID_SET_FILE_POINTER) // Test for failure
{
cout<< "\n\nSetFilePointer Failed to write,Err No: "<< GetLastError();
Sleep(5000);
ExitProcess(0);
}
// Write to file
if (WriteFile(MasterBootRecord, dataWrite, 512, &write, NULL)) {
cout << "Boot signature overwritten." << endl;
Sleep(5000);
ExitProcess(0);
} else...
It turns out successful but the values written to the MBR are wrong. I am rather new to C++ thus am a little confused with this. Any help will be appreciated. Thanks

Related

How to append in file in Windows in UnBuffered mode using CreateFile

Every time my function is getting called it is overwriting to the file. Kindly note I am opening file in unbuffered mode using below flags.
FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH
If I am using simple buffered mode it is working fine.
FILE_ATTRIBUTE_NORMAL
I am getting following error in unbuffered mode.
** ERROR ** CreateFile failed: The parameter is incorrect.
Kindly find the code snippets below. This piece of code getting called many times.
HANDLE hFile;
LPCWSTR file_path = convertCharArrayToLPCWSTR(UNBUFFERED_FILE);
hFile = CreateFile(file_path,
FILE_APPEND_DATA,
FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
{
std::cout << "Unable to open/create file for writing" << std::endl;
PrintError(TEXT("CreateFile failed"));
}
Data *data = new Data();
DWORD dwBytesToWrite = sizeof(Data);
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;
bErrorFlag = WriteFile(
hFile, // open file handle
data, // start of data to write
dwBytesToWrite, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL);
if (bErrorFlag == FALSE)
{
std::cout << "Unable to write to file" << std::endl;
PrintError(TEXT("Unable to write to file"));
}
if (dwBytesToWrite != dwBytesWritten)
{
std::cout << "Error in writing: Whole data not written" << std::endl;
PrintError(TEXT("Error in writing: Whole data not written"));
}
CloseHandle(hFile);
.
Kindly suggest if any alternative idea is available.
from NtCreateFile
FILE_NO_INTERMEDIATE_BUFFERING
The file cannot be cached or buffered in a driver's internal
buffers. This flag is incompatible with the DesiredAccess
parameter's FILE_APPEND_DATA flag.
so when you call
CreateFile(file_path,
FILE_APPEND_DATA, // !!
FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_FLAG_NO_BUFFERING /*!!*/| FILE_FLAG_WRITE_THROUGH,
NULL
);
you use FILE_FLAG_NO_BUFFERING (mapped to FILE_NO_INTERMEDIATE_BUFFERING) with FILE_APPEND_DATA - you and must got ERROR_INVALID_PARAMETER. you need remove one flag. i suggest remove FILE_FLAG_NO_BUFFERING flag, because with it you can write only integral of the sector size.

Why the file could be written after changing the attribute to readonly under windows?

Given one normal file, it could be read and written. Then I change this file attribute to Read-only through
However, this file still could be written through file handler. Here are my codes
#define CREATE_FILE_OPT FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_RANDOM_ACCESS
std::string name("test.txt");
HANDLE hfile = ::CreateFile(name.c_str(),
GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, CREATE_FILE_OPT, NULL);
if (hfile == INVALID_HANDLE_VALUE) {
hfile = ::CreateFile(name.c_str(),
GENERIC_READ | GENERIC_WRITE, NULL, NULL, CREATE_NEW, CREATE_FILE_OPT, NULL);
if (hfile == INVALID_HANDLE_VALUE) {
printf("so sad, invalid file handler....");
return -1;
}
}
int i = 0;
char rbuf[] = "you are";
DWORD bytesWritten;
do {
Sleep(5000);
++i;
bytesWritten = 0;
BOOL bret = ::WriteFile(hfile, rbuf, strlen(rbuf), &bytesWritten, NULL);
if (bret == FALSE) {
printf("Cannot write bytes into file.....");
DWORD err = GetLastError();
printf("The error code is %d\n", err);
}
else
printf("write %d bytes to file\n", bytesWritten);
DWORD ret = GetFileAttributes(name.c_str());
printf("The file attribute is %d\n", ret);
} while (i < 10000);
The file attribute is 32 before I change it to Read-only, but it will be 33 after this file is Read-only.
I want to know why the file could be written after change it to Read-only? Is there any issue in my test codes?
PS: test it in VS2015 under windows 7.
Sorry, I get your meaning finally. I guess you are talking about creating a file first, setting it readonly without closing the program. The READONLY attribute check only happens in CreateFile routine.
In Windows kernel, every object is assigned a temporary access right list once created, unless explicitly refreshed, a thing seldom happens on actual files on fixed disks. So even if you deny all rights after CreateFile using NTFS access control, your program will behave just as when CreateFile is called.
In conclusion, it is natural your program can still write to the file, after your hot-changing it into READONLY, which only writes information onto disk, not changing kernel access table.

Writing raw data to a disk in windows fails with error code 83 (invalid parameter)

I have a little snippet of code that I am trying to use to write a string that is roughly 100 bytes long to a disk at the address 0x600.
UCHAR szStr[0x4C] = {0};
memcpy(szStr, "Example string", 8);
DWORD bytes, cb;
HANDLE hDisk = CreateFile("\\\\.\\I:", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDisk == INVALID_HANDLE_VALUE)
{
cout << "CreateFile error"<< endl << GetLastError();
}
if (!DeviceIoControl(hDisk, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &cb, NULL))
{
cout << "IO Error"<< endl << GetLastError();
}
if (SetFilePointer(hDisk, 0x600, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
{
cout << "Pointer error"<< endl << GetLastError();
}
if (!WriteFile(hDisk, szStr, 0x4C, &bytes, 0))
{
cout << "Write error" << endl << GetLastError(); //Only one that triggers (err code 87)
}
CloseHandle(hDisk);
For some reason everything is OK until I call WriteFile() which fails. GetLastError() returns a code of 83 which means INVALID_PARAMETER. I have tried debugging it by specifing a normal file on the desktop instead of the drive I:\ and the operation fires off successfully so my best guess would be the problem lies with the disk handle to the drive I:\.
I read an article by MSDN located here that explains that raw disk I/O gets blocked if you don't lock/dismount the drive first. I am confused as to why that would be a problem as in my code I call DeviceIoControl with FSCTL_LOCK_VOLUME to lock the device before I perform anything else. The disk has an active file system (FAT32/FAT16) and the 0x600 region likely lies within the filesystem, but according to the article if I lock the drive I should be able to write to it. Any idea what is going on here? Thanks!
Are you checking DeviceIoControl and SetFilePointer for an error indication?
Do you have the rights to do the operations you're attempting? Administrator account is required for raw disk writes IIRC.
Is the disk you're trying to open a system disk? (Does it contain the OS files?) If so the Lock IOCTL will fail.
If there's a page file on the disk you're trying to lock the Lock IOCTL will fail.

C++: Implementing Named Pipes using the Win32 API

I'm trying to implement named pipes in C++, but either my reader isn't reading anything, or my writer isn't writing anything (or both). Here's my reader:
int main()
{
HANDLE pipe = CreateFile(GetPipeName(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
char data[1024];
DWORD numRead = 1;
while (numRead >= 0)
{
ReadFile(pipe, data, 1024, &numRead, NULL);
if (numRead > 0)
cout << data;
}
return 0;
}
LPCWSTR GetPipeName()
{
return L"\\\\.\\pipe\\LogPipe";
}
And here's my writer:
int main()
{
HANDLE pipe = CreateFile(GetPipeName(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
string message = "Hi";
WriteFile(pipe, message.c_str(), message.length() + 1, NULL, NULL);
return 0;
}
LPCWSTR GetPipeName()
{
return L"\\\\.\\pipe\\LogPipe";
}
Does that look right? numRead in the reader is always 0, for some reason, and it reads nothing but 1024 -54's (some weird I character).
Solution:
Reader (Server):
while (true)
{
HANDLE pipe = CreateNamedPipe(GetPipeName(), PIPE_ACCESS_INBOUND | PIPE_ACCESS_OUTBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
if (pipe == INVALID_HANDLE_VALUE)
{
cout << "Error: " << GetLastError();
}
char data[1024];
DWORD numRead;
ConnectNamedPipe(pipe, NULL);
ReadFile(pipe, data, 1024, &numRead, NULL);
if (numRead > 0)
cout << data << endl;
CloseHandle(pipe);
}
Writer (client):
HANDLE pipe = CreateFile(GetPipeName(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (pipe == INVALID_HANDLE_VALUE)
{
cout << "Error: " << GetLastError();
}
string message = "Hi";
cout << message.length();
DWORD numWritten;
WriteFile(pipe, message.c_str(), message.length(), &numWritten, NULL);
return 0;
The server blocks until it gets a connected client, reads what the client writes, and then sets itself up for a new connection, ad infinitum. Thanks for the help, all!
You must use CreateNamedPipe() to create the server end of a named pipe. Be sure to specify a non-zero buffer size, zero (documented by MSDN as 'use system default buffer size') doesn't work. MSDN has decent samples for a multi-threaded client&server.
A named pipe client can open the named pipe with CreateFile -- but the named pipe server needs to use CreateNamedPipe to create the named pipe. After it's created the named pipe, the server uses ConnectNamedPipe to wait for a client to connect. Only after the client has connected should the server do a blocking read like your call to ReadFile.

MapViewOfFile shared between 32bit and 64bit processes

I'm trying to use MapViewOfFile in a 64 bit process on a file that is already mapped to memory of another 32 bit process. It fails and gives me an "access denied" error. Is this a known Windows limitation or am I doing something wrong? Same code works fine with 2 32bit processes.
The code sort of looks like this:
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szShmName);
if (NULL == hMapFile)
{ /* failed to open - create new (this happens in the 32 bit app) */
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
/* give access to members of administrators group */
BOOL success = ConvertStringSecurityDescriptorToSecurityDescriptor(
"D:(A;OICI;GA;;;BA)",
SDDL_REVISION_1,
&(sa.lpSecurityDescriptor),
NULL);
HANDLE hShmFile = CreateFile(FILE_XXX_SHM,
FILE_ALL_ACCESS, 0,
&sa,
OPEN_ALWAYS, 0, NULL);
hMapFile = CreateFileMapping(hShmFile, &sa, PAGE_READWRITE,
0,
SHM_SIZE,
szShmName);
CloseHandle(hShmFile);
}
// this one fails in 64 bit app
pShm = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, SHM_SIZE);
When you call CreateFile in the 32-bit application, you're passing 0 for the sharing parameter, which means no sharing is allowed. Changing that to FILE_SHARE_READ | FiLE_SHARE_WRITE would probably be a step in the right direction.
Edit: I just whipped together a demo that works (at least for me):
#include <windows.h>
#include <iostream>
static const char map_name[] = "FileMapping1";
static const char event1_name[] = "EventName1";
static const char event2_name[] = "EventName2";
int main() {
HANDLE mapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, map_name);
if (NULL == mapping) {
std::cout << "Calling CreateFile\n";
HANDLE file = CreateFile("MappedFile",
FILE_ALL_ACCESS,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
0,
NULL);
std::cout << "Creating File mapping\n";
mapping = CreateFileMapping(file, NULL, PAGE_READWRITE, 0, 65536, map_name);
std::cout << "Closing file handle\n";
CloseHandle(file);
}
std::cout << "Mapping view of file\n";
char *memory = (char *)MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 65536);
if (memory == NULL) {
std::cerr << "Mapping Failed.\n";
return 1;
}
std::cout << "Mapping succeeded\n";
HANDLE event = CreateEvent(NULL, false, false, event1_name);
if (GetLastError()==ERROR_ALREADY_EXISTS) {
std::cout <<"Waiting to receive string:\n";
WaitForSingleObject(event, INFINITE);
std::cout << "Received: " << memory;
HANDLE event2 = CreateEvent(NULL, false, false, event2_name);
SetEvent(event2);
}
else {
char string[] = "This is the shared string";
std::cout << "Sending string: " << string << "\n";
strncpy(memory, string, sizeof(string));
SetEvent(event);
HANDLE event2 = CreateEvent(NULL, false, false, event2_name);
WaitForSingleObject(event2, INFINITE);
}
return 0;
}
Any combination of 32- or 64-bit executables seems to work fine.
Edit2: Note, however, that this is purely demo-level code. Just for example, the name of each shared object should normally contain a GUID-string to ensure against accidental collision with other programs. I've also skipped quite a bit of error checking, not to mention the minor detail that this code doesn't accomplish anything useful.