How to generate a serial number?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Caronte3D
Addict
Addict
Posts: 1355
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: How to generate a serial number?

Post by Caronte3D »

Paul wrote:You can end up spending more time trying to protect your software than actually developing it.
That's absolutely true! I discover it some time ago by the hard way :?
Anyway a very simple method of protection is enough in some cases (custom software), almost to prevents massive copy of your software by average users without crack experience.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: How to generate a serial number?

Post by J. Baker »

Paul is correct but it is up to the developer to be creative on protecting their apps. Everything can be hacked but you can at least stop you average user.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: How to generate a serial number?

Post by J. Baker »

Getting more creative. Again, nothing is 100% but you could make a hacker work harder for it.

Code: Select all

;-Run this bit of code in a separate progam to create the encrupted key.

UseSHA2Fingerprint()

Debug StringFingerprint("G4112h78ab", #PB_Cipher_SHA2)

;-Use this in your actual program so a user can activate their software.

Activation.a = 0
BS.s = "048"

If OpenWindow(0, 0, 0, 310, 40, "Verify Key", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
 
  StringGadget(0, 10, 10, 200, 20, "")
  ButtonGadget(1, 210, 10, 100, 20, "Activate")
  Tri.s = "3"
  
    Repeat
     
      Event = WaitWindowEvent()
        Select Event
          Case #PB_Event_Gadget
            Select EventGadget()
              Case 1
                
                String1.s = StringFingerprint(GetGadgetText(0), #PB_Cipher_SHA2)
                String2.s = BS + Tri + Tri + Str(Val(Tri) * Val(Tri)) + "c50de4e5f29f5c91c7eba9c9a0a3e294fea0fa684193664f21f6c0a78c"
                If Activation = 0 ;-You will have to figure out how to store Activation if it equals 1 on your own.
                  If CompareMemoryString(@String2,@String1)
                    Debug "Incorrect Key"
                  Else
                    Debug "Yahoo!"
                  EndIf
                EndIf
            EndSelect
        EndSelect 
     
    Until Event = #PB_Event_CloseWindow
EndIf
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1282
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Re: How to generate a serial number?

Post by Paul »

J. Baker wrote:Getting more creative. Again, nothing is 100% but you could make a hacker work harder for it.
And this validates my point.
The only one that has worked harder here is the developer by adding more code trying to obfuscate strings and comparing memory, etc.
It still compiles to a section of code that says "If Code = Valid Then Result" and all the other work you've done up to that point is irrelevant.

The disassembled code section that finishes the validation looks like this...
Image

And it's still a simple Poke $74 to $75 to change the behavior.
The same code I posted earlier will also patch your "more creative" version with no modification.


Guess that's why software protection systems are so expensive. You are actually paying someone else to deal with all the obfuscating of code and detecting of disassemblers and virtual machines, etc.
And over time even those protection systems are bypassed unless they are constantly updated, playing a cat & mouse game with those trying to do the bypassing ;)
Image Image
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: How to generate a serial number?

Post by J. Baker »

Paul wrote:It still compiles to a section of code that says "If Code = Valid Then Result"
While I knew it wasn't 100%, I guess when it comes down to disassembling it, there's always a equal to or not equal to that can be replaced. I'm no expert on this obviously but thought it was worth a shot. I would say it's a shame that you can disassemble an app but it's a real shame that people steal software.

Thanks for the feedback, Paul. ;)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
BarryG
Addict
Addict
Posts: 4121
Joined: Thu Apr 18, 2019 8:17 am

Re: How to generate a serial number?

Post by BarryG »

Everything can and will be cracked, so don't waste money paying for some protection software. Just have some basic protection and be done with it. It's no different to locking your front door at night: it keeps the honest users honest, but won't stop anyone who really wants in. If someone doesn't want to pay, they won't. A good protection scheme won't make them pay; they'll either just submit to a crack site to get help from others, or they'll pay and then get a refund from their credit card company.
Bitblazer
Enthusiast
Enthusiast
Posts: 761
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: How to generate a serial number?

Post by Bitblazer »

J. Baker wrote:
Paul wrote:It still compiles to a section of code that says "If Code = Valid Then Result"
While I knew it wasn't 100%, I guess when it comes down to disassembling it, there's always a equal to or not equal to that can be replaced.
A better way might be to enforce a remote connection which does additional license verification. That way you can avoid (if you do it right!) a simple local patch. You could for example have your app being 99% local with all the resource intensive work, but have something like a crucial processing setup calculation done by an external module on your server. The advantage is having less software theft, but the major disadvantage is that your software is crippled and cant be used without a network connection anymore. Plus you will have to keep your servers up, running, up to date and any network/ISP/server issue makes your software unuseable. It also introduces new vulnerabilities like DDOS attacks on your license server. Some criminals might use that to extort money from you once your business is running successfully.

It is an option but not a good one in my opinion. Better spend time to enhance your software so more people will see a real value in paying for it, some people will always steal it anyway - focus on the legal users and make their life better by increasing the value of your software instead of wasting your time in a race you can't win anyway.

There are ways by using a USB dongle that make hacking the software more difficult. So you have for example between 3 weeks to 6 months where your software can only be used legally before a hack exists. But again, it is a race you will lose in the end, so i doubt it makes much sense. The moment a crack/hack exists, your time invested in any protection is mostly wasted. If you invest your time to enhance your software instead, that time is likely better used.

Don't forget that it is also likely a race against the open source community ;)

Plus some users despise usb dongles a lot, i have experienced the problems with having to run 6 dongles on the same machine and it is not funny ;)
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: How to generate a serial number?

Post by J. Baker »

Ok. I'm not saying it is uncrackable but wondering if it's just as easy or not. No code this time. The title bar will update if it's the correct or incorrect key. Obviously, if cracked, it should display "Correct Key".

https://www.flashpulse.com/download/EnterKey.zip
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
VB6_to_PBx
Enthusiast
Enthusiast
Posts: 627
Joined: Mon May 09, 2011 9:36 am

Re: How to generate a serial number?

Post by VB6_to_PBx »

J. Baker wrote:Ok. I'm not saying it is uncrackable but wondering if it's just as easy or not. No code this time. The title bar will update if it's the correct or incorrect key. Obviously, if cracked, it should display "Correct Key".

https://www.flashpulse.com/download/EnterKey.zip
i use :
multiple Procedure () without any parameters
and
Division by Zero ERROR
and with
OnErrorGoto(?GetOut)

i haven't seen anywhere on the Web my program has been hacked yet ??

would this be any better than IF and a String ??

or is mine still worthless and easily hacked with Division by Zero ERROR

my Program just quits or does not calculate anything after
Division by Zero ERROR
and with
OnErrorGoto(?GetOut)

it displays no warning to the User
just doesn't do anything anymore .
 
PureBasic .... making tiny electrons do what you want !

"With every mistake we must surely be learning" - George Harrison
MacDefender
New User
New User
Posts: 5
Joined: Tue Jun 11, 2019 5:50 pm
Location: Germany

Re: How to generate a serial number?

Post by MacDefender »

VB6_to_PBx wrote: or is mine still worthless and easily hacked with Division by Zero ERROR
It's still very easy to 'hack'. I've just opened the exe in Hopper Disassembler (macOS) and let it analyze the exe. You then just select the 'Correct Key' string and jump to the place where this string is referenced (just 1 click in Hopper). Than let Hopper generate PseudoCode and look what the app is doing:
Image

Not too difficult to modify this :wink:
User avatar
KJ67
Enthusiast
Enthusiast
Posts: 218
Joined: Fri Jun 26, 2009 3:51 pm
Location: Westernmost tip of Norway

Re: How to generate a serial number?

Post by KJ67 »

MacDefender wrote:Not too difficult to modify this
You may want to look at mobfuscator maybe and use it for the critical parts?
https://github.com/xoreaxeaxeax/movfuscator

"The M/o/Vfuscator (short 'o', sounds like "mobfuscator") compiles programs into "mov" instructions, and only "mov" instructions. Arithmetic, comparisons, jumps, function calls, and everything else a program needs are all performed through mov operations; there is no self-modifying code, no transport-triggered calculation, and no other form of non-mov cheating."

I would say that anyone able to decode a program only made up of "mov" after "mov" would anyhow crack anything they want.
The best preparation for tomorrow is doing your best today.
User avatar
skywalk
Addict
Addict
Posts: 4210
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: How to generate a serial number?

Post by skywalk »

Good discussion but repeated many times through the years.
If you must license, use the web.
Does not have to be your own website unless you have excellent service.
Store your customers' info in images or scattered open text on multiple open sites like reddit, imgur, bitbucket, etc.
Then randomly cycle through those websites for the latest hashes matching this customer+registered info hash.
Disassembly can defeat this, but counter measures will get flagged by antivirus engines. Say, you attempt patching your exe.
The best approach is focus on your product and price it below the crack threshold $$.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: How to generate a serial number?

Post by Tenaja »

One way to discourage cracked software is to introduce "random" bugs if the je is changed to jne. Not all the time, but randomly. And, have the Help About change (reduce?) the version number (or license number) to let you know it's changed. Anyone complaining about the bug is clearly using an illegal copy... Just tell them the most recent version does not have that bug, so they can update using their account.
GPI
PureBasic Expert
PureBasic Expert
Posts: 1394
Joined: Fri Apr 25, 2003 6:41 pm

Re: How to generate a serial number?

Post by GPI »

it would not use a hardware-detection. Sometimes hardware breaks or is replaced (bigger ssd for example) and your programm will not run. I would add a very simple check. a License-file encoded with AES and a inbuild key. Of course a hacker could find the aes-key in the app, but when he can do this, he could also remove the check code at all.
When you want a time-limited-license, you can't trust the local date. You can try to validate the current date with the internet - or if not possible, simple check all files in the Temp-Folder and check the date. Also you can save the current-date when the program quits and check on start, if the date is older than the quit-date.
Why the temp-folder? A user can change the current date to an earlier date to bypass the date check. But he must set the date back to valid date (for example when he want to use a browser - or all https-sides will be invalid). And because many programms create Temp-files, there must be at least one file created with the correct date.

With an aes-encrypted license-file and a date check you should prevent 99.99% of all basic users to freely copy your program. And don't forget to add a "licensed to user"-message in the info-box.

here is my example:

Code: Select all

EnableExplicit

Procedure ValidateDate()
  Protected dir
  Protected date, mdate
  
  ;Get the date of the all entries in the Temp-Folder
  dir = ExamineDirectory(#PB_Any, GetTemporaryDirectory(), "*.*")
  If dir
    While NextDirectoryEntry(dir)
      mdate = DirectoryEntryDate(dir, #PB_Date_Modified)
      If mdate > date
        date = mdate
      EndIf
      mdate = DirectoryEntryDate(dir, #PB_Date_Accessed)
      If mdate > date
        date = mdate
      EndIf
      mdate = DirectoryEntryDate(dir, #PB_Date_Created)
      If mdate > date
        date = mdate
      EndIf
    Wend
    FinishDirectory(dir)
  EndIf
  
  ; current date older than Temp-Files?
  mdate = date - Date()
  If mdate > 60*60*24 ; little security-gab
    ProcedureReturn #Null
  EndIf
  
  ; older than compile-Time?
  If Date() < #PB_Compiler_Date 
    ProcedureReturn #Null
  EndIf
  
  ; it seems, that everything is all right
  
  ProcedureReturn Date()
EndProcedure

Structure License_File
  Serial.s
  UserName.s
  StartDate.l
  EndDate.l
EndStructure
 
 ;Generate Serial
 ;   for guid-code see https://www.purebasic.fr/english/viewtopic.php?f=12&t=74015
 ;   here is only the windows-code
Structure UUID
   data1.l
   data2.w
   data3.w
   data4.b[8]
 EndStructure
 Procedure.s GenerateSerial()
   Protected.uuid guid
   Protected.i pst
   Protected.s st
   
   If UuidCreate_(guid) = #RPC_S_OK
     If UuidToString_(guid, @pst) = #RPC_S_OK
       If pst
         st = PeekS(pst, -1, #PB_Unicode)
         RpcStringFree_(@pst)
       EndIf
     EndIf 
   EndIf
   
   ProcedureReturn st
 EndProcedure
 
 Procedure CreateLicenseFile(filename.s, *key, Name.s, Serial.s, startDate.l, endDate.l)
   
   Protected.License_File license_Data  
   
   ;Generate License-Structure
   license_Data\Serial = Serial
   license_Data\UserName = Name
   license_Data\StartDate = startDate
   license_Data\EndDate = endDate
   
   ;Transfer into json and generate a string from the structure
   Protected json, composed.s
   json = CreateJSON(#PB_Any)
   If json = 0
     ProcedureReturn #False
   EndIf
   InsertJSONStructure( JSONValue(json), license_Data, License_File)
   ComposeJSON(json)
   composed.s = ComposeJSON(json)
   
   ;encrypt structure
   Protected ByteLen = StringByteLength( composed + "*" ) ; "*" = Null-terminator
   Protected *out = AllocateMemory(ByteLen)
   If *out = #Null 
     ProcedureReturn #False
   EndIf
   AESEncoder(@composed, *out, ByteLen, *key, 256, #Null, #PB_Cipher_ECB)
   
   ;savefile
   Protected fout
   fout = CreateFile(#PB_Any,filename)
   If Not fout
     FreeMemory(*out)
     ProcedureReturn #False
   EndIf
   WriteData(fout, *out, ByteLen)
   CloseFile(fout)
   
   FreeMemory(*out)
   
   ProcedureReturn #True
   
 EndProcedure
 
 Procedure OpenLicenseFile(filename.s, *key, *ret.License_File)
   
   ; load file
   Protected fin
   Protected ByteLen
   Protected *in, *out
   fin = ReadFile(#PB_Any, filename)
   If Not fin 
     ProcedureReturn #False
   EndIf
   ByteLen = Lof(fin)
   *in = AllocateMemory(ByteLen)
   If *in = #Null
     CloseFile(fin)
     ProcedureReturn #False
   EndIf
   *out = AllocateMemory(ByteLen)
   If *out = #Null
     FreeMemory(*in)
     CloseFile(fin)
     ProcedureReturn #False
   EndIf
   ReadData(fin, *in, ByteLen)
   CloseFile(fin)
      
   ; decode
   AESDecoder(*in, *out, ByteLen, *key, 256, #Null, #PB_Cipher_ECB)
   FreeMemory(*in)
   Protected.s str = PeekS(*out,ByteLen)
   FreeMemory(*out)
   
   ; Create JSON
   Protected json = ParseJSON(#PB_Any,str)
   If Not json
     ProcedureReturn #False
   EndIf
   ExtractJSONStructure(JSONValue(json),*ret, License_File)   
   
 EndProcedure
 
 ;we create a license-file
 CreateLicenseFile("demo.lic", ?key, "Otto", GenerateSerial(), Date(), Date()+10000)
 
 ; now we read it
 Define.License_File license
 OpenLicenseFile("demo.lic", ?key, license)
 Debug "User:"+license\UserName
 Debug "Serial:"+license\Serial
 Debug "Start:"+FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", license\StartDate)
 Debug "End:"+FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", license\EndDate)
 
 ; check if the date is valid
 ; additional-check: Store the current date when the programms quits and check on start if the date is newer than the quit-date
 Define date = ValidateDate()
 If date >= license\StartDate And date <= license\EndDate
   Debug "Date is valid!"
 Else
   Debug "-- rejected - go to demo-mode"
 EndIf
 
 
 
  DataSection
    Key:; 256-bit-key - should be changed
    Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06
    Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06
  EndDataSection
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: How to generate a serial number?

Post by Saki »

You can copy the license data encrypted into the EXE.
But you can also hide it for example encrypted in a picture.
They should be created multiple times.
One of them should be easy to find, so that the one who is looking for it thinks he has found it.
Further one may not react immediately to a pirate copy or output a text immediately.
The easiest way is to make the program unstable.
The interest in it then disappears quickly.
Everyone has to decide that for himself.

But you should not overestimate this.
Probably no one is interested in buying a beginner software or any other worthless coded part, let alone cracking it.
Hardware keys are absolute shit in my eyes.
地球上の平和
Post Reply