Validating License Key on separate form? - vb.net

I have an application which has a license key function.
The user gets their license key, then type it into the TextBox where the license key is supposed to go, and if the license key is valid, they get taken to the main form, where all of the features are.
Now, to make my program more secure, I need to be able to check that the user has definitely typed in their license key, and they haven't done something like delete (by decompiling) the license key form so they can gain access to the main form where all of the features are.
Note: My license keys are stored on a server.
How would I check that the user has definitely typed in the license key?
Below is the code.
AddLicense.vb:
Imports SKM.V3
Imports SKM.V3.Models
Imports SKM.V3.Methods
Public Class AddLicense
Private p_oRandom As Random
Private Const INTERVAL_MIN_SEC As Integer = 4
Private Const INTERVAL_MAX_SEC As Integer = 25
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If BunifuProgressBar1.Value = 50 Then
Label3.Show()
Label2.Hide()
End If
BunifuProgressBar1.Value += 1
If BunifuProgressBar1.Value = BunifuProgressBar1.MaximumValue Then
BunifuProgressBar1.Hide()
Label3.Hide()
Label2.Hide()
Timer1.Stop()
BunifuMaterialTextbox1.Show()
BunifuThinButton21.Show()
Label4.Show()
LinkLabel1.Show()
BunifuThinButton22.Show()
End If
Timer1.Interval = p_oRandom.Next(INTERVAL_MIN_SEC, INTERVAL_MAX_SEC) * 3
End Sub
Private Sub BunifuImageButton1_Click(sender As Object, e As EventArgs) Handles BunifuImageButton1.Click
Me.Close()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
p_oRandom = New Random
End Sub
Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked
Try
Process.Start("https://selly.gg")
Catch ex As Exception
End Try
End Sub
Sub Nolicense()
BunifuThinButton21.Enabled = False
End Sub
Private Sub BunifuThinButton21_Click_1(sender As Object, e As EventArgs) Handles BunifuThinButton21.Click
Dim token = "WyIxMDM2IiwiZ082d2dnS0FmTkRuTXNPcGhlSkllVEx6ckFWMFhhSzlMM3Rvc01xUSJd"
Dim key = BunifuMaterialTextbox1.Text.Replace(" ", "")
Dim license = New LicenseKey() With
{
.ProductId = 3888,
.Key = key
}
If license.Refresh(token, True) Then
' we are able to auto complete missing key info
Me.BunifuThinButton21.Enabled = license.HasFeature(1).IsValid() ' either we have feature1 or not.
MsgBox("License is valid! Thanks for purchasing.")
Me.Hide()
Sploitbase.Show()
If license.HasFeature(4).HasNotExpired().IsValid() Then
Me.Hide()
Sploitbase.Show()
ElseIf license.HasNotFeature(4).IsValid() Then
Else
MsgBox("Your license has expired and cannot be used.")
Nolicense()
End If
license.SaveToFile()
Else
' something went wrong.
MsgBox("Unable to access the license server or the key is wrong.")
End If
Me.Close()
End Sub
Private Sub BunifuThinButton22_Click(sender As Object, e As EventArgs) Handles BunifuThinButton22.Click
End Sub
End Class
Sploitbase.vb - the main form:
Imports SKM.V3
Public Class Sploitbase
Private Sub Sploitbase_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Public Sub NoLicense()
End Sub
Private Sub TabPage1_Click(sender As Object, e As EventArgs)
End Sub
Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs)
Try
Process.Start("https://selly.gg")
Catch ex As Exception
End Try
End Sub
End Class

I believe what you want is to stop users from decompiling your program and removing the license key form entirely...
Unfortunately, it's impossible to stop that, as long as a program can be run on an ordinary computer, it can be decompiled, otherwise, it would be impossible for the processor to process it.
This means, that it would be possible to remove the relevant instructions for that, and C# and VB is easy to decompile - tools like dotPeek get valid source code (it won't be exactly the same as the original, but still readable and runs like the original) just with a click.
Keep in mind that even proper commercial programs made by whole companies have this problem.
So, what could you possibly "do"? Well, I only really have two suggestions... but they won't work too well.
One only makes it harder and the other one requires access to the internet all the time.
Obfuscation
Obfuscation essentially makes the code harder to read after decompiling, however, it won't stop people from deleting the form, it will just make it slightly harder.
I posted it as an option because it will make the code very confusing when recompiling and it might be helpful to "protect" it a bit more. However, just remember this: "It's a weak layer of defence for a weak attacker."
An obfuscator you could use is Eazfuscator.NET, that webpage I sent also has a description of essentially what it does and how to use it - it may be worth taking a look at.
Online Servers
This one requires a connection to the internet... but, it's the only other option you have at all - it's either this or... able-to-get-rid-of-product-key.
Essentially, in this idea, you make a server do all the work that the application has to do and then return the result of it.
Imagine the user's computer is a server. Their "server" runs the code, and so the code is on their "server" (otherwise it has nothing to run) and everything is processed on their server. Now, if you run it on your server, all the code is on your server and your server only returns the result, meaning, they can't get at the process that provides that result.
In the end, this would mean that the application physically would not be able to do anything without a license key, since the only way it can get its data processed is via the server, and the server won't process the data without a product key.
The only downside to this is that you must have an internet connection and if the internet connection is slow - the program will be slow.
Since you want to know how to do this in vb.net taking a look at ASP.NET may help, but it's really designed to make a full-website - not to just process a few tasks.
I can leave it up to you how you would want to approach this task but here's one way of doing this:
The code below will make a "request" to a certain URL and then get the result back - with this, you could make it so when it goes to that URL the server processes the data given (including the product key) and returns back a result.
Dim request As System.Net.HttpWebRequest
Dim response As System.Net.HttpWebResponse
request = System.Net.HttpWebRequest.Create("https://URLHERE")
response = askforupdate.GetResponse
Dim result As System.IO.StreamReader = New System.IO.StreamReader(response.GetResponseStream)
result now contains a String - but, keep in mind that you can use this for practically anything - even images! (Images are just New Bitmap(response.GetResponseStream))
You can pass data to the server via a Query String, for example:
my.website/processSomething?license=AAAAAAAA&sizeInput=241&somethingElse=asagsag
But, really, it's up to you how you do that.
I'm sorry I couldn't give you an exact solution, but, there really isn't one. You're going to end up sacrificing something either way.
Hopefully, this was at least helpful and helped you understand that it's really not possible to prevent people hacking your software without losing something.

Related

Unable to add rows to datatable, datatable is nothing error

I am not really sure what went wrong, i declared dt on top as a class variable then declare it as new datatable in fill function used in pageload but when i pressed buttonadd, dt is nothing error pops up.
Private dt As DataTable
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
fill()
End If
End Sub
Protected Sub fill()
dt = New DataTable
dt.Columns.Add("Status", GetType(String))
End Sub
Protected Sub btnadd_Click(sender As Object, e As EventArgs) Handles btnadd.Click
Dim R As DataRow = dt.NewRow
R("Status") = "Pending"
dt.Rows.Add(R)
'dt.Rows.Add("pending")
GridView1.DataSource = dt
GridView1.DataBind()
End Sub
The key concept is that web pages are "state-less".
That means for each event code stub, then the code is starting over from scratch.
And it means for each browser round trip, then the browser code starts from scratch EACH time. So, you only load up the data table one time (first time - this is GOOD!!!).
The problem of course, without a control on the web page. (say a data grid), or say a simple text box? Those controls survive that so called round trip. The MOST important concept, and if were going to learn ONE thing about asp.net web pages?
You must grasp the round trip concept, and the so called page state.
So, what happens in your case?
First time - page loads - code runs server side (often called code behind).
Your form instance class is created, your load event runs, you load up the table. The browser is THEN send down to the client side. The web page is just sitting here. Maybe you close the browser. Maybe you un-plug your computer. The server does not know, or care about this. In fact, the server does NOT even know the web page exists anymore!!!
So, your web page is sitting here, and you click on that button.
The web page is now sent up to the server, and the code behind starts running - but it STARTS FROM FRESH scratch each time!
So your form level variable called "data table" does NOT exist any more and does NOT have a value.
So, there are several solutions here. For starters, we need that "table" to persist and survive the rounds trip. As noted, most controls you drop into that page WILL keep their values. This is called the "viewstate". So, if we want that data table to survive and "exist" the next time the user does something? Then we need to save or persist that table variable.
Another way? You can use what is called the session(). Session() is a attempt and system to allow use to shove values into Session(). And the session() survives round trips.
Now, given your example?
Well, then our code would become this:
Private dt As DataTable
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
fill()
Session("MyCoolTable") = dt
else
' this is a page post back - re-load the active table into our
' forms level dt.
dt = Session("MyCoolTable")
end if
In a lot of cases, I would assume the table that drives the grid is a database. And thus I would add the row to the database, and then re-bind the data grid.
But the above use of session() will persist the dt table for you.

How can I let a code run permanent in the background, which waits for an input ? (Visual Basic)

I want to program a round based rpg like game in visual basic.
For that I want to make it possible, to show a picture of the current selected unit in the right bottom corner and add some information about the heal points and some other stats.
So I want to make a program part, which permanently asks, which of the units is selected and based on that let a other program part running, which changes the picture and the information about hp and this stuff, matching to the current unit.
But I am not able to run a program which runs in the background and doesn't freezes the main program while running (may I need a background worker ?)
Also I am not very sure, what for a program type I need to used for this (like a sub or something).
I don't know other types than sub's in vb, but I could derive it from my knowledge of java programming (functions and objects).
I know this is a bit much to ask, but I need to know, which program type I need to use and how I can let it run permanent in the background + how to transfer some information between these parts.
Would be nice, if someone could help me and explain a bit instead of just saying something like: you need a background worker use this link xy.
I tried to use a variable, which becomes a different number, when a other unit is clicked, unfortunately you cant see much of my code right now, since for this form, I didn't created much more than the graphical interface.
Public Class FormBattlescreen
Dim marked As Integer = 0
Private Sub Formsounds_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.WindowState = FormWindowState.Maximized
FormMainCampagne.Close()
End Sub
Private Sub OwnSoldier1_Click(sender As Object, e As EventArgs) Handles OwnSoldier1.Click
marked = 1
End Sub
Private Sub OwnSoldier2_Click(sender As Object, e As EventArgs) Handles OwnSoldier2.Click
marked = 2
End Sub
Private Sub OwnSoldier3_Click(sender As Object, e As EventArgs) Handles OwnSoldier3.Click
marked = 3
End Sub
Private Sub EnemyOfficer1_Click(sender As Object, e As EventArgs) Handles EnemyOfficer1.Click
marked = 4
End Sub
Private Sub RunGame()
Select Case marked
Case 0 'nothing is selected//at the beginning
Case 1
PictureBoxStats.Image = My.Resources.Soldier2
Case 2
Case 3
Case 4
End Select
End Sub
End Class
Thank you, I appreciate your help.

Visual Basic GUI Input Validation

I took an entry level computer programming class this past term and I'm having problems with my final project. I have to design a program in visual basic GUI that asks the player to accurately guess a number between 1-100 within a limited number of guesses.
My first form asks the user to set the number of guesses allowed. It has one textbox and an "enter" button, among other buttons that I've gotten to work.
I'm trying to get code to work that will validate the input on the guesses allowed. Specifically, I want a message box to pop up if the player enters letters or special characters instead of numbers, or enters a number less than zero, or greater than twenty. Here's what I have:
Public Class Noofguesses
Shared maxguesscnt As Integer
Private Sub Numberofguesses_TextChanged(sender As Object, e As EventArgs) Handles Numberofguesses.TextChanged
End Sub
Private Sub Quit_Click(sender As Object, e As EventArgs) Handles Quit.Click
End
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Form3.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Val(Numberofguesses) > 20 Then MsgBox("Number of Guesses Cannot Exceed 20")
If Val(Numberofguesses) < 0 Then MsgBox("Number of Guesses Must Be Greater Than 0")
If Not IsNumeric(Numberofguesses) Then MsgBox("Entry Cannot be Letters or Characters")
Me.Close()
Form2.Show()
End Sub
End Class
What am I doing wrong? Please let me know.
Thanks
I would generally suggest using a NumericUpDown rather than a TextBox, in which case no validation is required. As this is an assignment though, I'm guessing that validating a TextBox is a requirement. In that case, you should use Integer.TryParse to validate a String, i.e. the Text of the TextBox and convert it if it is valid. You can then test the converted value to make sure that it isn't less than zero, etc. I'm not going to write the code for you, given that this is homework, but that should be enough for you to do it yourself or, if you feel you must, find examples online.

Access database connecting to VS but no data showing and runtime error

Trying to use an access database with Visual studio 15. After failure I found a number of tutorials and followed them with a new project and new database.
The database is connecting but the data inside the database won't display (although no error) and even using the built in save function in VB results in a run time error.
If anyone can point me in the right direction I'd be grateful. Code below.
Public Class Form1
Private Sub CustomersBindingNavigatorSaveItem_Click(sender As Object, e As EventArgs) Handles CustomersBindingNavigatorSaveItem.Click
Me.Validate()
Me.CustomersBindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.CustomersDataSet) 'Error is here****
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'CustomersDataSet.Customers' table. You can move, or remove it, as needed.
Me.CustomersTableAdapter.Fill(Me.CustomersDataSet.Customers)
End Sub
Private Sub BindingNavigatorDeleteItem_Click(sender As Object, e As EventArgs) Handles BindingNavigatorDeleteItem.Click
End Sub
Private Sub BindingNavigatorAddNewItem_Click(sender As Object, e As EventArgs) Handles BindingNavigatorAddNewItem.Click
End Sub
End Class
The error message I get is An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll
Additional information: Unspecified error.
Here is a video that I made a while ago that should be able to help you, If you have any questions about it, i can definitely help you out.
https://www.youtube.com/watch?v=vvzY0LsAUNE
Also do you definitely need to use Access? I would recommend using an SQL database because when you publish your program, the end user may have to have a link to your access database in the same spot as yours, which can be a pain.
Nevertheless here is a video i also made regarding setting up an SQL database via Visual Studio.
https://www.youtube.com/watch?v=NLs44hxV514
If you have any issue, leave a comment and i will be happy to help you out :)
Keep In Mind
Don't forget that you need to also have a Number/unique word/or something a like in the Primary key column even if you haven't added any details to the database. eg Name and so on. If not your program may crash, so you could use the Try statement to fix this issue if the Primary Key column is left empty.

VB 2013 Persistent User Settings

On my form I have a menu with "file-save". When I click save I want to save particular settings to restore when the form is closed and re-opened. I've done this successfully for text in text-boxes and the checked states of check-boxes, but I'm failing when trying to loop through the items in a list-box. Please see below for what I've tried...
When I click save:
Private Sub SaveToolStripMenuItem_Click(sender As Object, e As EventArgs)
Handles SaveToolStripMenuItem.Click
For Each i In ListBox1.Items()
My.Settings.ListBox1.Add(i)
Next
My.Settings.Save()
End Sub
When my form loads:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load
For Each i In My.Settings.ListBox1()
ListBox1.Items.Add(i)
Next
End Sub
I've only been using VB for three days, so apologies if I am missing something simple ha! Thanks for any help!!!
There is one small glitch with the StringCollection in settings. If you do not seed it with a fake variable then it starts out as Nothing and you cannot add to Nothing. in your form load add this:
' if the collection has not been initialized, do so
If My.Settings.ListBox1 Is Nothing Then
My.Settings.ListBox1= New System.Collections.Specialized.StringCollection
End If
' now it is safe to use: load strings from Setting -> form listbox
For Each s As String In My.Settings.ListBox1()
ListBox1.Items.Add(s)
Next
The very first time it runs, there are likely no saved settings, so we have to create the container for them, basically.
Option Strict can be implemented by file, by adding this at the top:
Option Strict On
Or for the project: Project => Properties => Compile: Option Strict is likely to the right (I have 2012). You can also set it as a permanent option (recommended).
Among other things, this will prevent you from plucking variables out of the air and use them without declaring a type (which will lead to errors). For instance:
For Each i In My.Settings.ListBox1()
becomes
For Each s As String In My.Settings.ListBox1() ' tell the compiler the Type