Protecting Against Piracy Of Raspberry Pi Apps???

The new Raspberry Pi computer and Xojo able to write apps for it opens up a new opportunity for Xojo developers. However, because the SD card can be removed from the computer, there is no apparent way of protecting the app from being copied and distributed on to other SD cards outside of having copy protected cards made by a third party. Thus, it clears the way for people to easily pirate your apps.

I was wondering if there was a way that Xojo can read the Pi board’s serial number. I saw a python function called getserial() that reads the Pi’s unique serial number, but I don’t know how this could be rewritten in Xojo. The code is listed below:

[code]def getserial():

Extract serial from cpuinfo file

cpuserial = “0000000000000000”
try:
f = open(’/proc/cpuinfo’,‘r’)
for line in f:
if line[0:6]==‘Serial’:
cpuserial = line[10:26]
f.close()
except:
cpuserial = “ERROR000000000”

return cpuserial[/code]

That way code could be written to an encrypted database file on the card that matched the serial number of the board. (You sell the app and and the Raspberry Pi Unit as a package) That way if someone tried to remove the SD card and put it in another RP computer, it would not work.

Another way to protect from piracy was if there was a way to write directly to the Pi board somewhere. So when the app was loaded, it would compare a value on the board with the value stored in an encrypted database on the card.

If piracy could be prevented, this could offer Xojo developers a new revenue stream.

Dont have a pi to try but
This is purely ported here in the forum so this may not work as is

Sub getserial() as string
  // # Extract serial from cpuinfo file
  dim cpuserial as string = "0000000000000000"
  try
    dim f as FolderItem = new FolderItem("/proc/cpuinfo", FolderItem.PathTypeNative )
    dim tis as TextInputStream = TextInputStream.Open( f )
    while tis.EOF <> true
            dim line as string = tis.ReadLine
             if left(line,6) ="Serial" then
                      cpuserial = line.mid(10,16)
             endif
     wend
     tis = nil
     f = nil
   catch exc as RuntimeException
    cpuserial = "ERROR000000000"
   end try

  return cpuserial

end 

Hi Norman,

Thanks for trying to help. I guess I’m having a difficult time trying to write this.

I add the method called getserial. I set the return to string. I paste the code below into the code editor.

// # Extract serial from cpuinfo file dim cpuserial as string = "0000000000000000" try dim f as FolderItem = new FolderItem("/proc/cpuinfo", FolderItem.PathTypeNative ) dim tis as TextInputStream = TextInputStream.Open( f ) while tis.EOF <> true dim line as string = tis.ReadLine if left(line,6) ="Serial" then cpuserial = line.mid(10,16) end if wend tis = nil f = nil catch exc as RuntimeException cpuserial = "ERROR000000000" end try

return cpuserial

I then create a button and put “getserial” on the action event. When I run it, I get the error “You must use the value returned by this function getserial” on the button event. What am I doing wrong?

[quote=238019:@James Redway]Hi Norman,

Thanks for trying to help. I guess I’m having a difficult time trying to write this.

I add the method called getserial. I set the return to string. I paste the code below into the code editor.

// # Extract serial from cpuinfo file dim cpuserial as string = "0000000000000000" try dim f as FolderItem = new FolderItem("/proc/cpuinfo", FolderItem.PathTypeNative ) dim tis as TextInputStream = TextInputStream.Open( f ) while tis.EOF <> true dim line as string = tis.ReadLine if left(line,6) ="Serial" then cpuserial = line.mid(10,16) end if wend tis = nil f = nil catch exc as RuntimeException cpuserial = "ERROR000000000" end try

return cpuserial

I then create a button and put “getserial” on the action event. When I run it, I get the error “You must use the value returned by this function getserial” on the button event. What am I doing wrong?[/quote]

Sounds like you are calling the function wrong from your button action event.

Ensure you have something like:

Dim theSerial as String = getserial()

Then do something with the string returned in theSerial

Thanks Mike,

I think I was doing it wrong. I still don’t know if I’m doing it right, because the code does not give the Pi Serial number.

I have this code on the Action event of the button.

Dim cpuserial as String = getserial()

I have this code on the method:

[code] // # Extract serial from cpuinfo file
dim cpuserial as string = “0000000000000000”
try
dim f as FolderItem = new FolderItem("/proc/cpuinfo", FolderItem.PathTypeNative )
dim tis as TextInputStream = TextInputStream.Open( f )
while tis.EOF <> true
dim line as string = tis.ReadLine
if left(line,6) =“Serial” then
cpuserial = line.mid(10,16)
end if
wend
tis = nil
f = nil
catch exc as RuntimeException
cpuserial = “ERROR000000000”
end try

return cpuserial
txt1.Text=cpuserial //textbox that should display the serial number[/code]

Nothing happens when you click the button on the Pi.

I really think this would be a beneficial piece of code for Xojo developers who would like to protect their apps from piracy on the Raspberry Pi. If you can get the unique serial number from the board, you can protect your apps from being copied.

Have you used the IDE debugger to step through each line to see what is happening? Perhaps you are bombing on the try? Perhaps your path isn’t 100% correct?

Also the txt1.text = cpuserial won’t do anything since it is after you “return cpuserial”. I would go back into your button’s action event and add your txt1.text = cpuserial there.

remember I DO NOT HAVE A PI TO TEST THIS ON IN ANY WAY SHAPE OR FORM
The code could be 100% wrong
It may fail to get the serial because it cant open the stated folder item etc etc etc

Litter it wil system.debuglog etc & then launch it from the console to test & see if JUST THAT CODE works at all

Also remember that this will only work using Raspbian OS. If you use another variation like I do, this likely won’t work.

Hi Norman,

I know you do not have a Pi in which to test that code on. I understood that, and I appreciate you taking the time to help.

I think that Xojo deciding to support this little Raspberry Pi computer is a great thing and it opens up lots of potential for producing apps from a commercial point of view.

The problem IS, that the OS and the app is installed on the SAME SD card. One can easily copy the contents of a SD card. It was my intention to sell both the Pi unit and the app preinstalled on the card as one package. However, there would be nothing to prevent someone from simply copying the SD card and distributing my app.

That is why, IF we could ascertain the Raspberry Pi’s serial number and copy that number to an encrypted sqlite database, then when the app is run, the board’s stored serial number could be compared to the one stored in the database, and if they did not match the app would not open, than that would prevent piracy. I found python code that shows how to get the Pi’s board serial number. If this could be converted to Xojo, it would be a great benefit for any if the Xojo users that want to protect their intellectual property.

Eric was stating that the code would only work with the Raspbian OS. That would not be a problem since the Raspbian OS and app would already be preinstalled on the card.

I have worked with this little box for one day, and the board serial number was my first thought of how to get some sort of unique signature from the unit. If there was a better way to either read or write to the Pi outside the SD card, that would work too.

I think it would be an excellent example app for the Pi to have a way to read the board’s serial number. That would be extremely helpful, and I believe would be a benefit for anyone serious about writing commercial apps for the Pi. It’s hard to make it work commercially if it can be easily pirated.

I don’t have a Pi why do you prefer the boards serial above the cpu serial?
I think the cpu serial is much easier to grab.
cat /proc/cpuinfo
Or grab more info from there and use the hash.
And if your App checks if the file is valid (size = 0, fstat etc), it’s not easy to fake.

Edit: To get the boards serial is a bit more complicated: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface

Well this seems to be a broader topic, regarding all platforms and software in general. How to protect your software from being counterfeit. There are - even on singleboards - various ways to enable copy-protection already discussed here in the forum, I just show the top hits:

https://forum.xojo.com/6573-opinions-on-piracy-and-anti-piracy-techniques
https://forum.xojo.com/18606-how-secure-is-the-compiled-code-itself
https://forum.xojo.com/15841-local-disk-uuid

The bottomline is: There is no elegant way to do this. The deeper you dig and the more complex your anti-counterfeit strategy grows, the more bloaty and faulty your software gets. This is my opinion. And on singleboards there is nothing more worse than blaotware consuming space and cpu-times with lots of encryption or decryption. In the end you should ask yourself, if you’re not punishing your loyal and paying customer base in limiting your software to one board, OS or even SD card? One great advantage of singleboards is, that you can use a lot of them for small, little, dull tasks.

I do not know your software nor your business model. Perhaps there is another way in terms of service, support etc. to encourage your customers not to just copy your software. Or create additional desktop software or tools, monitoring and collecting data only from a given number of devices etc.

just my 5 cents…

[quote]I don’t have a Pi why do you prefer the boards serial above the cpu serial?
I think the cpu serial is much easier to grab.
cat /proc/cpuinfo
Or grab more info from there and use the hash.
And if your App checks if the file is valid (size = 0, fstat etc), it’s not easy to fake.[/quote]

Hi Marco,

Thank you for responding to my message. I guess I did not properly describe the code above. The code I posted above was for getting the serial number from the cpu, not the board. That code was Python that I picked up at:

link text

I just want to know, if there was a way to adapt this Python code to Xojo. I don’t know how to do that. I just want the Pi’s cpu serial number to be copied to a TextBox. That’s it.

Hi Tomas,

The solution may not be flawless, but it is simple, will help cut down on piracy, and it will not slow the app down nor bloat it up in any way.

I have been in the software business for almost 20 years. Unfortunately, our software is highly pirated. Years ago we made the decision to try to cut down on piracy by taking steps to prevent it. That has worked very well in our Windows and Mac software. The Raspberry Pi is unique because all the data and the OS is stored on a single inexpensive SD card. That is not the case with Windows and Mac computers in which data and the OS is stored on expensive high-capacity hard drives. If both the OS and my app is stored on the SD card, its very easy and inexpensive to make copies.

Here is how you help prevent piracy of your app on the Raspberry Pi if you are selling the entire unit plus the software.

  1. Before shipping, you determine the CPU Serial number off the computer.
  2. That serial number is stored in an encrypted database in your app.
  3. Every time that app is run there would be code that would check to see if the CPU Serial Number matched the Serial Number stored in the database. If it does not, the app will not open.

If the SD card is copied and transferred to another Raspberry Pi, it would not work because the stored serial number on the SD card will not match the cpu serial number.

So the million dollar question is… Is there a way to take that Python code and convert it so it could be used with Xojo?

[quote=238086:@James Redway]Hi Marco,

Thank you for responding to my message. I guess I did not properly describe the code above. The code I posted above was for getting the serial number from the cpu, not the board. That code was Python that I picked up at:

link text

I just want to know, if there was a way to adapt this Python code to Xojo. I don’t know how to do that. I just want the Pi’s cpu serial number to be copied to a TextBox. That’s it.

Hi Tomas,

The solution may not be flawless, but it is simple, will help cut down on piracy, and it will not slow the app down nor bloat it up in any way.

I have been in the software business for almost 20 years. Unfortunately, our software is highly pirated. Years ago we made the decision to try to cut down on piracy by taking steps to prevent it. That has worked very well in our Windows and Mac software. The Raspberry Pi is unique because all the data and the OS is stored on a single inexpensive SD card. That is not the case with Windows and Mac computers in which data and the OS is stored on expensive high-capacity hard drives. If both the OS and my app is stored on the SD card, its very easy and inexpensive to make copies.

Here is how you help prevent piracy of your app on the Raspberry Pi if you are selling the entire unit plus the software.

  1. Before shipping, you determine the CPU Serial number off the computer.
  2. That serial number is stored in an encrypted database in your app.
  3. Every time that app is run there would be code that would check to see if the CPU Serial Number matched the Serial Number stored in the database. If it does not, the app will not open.

If the SD card is copied and transferred to another Raspberry Pi, it would not work because the stored serial number on the SD card will not match the cpu serial number.

So the million dollar question is… Is there a way to take that Python code and convert it so it could be used with Xojo?[/quote]

James have you stepped through the debugger to “see” what each line value is? This doesn’t seem hard if you use the debugger to see what you are getting.

Hi James,

Here’s a quick example using shell output from[quote]cat /proc/cpuinfo[/quote] as Marco suggested. I’ll leave the parsing of the results as an exercise for you.

Mike, you can’t really do that since you run the debugger is running on a Mac and the app is suppose to be run on the Pi.

f comes back as Nil since there is no such folder on the Mac, and you get an “UnsupportedFormatException” which takes you to the catch exc line.

[code] // # Extract serial from cpuinfo file
dim cpuserial as string = “0000000000000000”
try
dim f as FolderItem = new FolderItem("/proc/cpuinfo", FolderItem.PathTypeNative )
dim tis as TextInputStream = TextInputStream.Open( f )
while tis.EOF <> true
dim line as string = tis.ReadLine
if left(line,6) =“Serial” then
cpuserial = line.mid(10,16)
end if
wend
tis = nil
f = nil
catch exc as RuntimeException
cpuserial = “ERROR000000000”
end try

return cpuserial
txt1.Text=cpuserial[/code]

I understand and Ill fake one for you to post the code… Also you still have the “txt1.text=cpuserial” which isn’t doing anything since you return above it.

I see the issue w/ Norman’s code. There are some white spaces. I am building a test project and validating it now.

James,

Here is a link to the text project that works on my Mac.
https://www.dropbox.com/s/t9sbbafurk6ewp5/Pi2SerialTest.xojo_binary_project?dl=0

I faked having a /proc/cpuinfo folder with pasted in contents of the following for this test:

Processor       : ARMv6-compatible processor rev 7 (v6l)
 BogoMIPS        : 697.95
 Features        : swp half thumb fastmult vfp edsp java tls
 CPU implementer : 0x41
 CPU architecture: 7
 CPU variant     : 0x0
 CPU part        : 0xb76
 CPU revision    : 7

 Hardware        : BCM2708
 Revision        : 1000002
 Serial          : 000054000000000d

Please let us know if this works on your Pi2.

Thanks!!

I also validated this pi2 /proc/cpuinfo works also with my project.

model name  : ARMv7 Processor rev 0 (v7l)
BogoMIPS    : 38.40
Features    : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xd03
CPU revision    : 0

processor   : 1
model name  : ARMv7 Processor rev 0 (v7l)
BogoMIPS    : 38.40
Features    : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xd03
CPU revision    : 0

processor   : 2
model name  : ARMv7 Processor rev 0 (v7l)
BogoMIPS    : 38.40
Features    : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xd03
CPU revision    : 0

processor   : 3
model name  : ARMv7 Processor rev 0 (v7l)
BogoMIPS    : 38.40
Features    : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xd03
CPU revision    : 0

Hardware    : Qualcomm Technologies, Inc MSM8916
Revision    : 0006
Serial      : 000009f200000001
Processor   : ARMv7 Processor rev 0 (v7l)

Hi Mike,

I tried it on the Pi2 and I get all zeros. No correct serial number.