////////////////////////////////////////////////// // RedoBlHooks Version 3.0 // Includes #include #include //#include #include "BlHooks.hpp" // Scanned structures BlFunctionDefIntern(tsh_BlPrintf); // Sig Scanning ADDR ImageBase; ADDR ImageSize; void tsh_i_InitScanner(){ HMODULE module = GetModuleHandle(NULL); if(module) { MODULEINFO info; GetModuleInformation(GetCurrentProcess(), module, &info, sizeof(MODULEINFO)); ImageBase = (ADDR)info.lpBaseOfDll; ImageSize = info.SizeOfImage; } } bool tsh_i_CompareData(BYTE *data, BYTE *pattern, char* mask){ for (; *mask; ++data, ++pattern, ++mask){ if (*mask=='x' && *data!=*pattern) return false; } return (*mask)==0; } ADDR tsh_i_FindPattern(ADDR imageBase, ADDR imageSize, BYTE *pattern, char *mask){ for (ADDR i=imageBase; i < imageBase+imageSize; i++){ if(tsh_i_CompareData((PBYTE)i, pattern, mask)){ return i; } } return 0; } // Convert a text-style pattern into code-style void tsh_i_PatternTextToCode(char* text, char** opatt, char** omask) { unsigned int len = strlen(text); char* patt = (char*)malloc(len); char* mask = (char*)malloc(len); int outidx = 0; int val = 0; bool uk = false; for(unsigned int i=0; i='0' && c<='9'){ val = (val<<4) + (c-'0'); }else if(c>='A' && c<='F'){ val = (val<<4) + (c-'A'+10); }else if(c>='a' && c<='f'){ val = (val<<4) + (c-'a'+10); }else if(c==' '){ patt[outidx] = uk ? 0 : val; mask[outidx] = uk ? '?' : 'x'; val = 0; uk = false; outidx++; } } patt[outidx] = uk ? 0 : val; mask[outidx] = uk ? '?' : 'x'; outidx++; patt[outidx] = 0; mask[outidx] = 0; *opatt = patt; *omask = mask; } // Public functions for sig scanning // Scan using code-style pattern ADDR tsh_ScanCode(char* pattern, char* mask) { return tsh_i_FindPattern(ImageBase, ImageSize-strlen(mask), (BYTE*)pattern, mask); } // Scan using a text-style pattern ADDR tsh_ScanText(char* text) { char* patt; char* mask; tsh_i_PatternTextToCode(text, &patt, &mask); ADDR res = tsh_ScanCode(patt, mask); free(patt); free(mask); return res; } // Call Patching and Hooking // Remove protection from address //std::map> tsh_DeprotectedAddresses; void tsh_DeprotectAddress(ADDR length, ADDR location) { DWORD oldProtection; VirtualProtect((void*)location, length, PAGE_EXECUTE_READWRITE, &oldProtection); //tsh_DeprotectedAddresses[location] = {length, oldProtection}; } // Patch a string of bytes by deprotecting and then overwriting void tsh_PatchBytes(ADDR length, ADDR location, BYTE* repl) { tsh_DeprotectAddress(length, location); memcpy((void*)location, (void*)repl, (size_t)length); } void tsh_PatchByte(ADDR location, BYTE value) { tsh_PatchBytes(location, 1, &value); } void tsh_ReplaceInt(ADDR addr, int rval) { tsh_PatchBytes(4, addr, (BYTE*)(&rval)); } int tsh_i_CallOffset(ADDR instr, ADDR func) { return func - (instr+4); } void tsh_i_ReplaceCall(ADDR instr, ADDR target) { tsh_ReplaceInt(instr, tsh_i_CallOffset(instr, target)); } void tsh_i_PatchCopy(ADDR dest, ADDR src, unsigned int len) { for(unsigned int i=0; i