Visual C++ appends 0xCC (int3) bytes at the end of functions

前端 未结 3 1305
小蘑菇
小蘑菇 2021-01-25 11:05

This is my first time around, and I really hope you guys can help me, as I have ran out of ideas by now.

I have searched for an answer for a couple of hours now, and cou

相关标签:
3条回答
  • 2021-01-25 11:08

    As Devolus points out, the compiler is inserting these extra bytes after your code in order to align the next function on a reasonable (usually divisible by 16) starting address.

    The compiler is actually trying to help you since 0xCC is the breakpoint instruction, the code will break into the debugger (if attached) should the instruction pointer accidentally point outside a function at any point during execution.

    None of this should worry you for your purposes. You can consider the 0xCC padding as part of the function.

    0 讨论(0)
  • 2021-01-25 11:23

    You don't need the extra padding when you're injecting the code, so it's fine to discard them. It should also be fine to copy them over, it will just result in a few extra bytes of copying. Chances are the memory you're injecting to will by a page-aligned block anyway, so you're not really gaining anything by stripping it out.

    But if you really want to strip it out, a simple solution to your problem would be to just iterate backwards from the last byte before the next function, until there are no more 0xcc bytes.

    i.e.:

    __declspec(naked) void Foo()
    {
       __asm
       {
          _emit 0x4A
          _emit 0x4B
       }
    }
    __declspec(naked) void FooEnd() {}
    
    
    int main(int argc, char** argv)
    {
       //start at the last byte of the memory-aligned code instead of the first byte of FooEnd
       unsigned char* fooLast = (unsigned char*)FooEnd-1;
    
       //keep going backwards until we don't have a 0xcc
       while(*fooLast == 0xCC)
          fooLast--;
    
       //fooLast will now point at the last byte of your function, so you need to add 1
       int length = ((int)fooLast - (int)Foo) + 1;
    
       //should output 2 for the length of Foo
       std::cout << length;
    }
    
    0 讨论(0)
  • 2021-01-25 11:30

    The extra bytes are inserted by the compiler to create a memory alignment, so you can't discard it, since you are using the next function as a marker.

    On the other hand, since you are writing the injected code in assembly anyway, you can just as well write the code, compile it, and then put the binary form in a byte array. That's how I would do this, because then you have the exact length.

    0 讨论(0)
提交回复
热议问题