Merge pull request #1920 from PhilippTakacs/fix_cow2

fix uc_mem write with cow when using upper half of the address
This commit is contained in:
lazymio 2024-01-16 20:29:02 +08:00 committed by GitHub
commit 97beeb6fa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 11 deletions

View File

@ -379,27 +379,29 @@ static void test_context_snapshot(void)
{
uc_engine *uc;
uc_context *ctx;
uint64_t baseaddr = 0xfffff1000;
uint64_t offset = 0x10;
uint64_t tmp = 1;
OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc));
OK(uc_ctl_context_mode(uc, UC_CTL_CONTEXT_MEMORY | UC_CTL_CONTEXT_CPU));
OK(uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL));
OK(uc_mem_map(uc, baseaddr, 0x1000, UC_PROT_ALL));
OK(uc_context_alloc(uc, &ctx));
OK(uc_context_save(uc, ctx));
OK(uc_mem_write(uc, 0x1000, &tmp, sizeof(tmp)));
OK(uc_mem_read(uc, 0x1000, &tmp, sizeof(tmp)));
OK(uc_mem_write(uc, baseaddr + offset, &tmp, sizeof(tmp)));
OK(uc_mem_read(uc, baseaddr + offset, &tmp, sizeof(tmp)));
TEST_CHECK(tmp == 1);
OK(uc_context_restore(uc, ctx));
OK(uc_mem_read(uc, 0x1000, &tmp, sizeof(tmp)));
OK(uc_mem_read(uc, baseaddr + offset, &tmp, sizeof(tmp)));
TEST_CHECK(tmp == 0);
tmp = 2;
OK(uc_mem_write(uc, 0x1000, &tmp, sizeof(tmp)));
OK(uc_mem_read(uc, 0x1000, &tmp, sizeof(tmp)));
OK(uc_mem_write(uc, baseaddr + offset, &tmp, sizeof(tmp)));
OK(uc_mem_read(uc, baseaddr + offset, &tmp, sizeof(tmp)));
TEST_CHECK(tmp == 2);
OK(uc_context_restore(uc, ctx));
OK(uc_mem_read(uc, 0x1000, &tmp, sizeof(tmp)));
OK(uc_mem_read(uc, baseaddr + offset, &tmp, sizeof(tmp)));
TEST_CHECK(tmp == 0);
OK(uc_context_free(ctx));

7
uc.c
View File

@ -780,6 +780,7 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes,
MemoryRegion *mr = uc->memory_mapping(uc, address);
if (mr) {
uint32_t operms = mr->perms;
uint64_t align = uc->target_page_align;
if (!(operms & UC_PROT_WRITE)) { // write protected
// but this is not the program accessing memory, so temporarily
// mark writable
@ -788,10 +789,8 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes,
len = memory_region_len(uc, mr, address, size - count);
if (uc->snapshot_level && uc->snapshot_level > mr->priority) {
mr = uc->memory_cow(uc, mr, address & ~uc->target_page_align,
(len + (address & uc->target_page_align) +
uc->target_page_align) &
~uc->target_page_align);
mr = uc->memory_cow(uc, mr, address & ~align,
(len + (address & align) + align) & ~align);
if (!mr) {
return UC_ERR_NOMEM;
}