If in a x64 application (Borland Delphi XE2) occurs exception in code in a block “try … except”, then instead of execution the code inside “except … end” block shows message like “This code requires valid serial number to run. Program will be terminated.” and application closes.
An error occurs in an non-encrypted part of the code, i.e. not inside code blocks of like “VMProtectBeginUltra … VMProtectEnd;”.
The serial do not loaded before. It is DEMO mode of application.
What to do? How to work with “try … except … end”?
Если в x64 приложении внутри блока try … except происходит исключение, то вместо выполнения кода внутри блока except … end, появляется сообщение вида “This code requires valid serial number to run. Program will be terminated.” и приложение закрывается.
Ошибка происходит в незашищенном участке кода, т.е. не внутри блоков кода вида VMProtectBeginUltra … VMProtectEnd;
Серийный номер не загружался перед этим. Это ДЕМО режим работы приложения.
Что делать? Как работать блоками “try … except … end”?
Обратите внимание, что блоки try/finally могут быть неявными (например когда компилятор уничтожает локальные String). Поэтому когда вы обрабатываете маркер, то туда же попадает и код между fynally/end, а после except/end управление попадает как раз на начало finally в результате чего показывается сообщение об отсутствии серийного номера.
Что делать? Как работать блоками “try … except … end”?
В данном случае уносить маркер в отдельную функцию.
try
VMProtectBeginVirtualizationLockByKey('');
...
VMProtectEnd();
finally
...
end;
try
try
...
[код где происходит ошибка]
...
except
...
end;
finally
end;
В 32-х разрядном приложении, после наложении защиты VMProtect, все отрабатывает как и должно.
В х64 приложении, после наложении защиты VMProtect, после ошибки в коде появляется сообщение:
This code requires valid serial number to run.
Program will be terminated.
Перефразирую свой ответ - в код маркера попадает часть функции, которая выполняется после except/end (скорее всего это неявный finally, который вставляет компилятор):
var S: String;
begin
try
// ваш код здесь и и вам не нужно вызывать деструктор S, потому что, компилятор делает это сам в собственном finally блоке
finally
S.Free();
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var sList : TStringList;
begin
VMProtectBeginUltraLockByKey('Test.Protect');
VMProtectEnd;
try
sList[0] := 'Test string'; // тут будет AccessViolation
finally
ShowMessage('finally for s[0]');
end;
end;
Почему появляется сообщение “This code requires valid serial number to run. Program will be terminated.” ?
Как сделать, чтобы было сообщение “finally for s[0]” ?
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses VMProtectSDK;
procedure TForm1.Button1Click(Sender: TObject);
var sList : TStringList;
begin
VMProtectBeginUltraLockByKey('Test.Protect');
VMProtectEnd;
try
sList[0] := 'Test string';
finally
ShowMessage('finally for s[0]');
end;
end;
end.
И собственно проект:
program Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1},
VMProtectSDK in '..\..\..\Borland Studio Projects\Project\Common.VCL.VMProtect\VMProtectSDK.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.