Я вижу некоторые проблемы с вашим кодом.
GetLastError()
. VirtualProtectEx()
. &baseAddr
требуется baseAddr
. Кроме того, вы выделяете и защищаете память с помощью разрешений EXECUTE
, которые вы не должны использовать, если не собираетесь хранить исполняемый код в памяти (который этот код не делает). sizeof(DWORD)
установить флаги защиты на удаленной памяти, но вы используете sizeof(SIZE_T)
для чтения памяти. DWORD
- фиксированный размер 32 бит, но SIZE_T
- 32 или 64 бита, в зависимости от платформы, для которой вы компилируете. Измените SIZE_T
на DWORD
, чтобы соответствовать остальной части вашего кода. ReadProcessMemory()
для записи. Измените void *buffer;
на DWORD buffer;
. Попробуйте следующее:
#include
#include
using namespace std;
int main()
{
DWORD dwError;
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_QUERY_INFORMATION, FALSE, (DWORD)7312);
if (hProc == NULL)
{
dwError = GetLastError();
cout << "OpenProcess has failed. Error: " << dwError << endl;
return 0;
}
HANDLE token;
if (!OpenProcessToken(hProc, TOKEN_ALL_ACCESS, &token))
{
dwError = GetLastError();
cout << "OpenProcessToken has failed. Error: " << dwError << endl;
return 0;
}
void *baseAddr = VirtualAllocEx(hProc, NULL, 500, MEM_RESERVE, PAGE_READWRITE);
if (baseAddr == NULL)
{
dwError = GetLastError();
cout << "VirtualAllocEx has failed. Error: " << dwError << endl;
return 0;
}
cout << "Base Address: " << baseAddr << endl;
DWORD prevProt;
if (!VirtualProtectEx(hProc, baseAddr, sizeof(DWORD), PAGE_READWRITE, &prevProt))
{
dwError = GetLastError();
cout << "VirtualAllocEx has failed. Error: ";
if (dwError == ERROR_INVALID_PARAMETER)
{
cout << "ERROR_INVALID_PARAMETER";
}
else if (dwError == ERROR_INVALID_ADDRESS)
{
cout << "ERROR_INVALID_ADDRESS";
}
else
{
cout << dwError;
}
cout << endl;
return 0;
}
DWORD buffer;
if (ReadProcessMemory(hProc, baseAddr, &buffer, sizeof(DWORD), NULL))
{
dwError = GetLastError();
cout << "ReadProcessMemory has failed. Error: ";
if (dwError == ERROR_PARTIAL_COPY)
{
cout << "ERROR_PARTIAL_COPY";
}
else
{
cout << dwError;
}
cout << endl;
return 0;
}
cout << "Value: " << buffer << endl;
return 0;
}
Еще несколько вопросов:
ReadProcessMemory
вернет FALSE и GetLastError
вернется ERROR_PARTIAL_COPY
, когда копия попадает на страницу с ошибкой. Рабочий набор Когда процесс ссылается на доступную для страниц память, которая в настоящее время не находится в рабочем наборе, возникает ошибка страницы. OpenProcessToken()
, так что вызов бесполезен. VirtualProtectEx()
, используя те же самые флаги защиты, которые вы указали, когда выделяя память. Таким образом, этот вызов тоже бесполезен. Чтобы проверить, когда кто-то отменяет возобновляемую подписку, вам необходимо периодически обновлять квитанцию на вашем сервере и проверять:
Обычно разработчики получают 2 и 3 смущенный. Apple не считает, что пользователь отказывается от автоматического продления «отмены» - тогда как на самом деле это то, что большинство разработчиков считают отменой. По этой причине НЕ достаточно прослушивать CANCEL
события с уведомлениями о статусе подписки .
Вот хороший пост в блоге, в котором подробно рассказывается: iOS-подписки жесткие