Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

patch multiple UC_HOOK_MEM callbacks for unaligned access #2063

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from

Conversation

Michael-c0de
Copy link

The issue #1041 has not been fully resolved,fixed this bug to prevent unaligned accesses from triggering extra callbacks.

@wtdcode
Copy link
Member

wtdcode commented Dec 7, 2024

Do you have a test case for this?

@Michael-c0de
Copy link
Author

Do you have a test case for this?

#include <unicorn/unicorn.h>

void hook_mem(uc_engine *uc, uc_mem_type type,
    uint64_t address, int size, int64_t value, void *user_data)
{
    printf("%s %p %d\n", (type == UC_MEM_WRITE) ? "write" : "read ", address, size);
}

int main(int argc, char **argv)
{
    const uint8_t code[] = {
        "\x48\x8b\x00"  //  mov         rax,qword ptr [rax]  
        "\x48\x89\x01"  //   mov         qword ptr [rcx],rax  
        "\xcc"
    };

    uc_engine *uc;
    uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
    uc_mem_map(uc, 0, 0x10000, UC_PROT_ALL);
    uc_mem_write(uc, 0, code, sizeof(code) - 1);

    uc_hook hh;
    uc_hook_add(uc, &hh, UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, hook_mem, NULL, 1, 0);

    const uint64_t addr = 0x1fff;
    uc_reg_write(uc, UC_X86_REG_RAX, &addr);
    uc_reg_write(uc, UC_X86_REG_RCX, &addr);
    uc_emu_start(uc, 0, sizeof(code) - 1, 0, 2);

    return 0;
}

before patch

read  0x1fff 8
read  0x1ff8 8
read  0x2000 8
write 0x1fff 8

after patch

read  0x1fff 8
write 0x1fff 8

@wtdcode
Copy link
Member

wtdcode commented Dec 7, 2024

Do you have a test case for this?

#include <unicorn/unicorn.h>

void hook_mem(uc_engine *uc, uc_mem_type type,
    uint64_t address, int size, int64_t value, void *user_data)
{
    printf("%s %p %d\n", (type == UC_MEM_WRITE) ? "write" : "read ", address, size);
}

int main(int argc, char **argv)
{
    const uint8_t code[] = {
        "\x48\x8b\x00"  //  mov         rax,qword ptr [rax]  
        "\x48\x89\x01"  //   mov         qword ptr [rcx],rax  
        "\xcc"
    };

    uc_engine *uc;
    uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
    uc_mem_map(uc, 0, 0x10000, UC_PROT_ALL);
    uc_mem_write(uc, 0, code, sizeof(code) - 1);

    uc_hook hh;
    uc_hook_add(uc, &hh, UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, hook_mem, NULL, 1, 0);

    const uint64_t addr = 0x1fff;
    uc_reg_write(uc, UC_X86_REG_RAX, &addr);
    uc_reg_write(uc, UC_X86_REG_RCX, &addr);
    uc_emu_start(uc, 0, sizeof(code) - 1, 0, 2);

    return 0;
}

before patch

read  0x1fff 8
read  0x1ff8 8
read  0x2000 8
write 0x1fff 8

after patch

read  0x1fff 8
write 0x1fff 8

Cool, could you add this to tests/unit/test_x86.c? This ensures that your use cases won't be broken in our futures releases.

@wtdcode
Copy link
Member

wtdcode commented Dec 7, 2024

No worry for CI. Github Action is buggy at this moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants