title: Executable encryption check anti piracy measure
body: <p>I read a very interesting blog about implementing some anti-piracy protection into your apps. Some of them dont work anymore, some of them do. The 2 ones that still are effective to an extent are the 2 last ones listed.
  <a href="http://shmoopi.wordpress.com/2011/06/19/27/" rel="noreferrer">http://shmoopi.wordpress.com/2011/06/19/27/</a></p>
  
  <p>The one I'm interested in is the very last one. Code below. I've implemented this in my AppDelegate.m</p>
  
  <p>Anti piracy via the encryption check.</p>
  
  <p>Required Headers</p>
  
  <pre><code>#import &lt;dlfcn.h&gt;
  #import &lt;mach-o/dyld.h&gt;
  #import &lt;TargetConditionals.h&gt;
  </code></pre>
  
  <p>Encryption Struct</p>
  
  <pre><code>#if TARGET_IPHONE_SIMULATOR &amp;&amp; !defined(LC_ENCRYPTION_INFO)
  #define LC_ENCRYPTION_INFO 0x21
  struct encryption_info_command 
  {
  uint32_t cmd;
  uint32_t cmdsize;
  uint32_t cryptoff;
  uint32_t cryptsize;
  uint32_t cryptid;
  };
  #endif
  </code></pre>
  
  <p>Needed Methods</p>
  
  <pre><code>int main (int argc, char *argv[]);
  
  static BOOL is_encrypted () 
  {
  const struct mach_header *header;
  Dl_info dlinfo;
  
  /* Fetch the dlinfo for main() */
  if (dladdr(main, &amp;dlinfo) == 0 || dlinfo.dli_fbase == NULL) 
  {
      NSLog(@"Could not find main() symbol (very odd)");
      return NO;
  }
  header = dlinfo.dli_fbase;
  
  /* Compute the image size and search for a UUID */
  struct load_command *cmd = (struct load_command *) (header+1);
  
  for (uint32_t i = 0; cmd != NULL &amp;&amp; i &lt; header-&gt;ncmds; i++) 
  {
      /* Encryption info segment */
      if (cmd-&gt;cmd == LC_ENCRYPTION_INFO) 
      {
          struct encryption_info_command *crypt_cmd = (struct encryption_info_command *) cmd;
          /* Check if binary encryption is enabled */
          if (crypt_cmd-&gt;cryptid &lt; 1) 
          {
              return NO;
          }
          return YES;
      }
  
      cmd = (struct load_command *) ((uint8_t *) cmd + cmd-&gt;cmdsize);
  }   
  return NO;
  }
  </code></pre>
  
  <p>This method checks to see if the binary is still encrypted. </p>
  
  <p>When I run this on the device attached to x-code it gives me a false positive on this line</p>
  
  <pre><code>if (crypt_cmd-&gt;cryptid &lt; 1) 
  {
      NSLog(@"Pirated from (crypt_cmd-&gt;cryptid &lt; 1) ");
      return NO;
  } 
  </code></pre>
  
  <p>I was wondering is it possible that the builds xcode puts onto the device for debugging purposes not encrypted? And its only encrypted when the build is submitted to Apple for use on iTunes. Hence why I am getting this false positive when check the code.</p>
  
  <p>Many Thanks,
  -Code</p>