Page 2 of 2

Re: How to generate a serial number?

Posted: Sun Sep 06, 2020 10:36 am
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.

Re: How to generate a serial number?

Posted: Mon Sep 07, 2020 1:50 pm
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.

Re: How to generate a serial number?

Posted: Mon Sep 07, 2020 5:18 pm
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

Re: How to generate a serial number?

Posted: Tue Sep 08, 2020 1:30 am
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 ;)

Re: How to generate a serial number?

Posted: Tue Sep 08, 2020 3:47 am
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. ;)

Re: How to generate a serial number?

Posted: Tue Sep 08, 2020 9:00 am
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.

Re: How to generate a serial number?

Posted: Tue Sep 08, 2020 9:10 am
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 ;)

Re: How to generate a serial number?

Posted: Tue Sep 08, 2020 3:53 pm
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

Re: How to generate a serial number?

Posted: Tue Sep 08, 2020 4:44 pm
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 .

Re: How to generate a serial number?

Posted: Sun Oct 25, 2020 4:30 pm
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:

Re: How to generate a serial number?

Posted: Mon Oct 26, 2020 7:30 pm
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.

Re: How to generate a serial number?

Posted: Mon Oct 26, 2020 9:29 pm
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 $$.

Re: How to generate a serial number?

Posted: Tue Oct 27, 2020 4:10 am
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.

Re: How to generate a serial number?

Posted: Tue Oct 27, 2020 10:58 am
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

Re: How to generate a serial number?

Posted: Tue Oct 27, 2020 11:13 am
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.