简体   繁体   中英

memcpy on __declspec naked returns unexpected bytes

I am trying to get the raw bytes of a __declspec(naked) function but memcpy is returning bytes that I am not expecting.

I have used a debugger to inspect the bytes/addresses. Everything looks fine but the result of memcpy produces different, seemingly unchanging bytes.

void __declspec(naked) widget_click_fix_asm()
{
    __asm {
        nop
        call patched_widget_handler
    }
}

void test_patch()
{
    char buf[7];

    ::memcpy(&buf, &widget_click_fix_asm, 7);
}

In the VS debugger, in the intermediate window I have executed:

&widget_click_fix_asm
0x778816f0

Navigating to that memory location shows the following bytes:

778816F0 90
778816F1 FF 15 38 91 88 77

I would expect buf to be a container of the following bytes:

[0x90, 0xFF, 0x15, 0x38, 0x91, 0x88, 0x77]

Instead buf contains the following constant bytes every time I test:

[0xE9, 0xD8, 0x05, 0x00, 0x00, 0xE9, 0x63]

Why aren't I getting the bytes I would expect?

What you are observing is due to incremental linking in MSVC's Debug Mode. The address of widget_click_fix_asm isn't actually the function itself, but the address of a JMP instruction in the JMP Thunk Table . This table is used to patch new versions of functions into an existing executable. This is done by writing the new function in a free area of the executable that has enough space and then updating the JMP thunk table with the new address. This facilitates the edit and continue debugging feature in Visual Studio.

In your example your call to memcpy ended up copying part of the JMP Thunk Table to buf rather than the function itself. You may wish to consider turning off the incremental linking feature to get the desired behaviour you are seeking.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM