1

Whenever I try to emulate my obfuscated driver it fails at uc_emu_start with UC_ERR_WRITE_UNMAPPED. I get all success return codes on: uc_mem_map and uc_mem_write but when I call uc_emu_start ; I get the UC_ERR_WRITE_UNMAPPED error. So, I added a hook on the error code to see what address it was writing to and I found that it was: 0xfffffffffffffff8. I don't understand why it is writing to this address because I put 0x1000 as my base address (std::uint64_t BASE_ADDRESS = 0x1000;) which is then used at uc_emu_start. Any help would be appreciated. enter image description here

// EMU.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <unicorn.h>
#include "capstone/capstone.h"
#include <iostream>
#include <list>
#include <queue>
#include <iomanip>
#include "PE.h"
#include "BasicBlock.h"
#include "Optimizations.h"
#include "CCapstoneHelper.h"
static bool hook_mem_invalid(uc_engine* uc, uc_mem_type type, uint64_t address,
    int size, int64_t value, void* user_data)
{
    switch (type) {
    default:
        // return false to indicate we want to stop emulation
        return false;
    case UC_MEM_WRITE_UNMAPPED:
        printf(">>> Missing memory is being WRITE at 0x%" PRIx64
            ", data size = %u, data value = 0x%" PRIx64 "\n",
            address, size, value);
        // map this memory in with 2MB in size
        uc_mem_map(uc, 0xaaaa0000, 2 * 1024 * 1024, UC_PROT_ALL);
        // return true to indicate we want to continue
        return true;
    }
}
int main()
{
    try {
        // UNICORN
        uc_engine* uc;
       uc_err err;

        // CAPSTONE
        csh handle{};
        cs_insn* insn;
        //size_t count; 
        std::queue<uint64_t> Q;
        std::map<uint64_t, bool> seen;
        std::uint64_t BASE_ADDRESS = 0x1000;

        
#define MEGABYTES_TO_MAP 15
        
        std::cout << "[+] Starting emulation..." << std::endl;
        if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) {
            throw std::runtime_error("cs_open failed");
        }

        if (uc_open(UC_ARCH_X86, UC_MODE_64, &uc) != UC_ERR_OK) {
            throw std::runtime_error("uc_open failed");
        }
       
        if (uc_mem_map(uc, BASE_ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL) != UC_ERR_OK) {
            throw std::runtime_error("uc_mem_map failed");
        }




        cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);

       
        // get pointer to file from Init()
        insn = cs_malloc(handle);
        std::cout << "[+] Finding driver entry point..." << std::endl;
       PE::CPe pe = PE::CPe::CPe("C:\\Program Files (x86)\\Driver\\Driver.sys");

   
       std::cout << "[+] Found: " << std::hex << pe.get_entry_point_address_relative_to_mapped_file() << std::endl;

       std::cout << "[+] Starting emulation..." << std::endl;
       BasicBlock::CBasicBlock block_buffer{};
       BasicBlock::_basic_block basic_block{};
       basic_block.start_address = pe.get_entry_point_address_relative_to_mapped_file();
    //   BASE_ADDRESS += pe.get_entry_point_file_offset();
        const std::uint8_t* addr = (std::uint8_t*) basic_block.start_address;
      
       // we are at entry point. Start emulation until we reach end of basic block?
       // At entrypoint, set start of basic block to entry point address.
       // Emulate until we reach a JUMP instruction
        std::cout << "[+] Removing anti-disassembly..." << std::endl;
        Optimizations::COptimizations optimizations;
        std::uint8_t anti_d_pattern[] = {0xEB, 0xFF, 0x64, 0x24, 0x08};
        std::uint64_t num_of_bytes_fixed = optimizations.remove_antidisassembly(anti_d_pattern, sizeof(anti_d_pattern), pe);
       
        uint64_t target = 0;
       size_t code_size = 0x1000;
       
       CapstoneHelper::CCapstoneHelper capstone_helper_obj;


       uc_hook hook;
       err = uc_hook_add(uc, &hook, UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_invalid, NULL, 1, 0);
      
       while (true) {
 
           std::uint64_t prev_base_address = BASE_ADDRESS;
          while (cs_disasm_iter(handle, &addr, &code_size, &BASE_ADDRESS, insn)) {
               if (capstone_helper_obj.is_cs_cflow_ins(insn)) {
                   basic_block.end_address = (std::uint64_t)addr;
                   break;
               }
               

           }

           
           std::uint32_t error;
           // write code and then some into memory
           //uc_mem_map(uc, prev_base_address, MEGABYTES_TO_MAP * 1024 * 1024, UC_PROT_ALL);
          // if (uc_mem_map(uc, BASE_ADDRESS, MEGABYTES_TO_MAP * 1024 * 1024, UC_PROT_ALL) != UC_ERR_OK) {
          
               err = uc_mem_write(uc, prev_base_address, reinterpret_cast<void*>(basic_block.start_address), (basic_block.end_address - basic_block.start_address));
               if (err != UC_ERR_OK) {
                  throw std::runtime_error("uc_mem_write failed");
              }
            
              
            // resolve file offset from base_address;
              

               err = uc_emu_start(uc, prev_base_address, prev_base_address + (basic_block.end_address - basic_block.start_address) , 0, 0);
               if (err != UC_ERR_OK) {
                   throw std::runtime_error("uc_emu_start failed");
               }



               /* TODO:
               1. Write anti-disassembly remover because capstone won't properly disassemble.
               Anti disassembly byte string: EB FF 64 24 08 (Removing EB byte results in " jmp    QWORD PTR [rsp+0x8]"
               Use file pointer to do operations before we disassemble with capstone.
               2. Add check for control flow instructions (look at PBA)
               */

          
       }

        
       










        
        uc_close(uc);
        cs_close(&handle);
        
    }
    catch (std::exception& e) {
        std::cout << "Error: " << e.what();
        getchar();
        std::abort();
    }
    
        return 0;
}
1
  • Deleted my answer, too early in the morning and I confused hex and binary Jul 15, 2022 at 2:26

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.