Нужно знать, когда кто-то отменяет возобновляемую подписку

Я вижу некоторые проблемы с вашим кодом.

  1. Плохая обработка ошибок. Если произошла ошибка, вы регистрируете ее, но продолжаете идти вперед с плохими данными. Если произошла ошибка, STOP. И вы злоупотребляете GetLastError().
  2. Вы передаете неправильную базовую аддрию в VirtualProtectEx(). &baseAddr требуется baseAddr. Кроме того, вы выделяете и защищаете память с помощью разрешений EXECUTE, которые вы не должны использовать, если не собираетесь хранить исполняемый код в памяти (который этот код не делает).
  3. Вы используете sizeof(DWORD) установить флаги защиты на удаленной памяти, но вы используете sizeof(SIZE_T) для чтения памяти. DWORD - фиксированный размер 32 бит, но SIZE_T - 32 или 64 бита, в зависимости от платформы, для которой вы компилируете. Измените SIZE_T на DWORD, чтобы соответствовать остальной части вашего кода.
  4. Вы не выделяете какую-либо память в вызывающем процессе для записи 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;
}

Еще несколько вопросов:

  1. Вы резервирование памяти в удаленном процессе, но вы не , фиксируя физическое хранилище для этой памяти, и вы не пишете что-либо в памяти перед чтением с нее. Чтение зарезервированной незафиксированной памяти не очень полезно и является вероятным виновником вашей ошибки: https://stackoverflow.com/a/4457745/65863 ReadProcessMemory вернет FALSE и GetLastError вернется ERROR_PARTIAL_COPY, когда копия попадает на страницу с ошибкой. Рабочий набор Когда процесс ссылается на доступную для страниц память, которая в настоящее время не находится в рабочем наборе, возникает ошибка страницы.
  2. Вы не используете токен, возвращенный функцией OpenProcessToken(), так что вызов бесполезен.
  3. Вы защищаете удаленную память с помощью VirtualProtectEx(), используя те же самые флаги защиты, которые вы указали, когда выделяя память. Таким образом, этот вызов тоже бесполезен.

0
задан Callum 16 January 2019 в 05:26
поделиться

1 ответ

Чтобы проверить, когда кто-то отменяет возобновляемую подписку, вам необходимо периодически обновлять квитанцию ​​на вашем сервере и проверять:

  1. Дата истечения срока действия (позволяет узнать, активна ли подписка)
  2. Состояние автоматического обновления (позволяет узнать, был ли пользователь «отменен»)
  3. Дата отмены (сообщает, почему подписка отменена службой поддержки)

Обычно разработчики получают 2 и 3 смущенный. Apple не считает, что пользователь отказывается от автоматического продления «отмены» - тогда как на самом деле это то, что большинство разработчиков считают отменой. По этой причине НЕ достаточно прослушивать CANCEL события с уведомлениями о статусе подписки .

Вот хороший пост в блоге, в котором подробно рассказывается: iOS-подписки жесткие

0
ответ дан enc_life 16 January 2019 в 05:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: