Ты был очень близок к разгадке.
Уже тут всё стало понятно:
Если посмотреть с другой стороны(без использования патча), то ответ на поверхности - как приложения учитывают кол-во копий?
-Объекты ядра(Events, Mutex, Jobs).
При запуске первого приложения, создаётся Mutex с именем "PoERunMutexA", где A - указывает, что это первая копия игры, а так же, проверяется создан ли мютекс PoERunMutexB. Если создан - значит показываем сообщение с огр. кол-ва запуска.
При запуске второго, проверяется первый мютекс и создаётся второй
После этого, если мы попытаемся запустить третью копию - вылезет ошибка.
Лечение:
Закрывать PoERunMutexB или PoERunMutexA , и тогда мы сможем запускать сколько угодно копий, без патча и прочих извров.
Примерный код реализации в игре:
function CreateMutexEx(name: PWideChar): LongBool;
begin
CreateMutex(nil, false, name);
if GetLastError = ERROR_ALREADY_EXISTS
then Result := False
else Result := True;
end;
begin
if (CreateMutexEx('PoERunMutexA') = false) //первая копия запущена
then if (CreateMutexEx('PoERunMutexB') = false) //если вторая копия запущена
then MessageBox(0, 'You may only run бла бла бла', 'Error', 1);
end.
Моего ПК хватило только на 5 копий: