#c #winapi
#c #winapi
Вопрос:
Я пытаюсь прочитать файл с помощью readfile, сохранить его в широком массиве, затем записать в другой файл. Проблема в том, что когда я помещаю их рядом в формате HxD, некоторые байты верны (например, текст), но все остальное совершенно другое. Я тоже не могу его запустить
struct a
{
BYTE* buff;
long siz;
};
int main()
{
HANDLE hFile;
a struct_a;
if (hFile = CreateFileW(L"C:\Windows\System32\notepad.exe", GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr))
{
long lFileSize = GetFileSize(hFile, nullptr);
if (lFileSize)
{
struct_a.siz = lFileSize;
struct_a.buff = new BYTE[struct_a.siz];
if (ReadFile(hFile, struct_a.buff, struct_a.siz,
nullptr, nullptr))
{
CloseHandle(hFile);
}
}
}
HANDLE h = CreateFileA("C:\Users\USER\Desktop\notepad_new.exe", GENERIC_WRITE, FILE_SHARE_WRITE, nullptr,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr);
WriteFile(h, struct_a.buff, struct_a.siz, nullptr, nullptr);
return 0;
}
Я хочу, чтобы он мог правильно прочитать файл, а затем записать его, чтобы я мог его запустить.
В качестве бонуса я также попытался записать несколько байтов в конце файла после того, как прочитал его, выполнив
struct_a.buff[struct_a.siz - 5] = L'A';
но это нигде не отображалось. Но когда я попытался записать это в начале (убрав скобки), он записал это нормально.
РЕДАКТИРОВАТЬ: я попытался прочитать его впоследствии, и он, как ни странно, прочитал правильную букву
Комментарии:
1. Похоже, вы не хотите работать с файлом как с текстовым файлом и должны вместо этого обрабатывать его как двоичные данные.
2. Объясните дальнейший помощник
3. Можете ли вы, ребята, сказать мне, в чем мои проблемы, вместо того, чтобы голосовать против меня? Я не эксперт, но я изо всех сил старался сделать все сам, поэтому я подумал, что могут возникнуть некоторые ошибки
4. Еще не проголосовал. Но, вероятно, избиратели обескуражены тем, что в вашем примере кода не хватает информации. Возможно, это неверное представление вашей реальной программы. Примечательно, что мы не видим, происходят ли эти чтения и записи в одной и той же функции или именно там, где
struct_a
определено. Что касается вашего «бонусного» теста, это вызывает тревогу. Если вы не видите никаких изменений, то, возможно, вы на самом деле никогда не записывали (возможно, файл уже открыт?) — проверьте, действителен ли дескриптор после открытия файла, и выдайте ошибку, если нет. Что касается двоичного режима, это необходимо, чтобы избежать перевода новой строки.5. На самом деле проблема с «бонусом» заключается в том, что вы выделили
wchar_t
массив. Не считывайте ваш файл какwchar_t
значения!! Размер файла указан в байтах . Когда вы обращаетесь кsize-5
элементу вwchar_t
массиве, это далеко от конца файла.
Ответ №1:
Левый файл на скриншоте является 32-разрядным EXE-файлом. Выделенный вами байт, который отличается, является адресом структуры IMAGE_NT_HEADERS в файле.
По адресу 0xFC, 4 байта в этой структуре, 2 байта равны 4C 01. Это поле Machine в IMAGE_FILE_HEADERS, и это значение указывает, что на компьютере установлен «i386» (т. е. 32-разрядная программа).
В нужном файле вместо адреса указан 0xEC, а байты равны 64 86, что означает «AMD64» (т. е. это 64-разрядная программа).
Вероятно, ваша программа является 32-разрядной программой, и поэтому она обращается к 32-разрядной версии System32 из-за функции Windows, называемой перенаправлением файловой системы (спасибо Полу Сандерсу за ссылку). В 64-разрядной Windows 32-разрядные программы перенаправляют System32 в другую папку (которая на самом деле называется SysWOW64) — согласно этой таблице:
32-bit System32 64-bit System32
32-bit program C:WindowsSystem32 C:Windowssysnative
64-bit program C:WindowsSysWOW64 C:WindowsSystem32
Вы можете решить эту проблему, либо прочитав notepad.exe из sysnative, или сравнивая его с файлом в SysWOW64 вместо файла в System32, или компилируя вашу программу как 64-разрядную.
Комментарии:
1. Вы очень правы, я не могу поверить, что я этого не видел. У меня даже вызов ReadProcessMemory возвращал несоответствующую длину, потому что я пытался получить доступ к процессу x64 из скомпилированного exe-файла x86. Большое спасибо