Пример #1
0
inline void drawEdgeAlignTextY(CSkPainter *p, int px, int py, const QString &text)
{
  double offset = 4;
  int w, h;

  trfGetScreenSize(w, h);
  setSetFontColor(FONT_GRID, p);

  if (IS_NEAR(py, 0, 2))
  {
    p->renderText(px, 0, offset, text, RT_BOTTOM);
  }
  else
  if (IS_NEAR(py, h, 2))
  {
    p->renderText(px, h, offset, text, RT_TOP);
  }
}
Пример #2
0
inline void drawEdgeAlignTextX(CSkPainter *p, int px, int py, const QString &text)
{
  double offset = 4;
  int w, h;

  trfGetScreenSize(w, h);
  setSetFontColor(FONT_GRID, p);

  if (IS_NEAR(px, 0, 2))
  {
    p->renderText(0, py, offset, text, RT_RIGHT);
  }
  else
  if (IS_NEAR(px, w, 2))
  {
    p->renderText(w, py, offset, text, RT_LEFT);
  }
}
Пример #3
0
void throw_hook(void *orig, void *repl, void **orig_ptr)
{
  //__DBG("throw_hook: (%p)\n", orig);
    opst x;
#ifdef __x86_64__
    x.a = 0xb848; // mov rax, target
    x.c = 0xc350; // pop rax; ret
#elif __i386__
    x.a = 0xE9;   // abs jump
#endif
    
    pthread_mutex_lock(&hook_lck);

    void *tramp = zalloc(&zone_free_list);

    int hook_size = sizeof(opst);
    
#ifdef __x86_64__
#ifdef __x86_64__COMPACT_HOOK
    opst_compact xc;
    vm_address_t nalloc=0;
    xc.a = 0xE9;
    if (IS_NEAR(orig,repl)) {
        printf("no trampoline needed for short jump to %p from %p\n", repl, orig);
        hook_size = sizeof(opst_compact);
    } else
    if (( nalloc = find_near((vm_address_t)orig)) != 0) {
        printf("allocated trampoline at %p\n", nalloc);
        hook_size = sizeof(opst_compact);
        x.b = (native_word_t) repl - ABSJUMP_SUB(orig);
        memcpy((void*)nalloc, &x, sizeof(x));
        repl = (void*) nalloc;
        assert(IS_NEAR(orig,repl));
    }
#endif
#endif
    
    // orig_ptr
    size_t eaten = eat_instructions(orig, hook_size);
    if (!eaten) {
        printf("throw_hook: eaten = 0, couldn't analyse function to hook\n");
        goto out;
    }
    
    x.b = (native_word_t) repl - ABSJUMP_SUB(orig);

    vm_protect(mach_task_self_, (vm_address_t)orig, PAGE_SIZE, 0, VM_PROT_ALL);
    vm_protect(mach_task_self_, (vm_address_t)orig+sizeof(opst), PAGE_SIZE, 0, VM_PROT_ALL);
    
#ifdef __x86_64__
#ifdef __x86_64__COMPACT_HOOK
    if ( hook_size == sizeof(opst_compact) ) {
        xc.b =  (uint32_t) (repl - ABSJUMP_SUB_COMPACT(orig));
        memcpy(tramp, orig, eaten);
        memset(orig, 0x90, eaten);
        memcpy(orig, &xc, sizeof(opst_compact));
    } else
#endif
#endif
    {
        memcpy(tramp, orig, eaten);
        memset(orig, 0x90, eaten);
        memcpy(orig, &x, sizeof(opst));
    }
    x.b = (native_word_t) (orig + eaten) - ABSJUMP_SUB(tramp+eaten);
    
    memcpy(tramp+eaten, &x, sizeof(opst));
    
    vm_protect(mach_task_self_, (vm_address_t)orig, PAGE_SIZE, 0, VM_PROT_READ|VM_PROT_EXECUTE);
    vm_protect(mach_task_self_, (vm_address_t)orig+sizeof(opst), PAGE_SIZE, 0, VM_PROT_READ|VM_PROT_EXECUTE);

    if (orig_ptr) {
        *orig_ptr = tramp;
    }
out:
    pthread_mutex_unlock(&hook_lck);
}
Пример #4
0
vm_address_t find_near(vm_address_t addr) {
    struct current_zone* cur = &zbg;
    struct current_zone* prev = NULL;
    while (cur) {
        if (cur->zone_free_list && IS_NEAR(addr,cur->zone_free_list)) {
            vm_address_t rtn = (vm_address_t)zalloc(&cur->zone_free_list);
            if (prev && !cur->zone_free_list) {
                prev->list_next = cur->list_next;
                free(cur);
            }
            printf("got NEAR tramp\n");

            return rtn;
        }
        prev = cur;
        cur = cur->list_next;
    }
    cur = &zbg;
    printf("allocating new near zone\n");
    kern_return_t kr      = KERN_SUCCESS;
    vm_size_t     size    = 0;
    vm_size_t     old_size    = 0;
    vm_address_t     old_address    = 0;
    vm_address_t     address    = addr - ((1ULL << 31ULL) - 1ULL);
    
    while (1) {
        mach_msg_type_number_t count;
        struct vm_region_submap_info_64 info;
        uint32_t nesting_depth;
        
        count = VM_REGION_SUBMAP_INFO_COUNT_64;
        kr = vm_region_recurse_64(mach_task_self_, &address, &size, &nesting_depth,
                                  (vm_region_info_64_t)&info, &count);
        if (kr == KERN_INVALID_ADDRESS) {
            break;
        } else if (kr) {
            mach_error("vm_region:", kr);
            break; /* last region done */
        }
        
        if (info.is_submap) {
            nesting_depth++;
        } else {
           // printf("near_region[%p]: %p -> %p (%lx bytes)\n", addr, (void*)address, (void*)(address+size), size);
            if (old_address && old_address + old_size < address) {
                //printf("GOT SPACE_region[%p]: %p -> %p (%lx bytes)\n", addr, (void*)address, (void*)(address+size), size);
                if ((IS_NEAR(addr, old_address+old_size))) {
                    if (ZONE_SIZE % 2 || ZONE_SIZE < sizeof(native_word_t)) {
                        //puts("zalloc error: zone size must be a multiple of 2 and bigger than sizeof(native_word_t)");
                        exit(-1);
                    }
                    
                    native_word_t* szfl = (native_word_t*)old_address + old_size;
                    
                    vm_allocate(mach_task_self_, (vm_address_t*)&szfl, PAGE_SIZE, 0);
                    if (!szfl) {
                        if (kr == KERN_INVALID_ADDRESS) {
                            return 0;
                        }
                        continue;
                    }
                    vm_protect(mach_task_self_, (vm_address_t)szfl, PAGE_SIZE, 0, VM_PROT_ALL);
                    if (cur->zone_free_list) {
                        while (cur->list_next) {
                            cur = cur->list_next;
                            if (!cur->zone_free_list) {
                                break;
                            }
                        }
                        if (cur->zone_free_list) {
                            cur->list_next = malloc(sizeof(struct current_zone));
                            cur->list_next->zone_free_list = 0;
                            cur->list_next->list_next = 0;
                            cur = cur->list_next;
                            assert(cur->zone_free_list == 0);
                        }
                    }
                    for (int i = 0; i < (PAGE_SIZE/ZONE_SIZE); i++) {
                        zfree((void*)((native_word_t)&szfl[i*(ZONE_SIZE/sizeof(native_word_t))]), &cur->zone_free_list);
                    }
                    return (vm_address_t)zalloc(&cur->zone_free_list);
                }
            }
            
            old_address = address;
            old_size = size;
            address += size;
        }
    }
    return 0;
}