Checking Codesign Signature In-App code

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 :wink:

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…

are you sure codesign is not there always?

and I would also check with “spctl” tool if GateKeeper accepts it.

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.

Works fine for sure.

Which? Couldn’t find this.

This is what you get if the app was patched:

/Users/Xtophe/Desktop/test.app: invalid signature (code or signature have been modified)
In architecture: i386

If it is not patched it just return an empty string.

Yes it is from OSX10.7 and upwards.

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…

True, but checking the validation inapp is good enough to keep your app not being patched (without knowing it).

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.

Certainly could strip the original signature, patch it , sign it voila !
Signed & hacked :slight_smile:

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…)

And how to verify it is urge correct, original signature?

[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.

Interesting. :slight_smile:

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. :slight_smile:
Very tempting though … but … :slight_smile:

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!

return true
End Function
[/code]

The requirement language is a chore to figure out, but…

entitlement["“com.apple.security.app-sandbox”"] exists

will check that the signature includes a sandbox requirement.

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.

[quote=144511:@Christoph De Vocht]Interesting. :slight_smile:

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. :slight_smile:
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).