/** HookEngine_Memset memset without calling memset */ __forceinline void HookEngine_Memset(LPVOID dst, BYTE set, SIZE_T length) { if (dst && length) { __stosb((unsigned char*)dst, set, length); } }
void *memset (void *dest, int value, size_t bytes) { // Rep stosb is faster than a byte loop, but still quite slow // for large operations. However, it is a good choice here because // this function is intended for use by the compiler only. For // large fill operations, call LibAmdMemFill. __stosb (dest, value, bytes); return dest; }
//------------------------------------------------------------------------- static void EnumerateThreads(void) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (hSnapshot != INVALID_HANDLE_VALUE) { THREADENTRY32 te; __stosb((PBYTE)&te, 0, sizeof(THREADENTRY32)); te.dwSize = sizeof(THREADENTRY32); if (Thread32First(hSnapshot, &te)) { do { if (te.th32OwnerProcessID == GetCurrentProcessId() && te.th32ThreadID != GetCurrentThreadId()) { if (g_threads.items == NULL) { g_threads.capacity = MH_INITIAL_THREAD_CAPACITY; g_threads.items = (LPDWORD)HeapAlloc(g_hHeap, 0, g_threads.capacity * sizeof(DWORD)); if (g_threads.items == NULL) break; } else if (g_threads.size >= g_threads.capacity) { LPDWORD p; g_threads.capacity *= 2; p = (LPDWORD)HeapReAlloc( g_hHeap, 0, g_threads.items, g_threads.capacity * sizeof(DWORD)); if (p != NULL) g_threads.items = p; else break; } g_threads.items[g_threads.size++] = te.th32ThreadID; } } while (Thread32Next(hSnapshot, &te)); } } CloseHandle(hSnapshot); }
unsigned int hde32_disasm(const void *code, hde32s *hs) { uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0; // Avoid using memset to reduce the footprint. __stosb((LPBYTE)hs, 0, sizeof(hde32s)); for (x = 16; x; x--) switch (c = *p++) { case 0xf3: hs->p_rep = c; pref |= PRE_F3; break; case 0xf2: hs->p_rep = c; pref |= PRE_F2; break; case 0xf0: hs->p_lock = c; pref |= PRE_LOCK; break; case 0x26: case 0x2e: case 0x36: case 0x3e: case 0x64: case 0x65: hs->p_seg = c; pref |= PRE_SEG; break; case 0x66: hs->p_66 = c; pref |= PRE_66; break; case 0x67: hs->p_67 = c; pref |= PRE_67; break; default: goto pref_done; } pref_done: hs->flags = (uint32_t)pref << 23; if (!pref) pref |= PRE_NONE; if ((hs->opcode = c) == 0x0f) { hs->opcode2 = c = *p++; ht += DELTA_OPCODES; } else if (c >= 0xa0 && c <= 0xa3) { if (pref & PRE_67) pref |= PRE_66; else pref &= ~PRE_66; } opcode = c; cflags = ht[ht[opcode / 4] + (opcode % 4)]; if (cflags == C_ERROR) { hs->flags |= F_ERROR | F_ERROR_OPCODE; cflags = 0; if ((opcode & -3) == 0x24) cflags++; } x = 0; if (cflags & C_GROUP) { uint16_t t; t = *(uint16_t *)(ht + (cflags & 0x7f)); cflags = (uint8_t)t; x = (uint8_t)(t >> 8); }
extern "C" void * __cdecl memset(void *ptr, int value, size_t num) { __stosb(static_cast<unsigned char*>(ptr), static_cast<unsigned char>(value), num); return ptr; }
//------------------------------------------------------------------------- static void ProcessThreadIPs(HANDLE hThread, int pos, int action) { // If the thread suspended in the overwritten area, // move IP to the proper address. CONTEXT c; #if defined _M_X64 DWORD_PTR *pIP = &c.Rip; #elif defined _M_IX86 DWORD_PTR *pIP = &c.Eip; #endif int count; __stosb((PBYTE)&c, 0, sizeof(CONTEXT)); c.ContextFlags = CONTEXT_CONTROL; if (!GetThreadContext(hThread, &c)) return; if (pos < 0) { pos = 0; count = g_hooks.size; } else { count = pos + 1; } for (; pos < count; ++pos) { PHOOK_ENTRY pHook = &g_hooks.items[pos]; BOOL enable; DWORD_PTR ip; switch (action) { case 0: enable = FALSE; break; case 1: enable = TRUE; break; default: enable = pHook->queueEnable; break; } if (pHook->isEnabled == enable) continue; if (enable) ip = FindNewIP(pHook, *pIP); else ip = FindOldIP(pHook, *pIP); if (ip != 0) { *pIP = ip; SetThreadContext(hThread, &c); } } }