' аварийное завершение произойдет при истекшем лиц. периоде Private Sub Процедура1() Var1 = False ... ' например, Var2 = &H80000000, а Var3 - содержит кол-во оставшихся дней лиц. периода, тогда если период истек - значение Var3 будет отрицательным и выражение (&H80000000 And <отрицат.>) будет не равно нулю, и это вызовет переход на ваш "левый" код. If Var2 And Var3 Then GoTo SomeErr ... Exit Sub SomeErr: ' здесь какой-нибудь "левый", отвлекающий, код, который вызовет критическую ошибку и не даст продолжить, или отработав просто завершит работу программы. ... Var4 = Var4 / Var1 ' деление на ноль! ... End ' или просто завершение программы. End Sub ' аварийное завершение произойдет при истекшем лиц. периоде Private Sub Процедура2() On Error GoTo ErrHandler ... (отлаженный код, не вызывающий ошибок) Процедура3 ... (отлаженный код, не вызывающий ошибок) Exit Sub ErrHandler: End End Sub Private Sub Процедура3() ... (отлаженный код, не вызывающий ошибок) ' например, Var5 - срок оконч. лиц., а Var6 - текущая дата (чтобы сильнее "запутать", даты можно хранить в переменных с числовым типом: Long, Single, Double) ' и т.к. переменная <счетчик1> имеет тип Byte - когда-то (зависит от первоначального, рандомного знач., присвоенного при запуске программы) это выражение вызовет ошибку переполнения и завершение программы. ' причем, ошибка произойдет в этой процедуре, а "точка выхода" будет в Процедура2, что также должно усложнить работу взломщика... ' (можно разбросать по коду, по разным функциям, несколько счетчиков с разными рандомными первоначальными значениями, чтобы сложнее было понять условия срабатывания, т.е. при одном запуске программы первонач. знач. может быть большим и ошибка может сгенерится уже при первом или втором вызове процедуры, а при другом запуске - первонач. знач. может быть маленьким и ошибка сгенерится только, например, на 15 вызове процедуры) If Var5 >= Var6 Then <счетчик1> = <счетчик1> + 32 'If Var5 >= Var6 Then <счетчик1> = <счетчик1> - 7 ' (или так) ... (отлаженный код, не вызывающий ошибок) End Sub ' аварийное завершение произойдет при неверном ключе Private Sub Процедура4() On Error GoTo ErrHandler ... ' некоторые процедуры и функции вызываем подобным способом: CallByName Me, Var7 Xor Var8, VbMethod, True ' где одна из переменных содержит закодированное имя вызываемой процедуры, а другая - "ключ", получаемый преобразованием из лиц. ключа и хэша данных из лиц. файла. ' если в лиц. файле ВСЕ данные верны, то выражение (Var7 Xor Var8) вернет правильное имя процедуры и произойдет ее вызов, ' если какие-то данные в лиц. файле изменены или повреждены - выражение вернет мусор, что вызовет ошибку и завершение программы. ... Exit Sub ErrHandler: End End Sub (файл лиц. - у меня это обычный ini-файл, поэтому можно использовать стандартный функции GetPrivateProfile..., и в одном файле можно хранить лиц. для нескольких программ, в разных секциях, а при небольшой переделке - все это можно хранить в реестре) [Название программы] Owner=ЗАО АКБ "Рога и копыта" BIC=044585... SN=00010257 ExpiredDate=06/06/2015 Key=Q3WRV-TR5WQ-U7XUP-UTR2D-RQ7RW P.S. чтобы продлить лиц., нужно установить новую дату окончания, вычислить новый хэш, закодировать им "ключ" (можно выполнить с ним еще какие-то преобразования) - это и будет новым лиц. ключом.