<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Tewha.net</title>
    <link>https://tewha.net/tags/getsectbyname/</link>
    <description>Recent content on Tewha.net</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 12 Mar 2015 05:56:07 +0000</lastBuildDate>
    <atom:link href="https://tewha.net/tags/getsectbyname/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Info.plist for command line tools</title>
      <link>https://tewha.net/2015/03/info-plist-for-command-line-tools/</link>
      <pubDate>Thu, 12 Mar 2015 05:56:07 +0000</pubDate>
      <guid>https://tewha.net/2015/03/info-plist-for-command-line-tools/</guid>
      <description>&lt;p&gt;In the past if you wanted to include data in your command line app, you could either include it in a separate file or do some linker trickery to embed it. Personally, I never really got into the linker trickery (though it&amp;rsquo;s probably the better solution of the two).&lt;/p&gt;
&lt;p&gt;For a while, though, Xcode has supported a build option &lt;strong&gt;Create Info.plist Section In Binary&lt;/strong&gt;, also known as &lt;code&gt;CREATE_INFOPLIST_SECTION_IN_BINARY&lt;/code&gt;. If on, this will embed the target&amp;rsquo;s Info.plist into the executable as a data segment.&lt;/p&gt;
&lt;p&gt;I couldn&amp;rsquo;t find any documentation on how to get it out, though. After a lot of searching, I came up with &lt;code&gt;getsectbyname&lt;/code&gt;. This is defined in &lt;strong&gt;mach-o/getsect.h&lt;/strong&gt; like so:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In the past if you wanted to include data in your command line app, you could either include it in a separate file or do some linker trickery to embed it. Personally, I never really got into the linker trickery (though it&rsquo;s probably the better solution of the two).</p>
<p>For a while, though, Xcode has supported a build option <strong>Create Info.plist Section In Binary</strong>, also known as <code>CREATE_INFOPLIST_SECTION_IN_BINARY</code>. If on, this will embed the target&rsquo;s Info.plist into the executable as a data segment.</p>
<p>I couldn&rsquo;t find any documentation on how to get it out, though. After a lot of searching, I came up with <code>getsectbyname</code>. This is defined in <strong>mach-o/getsect.h</strong> like so:</p>






<pre tabindex="0"><code>extern const struct section_64 *getsectbyname(
    const char *segname,
    const char *sectname);</code></pre>
<p>(There&rsquo;s a 32-bit version as well, but I was only interested in 64-bit.)</p>
<p>One of the fields in <code>section_64</code> was the address of the data in memory, another its size. Easy to wrap with a <code>NSData</code>, right?</p>
<p>Not so fast. This worked in debug <em>and</em> release builds when run in Xcode, but didn&rsquo;t work when run on Terminal or Instruments. There, accessing the raw bytes caused a segmentation fault.</p>
<p><a href="https://twitter.com/gparker/status/575527435539771392">A tweet from Greg Parker</a> put me on track.</p>
<p>The difference turned out to be <a href="https://en.wikipedia.org/wiki/Address_space_layout_randomization">Address space layout randomization (ASLR)</a>. You can read all about it on Wikipedia, but the gist of it is that in order to make it harder to exploit a vulnerability many operating systems have implemented a system where executables are randomly located in the address space. This makes it harder for injected code to access application or system code. The results returned by <code>getsectbyname</code> don&rsquo;t take ASLR into account.</p>
<p>Instead of using <code>getsectbyname</code>, I had to use <code>getsectiondata</code>. <code>getsectiondata</code> would return a pointer to the exact data I needed. It took me quite a while to find anything relevant online.</p>
<p>It&rsquo;s declared like this:</p>






<pre tabindex="0"><code>extern uint8_t *getsectiondata(
    const struct mach_header *mhp,
    const char *segname,
    const char *sectname,
    unsigned long *size);</code></pre>
<p>But what&rsquo;s that fist thing, the <code>mach_header</code>?</p>
<p>It took me a long time to find anything relevant, but I eventually found out that I needed to use <code>_mh_execute_header</code> from <strong>mach-o/ldsyms.h</strong>.</p>
<p>The resulting code looks like this, and works:</p>






<pre tabindex="0"><code>#include &amp;lt;mach-o/getsect.h&amp;gt;
#include &amp;lt;mach-o/ldsyms.h&amp;gt;

- (instancetype)init {
    self = [super init];
    if (!self) return nil;
    
    NSError *e;
    unsigned long size;
    void *ptr = getsectiondata(&amp;_mh_execute_header, &#34;__TEXT&#34;, &#34;__info_plist&#34;, &amp;size);
    NSData *plistData = [NSData dataWithBytesNoCopy:ptr length:size freeWhenDone:NO];
   _infoPlistContents = [NSPropertyListSerialization propertyListWithData:plistData options:NSPropertyListImmutable format:NULL error:&amp;e];

   return self;
}</code></pre>
<p>This only works in the application; if you need to do this from a dynamic library, try <a href="http://stackoverflow.com/questions/19848567/how-to-get-the-build-uuid-in-runtime-and-the-image-base-address/22674561#22674561">this approach from Cédric Luthi</a>.</p>
<p>Full credit to those two, but I wanted to post something about this so that future searches might find it. Thanks, guys!</p>]]></content:encoded>
    </item>
  </channel>
</rss>
