One of the advantages of Code signing your app is it also protects your app from being patched (read: cracked - well sort off).
So when it is patched, the Codesign signature is broken and your app will not launch anymore.
However, lately there seems to be a way to bypass this so an app that has a broken signature, still can be launched without any warning.
Therefore I wrote a small method to test the codesign signature from within your app.
You can call this method at random (with for example a timer to trigger it) and see if the codesign signature is broken or not. If yes, you can do whatever you want : quit the app, remove the license, delete the users harddisk (that would teach them but not advised
Function checkCodesignSignature() As boolean
dim checkShell as new Shell
checkShell.execute ("codesign -v "+App.ExecutableFile.parent.parent.parent.ShellPath)
do
loop until not checkShell.isrunning
if instr(checkShell.readAll,"invalid signature") <> 0 then return false
return true
End Function
I wouldn’t do that… No guarantee the end user has the codesign command (it’s installed with XCode I believe) and it would be trivial to swap it out with an executable that does nothing, and returns an empty string. There is a method using declares and MBS has functions in the plugins to do this properly…
Every OS X 10.7 and higher has codesign available. Even if Xcode is not installed.
If it returns a empty string, it will do nothing. Only when the string returned has ‘invalid signature’ it return false.
Oh, you’re right… not sure what I was thinking of. I would recommend using declares though, just seems more secure. And since I mentioned it, here’s a function to check for a valid sgnature.
[code]Function amSigned() As Boolean
Declare Function SecCodeCopySelf Lib “Security” (flags as integer, byref proc as ptr) As Integer
Declare Function SecCodeCheckValidity Lib “Security” (code as ptr, flags as integer, requirement as ptr) As Integer
dim myProc as ptr
dim res As integer
res=SecCodeCopySelf(0,myProc) //get a code object for the current process
res=res+SecCodeCheckValidity(myProc,0,nil)
if res<>0 then Return false //error or failure… in either case, we failed!
return true
End Function
[/code]
There’s also more you can do to add a requirement to check for your signature rather than just any valid signature…
My concern would be that if someone were to patch your app, I think they could just sign it with a different signature afterwards causing validation to pass. Hence the need to verify that it is the correct (original) signature.
BUT, if you’re signing with an Apple issued certificate, you could check that the root is Apple and the cert is your certificate. I don’t think it’s reasonably possible to get an app signed with a forged Apple cert on a Mac to launch without hacking the OS itself and at that point, forget it. (I could be wrong…)
[quote=144496:@Norman Palardy]Certainly could strip the original signature, patch it , sign it voila !
Signed & hacked[/quote]
In that case you could send Apple a mail your apps has been cracked and re-codesigned with another signature. Maybe Apple blocks that signature for future use?
Right, and if it was a certificate issued by Apple, I think they could be legally required to provide the owner’s info if there were criminal charges involved.
BTW I ones seriously thought about putting some ‘delete hdd’ code so the cracker that tries the patched app himself, will be in for a big surprise. In the end he will be the first to try it out and for sure will not try it again with the same app.
Very tempting though … but …
This should work for adding a requirement to the check.
[code]Function amSigned(requirement As String) As Boolean
Declare Function SecCodeCopySelf Lib “Security” (flags as integer, byref proc as ptr) As Integer
Declare Function SecCodeCheckValidity Lib “Security” (code as ptr, flags as integer, requirement as ptr) As Integer
Declare Function SecRequirementCreateWithString Lib “Security” (text as cfstringref, flags as integer, byref requirement as ptr) As Integer
dim myProc as ptr
dim res As integer
dim req As ptr
res=SecCodeCopySelf(0,myProc) //get a code object for the current process
res=res+SecRequirementCreateWithString(requirement,0,req) //create a code requirement
res=res+SecCodeCheckValidity(myProc,0,req) //check the validity with a requirement
if res<>0 then Return false //error or failure… in either case, we failed!
If you’re going to go through all the trouble to validate the signature is yours they’re just going to skip trying to fake it and modify the subroutine to return true always.
Hacked + Patched with no checking.
Anything more than stopping casual piracy is a waste of your and your legitimate customers time and resources.
It’s true that if a hacker wants to crack your app, they will. But I don’t see anything wrong with at least making it difficult. Change the method name and put it in various places and check it from various places. There’s a million apps to hack and getting put on the back burner is really the goal.
BTW I ones seriously thought about putting some ‘delete hdd’ code so the cracker that tries the patched app himself, will be in for a big surprise. In the end he will be the first to try it out and for sure will not try it again with the same app.
Very tempting though … but … :)[/quote]
I know how you feel, but you gotta be real careful with stuff like this, in case some casual user runs a cleanup app or some other tool without realizing that it breaks the code signature and boom… They’ve wiped their drive.
I had once case where a customer was using a tool to clean his drive and it broke the code signature on my application… It took him and I a while to realize what broke it, I had presumed that he was using a cracked version (because the code signature was broken).