Android Tutorial Check Trial Period using Dropbox (new with admin tool)

Gunnar Daehling

Active Member
Licensed User
Check Trial Period using Dropbox (first version, improved version in Post #2)

Hello,

I have tried to find a solution to solve the control of the trial period of an app using the Dropbox. The idea arose when using the solution of the member "gregchao" which realized it with FTP:

https://www.b4x.com/android/forum/threads/trial-period-using-ftp.95338/

The solution works perfectly. However, it requires web space. Everyone gets a Dropbox account for free. The limited space in the free version is no problem for this task.

I use the dropbox library of "DonManfred" for this task:

https://www.b4x.com/android/forum/threads/dropbox-sdk-v2-java.74019/#content

To disguise the access data of the Dropbox I use the library F5Steg from the Probundle Pack of Informatix:

https://www.b4x.com/android/forum/threads/probundle-chargeable.58754/#content

The dropbox must already be set up for the project example. In addition, an App must be set up in the Dropbox App Console:

https://www.dropbox.com/developers/

There you can also generate the required token. This will be integrated into the app.

I've written a small app (it's nothing more than an edited example from the author of the library). With this one can hide the Dropbox token in a picture. The source text must be supplemented with the token (variable "PASSWORD"). If you run them in debug mode, the location for the output file "tresor.jpg" will be displayed in the log window. This image file must be copied to the "Files" folder in the example project (overwrite existing invalid file).

Important !!! Both projects must be compiled with the same "private sign key". If you later change the signature of the app, a new image must be generated (with the same key). The app decrypts the image with the signature. Consequently, encryption and decryption must be done with the same signature.

B4X:
#Region  Project Attributes
    #ApplicationLabel: Encrypt PW
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    Dim Const PASSWORD As String = "xxxxxxxxxxxxxxxxxxxxxx"
End Sub

Sub Globals
    Dim F5S As F5Steg
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Starter.Rp.CheckAndRequest(Starter.Rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
End Sub

Sub Activity_Resume
 
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub Activity_PermissionResult (Permission As String, Result As Boolean)
    If Permission = Starter.rp.PERMISSION_WRITE_EXTERNAL_STORAGE Then
        If Result Then
            File.Copy(File.DirAssets, "tresor.png", File.DirInternalCache, "tresor.png")
            EmbedInImages
        Else
            Activity.Finish
            ExitApplication
        End If
    End If
End Sub

Sub EmbedInImages
    File.Delete(File.DirRootExternal, "tresor.jpg")
    F5S.EmbedArray(File.DirInternalCache & "/tresor.png", File.DirRootExternal & "/tresor.jpg", PASSWORD.GetBytes("UTF-8"), 80, "PW")
    Log("Encrypted file: " & File.DirRootExternal & "/tresor.jpg")
End Sub

Sub PW_Embedded(OutFileName As String)
    F5S.ExtractToArray(OutFileName, "PW")
End Sub

Sub PW_ArrayExtracted(SecretMessage() As Byte)
    Dim PlainText As String = BytesToString(SecretMessage, 0, SecretMessage.Length, "UTF-8")
    Log("SECRET = " & PlainText)
    If PlainText = PASSWORD Then
        LogColor("MATCH !", Colors.Green)
    Else
        LogColor("DIFFERENT !", Colors.Red)
    End If
    Sleep(6000)
    Activity.Finish
End Sub

I wrote a class file "daycheck". This is very easy to call in any app:

B4X:
#Region Project Attributes
   #ApplicationLabel: Trial Check
   #VersionCode: 1
   #VersionName:
   'SupportedOrientations possible values: unspecified, landscape or portrait.
   #SupportedOrientations: unspecified
   #CanInstallToExternalStorage: False
#End Region

#Region Activity Attributes
   #FullScreen: False
   #IncludeTitle: True
#End Region

Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   Dim fullversion As daycheck
   Dim trialperiod As Int = 14
   Dim proversion As Boolean = False
End Sub

Sub Globals
End Sub

Sub Activity_Create(FirstTime As Boolean)
End Sub

Sub Activity_Resume
   fullversion.Initialize(Activity, "main","fullversion")
End Sub

Sub Activity_Pause (UserClosed As Boolean)
   File.WriteString(File.DirInternal, "lastuse.ini", DateTime.now)
End Sub

Public Sub fullversion_Result(days As Int)
   ToastMessageShow("Proversion = " & proversion & ", Days left: " & days, True)
   Activity.Finish
End Sub

Class "daycheck"

B4X:
Sub Class_Globals
   Private mymodule As Object
   Private myname As String
   Dim daysleft As Int
   Dim auth As DbxAuth
   Dim Dropbox As DropboxV2
   Dim token As String
   Dim client As DbxClientV2
   Dim config As DbxRequestConfig
   Dim dbxFiles As DbxUserFilesRequests
   Dim F5S As F5Steg
   Dim uniqueid As String
   Dim job As HttpJob
End Sub

Public Sub Initialize(Parent As Activity, Module As Object, Eventname As String)
   mymodule = Module
   myname = Eventname
   trialcheck
End Sub

Sub trialcheck
   File.Copy(File.DirAssets, "tresor.jpg", File.DirInternalCache, "tresor.jpg")
   F5S.ExtractToArray(File.DirInternalCache & "/tresor.jpg", "dbopen")
End Sub

Sub dbopen_ArrayExtracted(SecretMessage() As Byte)
   Dim PlainText As String = BytesToString(SecretMessage, 0, SecretMessage.Length, "UTF-8")
   token = PlainText
   uniqueid = GetDeviceId
   If File.Exists(File.DirInternal, uniqueid) = False Then
       ToastMessageShow("Please wait, check internet connection", False)
       job.Initialize("Job1", Me)
       job.Download("http://www.google.com")
   Else
       Dim ts As String
       If File.Exists(File.DirInternal, "lastuse.ini") Then
           ts = File.ReadString(File.DirInternal, "lastuse.ini")
           If DateTime.Now < ts Then
               ' Date manipulation
               File.writeString(File.DirInternal, uniqueid, encrypt("973897200000")) ' first install: 11/11/2000 (manipulation)
               Main.proversion = False
               CallSub2(mymodule, myname & "_Result", 0)
               Return
           End If
       End If
       ts = File.ReadString(File.DirInternal, uniqueid)
       ts = decrypt(ts)
       If ts = "973897200000" Then
           ' pro version expiried
           Main.proversion = False
           CallSub2(mymodule, myname & "_Result", 0)
       Else If DateTime.Now > ts Then
           Dim per As Period = DateUtils.PeriodBetweenindays(ts, DateTime.Now)
           If per.days <= Main.trialperiod Then
               Dim daysleft As Int = Main.trialperiod - per.days
               Main.proversion = True
               CallSub2(mymodule, myname & "_Result", daysleft)
               Return
           Else
               File.writeString(File.DirInternal, uniqueid, encrypt("973897200000")) ' first install: 11/11/2000 (manipulation)
               Main.proversion = False
               CallSub2(mymodule, myname & "_Result", 0)
           End If
       Else
           ' Date manipulation
           File.writeString(File.DirInternal, uniqueid, encrypt("973897200000")) ' first install: 11/11/2000 (manipulation)
           Main.proversion = False
           CallSub2(mymodule, myname & "_Result", 0)
       End If
   End If
End Sub

Sub JobDone(jobx As HttpJob)
   If jobx.JobName="Job1" And job.Success=False Then
       job.Release
       Main.proversion = False
       ToastMessageShow("Test time can only be activated when the internet connection is active", True)
       CallSubDelayed2(mymodule, myname & "_Result", 0)
   Else
       job.Release
       Sleep(2000)
       check
   End If
End Sub

Sub check
   config.Initialize("",token,"","", 5)
   Dim dbxhost As DbxHost
   dbxhost.Initialize
   client.Initialize("Dropbox", config, token, dbxhost)
   dbxFiles = client.files
   dbxFiles.setEventname("dbxFiles")
   Dropbox.Initialize("")
   auth.Initialize(token)
   dbxFiles.search("",uniqueid,"FILENAME", 2, 0)
End Sub

Sub dbxFiles_Search(results As List)
   Dim foundit As Int = 0
   If results.Size > 0 Then
       For i = 0 To results.Size - 1
           Dim match As Map = results.Get(i)
           Dim meta As Metadata = match.Get("Metadata")
           If meta.Name = uniqueid Then
               foundit = 1
           End If
       Next
   End If
   If foundit = 0 Then
       ' create a file and upload it
       File.WriteString(File.DirInternal, uniqueid, encrypt(DateTime.now))
       dbxFiles.upload(File.DirInternal, uniqueid, "/" & uniqueid, False, False)
   Else
       ' download the file
       dbxFiles.download("/" & uniqueid, File.DirInternal, uniqueid)
   End If
End Sub

Sub dbxFiles_UploadFinished(success As Boolean, meta As FileMetadata, sessionId As String)
   If success = False Then
       ToastMessageShow("Upload error for trial check", True)
       '   Log(LastException.Message)
       Main.proversion = False
       daysleft = 0
   Else
       Main.proversion = True
       daysleft = Main.trialperiod
   End If
   CallSub2(mymodule, myname & "_Result", daysleft)
End Sub

Sub dbxFiles_DownloadFinished(success As Boolean, meta As FileMetadata, error As String)
   If success = False Then
       ToastMessageShow("Download error for trial check", True)
       '   Log(LastException.Message)
       Main.proversion = False
       CallSub2(mymodule, myname & "_Result", 0)
       Return
   Else
       Dim ts As String = File.ReadString(File.DirInternal, uniqueid)
       ts = decrypt(ts)
       If DateTime.Now > ts Then
           Dim per As Period = DateUtils.PeriodBetweenindays(ts, DateTime.Now)
           If per.days <= Main.trialperiod Then
               daysleft = Main.trialperiod - per.days
               Main.proversion = True
               CallSub2(mymodule, myname & "_Result", daysleft)
               Return
           Else
               File.writeString(File.DirInternal, uniqueid, encrypt("973897200000")) ' first install: 11/11/2000 (manipulation)
               Main.proversion = False
               CallSub2(mymodule, myname & "_Result", 0)
           End If
       Else
           Main.proversion = False
           CallSub2(mymodule, myname & "_Result", 0)
       End If
   End If
End Sub

Sub GetDeviceId As String
   Dim p As Phone
   Dim r As Reflector
   Dim id As String
   id = p.GetSettings("android_id") & r.GetStaticField("android.os.Build", "SERIAL")
   Return id
End Sub

Sub encrypt(tstr As String) As String
   Dim ztxt As String
   Dim checksum As Int
   ztxt = ""
   checksum = 0
   For i = tstr.Length - 1 To 0 Step - 1
       ztxt = ztxt & tstr.SubString2(i, i + 1)
       checksum = checksum + tstr.SubString2(i, i + 1)
   Next
   ' Manipulate checksum
   checksum = checksum + ztxt.SubString2(0, 3)
   ztxt = ztxt & "." & checksum
   Return ztxt
End Sub

Sub decrypt(tstr As String) As String
   Dim ztxt As String
   Dim digit, checksum, checksumorg As Int
   Try
       digit = tstr.IndexOf(".")
       ztxt = tstr.SubString(digit + 1)
       checksum = ztxt
       ' Remanipulate checksum
       checksum = checksum - tstr.SubString2(0, 3)
       ztxt = ""
       checksumorg = 0
       tstr = tstr.SubString2(0, digit)
       For i = tstr.Length - 1 To 0 Step - 1
           ztxt = ztxt & tstr.SubString2(i, i + 1)
           checksumorg = checksumorg + tstr.SubString2(i, i + 1)
       Next
       If checksum = checksumorg Then
           Return ztxt
       Else
           Return "973897200000" ' first install: 11/11/2000 (manipulation)
       End If
   Catch
       Return "973897200000" ' first install: 11/11/2000 (manipulation)
   End Try
End Sub
The sample project also contains the libraries that have to be copied to the folder "Userlib" of B4A (if necessary).

In addition, the following file must be downloaded and copied to the "Userlib" folder:

http://central.maven.org/maven2/com/dropbox/core/dropbox-core-sdk/3.0.10/dropbox-core-sdk-3.0.10.jar

It will first try to find a file in File.DirInternal. If it is missing, it will be generated and stored additional in the Dropbox in the folder "... \ Apps \ ...". This works only if an internet connection is available. Otherwise the variable "proversion" is set to false. This file stores the date of installation. In order to complicate a manipulation in rooted devices, a checksum is additionally stored in addition to this time. If this file is deleted (for example, during uninstallation and new installation) it must be recreated. If the file already exists in the dropbox, the original time will be read out and set again.

I have still made it difficult to reset the date. That would force an immediate reinstallation. However, this would only restore the function until the end of the regular test time. The chosen method has the advantage that the app requires an online connection only in the absence of the internal file. This is the case in the normal only after the first installation.

For reviews and hints I am always very grateful.

31.3.2019 Edit: daycheck.bas - small error correction (line 153 added new)

Best regards,
Gunnar
 

Attachments

Last edited:

Gunnar Daehling

Active Member
Licensed User
Check Trial Period using Dropbox (new with admin tool)

Hello,

I have written a second version of the trial time testing with the Dropbox. It represents a completely independent version. The files of the first version have a completely different format. If this version is used, all files in the Dropbox must be deleted beforehand.

The new version stores the trial time information in an little encrypted archive for every user. I also use the library ArchiverPlusZip from the Probundle Pack from Informatix. As password I use the token from the Dropbox (see first version). In the encrypted file the installation date, the trial time and the name of the file are packed. So this file only applies to the device on which it was written.

The first 16 characters of the internal file are the "Android_ID". These can be published in the app (for example in the setup). With an admin tool one is thus able to change the entries of the individual users of the app. You can set the app as freeware for individual users. You can mark the app completely as expired. In addition, you can assign any number of test days. To do this, the user simply has to give his ID (first 16 characters of the file name).

After a change with the Admin Tool, the user only needs to uninstall the app and reinstall it. Thereafter, the newly prescribed values apply immediately.

The instructions for generating the password image in the first version also apply to this version.

B4X:
#Region Project Attributes
   #ApplicationLabel: Trial Check 2
   #VersionCode: 1
   #VersionName:
   'SupportedOrientations possible values: unspecified, landscape or portrait.
   #SupportedOrientations: unspecified
   #CanInstallToExternalStorage: False
#End Region

#Region Activity Attributes
   #FullScreen: False
   #IncludeTitle: True
#End Region

'#BridgeLogger: True
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   Dim fullversion As daycheck
   Dim normtrialperiod As Int = 14
   Dim proversion As Boolean = False
End Sub

Sub Globals
End Sub

Sub Activity_Create(FirstTime As Boolean)
End Sub

Sub Activity_Resume
   fullversion.Initialize(Activity, "main","fullversion")
End Sub

Sub Activity_Pause (UserClosed As Boolean)
   File.WriteString(File.DirInternal, "lastuse.ini", DateTime.now)
End Sub

Public Sub fullversion_Result(days As Int)
   ToastMessageShow("Proversion = " & proversion & ", Days left: " & days, True)
   Activity.Finish
End Sub

The class "daycheck":

B4X:
Sub Class_Globals
   Private mymodule As Object
   Private myname As String
   Dim daysleft As Int
   Dim auth As DbxAuth
   Dim Dropbox As DropboxV2
   Dim token As String
   Dim client As DbxClientV2
   Dim config As DbxRequestConfig
   Dim dbxFiles As DbxUserFilesRequests
   Dim F5S As F5Steg
   Dim Arc As ArchiverPlusZip
   Dim uniqueid As String
   Dim dbupload As Boolean
   Dim job As HttpJob
End Sub

Public Sub Initialize(Parent As Activity, Module As Object, Eventname As String)
   mymodule = Module
   myname = Eventname
   trialcheck
End Sub

Sub trialcheck
   File.Copy(File.DirAssets, "tresor.jpg", File.DirInternalCache, "tresor.jpg")
   F5S.ExtractToArray(File.DirInternalCache & "/tresor.jpg", "dbopen")
End Sub

Sub dbopen_ArrayExtracted(SecretMessage() As Byte)
   Dim PlainText As String = BytesToString(SecretMessage, 0, SecretMessage.Length, "UTF-8")
   token = PlainText
   dbupload = False
   uniqueid = GetDeviceId
   If File.Exists(File.DirInternal, uniqueid) = False Then
       ToastMessageShow("Please wait, check internet connection", False)
       job.Initialize("Job1", Me)
       job.Download("http://www.google.com")
   Else
       readfile
   End If
End Sub

Sub JobDone(jobx As HttpJob)
   If jobx.JobName="Job1" And job.Success=False Then
       job.Release
       Main.proversion = False
       ToastMessageShow("Test time can only be activated when the internet connection is active", True)
       CallSubDelayed2(mymodule, myname & "_Result", 0)
   Else
       job.Release
       Sleep(2000)
       check
   End If
End Sub

Sub readfile
   Arc.DecryptZipWithstring(token)
   Arc.UnZipFile2(File.DirInternal & "/" & uniqueid, "trial.dat", File.DirInternalCache, "trial.dat", "Unzipp")
End Sub

Sub Unzipp_ZipResult(Result As Int, ErrorMsg As String)
   Select Result
       Case Arc.ZIP_RESULT_SUCCESS
           Dim ts, idhide As String
           Dim daysleft As Int
           Dim textreader1 As TextReader
           textreader1.Initialize(File.OpenInput(File.DirInternalCache, "trial.dat"))
           ts = textreader1.ReadLine
           Main.normtrialperiod = textreader1.ReadLine
           idhide = textreader1.ReadLine
           textreader1.close
           File.Delete(File.DirInternalCache, "trial.dat")
           ' ts->Install Date
           If Main.normtrialperiod <> "-1" And Main.normtrialperiod <> "-2" Then
'               Dim ts As String
               If File.Exists(File.DirInternal, "lastuse.ini") Then
                   ts = File.ReadString(File.DirInternal, "lastuse.ini")
                   If DateTime.Now < ts Then
                       ' Date manipulation
                       Trialdatawrite("973897200000", - 2)
                       Return
                   End If
               End If
               If idhide <> uniqueid Then  ' illegal device ID
                   Main.proversion = False
                   CallSubDelayed2(mymodule, myname & "_Result", - 2)
                   Return
               End If
           End If
           If Main.normtrialperiod = "-1" Then
               Main.proversion = True
               CallSubDelayed2(mymodule, myname & "_Result", - 1)
           Else If Main.normtrialperiod = "-2" Then
               Main.proversion = False
               CallSubDelayed2(mymodule, myname & "_Result", - 2) 
           Else If ts = "973897200000" Then
               ' pro version expiried
               Main.proversion = False
               CallSubDelayed2(mymodule, myname & "_Result", - 2)
           Else If DateTime.Now > ts Then
               Dim per As Period = DateUtils.PeriodBetweenindays(ts, DateTime.Now)
               If per.days <= Main.normtrialperiod Then
                   daysleft = Main.normtrialperiod - per.days
                   Main.proversion = True
                   CallSubDelayed2(mymodule, myname & "_Result", daysleft)
               Else
                   Trialdatawrite("973897200000", - 2)
               End If
           Else
               ' Date manipulation
               Trialdatawrite("973897200000", - 2)
           End If
       Case Else
'               Log("File zip error")
           Main.proversion = False
           CallSubDelayed2(mymodule, myname & "_Result", 0)
   End Select
End Sub

Sub Trialdatawrite(instdate As String, testdays As Int)
   Dim textwriter1 As TextWriter
   textwriter1.Initialize(File.OpenOutput(File.DirInternalCache, "trial.dat", False))
   textwriter1.WriteLine(instdate)
   textwriter1.WriteLine(testdays)
   textwriter1.WriteLine(uniqueid)
   textwriter1.Close
   Arc.EncryptZipWithString(Arc.ZIP_ENC_METHOD_AES, Arc.ZIP_AES_STRENGTH_256, token)
   Arc.AddFileToZip(File.DirInternalcache & "/trial.dat", File.DirInternal & "/" & uniqueid, "Zipp")
End Sub
Sub Zipp_ZipResult(Result As Int, ErrorMsg As String)
   Select Result
       Case Arc.ZIP_RESULT_SUCCESS
'           Log("File zip ok")
           File.delete(File.DirInternalcache, "trial.dat")
           If dbupload Then
               dbxFiles.upload(File.DirInternal, uniqueid, "/" & uniqueid, False, False)
           Else
               Main.proversion = False
               CallSubDelayed2(mymodule, myname & "_Result", 0)
           End If
       Case Else
'           Log("File zip error")
           Main.proversion = False
           CallSubDelayed2(mymodule, myname & "_Result", 0)
   End Select
End Sub

Sub check
   config.Initialize("",token,"","", 5)
   Dim dbxhost As DbxHost
   dbxhost.Initialize
   client.Initialize("Dropbox", config, token, dbxhost)
   dbxFiles = client.files
   dbxFiles.setEventname("dbxFiles")
   Dropbox.Initialize("")
   auth.Initialize(token)
   dbxFiles.search("",uniqueid,"FILENAME", 2, 0)
End Sub

Sub dbxFiles_Search(results As List)
   Dim foundit As Int = 0
   If results.Size > 0 Then
       For i = 0 To results.Size - 1
           Dim match As Map = results.Get(i)
           Dim meta As Metadata = match.Get("Metadata")
           If meta.Name = uniqueid Then
               foundit = 1
           End If
       Next
   End If
   If foundit = 0 Then
       'create a file and upload it
       dbupload = True
       Trialdatawrite(DateTime.now, Main.normtrialperiod)
   Else
       ' download the file
       dbxFiles.download("/" & uniqueid, File.DirInternal, uniqueid)
   End If
End Sub

Sub dbxFiles_UploadFinished(success As Boolean, meta As FileMetadata, sessionId As String)
   If success = False Then
       ToastMessageShow("Upload error for trial check", True)
       '   Log(LastException.Message)
       Main.proversion = False
       daysleft = 0
   Else
       Main.proversion = True
       daysleft = Main.normtrialperiod
   End If
   CallSubDelayed2(mymodule, myname & "_Result", daysleft)
End Sub

Sub dbxFiles_DownloadFinished(success As Boolean, meta As FileMetadata, error As String)
   If success = False Then
       ToastMessageShow("Download error for trial check", True)
       '   Log(LastException.Message)
       Main.proversion = False
       CallSubDelayed2(mymodule, myname & "_Result", 0)
       Return
   Else
       readfile
   End If
End Sub

Sub GetDeviceId As String
   Dim p As Phone
   Dim r As Reflector
   Dim id As String
   id = p.GetSettings("android_id") & r.GetStaticField("android.os.Build", "SERIAL")
   Return id
End Sub

The Admin Tool:

B4X:
#Region Project Attributes
   #ApplicationLabel: Trial Admin
   #VersionCode: 1
   #VersionName:
   ' SupportedOrientations possible values: unspecified, landscape or portrait.
   #SupportedOrientations: unspecified
   #CanInstallToExternalStorage: False
#End Region

#Region Activity Attributes
   #FullScreen: true
   #IncludeTitle: false
#End Region

' #BridgeLogger: True
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   Dim daysleft As Int
   Dim token As String
   Dim auth As DbxAuth
   Dim Dropbox As DropboxV2
   Dim client As DbxClientV2
   Dim config As DbxRequestConfig
   Dim dbxFiles As DbxUserFilesRequests
   Dim uniqueid As String
   Dim dbdelTimer As Timer
   Dim inedit As Boolean
End Sub

Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
   Dim Arc As ArchiverPlusZip
   Dim F5S As F5Steg
   Private idnr As EditText
   Private search As Button
   Private full As CheckBox
   Private dayval As EditText
   Private cancel As Button
   Private ok As Button
   Private idlist As ListView
   Private trialout As CheckBox
   Dim tastatur As IME
End Sub

Sub Activity_Create(FirstTime As Boolean)
   'Do not forget to load the layout file created with the visual designer. For example:
   'Activity.LoadLayout("Layout1")
End Sub

Sub Activity_Resume
   tastatur.Initialize("")
   start
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub start
   dbdelTimer.Initialize("deltimer", 50)
   Activity.Color=Colors.Black
   Activity.LoadLayout("1")
   File.Copy(File.DirAssets, "tresor.jpg", File.DirInternalCache, "tresor.jpg")
   F5S.ExtractToArray(File.DirInternalCache & "/tresor.jpg", "dbopen")
End Sub

Sub dbopen_ArrayExtracted(SecretMessage() As Byte)
   Dim PlainText As String = BytesToString(SecretMessage, 0, SecretMessage.Length, "UTF-8")
   token = PlainText
End Sub

Sub idnr_TextChanged (Old As String, New As String)
   If New.Length >= 8 Then
       search.Enabled = True
   Else
       search.Enabled = False
   End If
End Sub

Sub search_Click
   tastatur.HideKeyboard
   ToastMessageShow("Please wait ...", True)
   config.Initialize("",token,"","", 5)
   Dim dbxhost As DbxHost
   dbxhost.Initialize
   client.Initialize("Dropbox", config, token, dbxhost)
   dbxFiles = client.files
   dbxFiles.setEventname("dbxFiles")
   Dropbox.Initialize("")
   auth.Initialize(token)
   dbxFiles.search("",idnr.Text,"FILENAME", 2, 0)
End Sub

Sub dbxFiles_Search(results As List)
   If results.Size > 0 Then
       idlist.Visible = True
       For i = 0 To results.Size - 1
           Dim match As Map = results.Get(i)
           Dim meta As Metadata = match.Get("Metadata")
           idlist.AddSingleLine(meta.Name)
       Next
       ToastMessageShow("Please select the ID", True)
   Else
       ToastMessageShow("No file found", True)
   End If
End Sub

Sub cancel_Click
   Activity.RemoveAllViews
   Activity.Finish
End Sub

Sub ok_Click
   ok.Enabled = False
   cancel.Enabled = False
   search.Enabled = False
   trialout.Enabled = False
   idnr.Enabled = False
   full.Enabled = False
   idlist.Enabled = False
   trialout.Enabled = False
   full.Enabled = False
   dayval.Enabled = False
   Trialdatawrite(DateTime.now, dayval.text)
End Sub

Sub idlist_ItemClick (Position As Int, Value As Object)
   tastatur.HideKeyboard
   uniqueid = Value
   full.Enabled = True
   trialout.Enabled = True
   dayval.Enabled = True
   ' download the file
   dbxFiles.download("/" & uniqueid, File.DirInternal, uniqueid)
End Sub

Sub dbxFiles_DownloadFinished(success As Boolean, meta As FileMetadata, error As String)
   If success = False Then
       '   Msgbox("Error", "Hint")
       ToastMessageShow("Dropbox download error", True)
   Else
       readfile
   End If
End Sub

Sub readfile
   ok.Enabled = True
   Arc.DecryptZipWithstring(token)
   Arc.UnZipFile2(File.DirInternal & "/" & uniqueid, "trial.dat", File.DirInternalCache, "trial.dat", "Unzipp")
End Sub

Sub Unzipp_ZipResult(Result As Int, ErrorMsg As String)
   Select Result
       Case Arc.ZIP_RESULT_SUCCESS
           Dim ts, trialperiod, idhide As String
           Dim daysleft As Int
           Dim textreader1 As TextReader
           textreader1.Initialize(File.OpenInput(File.DirInternalCache, "trial.dat"))
           ts = textreader1.ReadLine
           trialperiod = textreader1.ReadLine
           idhide = textreader1.ReadLine
           textreader1.close
           File.Delete(File.DirInternalCache, "trial.dat")
           ' ts->Install Date
           If idhide <> uniqueid Then
               ToastMessageShow("Illegal device ID", True)
               trialout.Checked = True
               full.Checked = False
               dayval.Text = "-2"
           Else If trialperiod = "-1" Then
               trialout.Checked = False
               full.Checked = True
               dayval.Text = "-1"
           Else If trialperiod = "-2" Then 
               trialout.Checked = True
               full.Checked = False
               dayval.Text = "-2"
           Else If ts = "973897200000" Then
               trialout.Checked = True
               full.Checked = False
               dayval.Text = "-2"
           Else
               Dim per As Period = DateUtils.PeriodBetweenindays(ts, DateTime.Now)
               daysleft = trialperiod - per.days
               dayval.Text = daysleft
           End If
           ok.Enabled = True
       Case Else
           '   Log("File zip error")
   End Select
End Sub

Sub trialout_CheckedChange(Checked As Boolean)
   If inedit=False Then
       If trialout.Checked Then
           full.Checked = False
           dayval.Text = "-2"
       Else
           dayval.Text = "0" 
       End If
       ok.Enabled = True
   End If
End Sub

Sub full_CheckedChange(Checked As Boolean)
   If inedit=False Then
       If full.Checked Then
           trialout.Checked = False
           dayval.Text = "-1"
       Else
           dayval.Text = "0"     
       End If
       ok.Enabled = True
   End If
End Sub

Sub dayval_TextChanged (Old As String, New As String)
   inedit=True
   Try
       If New >= "0" Or New="-1" Or New="-2" Then
           If New = "-1" Then
               full.Checked = True
               trialout.Checked = False
           Else If    New = "-2" Then
               full.Checked = False
               trialout.Checked = True
           Else
               full.Checked = False
               trialout.Checked = False
           End If
           ok.Enabled = True
       Else
           ok.Enabled = False
       End If
   Catch
       ok.Enabled = False
   End Try
   inedit=False
End Sub

Sub Trialdatawrite(instdate As String, testdays As Int)
   Dim textwriter1 As TextWriter
   textwriter1.Initialize(File.OpenOutput(File.DirInternalCache, "trial.dat", False))
   textwriter1.WriteLine(instdate-DateTime.TicksPerDay)
   textwriter1.WriteLine(testdays+1)
   textwriter1.WriteLine(uniqueid)
   textwriter1.Close
   Arc.EncryptZipWithString(Arc.ZIP_ENC_METHOD_AES, Arc.ZIP_AES_STRENGTH_256, token)
   Arc.AddFileToZip(File.DirInternalcache & "/trial.dat", File.DirInternal & "/" & uniqueid, "Zipp")
End Sub

Sub Zipp_ZipResult(Result As Int, ErrorMsg As String)
   Select Result
       Case Arc.ZIP_RESULT_SUCCESS
           File.delete(File.DirInternalcache, "trial.dat")
           dbxFiles.move("/" & uniqueid, "/" & uniqueid & ".bak")
       Case Else
           '   Msgbox("Error", "Hint")
           ToastMessageShow("File zip error", True)
           Sleep(3000)
           Activity.RemoveAllViews
           Activity.Finish
   End Select 
End Sub 

Sub dbxFiles_Move(success As Boolean, meta As Metadata, error As String)
   dbdelTimer.Enabled = True '   dbxFiles.delete("/" & uniqueid & ".bak")
   If success = False Then
       '   Msgbox("Error", "Hint")
       ToastMessageShow("Dropbox delete error", True)
       Sleep(3000)
       Activity.RemoveAllViews
       Activity.Finish
   End If
   dbxFiles.upload(File.DirInternal, uniqueid, "/" & uniqueid, False, False)
End Sub

Sub deltimer_Tick
   dbdelTimer.Enabled = False
   Try
       dbxFiles.delete("/" & uniqueid & ".bak")
       wait for dbxFiles_Delete(success As Boolean, msg As Object , error As String)
   Catch
       Log(LastException)
   End Try
End Sub

Sub dbxFiles_UploadFinished(success As Boolean, meta As FileMetadata, sessionId As String)
   If success = False Then
       ToastMessageShow("Dropbox upload error", True)
   Else
       ToastMessageShow("Dropbox update ok", True)
   End If
   Sleep(3000)
   Activity.RemoveAllViews
   Activity.Finish
End Sub


Maybe one or the other can use it for his app.


Best regards,
Gunnar
 

Attachments

Last edited:

Gunnar Daehling

Active Member
Licensed User
Hello,

I changed the verification of the internet connection in both variants. I uploaded the zip files again.

Furthermore, I made a change in the admin tool. When setting a new test time, the installation date is set minus 1 day. The test duration is extended by one day. Thus, the encrypted file is always valid immediately even if there is a large time difference to the user of the app.

Best regards,
Gunnar
 

techknight

Well-Known Member
Licensed User
Just some FYI here. And this is really up to the developer at this point, but I just want to put this out there.

As a hacker, your layers and layers of protection and obfuscation all comes down to a single variable. a boolean. True = good. False = Bad.

This is the absolute worst way to protect an application from licensing/demo etc. a simple false/true patch would totally break all layers of the protection. This is like putting a lock on a fence gate, in a bad neighborhood with nobody watching that lock, and then building a fortress around the key. Whats going to happen? your going to cut the lock off. Game over.

So my advice is dont rely on a single boolean to protect your app. Even with Erel's obfuscation, that can be figured out easily, especially if you give a reason for your customer base to want something for free. Also, when I say "your", its directed to anyone who uses techniques like these for protection.

The best way is hide algorithms or some variables or data that would be present in the pro version, but not in the trial version, and that data can only get sent to paid pro users. So even if someone patches out the boolean so it thinks its pro all the time, it still wont work properly because its missing keys and codes/scripts sent through the registration channels. So in other words, You need many locks, with different types of keys/protection.

Good place to start is with a scripting library where its inputs/outputs and algorithms matter to the program's operation. Still can be cracked, anything can be cracked, but that method is at least an order of magnitude harder, and it guarantees at least one purchase of the program to figure out the crack. whereas the boolean method, not so much.
 
Last edited:

Gunnar Daehling

Active Member
Licensed User
@techknight

Thank you for your hints. I completely agree with you. I read the manual "Protectmyapp" by Informatix. That's how I learned a lot about this topic. However, I will be careful not to expose my other ideas for the protection of my apps here. I do not want to make it that easy for the potential hackers. I show here only how one can check the test period of individual users. If my app gets hacked, so many things are not working properly anymore, so maybe the joke on the thing goes away. And if not, I just have to live with it.

Best regards,
Gunnar
 
Top