Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First of all, as other said you should consider using a DLL or SO.</p> <p>That said, if you really want to do this, you need to replace the linker script. Something like this (not very well tested, but I think it works):</p> <pre><code>ENTRY(_dummy_start) SECTIONS { _dummy_start = 0; _GLOBAL_OFFSET_TABLE_ = 0; .all : { _all = .; LONG(f1 - _all); *( .text .text.* .data .data.* .rodata .rodata.* ) } } </code></pre> <p>Then compile with:</p> <pre><code>$ gcc -c -fPIC test.c </code></pre> <p>Link with:</p> <pre><code>$ ld -T script.ld test.o -o test.elf </code></pre> <p>And extract the binary blob with:</p> <pre><code>$ objcopy -j .all -O binary test.elf test.bin </code></pre> <p>Probably some explanation of the script is welcome:</p> <ul> <li><code>ENTRY(_dummy_start)</code> That just avoids the warning about the program not having an entry point.</li> <li><code>_dummy_start = 0;</code> That defines the symbol used in the previous line. The value is not used.</li> <li><code>_GLOBAL_OFFSET_TABLE_ = 0;</code> That prevents another linker error. I don't think you really need this symbol, so it can be defined as 0.</li> <li><code>.all</code> That's the name of the section that will collect all the bytes of your blob. In this sample it will be all the <code>.text</code>, <code>.data</code> and <code>.rodata</code> sections together. You may need some more if you have complicated functions, in this case <code>objdump -x test.o</code> is your friend.</li> <li><code>LONG(f1 - _all)</code> Not really needed, but you want to know the offset of your function into the blob, don't you? You cannot assume that it will be at offset 0. With this line the very first 4 bytes in the blob will be the offset of the symbol <code>f1</code> (your function). Change <code>LONG</code> with <code>QUAD</code> if using 64-bit pointers.</li> </ul> <p><strong>UPDATE</strong>: And now a quick'n'dirty test (it works!):</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;sys/mman.h&gt; typedef void (*f1_t)(char *a, char *b, int len); f1_t f1; int main() { char *blob = (char*)valloc(4096); FILE *f = fopen("test.bin", "rb"); fread(blob, 1, 4096, f); fclose(f); unsigned offs = *(unsigned*)blob; f1 = (f1_t)(blob + offs); mprotect(blob, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); char txt[] = "¡hello world!"; char txt2[sizeof(txt)] = ""; f1(txt, txt2, sizeof(txt) - 1); printf("%s\n%s\n", txt, txt2); return 0; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload