Skip to content

segfault in diff optimize level #8

@wenxichang

Description

@wenxichang

// start of the function to inject always happens to be 2 bytes long.
? this is not reliable, this my modification:

  1. fill 32 nop in the begin of injectSharedLibrary to ensure the code copy to target is clean.

the second question is that why the last INT 3 inst. not supply in injectSharedLibrary but find and replace the RET inst. ?

the .patch:

Index:

 inject-x86_64.c
===================================================================
--- inject-x86_64.c (revision 654940)
+++ inject-x86_64.c (working copy)
@@ -25,6 +25,13 @@

 void injectSharedLibrary(long mallocaddr, long freeaddr, long dlopenaddr)
 {
+   // add nop in the function head, so that we can jump into it for diff c-compiler optimize
+   asm(
+       "nop \nnop \nnop \nnop \nnop \nnop \nnop \nnop \n"
+       "nop \nnop \nnop \nnop \nnop \nnop \nnop \nnop \n"
+       "nop \nnop \nnop \nnop \nnop \nnop \nnop \nnop \n"
+       "nop \nnop \nnop \nnop \nnop \nnop \nnop \nnop \n"
+   );
    // here are the assumptions I'm making about what data will be located
    // where at the time the target executes this code:
    //
@@ -103,7 +110,9 @@
        // call free()
        "callq *%rbx \n"
        // restore previous rbx value
-       "pop %rbx"
+       "pop %rbx \n"
+       // break to restore everything
+       "int $3"
    );

    // we already overwrote the RET instruction at the end of this function
@@ -223,8 +232,12 @@
    regs.rcx = libPathLength;
    ptrace_setregs(target, &regs);

+   // +30 to skip function header(we have 32 nop after the header)
+   // ensure clean code is copied
+   void *safeInjectSharedLibrary = (void *)((intptr_t)injectSharedLibrary + 30);
+   
    // figure out the size of injectSharedLibrary() so we know how big of a buffer to allocate. 
-   size_t injectSharedLibrary_size = (intptr_t)injectSharedLibrary_end - (intptr_t)injectSharedLibrary;
+   size_t injectSharedLibrary_size = (intptr_t)injectSharedLibrary_end - (intptr_t)safeInjectSharedLibrary;

    // also figure out where the RET instruction at the end of
    // injectSharedLibrary() lies so that we can overwrite it with an INT 3
@@ -233,7 +246,6 @@
    // which means that functions are padded with NOPs. as a result, even
    // though we've found the length of the function, it is very likely
    // padded with NOPs, so we need to actually search to find the RET.
-   intptr_t injectSharedLibrary_ret = (intptr_t)findRet(injectSharedLibrary_end) - (intptr_t)injectSharedLibrary;

    // back up whatever data used to be at the address we want to modify.
    char* backup = malloc(injectSharedLibrary_size * sizeof(char));
@@ -245,9 +257,8 @@
    memset(newcode, 0, injectSharedLibrary_size * sizeof(char));

    // copy the code of injectSharedLibrary() to a buffer.
-   memcpy(newcode, injectSharedLibrary, injectSharedLibrary_size - 1);
+   memcpy(newcode, safeInjectSharedLibrary, injectSharedLibrary_size);
    // overwrite the RET instruction with an INT 3.
-   newcode[injectSharedLibrary_ret] = INTEL_INT3_INSTRUCTION;

    // copy injectSharedLibrary()'s code to the target address inside the
    // target process' address space.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions