void free_code(struct jit* jit, lua_State* L, cfunction func) { size_t i; struct jit_head* h = ((struct jit_head*) func) - 1; for (i = 0; i < jit->pagenum; i++) { struct page* p = jit->pages[i]; if ((uint8_t*) h < (uint8_t*) p || (uint8_t*) p + p->size <= (uint8_t*) h) { continue; } luaL_unref(L, LUA_REGISTRYINDEX, h->ref); EnableWrite(p, p->size); p->freed += h->size; shred(h, 0, h->size); if (p->freed < p->off) { EnableExecute(p, p->size); return; } FreePage(p, p->size); memmove(&jit->pages[i], &jit->pages[i+1], (jit->pagenum - (i+1)) * sizeof(jit->pages[0])); jit->pagenum--; return; } assert(!"couldn't find func in the jit pages"); }
void PatchImage() { char *pPatch = (char *) 0x004D4AF7; EnableWrite((DWORD) pPatch); fprintf(logFile, "Patching: was %x\n", *(unsigned int *)pPatch); pPatch[0] = 0x84; pPatch[1] = 0xF2; pPatch[2] = 0x06; fprintf(logFile, "Patching: now %x\n", *(unsigned int *)pPatch); fflush(logFile); }
bool HttpRequest::OnPrePerform(CURL* curl) { // if (m_upload) // curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); if (m_method == MethodPOST) { if (m_postargs != 0) curl_easy_setopt(curl, CURLOPT_HTTPPOST, m_postargs); } if (m_headers != 0) curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_headers); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); EnableWrite(curl); return true; }
static void* reserve_code(struct jit* jit, lua_State* L, size_t sz) { struct page* page; size_t off = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->off : 0; size_t size = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->size : 0; if (off + sz >= size) { int i; uint8_t* pdata; cfunction func; /* need to create a new page */ jit->pages = (struct page**) realloc(jit->pages, (++jit->pagenum) * sizeof(jit->pages[0])); size = ALIGN_UP(sz + LINKTABLE_MAX_SIZE + sizeof(struct page), jit->align_page_size); page = (struct page*) AllocPage(size); jit->pages[jit->pagenum-1] = page; pdata = (uint8_t*) page; page->size = size; page->off = sizeof(struct page); lua_newtable(L); #define ADDFUNC(DLL, NAME) \ lua_pushliteral(L, #NAME); \ func = DLL ? (cfunction) GetProcAddressA(DLL, #NAME) : NULL; \ func = func ? func : (cfunction) &NAME; \ lua_pushcfunction(L, (lua_CFunction) func); \ lua_rawset(L, -3) ADDFUNC(NULL, check_double); ADDFUNC(NULL, check_float); ADDFUNC(NULL, check_uint64); ADDFUNC(NULL, check_int64); ADDFUNC(NULL, check_int32); ADDFUNC(NULL, check_uint32); ADDFUNC(NULL, check_uintptr); ADDFUNC(NULL, check_enum); ADDFUNC(NULL, check_typed_pointer); ADDFUNC(NULL, check_typed_cfunction); ADDFUNC(NULL, check_complex_double); ADDFUNC(NULL, check_complex_float); ADDFUNC(NULL, unpack_varargs_stack); ADDFUNC(NULL, unpack_varargs_stack_skip); ADDFUNC(NULL, unpack_varargs_reg); ADDFUNC(NULL, unpack_varargs_float); ADDFUNC(NULL, unpack_varargs_int); ADDFUNC(NULL, push_cdata); ADDFUNC(NULL, push_int); ADDFUNC(NULL, push_uint); ADDFUNC(NULL, lua_pushinteger); ADDFUNC(NULL, push_float); ADDFUNC(jit->kernel32_dll, SetLastError); ADDFUNC(jit->kernel32_dll, GetLastError); ADDFUNC(jit->lua_dll, luaL_error); ADDFUNC(jit->lua_dll, lua_pushnumber); ADDFUNC(jit->lua_dll, lua_pushboolean); ADDFUNC(jit->lua_dll, lua_gettop); ADDFUNC(jit->lua_dll, lua_rawgeti); ADDFUNC(jit->lua_dll, lua_pushnil); ADDFUNC(jit->lua_dll, lua_callk); ADDFUNC(jit->lua_dll, lua_settop); ADDFUNC(jit->lua_dll, lua_remove); //CHANGES: BEGIN ADDFUNC(jit->lua_dll, lua_pushlightuserdata); //CHANGES: END #undef ADDFUNC for (i = 0; extnames[i] != NULL; i++) { if (strcmp(extnames[i], "FUNCTION") == 0) { shred(pdata + page->off, 0, JUMP_SIZE); jit->function_extern = i; } else { lua_getfield(L, -1, extnames[i]); func = (cfunction) lua_tocfunction(L, -1); if (func == NULL) { luaL_error(L, "internal error: missing link for %s", extnames[i]); } compile_extern_jump(jit, L, func, pdata + page->off); lua_pop(L, 1); } page->off += JUMP_SIZE; } page->freed = page->off; lua_pop(L, 1); } else { page = jit->pages[jit->pagenum-1]; EnableWrite(page, page->size); } return (uint8_t*) page + page->off; }
int _InstallHook(char* real, char* hook, char* thunk){ t_disasm disasm; t_asmmodel am; char myAsm[TEXTLEN] , errtext[TEXTLEN]; char *pointer = real; int length=0, l=0, asmLen=0, wasJMP=0, oldPerm = 0;; if(!EnableWrite(thunk,20)){ sprintf(lastError,"Could not set writable memory perm on thunk?"); return 0; } while(length<5){ //copy min space of first instructions of real fx to our thunk l = Disasm(pointer,10, (unsigned long)pointer, &disasm, DISASM_CODE); if(l<1){ sprintf(lastError,"Disasm Error?"); return 0; } switch(disasm.cmdtype){ case C_JMP: case C_JMC: case C_CAL: if(length==0){ //first instruction only //printf("Your target fx address first inst is a jmp or call %s\n", disasm.result ); if(l<5){ sprintf(lastError,"Not enough space to embed our patch?"); return 0; } //printf("Ok Trying to reasm for new thunk address...\n"); l = Assemble(disasm.result,((unsigned long)thunk+length),&am,0,0,errtext); if(l<1){ sprintf(lastError,"Asm Length failed? %d %s %s", asmLen, &disasm.result ,errtext); return 0; } wasJMP=1; memcpy( (void*)&thunk[length],am.code ,l); break; } default: memcpy( (void*)&thunk[length], pointer ,l); break; } length+=l; pointer+=l; } if(!wasJMP){ sprintf(myAsm,"jmp 0%X", pointer); //where we will hop back into real api + x asmLen = Assemble(myAsm,((unsigned long)thunk+length),&am,0,0,errtext); if(asmLen<1){ sprintf(lastError,"Asm Length failed? %d %s", asmLen,errtext); return 0; } memcpy( (void*)&thunk[length], am.code, asmLen); } //printf("Ok i think the thunk is built! final size: %d\n", (length+asmLen) ); //now we replace the first bytes of the real function with a //rdirection to our hook replacement sprintf(myAsm,"jmp 0%X", (int)hook); //jmp hook asmLen = Assemble(myAsm,(int)real,&am,0,0,errtext); //asm to embed at real fx start if(asmLen<1){ sprintf(lastError,"Asm Length failed? %d %s", asmLen,errtext); return 0; } oldPerm = EnableWrite(real,asmLen); if(!oldPerm){ sprintf(lastError,"Could not enable write on real function address? %x", real); return 0 ; } while(length--) real[length] = 0xCC; //be tidy for debugging sake memcpy(real, am.code, asmLen); //embed our patch at beginning of real function RestorePerm(real,asmLen,oldPerm); return 1; }