#include "stdafx.h" #include "definitions.h" #include "Global.Engine.h" #include "Global.Debugger.h" #include "Global.Mapping.h" #include "Global.Engine.Hash.h" #include "Global.Injector.h" // Global.Engine.Tracer.functions: static ULONG_PTR EngineGlobalTracerHandler1(HANDLE hProcess, ULONG_PTR AddressToTrace, bool HashInstructions, DWORD InputNumberOfInstructions) { SIZE_T memSize = 0; int NumberOfInstructions = 0; int LengthOfValidInstruction = 0; int CurrentNumberOfInstructions = 0; MEMORY_BASIC_INFORMATION MemInfo; DynBuf tracmem; LPVOID TraceMemory, cTraceMemory; ULONG_PTR ueNumberOfBytesRead = NULL; DWORD LastPushValue = NULL; ULONG_PTR TraceStartAddress; ULONG_PTR TraceTestAddress; ULONG_PTR TraceTestReadAddress; DWORD CurrentInstructionSize; PMEMORY_CMP_HANDLER CompareMemory; PMEMORY_COMPARE_HANDLER longCompareMemory; DWORD InstructionHash = NULL; bool FoundValidAPI = false; bool SkipThisInstruction = false; bool LoopCondition = true; bool SkipHashing = false; BYTE EmptyCall[5] = {0xE8, 0x00, 0x00, 0x00, 0x00}; if(VirtualQueryEx(hProcess, (LPVOID)AddressToTrace, &MemInfo, sizeof MEMORY_BASIC_INFORMATION) != NULL) { if(MemInfo.RegionSize > NULL) { memSize = MemInfo.RegionSize; if(memSize > 0x4000) { memSize = 0x4000; } TraceMemory = tracmem.Allocate(memSize); cTraceMemory = TraceMemory; if(ReadProcessMemory(hProcess, (LPVOID)MemInfo.BaseAddress, TraceMemory, memSize, &ueNumberOfBytesRead)) { TraceStartAddress = AddressToTrace - (ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)TraceMemory; if(HashInstructions && InputNumberOfInstructions > NULL) { LoopCondition = true; } else { LoopCondition = false; } while(LoopCondition) { SkipHashing = false; SkipThisInstruction = false; CompareMemory = (PMEMORY_CMP_HANDLER)TraceStartAddress; CurrentInstructionSize = StaticLengthDisassemble((LPVOID)TraceStartAddress); CurrentNumberOfInstructions++; /* Long JUMP (0xE9) */ if(HashInstructions == false && CompareMemory->DataByte[0] == 0xE9 && CurrentInstructionSize == 5) { TraceTestAddress = (ULONG_PTR)GetJumpDestination(NULL, TraceStartAddress) - (ULONG_PTR)TraceMemory + (ULONG_PTR)MemInfo.BaseAddress; if(TraceTestAddress <= (ULONG_PTR)MemInfo.BaseAddress || TraceTestAddress >= (ULONG_PTR)MemInfo.BaseAddress + MemInfo.RegionSize) { if(LengthOfValidInstruction == NULL) { if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL) { FoundValidAPI = true; break; } } if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL) { FoundValidAPI = true; break; } else { if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress - LengthOfValidInstruction) != NULL) { FoundValidAPI = true; TraceTestAddress = TraceTestAddress - LengthOfValidInstruction; break; } } } /* Near JUMP (0xFF25) */ } else if(HashInstructions == false && CompareMemory->DataByte[0] == 0xFF && CompareMemory->DataByte[1] == 0x25 && CurrentInstructionSize == 6) { TraceTestAddress = (ULONG_PTR)GetJumpDestination(NULL, TraceStartAddress); if(ReadProcessMemory(hProcess, (LPVOID)TraceTestAddress, &TraceTestAddress, 4, &ueNumberOfBytesRead)) { if(TraceTestAddress <= (ULONG_PTR)MemInfo.BaseAddress || TraceTestAddress >= (ULONG_PTR)MemInfo.BaseAddress + MemInfo.RegionSize) { if(LengthOfValidInstruction == NULL) { if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL) { FoundValidAPI = true; break; } } if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL) { FoundValidAPI = true; break; } else { if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress - LengthOfValidInstruction) != NULL) { FoundValidAPI = true; TraceTestAddress = TraceTestAddress - LengthOfValidInstruction; break; } } } } /* PUSH then RET (0x68 ???????? 0xC3) */ } else if(HashInstructions == false && CompareMemory->DataByte[0] == 0x68 && CompareMemory->DataByte[5] == 0xC3 && CurrentInstructionSize == 5) { longCompareMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)CompareMemory + 1); TraceTestAddress = (DWORD)(longCompareMemory->Array.dwArrayEntry[0]); if(ReadProcessMemory(hProcess, (LPVOID)TraceTestAddress, &TraceTestReadAddress, 4, &ueNumberOfBytesRead)) { if(TraceTestAddress <= (ULONG_PTR)MemInfo.BaseAddress || TraceTestAddress >= (ULONG_PTR)MemInfo.BaseAddress + MemInfo.RegionSize) { if(LengthOfValidInstruction == NULL) { if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL) { FoundValidAPI = true; break; } } if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL) { FoundValidAPI = true; break; } else { if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress - LengthOfValidInstruction) != NULL) { FoundValidAPI = true; TraceTestAddress = TraceTestAddress - LengthOfValidInstruction; break; } } } else { TraceStartAddress = TraceStartAddress - (ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)TraceMemory; } } /* CALL (0xE8) */ } else if(HashInstructions == true && CompareMemory->DataByte[0] == 0xE8 && CurrentInstructionSize == 5) { SkipHashing = true; InstructionHash = EngineHashMemory((char*)&EmptyCall, CurrentInstructionSize, InstructionHash); /* PUSH (0x68) */ } else if(CompareMemory->DataByte[0] == 0x68 && CurrentInstructionSize == 5) { LastPushValue = (DWORD)(CompareMemory->DataByte[1] + CompareMemory->DataByte[2] * 0x1000 + CompareMemory->DataByte[3] * 0x100000 + CompareMemory->DataByte[4] * 0x10000000); /* ADD BYTE PTR[AL],AL (0x00, 0x00) -> End of page! */ } else if(CompareMemory->DataByte[0] == 0x00 && CurrentInstructionSize == 2) { FoundValidAPI = false; break; /* RET (0xC3) */ } else if(CompareMemory->DataByte[0] == 0xC3 && CurrentInstructionSize == 1) { NumberOfInstructions++; break; /* RET (0xC2) */ } else if(CompareMemory->DataByte[0] == 0xC2 && CurrentInstructionSize == 3) { NumberOfInstructions++; break; /* Short JUMP (0xEB) */ } else if(CompareMemory->DataByte[0] == 0xEB && CurrentInstructionSize == 2) { TraceStartAddress = TraceStartAddress + CompareMemory->DataByte[1]; SkipThisInstruction = true; /* CLC (0xF8) */ } else if(CompareMemory->DataByte[0] == 0xF8 && CurrentInstructionSize == 1) { SkipThisInstruction = true; /* STC (0xF9) */ } else if(CompareMemory->DataByte[0] == 0xF9 && CurrentInstructionSize == 1) { SkipThisInstruction = true; /* NOP (0x90) */ } else if(CompareMemory->DataByte[0] == 0x90 && CurrentInstructionSize == 1) { SkipThisInstruction = true; /* FNOP (0xD9 0xD0) */ } else if(CompareMemory->DataByte[0] == 0xD9 && CompareMemory->DataByte[1] == 0xD0 && CurrentInstructionSize == 2) { SkipThisInstruction = true; /* Multiple MOV */ } else if(CompareMemory->DataByte[0] >= 0x8A && CompareMemory->DataByte[0] <= 0x8B) { /* MOV EAX,EAX (0x8B 0xC8) */ if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xC8 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV EBX,EBX (0x8B 0xC9) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xC9 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV ECX,ECX (0x8B 0xDB) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xDB && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8B 0xED) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xED && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8B 0xF6) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xF6 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8B 0xE4) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xE4 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV EDX,EDX (0x8B 0xD2) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xD2 && CurrentNumberOfInstructions != 1 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV EDI,EDI (0x8B 0xFF) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xFF && CurrentNumberOfInstructions != 1 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV AL,AL (0x8A 0xC0) */ else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xC0 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV BL,BL (0x8A 0xDB) */ else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xDB && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV CL,CL (0x8A 0xC9) */ else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xC9 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8A 0xD2) */ else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xD2 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8A 0xE4) */ else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xE4 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8A 0xED) */ else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xED && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8A 0xFF) */ else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xFF && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8A 0xF6) */ else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xF6 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV AX,AX (0x8B 0xC0) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xC0 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8B 0xDB) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xDB && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8B 0xC9) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xC9 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8B 0xF6) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xF6 && CurrentInstructionSize == 2) { SkipThisInstruction = true; } /* MOV (0x8B 0xED) */ else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xED && CurrentInstructionSize == 2) { SkipThisInstruction = true; } } /* RDTSC (0x0F 0x31) */ else if(CompareMemory->DataByte[0] == 0x0F && CompareMemory->DataByte[1] == 0x31 && CurrentInstructionSize == 2) { SkipThisInstruction = true; /* CPUID (0x0F 0xA2) */ } else if(CompareMemory->DataByte[0] == 0x0F && CompareMemory->DataByte[1] == 0xA2 && CurrentInstructionSize == 2) { SkipThisInstruction = true; /* XCHG EAX,EAX (0x87 0xC0) */ } else if(CompareMemory->DataByte[0] == 0x87 && CompareMemory->DataByte[1] == 0xC0 && CurrentInstructionSize == 2) { SkipThisInstruction = true; /* SHL EAX,0 - SHL EDI,0 && SHR EAX,0 - SHR EDI,0 */ } else if(CompareMemory->DataByte[0] == 0xC1 && CurrentInstructionSize == 3) { if(CompareMemory->DataByte[1] >= 0xE0 && CompareMemory->DataByte[1] <= 0xEF && CompareMemory->DataByte[2] == 0x00) { SkipThisInstruction = true; } /* ROR EAX,0 - ROR EDI,0 && ROL EAX,0 - ROL EDI,0 */ } else if(CompareMemory->DataByte[0] == 0xC1 && CurrentInstructionSize == 3) { if(CompareMemory->DataByte[1] >= 0xC0 && CompareMemory->DataByte[1] <= 0xCF && CompareMemory->DataByte[2] == 0x00) { SkipThisInstruction = true; } /* LEA EAX,DWORD PTR[EAX] -> LEA EDI,DWORD PTR[EDI] */ } else if(CompareMemory->DataByte[0] == 0x8D && CurrentInstructionSize == 2) { if(CompareMemory->DataByte[1] == 0x00 || CompareMemory->DataByte[1] == 0x09 || CompareMemory->DataByte[1] == 0x1B || CompareMemory->DataByte[1] == 0x12) { SkipThisInstruction = true; } if(CompareMemory->DataByte[1] == 0x36 || CompareMemory->DataByte[1] == 0x3F) { SkipThisInstruction = true; } if(CompareMemory->DataByte[1] == 0x6D && CompareMemory->DataByte[2] == 0x00) { SkipThisInstruction = true; } } if(!SkipThisInstruction) { if(HashInstructions == true && SkipHashing == false) { InstructionHash = EngineHashMemory((char*)TraceStartAddress, CurrentInstructionSize, InstructionHash); } LengthOfValidInstruction = LengthOfValidInstruction + CurrentInstructionSize; NumberOfInstructions++; } if(HashInstructions) { InputNumberOfInstructions--; if(InputNumberOfInstructions > NULL) { LoopCondition = true; } else { LoopCondition = false; } } else { if(CurrentNumberOfInstructions < 1000 && FoundValidAPI == false) { LoopCondition = true; } else { LoopCondition = false; } } TraceStartAddress = TraceStartAddress + CurrentInstructionSize; } if(!HashInstructions) { if(FoundValidAPI == true) { return((ULONG_PTR)TraceTestAddress); } else if(CurrentNumberOfInstructions < 1000) { if(ImporterGetAPINameFromDebugee(hProcess, LastPushValue) != NULL) { return((ULONG_PTR)LastPushValue); } else if(ImporterGetAPINameFromDebugee(hProcess, LastPushValue - LengthOfValidInstruction) != NULL) { return((ULONG_PTR)(LastPushValue - LengthOfValidInstruction)); } return((DWORD)NumberOfInstructions); } } else { return((DWORD)InstructionHash); } } else { } } } return(NULL); } // TitanEngine.Tracer.functions: __declspec(dllexport) void TITCALL TracerInit() { return; // UE 1.5 compatibility mode } __declspec(dllexport) ULONG_PTR TITCALL TracerLevel1(HANDLE hProcess, ULONG_PTR AddressToTrace) { return((ULONG_PTR)EngineGlobalTracerHandler1(hProcess, AddressToTrace, false, NULL)); } __declspec(dllexport) ULONG_PTR TITCALL HashTracerLevel1(HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD InputNumberOfInstructions) { unsigned int i = 0; unsigned int j = 0; DWORD Dummy = NULL; MODULEINFO RemoteModuleInfo; ULONG_PTR EnumeratedModules[0x2000] = {0}; ULONG_PTR LoadedModules[1000][4] = {0}; char RemoteDLLName[MAX_PATH]; HANDLE hLoadedModule = NULL; HANDLE ModuleHandle = NULL; PIMAGE_DOS_HEADER DOSHeader; PIMAGE_NT_HEADERS32 PEHeader32; PIMAGE_NT_HEADERS64 PEHeader64; PIMAGE_EXPORT_DIRECTORY PEExports; PEXPORTED_DATA ExportedFunctions; ULONG_PTR APIFoundAddress = NULL; bool ValidateHeader = false; bool FileIs64 = false; bool FoundAPI = false; DWORD CompareHash = NULL; DWORD TestHash = NULL; if(InputNumberOfInstructions > NULL) { CompareHash = (DWORD)EngineGlobalTracerHandler1(hProcess, AddressToTrace, true, InputNumberOfInstructions); } else { InputNumberOfInstructions = (DWORD)TracerLevel1(hProcess, AddressToTrace); if(InputNumberOfInstructions < 1000) { CompareHash = (DWORD)EngineGlobalTracerHandler1(hProcess, AddressToTrace, true, InputNumberOfInstructions); } else { return(NULL); } } if(hProcess == NULL) { if(dbgProcessInformation.hProcess == NULL) { hProcess = GetCurrentProcess(); } else { hProcess = dbgProcessInformation.hProcess; } } if(EnumProcessModules(hProcess, (HMODULE*)EnumeratedModules, sizeof(EnumeratedModules), &Dummy)) { i++; while(FoundAPI == false && EnumeratedModules[i] != NULL) { ValidateHeader = false; RtlZeroMemory(&RemoteDLLName, MAX_PATH); GetModuleFileNameExA(hProcess, (HMODULE)EnumeratedModules[i], (LPSTR)RemoteDLLName, MAX_PATH); if(GetModuleHandleA(RemoteDLLName) == NULL) { RtlZeroMemory(&RemoteDLLName, MAX_PATH); GetModuleBaseNameA(hProcess, (HMODULE)EnumeratedModules[i], (LPSTR)RemoteDLLName, MAX_PATH); if(GetModuleHandleA(RemoteDLLName) == NULL) { if(engineAlowModuleLoading) { hLoadedModule = LoadLibraryA(RemoteDLLName); if(hLoadedModule != NULL) { LoadedModules[i][0] = EnumeratedModules[i]; LoadedModules[i][1] = (ULONG_PTR)hLoadedModule; LoadedModules[i][2] = 1; } } else { hLoadedModule = (HANDLE)EngineSimulateDllLoader(hProcess, RemoteDLLName); if(hLoadedModule != NULL) { LoadedModules[i][0] = EnumeratedModules[i]; LoadedModules[i][1] = (ULONG_PTR)hLoadedModule; LoadedModules[i][2] = 1; ValidateHeader = true; } } } else { LoadedModules[i][0] = EnumeratedModules[i]; LoadedModules[i][1] = (ULONG_PTR)GetModuleHandleA(RemoteDLLName); LoadedModules[i][2] = 0; } } else { LoadedModules[i][0] = EnumeratedModules[i]; LoadedModules[i][1] = (ULONG_PTR)GetModuleHandleA(RemoteDLLName); LoadedModules[i][2] = 0; } if(!FoundAPI) { DOSHeader = (PIMAGE_DOS_HEADER)LoadedModules[i][1]; RtlZeroMemory(&RemoteModuleInfo, sizeof MODULEINFO); GetModuleInformation(hProcess, (HMODULE)LoadedModules[i][1], &RemoteModuleInfo, sizeof MODULEINFO); if(ValidateHeader || EngineValidateHeader((ULONG_PTR)LoadedModules[i][1], hProcess, RemoteModuleInfo.lpBaseOfDll, DOSHeader, false)) { PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); if(PEHeader32->OptionalHeader.Magic == 0x10B) { FileIs64 = false; } else if(PEHeader32->OptionalHeader.Magic == 0x20B) { FileIs64 = true; } else { return(NULL); } if(!FileIs64) { PEExports = (PIMAGE_EXPORT_DIRECTORY)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + LoadedModules[i][1]); ExportedFunctions = (PEXPORTED_DATA)(PEExports->AddressOfFunctions + LoadedModules[i][1]); } else { PEExports = (PIMAGE_EXPORT_DIRECTORY)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + LoadedModules[i][1]); ExportedFunctions = (PEXPORTED_DATA)(PEExports->AddressOfFunctions + LoadedModules[i][1]); } for(j = 0; j < PEExports->NumberOfFunctions; j++) { TestHash = (DWORD)EngineGlobalTracerHandler1(hProcess, (ULONG_PTR)(ExportedFunctions->ExportedItem + LoadedModules[i][1]), true, InputNumberOfInstructions); if(TestHash == CompareHash) { APIFoundAddress = (ULONG_PTR)(ExportedFunctions->ExportedItem + LoadedModules[i][0]); FoundAPI = true; } ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + 4); } } } i++; } i = 1; while(EnumeratedModules[i] != NULL) { if(engineAlowModuleLoading) { if(LoadedModules[i][2] == 1) { FreeLibrary((HMODULE)LoadedModules[i][1]); } } else { if(LoadedModules[i][2] == 1) { VirtualFree((void*)LoadedModules[i][1], NULL, MEM_RELEASE); } } i++; } } return((ULONG_PTR)APIFoundAddress); } __declspec(dllexport) long TITCALL TracerDetectRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace) { int i, j; MEMORY_BASIC_INFORMATION MemInfo; DWORD KnownRedirectionIndex = NULL; ULONG_PTR ueNumberOfBytesRead = NULL; PMEMORY_CMP_HANDLER cMem; DWORD MemoryHash = NULL; DWORD MaximumReadSize = 0; DWORD TestAddressX86; DynBuf tracemem; LPVOID TraceMemory; bool HashCheck = false; VirtualQueryEx(hProcess, (LPVOID)AddressToTrace, &MemInfo, sizeof MEMORY_BASIC_INFORMATION); if(MemInfo.RegionSize > NULL) { MaximumReadSize = (DWORD)((ULONG_PTR)MemInfo.AllocationBase + MemInfo.RegionSize - AddressToTrace); if(MaximumReadSize > 0x1000) { MaximumReadSize = 0x1000; HashCheck = true; } else if(MaximumReadSize > 256) { HashCheck = true; } if(sizeof HANDLE == 4) { TraceMemory = tracemem.Allocate(MaximumReadSize); if(!TraceMemory) { return (NULL); } if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TraceMemory, MaximumReadSize, &ueNumberOfBytesRead)) { cMem = (PMEMORY_CMP_HANDLER)TraceMemory; if(cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x01 && ((cMem->DataByte[3] >= 0x50 && cMem->DataByte[3] <= 0x5F) || cMem->DataByte[3] == 0x6A || cMem->DataByte[3] == 0x68)) { KnownRedirectionIndex = NULL; // ; PeX 0.99 fail safe! } else if(cMem->DataByte[0] == 0x68 && cMem->DataByte[5] == 0x81 && cMem->DataByte[12] == 0xC3) { KnownRedirectionIndex = 1; // ; RLP 0.7.4 & CryptoPeProtector 0.9.x & ACProtect /* ;$ ==> > 68 904B4013 PUSH 13404B90 ;$+5 > 812C24 0A9E589B SUB DWORD PTR SS:[ESP],9B589E0A ;$+C > C3 RET ;$+D > 68 E21554DF PUSH DF5415E2 ;$+12 > 813424 B6DCB2A8 XOR DWORD PTR SS:[ESP],A8B2DCB6 ;$+19 > C3 RET ;$+1A > 68 34B2C6B1 PUSH B1C6B234 ;$+1F > 810424 4A2C21C6 ADD DWORD PTR SS:[ESP],C6212C4A ;$+26 > C3 RET */ } else if(cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x25) { KnownRedirectionIndex = 2; // ; tELock 0.80 - 0.85 // ;$ ==> >- FF25 48018E00 JMP NEAR DWORD PTR DS:[8E0148] } else if((cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x35) || (cMem->DataByte[1] == 0xFF && cMem->DataByte[2] == 0x35) && (cMem->DataByte[8] == 0xC3 || cMem->DataByte[9] == 0xC3)) { KnownRedirectionIndex = 3; // ; tELock 0.90 - 0.95 /* ;$ ==> > FF35 AE018E00 PUSH DWORD PTR DS:[8E01AE] ; kernel32.InitializeCriticalSection ;$+6 > A8 C3 TEST AL,0C3 ;$+8 > C3 RET ;$+9 > F9 STC ;$+A > FF35 B2018E00 PUSH DWORD PTR DS:[8E01B2] ; kernel32.VirtualFree ;$+10 > 80FA C3 CMP DL,0C3 ;$+13 > C3 RET */ } else if(cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x01 && cMem->DataByte[2] == 0xC9 && cMem->DataByte[3] == 0x60 && cMem->DataByte[4] == 0x0F && cMem->DataByte[5] == 0x31) { KnownRedirectionIndex = 8; // ; AlexProtector 1.x /* ;$ ==> > /EB 01 JMP SHORT 008413F9 ;$+2 > |C9 LEAVE ;$+3 > \60 PUSHAD ;$+4 > 0F31 RDTSC ;$+6 > EB 01 JMP SHORT 008413FF ;$+8 > C9 LEAVE ;$+9 > 8BD8 MOV EBX,EAX ;$+B > EB 01 JMP SHORT 00841404 ;... ;$+33 > 68 E9B9D477 PUSH USER32.PostQuitMessage ;$+38 > EB 01 JMP SHORT 00841431 ;$+3A >- E9 C3EB01E9 JMP E985FFF8 */ } else if((cMem->DataByte[0] == 0x0B && cMem->DataByte[1] == 0xC5) || (cMem->DataByte[0] == 0x05 && cMem->DataByte[5] == 0xB8 && cMem->DataByte[10] == 0xEB && cMem->DataByte[11] == 0x02)) { KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private! /* ;008E0122 05 F9DEBE71 ADD EAX,71BEDEF9 ;008E0127 B8 28018E00 MOV EAX,8E0128 ;008E012C EB 02 JMP SHORT 008E0130 ;008E012E CD 20 INT 20 ;008E0130 05 18000000 ADD EAX,18 ;008E0135 8B00 MOV EAX,DWORD PTR DS:[EAX] ;008E0137 35 22018E00 XOR EAX,8E0122 ;008E013C 90 NOP ;008E013D 90 NOP ;008E013E 50 PUSH EAX ;008E013F C3 RET ; ;00850036 13C4 ADC EAX,ESP ;00850038 E8 0A000000 CALL 00850047 ;0085003D 90 NOP ;0085003E 1BC2 SBB EAX,EDX ;00850040 E9 09000000 JMP 0085004E ;00850045 1BC3 SBB EAX,EBX ;00850047 83F8 74 CMP EAX,74 ;0085004A C3 RET ;0085004B 98 CWDE ;0085004C 33C7 XOR EAX,EDI ;0085004E D6 SALC ;0085004F B8 50008500 MOV EAX,850050 ;00850054 EB 02 JMP SHORT 00850058 ;00850056 CD 20 INT 20 ;00850058 05 18000000 ADD EAX,18 ;0085005D 8B00 MOV EAX,DWORD PTR DS:[EAX] ;0085005F 35 36008500 XOR EAX,850036 ;00850064 90 NOP ;00850065 90 NOP ;00850066 50 PUSH EAX ;00850067 C3 RET */ } else if((cMem->DataByte[0] == 0x13 && cMem->DataByte[1] == 0xC4 && cMem->DataByte[2] == 0xE8) || (cMem->DataByte[0] == 0x83 && cMem->DataByte[3] == 0xE8)) { KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private! } else if((cMem->DataByte[0] == 0xB8 || cMem->DataByte[0] == 0x1D || cMem->DataByte[0] == 0x0D || cMem->DataByte[0] == 0x2D) && cMem->DataByte[5] == 0xB8 && cMem->DataByte[10] == 0xEB && cMem->DataByte[11] == 0x02) { KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private! /* ;011F0000 B8 2107F205 MOV EAX,5F20721 ;011F0005 B8 06008D00 MOV EAX,8D0006 ;011F000A EB 02 JMP SHORT 011F000E ;011F000C CD 20 INT 20 ;011F000E 05 18000000 ADD EAX,18 ;011F0013 8B00 MOV EAX,DWORD PTR DS:[EAX] ;011F0015 35 00008D00 XOR EAX,8D0000 ;011F001A 90 NOP ;011F001B 90 NOP ;011F001C 50 PUSH EAX ;011F001D C3 RET ; ;01360000 1D A508F205 SBB EAX,5F208A5 ;01360005 B8 28008D00 MOV EAX,8D0028 ;0136000A EB 02 JMP SHORT 0136000E ;0136000C CD 20 INT 20 ;0136000E 05 18000000 ADD EAX,18 ;01360013 8B00 MOV EAX,DWORD PTR DS:[EAX] ;01360015 35 22008D00 XOR EAX,8D0022 ;0136001A 90 NOP ;0136001B 90 NOP ;0136001C 50 PUSH EAX ;0136001D C3 RET ; ;014B0000 0D F918F205 OR EAX,5F218F9 ;014B0005 B8 4A008D00 MOV EAX,8D004A ;014B000A EB 02 JMP SHORT 014B000E ;014B000C CD 20 INT 20 ;014B000E 05 18000000 ADD EAX,18 ;014B0013 8B00 MOV EAX,DWORD PTR DS:[EAX] ;014B0015 35 44008D00 XOR EAX,8D0044 ;014B001A 90 NOP ;014B001B 90 NOP ;014B001C 50 PUSH EAX ;014B001D C3 RET ; ;01750000 2D 0B37F205 SUB EAX,5F2370B ;01750005 B8 8E008D00 MOV EAX,8D008E ;0175000A EB 02 JMP SHORT 0175000E ;0175000C CD 20 INT 20 ;0175000E 05 18000000 ADD EAX,18 ;01750013 8B00 MOV EAX,DWORD PTR DS:[EAX] ;01750015 35 88008D00 XOR EAX,8D0088 ;0175001A 90 NOP ;0175001B 90 NOP ;0175001C 50 PUSH EAX ;0175001D C3 RET ; ;019F0000 0BC4 OR EAX,ESP ;019F0002 F9 STC ;019F0003 E8 0B000000 CALL 019F0013 ;019F0008 90 NOP ;019F0009 13C4 ADC EAX,ESP ;019F000B E9 0A000000 JMP 019F001A ;019F0010 F9 STC ;019F0011 13C3 ADC EAX,EBX ;019F0013 98 CWDE ;019F0014 03C2 ADD EAX,EDX ;019F0016 C3 RET ; ;01B40000 48 DEC EAX ;01B40001 E8 0D000000 CALL 01B40013 ;01B40006 03C5 ADD EAX,EBP ;01B40008 FC CLD ;01B40009 E9 0A000000 JMP 01B40018 ;01B4000E 35 D82FF205 XOR EAX,5F22FD8 ;01B40013 C1C8 9A ROR EAX,9A ;01B40016 C3 RET */ } else if((cMem->DataByte[0] == 0x0B && cMem->DataByte[1] == 0xC4 && cMem->DataByte[2] == 0xF9 && cMem->DataByte[3] == 0xE8) || (cMem->DataByte[0] == 0x48 && cMem->DataByte[1] == 0xE8)) { KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private! } else if((cMem->DataByte[0] == 0xB8 && cMem->DataByte[5] == 0xE8 && cMem->DataByte[10] == 0xF9 && cMem->DataByte[11] == 0xE9) && (cMem->DataByte[0] == 0xE8 && cMem->DataByte[1] == 0x0B && cMem->DataByte[10] == 0xE9 && cMem->DataByte[11] == 0x05 && cMem->DataByte[15] == 0x90 && cMem->DataByte[16] == 0xC3)) { KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private! /* ;01C90000 B8 B853F205 MOV EAX,5F253B8 ;01C90005 E8 07000000 CALL 01C90011 ;01C9000A F9 STC ;01C9000B E9 07000000 JMP 01C90017 ;01C90010 90 NOP ;01C90011 23C3 AND EAX,EBX ;01C90013 C3 RET ; ;00A40022 1BC2 SBB EAX,EDX ;00A40024 E8 08000000 CALL 00A40031 ;00A40029 40 INC EAX ;00A4002A E9 09000000 JMP 00A40038 ;00A4002F 33C7 XOR EAX,EDI ;00A40031 C1E8 92 SHR EAX,92 ;00A40034 C3 RET ;00A40035 83E0 25 AND EAX,25 ;00A40038 25 E5AE65DD AND EAX,DD65AEE5 ;00A4003D B8 3E00A400 MOV EAX,0A4003E ;00A40042 EB 02 JMP SHORT 00A40046 ;00A40044 CD 20 INT 20 ;00A40046 05 18000000 ADD EAX,18 ;00A4004B 8B00 MOV EAX,DWORD PTR DS:[EAX] ;00A4004D 35 2200A400 XOR EAX,0A40022 ;00A40052 90 NOP ;00A40053 90 NOP ;00A40054 50 PUSH EAX ;00A40055 C3 RET ; ;00A4005A E8 0B000000 CALL 00A4006A ;00A4005F 15 06F265DD ADC EAX,DD65F206 ;00A40064 E9 05000000 JMP 00A4006E ;00A40069 90 NOP ;00A4006A C3 RET ;00A4006B 1BC5 SBB EAX,EBP ;00A4006D 40 INC EAX ;00A4006E 1BC0 SBB EAX,EAX ;00A40070 F9 STC ;00A40071 B8 7200A400 MOV EAX,0A40072 ;00A40076 EB 02 JMP SHORT 00A4007A ;00A40078 CD 20 INT 20 ;00A4007A 05 18000000 ADD EAX,18 ;00A4007F 8B00 MOV EAX,DWORD PTR DS:[EAX] ;00A40081 35 5A00A400 XOR EAX,0A4005A ;00A40086 90 NOP ;00A40087 90 NOP ;00A40088 50 PUSH EAX ;00A40089 C3 RET */ } else if(cMem->DataByte[0] == 0x1B && cMem->DataByte[1] == 0xC2 && cMem->DataByte[2] == 0xE8 && cMem->DataByte[3] == 0x08 && cMem->DataByte[7] == 0x40 && cMem->DataByte[8] == 0xE9 && cMem->DataByte[9] == 0x09 && cMem->DataByte[10] == 0x00) { KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private! } else if(cMem->DataByte[0] == 0x68 && cMem->DataByte[5] == 0xE9) { RtlMoveMemory(&TestAddressX86, &cMem->DataByte[1], 4); if(TestAddressX86 > AddressToTrace) { if(ImporterGetAPIName((ULONG_PTR)TestAddressX86) != NULL) { KnownRedirectionIndex = 6; // ; ReCrypt 0.74 /* ;001739F1 68 E9D9D477 PUSH User32.EndDialog ;001739F6 ^ E9 FDFEFFFF JMP 001738F8 */ } } } else if((cMem->DataByte[0] == 0xE8 && cMem->DataByte[5] == 0x58 && cMem->DataByte[6] == 0xEB && cMem->DataByte[7] == 0x01) || (cMem->DataByte[0] == 0xC8 && cMem->DataByte[4] == 0xE8 && cMem->DataByte[9] == 0x5B)) { KnownRedirectionIndex = 7; // ; Orien 2.1x /* ;GetCommandLineA ;$ ==> >/$ E8 00000000 CALL crackme_.0040DF8F ;$+5 >|$ 58 POP EAX ;$+6 >|. EB 01 JMP SHORT crackme_.0040DF93 ;$+8 >| B8 DB B8 ;$+9 >|> 85DB TEST EBX,EBX ;$+B >|. 2D 8F1F0000 SUB EAX,1F8F ;$+10 >|. EB 01 JMP SHORT crackme_.0040DF9D ;$+12 >| A8 DB A8 ;$+13 >|> 8D80 F0550000 LEA EAX,DWORD PTR DS:[EAX+55F0] ;$+19 >\. C3 RET ;GetCommandLineW ;$ ==> > . E8 00000000 CALL crackme_.0040DFA9 ;$+5 >/$ 58 POP EAX ;$+6 >|. EB 01 JMP SHORT crackme_.0040DFAD ;$+8 >| B8 DB B8 ;$+9 >|> 85DB TEST EBX,EBX ;$+B >|. 2D A91F0000 SUB EAX,1FA9 ;$+10 >|. EB 01 JMP SHORT crackme_.0040DFB7 ;$+12 >| A8 DB A8 ;$+13 >|> 8D80 F4560000 LEA EAX,DWORD PTR DS:[EAX+56F4] ;$+19 >\. C3 RET ;ExitProcess ;$ ==> > $ C8 000000 ENTER 0,0 ;$+4 > . E8 00000000 CALL crackme_.0040DF2A ;$+9 > $ 5B POP EBX ;$+A > . EB 01 JMP SHORT crackme_.0040DF2E ;$+C > B8 DB B8 ;$+D > > 85DB TEST EBX,EBX ;$+F > . 81EB 2A1F0000 SUB EBX,1F2A ;$+15 > . EB 01 JMP SHORT crackme_.0040DF39 ;$+17 > A8 DB A8 ;$+18 > > 8D83 4D310000 LEA EAX,DWORD PTR DS:[EBX+314D] ;$+1E > . 8038 00 CMP BYTE PTR DS:[EAX],0 ;$+21 > . 74 29 JE SHORT crackme_.0040DF6D ;$+23 > . EB 01 JMP SHORT crackme_.0040DF47 ;$+25 > A8 DB A8 ;$+26 > > 8D93 55380000 LEA EDX,DWORD PTR DS:[EBX+3855] ;$+2C > . E8 01000000 CALL crackme_.0040DF53 ;$+31 > E9 DB E9 ;$+32 > $ 83EC FC SUB ESP,-4 ;$+35 > . 6A 00 PUSH 0 ;$+37 > . 52 PUSH EDX ;$+38 > . 50 PUSH EAX ;$+39 > . 6A 00 PUSH 0 ;$+3B > . E8 05000000 CALL crackme_.0040DF66 ;$+40 > . EB 0A JMP SHORT crackme_.0040DF6D ;$+42 > 88 DB 88 ;$+43 > FC DB FC ;$+44 > B6 DB B6 ;$+45 > $ FFA3 FF3A0000 JMP NEAR DWORD PTR DS:[EBX+3AFF] ;$+4B > CD DB CD ;$+4C > > E8 01000000 CALL crackme_.0040DF73 ;$+51 > E9 DB E9 ;$+52 > $ 83EC FC SUB ESP,-4 ;$+55 > . FF75 08 PUSH DWORD PTR SS:[EBP+8] ;$+58 > . E8 05000000 CALL crackme_.0040DF83 ;$+5D > . EB 0A JMP SHORT crackme_.0040DF8A ;$+5F > 88 DB 88 ;$+60 > FC DB FC ;$+61 > B6 DB B6 ;$+62 > $ FFA3 BF3A0000 JMP NEAR DWORD PTR DS:[EBX+3ABF] */ } else if((cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x01 && cMem->DataByte[2] == 0x66 && cMem->DataByte[3] == 0x1B) || (cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x02 && cMem->DataByte[2] == 0xCD && cMem->DataByte[3] == 0x20) || (cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x01 && cMem->DataByte[2] == 0xB8 && cMem->DataByte[3] == 0xEB)) { KnownRedirectionIndex = 4; // ; tELock 0.96 - 0.98 /* ;(BYTE PTR[ESI] == 0EBh && (BYTE PTR[ESI+3] == 0EBh || BYTE PTR[ESI+2] == 0EBh)) ;017B0000 0BE4 OR ESP,ESP ;017B0002 75 01 JNZ SHORT 017B0005 ; ;15940000 85E4 TEST ESP,ESP ;15940002 79 03 JNS SHORT 15940007 ; ;008E0359 B8 8DE44500 MOV EAX,45E48D ;008E035E 90 NOP ;008E035F FF30 PUSH DWORD PTR DS:[EAX] ;008E0361 C3 RET ; ;008F0033 B8 AF008F00 MOV EAX,8F00AF ;008F0038 40 INC EAX ;008F0039 FF30 PUSH DWORD PTR DS:[EAX] ;008F003B C3 RET ; ;008E02F7 B8 20078E00 MOV EAX,8E0720 ;008E02FC FF20 JMP NEAR DWORD PTR DS:[EAX] */ } else if((cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x03 && cMem->DataByte[2] == 0xFF && cMem->DataByte[3] == 0xEB) || (cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x01 && cMem->DataByte[2] == 0xB8 && cMem->DataByte[3] == 0x05) || (cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x02 && cMem->DataByte[2] == 0xFF && cMem->DataByte[3] == 0x20)) { KnownRedirectionIndex = 4; // ; tELock 0.96 - 0.98 } else if((cMem->DataByte[0] == 0xF9 || cMem->DataByte[0] == 0xF8) || (cMem->DataByte[0] == 0x0B && cMem->DataByte[1] == 0xE4) || (cMem->DataByte[0] == 0x85 && cMem->DataByte[1] == 0xE4)) { KnownRedirectionIndex = 4; // ; tELock 0.96 - 0.98 } else if(cMem->DataByte[0] == 0xEB && (cMem->DataByte[1] > NULL && cMem->DataByte[1] < 4)) { i = 2; j = 30; while(j > NULL) { if(cMem->DataByte[i] == 0xB8 && (cMem->DataByte[i + 5] == 0x40 || cMem->DataByte[i + 5] == 0x90) && cMem->DataByte[i + 6] == 0xFF && cMem->DataByte[i + 7] == 0x30 && cMem->DataByte[i + 8] == 0xC3) { KnownRedirectionIndex = 4; // ; tELock 0.96 - 0.98 j = 1; } i++; j--; } } else if(HashCheck) { if(cMem->DataByte[0] == 0x9C || cMem->DataByte[0] == 0xEB) { MemoryHash = EngineHashMemory((char*)TraceMemory, 192, MemoryHash); if(MemoryHash == 0x5AF7E209 || MemoryHash == 0xEB480CAC || MemoryHash == 0x86218561 || MemoryHash == 0xCA9ABD85) { KnownRedirectionIndex = 9; // ; SVKP 1.x } else if(MemoryHash == 0xF1F84A98 || MemoryHash == 0x91823290 || MemoryHash == 0xBEE6BAA0 || MemoryHash == 0x79603232) { KnownRedirectionIndex = 9; // ; SVKP 1.x } } } return(KnownRedirectionIndex); } else { } } } return(NULL); } __declspec(dllexport) ULONG_PTR TITCALL TracerFixKnownRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD RedirectionId) { int i = NULL; DWORD TestAddressX86; DWORD ReadAddressX86; DWORD MemoryHash = NULL; PMEMORY_CMP_HANDLER cMem; MEMORY_BASIC_INFORMATION MemInfo; ULONG_PTR ueNumberOfBytesRead = NULL; char TracerReadMemory[0x1000] = {0}; DWORD MaximumReadSize = 0x1000; cMem = (PMEMORY_CMP_HANDLER)TracerReadMemory; VirtualQueryEx(hProcess, (LPVOID)AddressToTrace, &MemInfo, sizeof MEMORY_BASIC_INFORMATION); if(MemInfo.RegionSize > NULL) { MaximumReadSize = (DWORD)((ULONG_PTR)MemInfo.BaseAddress + MemInfo.RegionSize - AddressToTrace); if(MaximumReadSize > 0x1000) { MaximumReadSize = 0x1000; } } if(RedirectionId == NULL) { RedirectionId = (DWORD)TracerDetectRedirection(hProcess, AddressToTrace); } if(RedirectionId == 1) // TracerFix_ACProtect { __try { if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead)) { RtlMoveMemory(&TestAddressX86, &cMem->DataByte[1], 4); if(cMem->DataByte[5] == 0x81 && cMem->DataByte[6] == 0x2C) { RtlMoveMemory(&ReadAddressX86, &cMem->DataByte[8], 4); TestAddressX86 = TestAddressX86 - ReadAddressX86; } else if(cMem->DataByte[5] == 0x81 && cMem->DataByte[6] == 0x34) { RtlMoveMemory(&ReadAddressX86, &cMem->DataByte[8], 4); TestAddressX86 = TestAddressX86 ^ ReadAddressX86; } else if(cMem->DataByte[5] == 0x81 && cMem->DataByte[6] == 0x04) { RtlMoveMemory(&ReadAddressX86, &cMem->DataByte[8], 4); TestAddressX86 = TestAddressX86 + ReadAddressX86; } return((DWORD)TestAddressX86); } } __except(EXCEPTION_EXECUTE_HANDLER) { return(NULL); } } else if(RedirectionId == 2) // TracerFix_tELock_varA { __try { if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead)) { RtlMoveMemory(&TestAddressX86, &cMem->DataByte[2], 4); if(ReadProcessMemory(hProcess, (LPVOID)TestAddressX86, &TestAddressX86, 4, &ueNumberOfBytesRead)) { return((DWORD)TestAddressX86); } } } __except(EXCEPTION_EXECUTE_HANDLER) { return(NULL); } } else if(RedirectionId == 3) // TracerFix_tELock_varB { __try { if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead)) { if(cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x35) { RtlMoveMemory(&TestAddressX86, &cMem->DataByte[2], 4); } else { RtlMoveMemory(&TestAddressX86, &cMem->DataByte[3], 4); } if(ReadProcessMemory(hProcess, (LPVOID)TestAddressX86, &TestAddressX86, 4, &ueNumberOfBytesRead)) { return((DWORD)TestAddressX86); } } } __except(EXCEPTION_EXECUTE_HANDLER) { return(NULL); } } else if(RedirectionId == 4) // TracerFix_tELock_varC { __try { if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead)) { i = 100; if(cMem->DataByte[0] == 0xEB && (cMem->DataByte[1] > 0 && cMem->DataByte[1] < 4)) { cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + cMem->DataByte[1] + 2); } while(i > NULL && (cMem->DataByte[0] == 0xFF && (cMem->DataByte[1] == 0x20 || cMem->DataByte[1] == 0x30))) { cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + 1); i--; } if(i != NULL && cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x20) { if(cMem->DataByte[2] != 0x90) { cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + 1); while(i > NULL && (cMem->DataByte[0] == 0xFF && (cMem->DataByte[1] == 0x20 || cMem->DataByte[1] == 0x30))) { cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + 1); i--; } } } if(i != NULL && cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x30) { cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem - 6); if(cMem->DataByte[0] == 0xB8) { RtlMoveMemory(&TestAddressX86, &cMem->DataByte[1], 4); if(cMem->DataByte[5] == 0x40) { TestAddressX86++; } } else { RtlMoveMemory(&TestAddressX86, &cMem->DataByte[2], 4); } if(ReadProcessMemory(hProcess, (LPVOID)TestAddressX86, &TestAddressX86, 4, &ueNumberOfBytesRead)) { return((DWORD)TestAddressX86); } } else if(i != NULL && cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x20) { cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem - 6); RtlMoveMemory(&TestAddressX86, &cMem->DataByte[2], 4); if(ReadProcessMemory(hProcess, (LPVOID)TestAddressX86, &TestAddressX86, 4, &ueNumberOfBytesRead)) { return((DWORD)TestAddressX86); } } } } __except(EXCEPTION_EXECUTE_HANDLER) { return(NULL); } } else if(RedirectionId == 5) // TracerFix_tELock_varD { __try { if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead)) { i = 100; while(i > NULL && (cMem->DataByte[0] != 0x50 || cMem->DataByte[1] != 0xC3)) { cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + 1); i--; } if(i != NULL && cMem->DataByte[0] == 0x50 && cMem->DataByte[1] == 0xC3) { cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem - 0x16); RtlMoveMemory(&ReadAddressX86, &cMem->DataByte[0x10], 4); RtlMoveMemory(&TestAddressX86, &cMem->DataByte[0], 4); TestAddressX86 = TestAddressX86 + 0x18; if(ReadProcessMemory(hProcess, (LPVOID)TestAddressX86, &TestAddressX86, 4, &ueNumberOfBytesRead)) { TestAddressX86 = TestAddressX86 ^ ReadAddressX86; return((DWORD)TestAddressX86); } } } } __except(EXCEPTION_EXECUTE_HANDLER) { return(NULL); } } else if(RedirectionId == 6) // TracerFix_ReCrypt { __try { if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead)) { RtlMoveMemory(&TestAddressX86, &cMem->DataByte[1], 4); return((DWORD)TestAddressX86); } } __except(EXCEPTION_EXECUTE_HANDLER) { return(NULL); } } else if(RedirectionId == 7) // TracerFix_Orien { __try { if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead)) { if(cMem->DataByte[0] == 0xE8) { RtlMoveMemory(&ReadAddressX86, &cMem->DataByte[0x15], 4); if(ReadAddressX86 == 0x55F0) { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCommandLineA")); } else { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCommandLineW")); } return((DWORD)TestAddressX86); } else if(cMem->DataByte[0] == 0xC8) { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ExitProcess")); return((DWORD)TestAddressX86); } } } __except(EXCEPTION_EXECUTE_HANDLER) { return(NULL); } } else if(RedirectionId == 8) // TracerFix_AlexProtector { __try { if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead)) { cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + 0x34); RtlMoveMemory(&TestAddressX86, &cMem->DataByte[0], 4); return((DWORD)TestAddressX86); } } __except(EXCEPTION_EXECUTE_HANDLER) { return(NULL); } } else if(RedirectionId == 9 && MaximumReadSize > 192) // TracerFix_SVKP { __try { if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead)) { if(cMem->DataByte[0] == 0x9C || cMem->DataByte[0] == 0xEB) { MemoryHash = EngineHashMemory((char*)TracerReadMemory, 192, MemoryHash); if(MemoryHash == 0x5AF7E209) { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCommandLineA")); } else if(MemoryHash == 0xEB480CAC) { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ExitProcess")); } else if(MemoryHash == 0x86218561) { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCurrentProcess")); } else if(MemoryHash == 0xCA9ABD85) { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetVersion")); } else if(MemoryHash == 0xF1F84A98) { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetVersionExA")); } else if(MemoryHash == 0x91823290) { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetModuleHandleA")); } else if(MemoryHash == 0xBEE6BAA0) { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA")); } else if(MemoryHash == 0x79603232) { TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetModuleHandleA")); } return((DWORD)TestAddressX86); } } } __except(EXCEPTION_EXECUTE_HANDLER) { return(NULL); } } return(NULL); } // TitanEngine.Tracer.functions: __declspec(dllexport) long TITCALL TracerFixRedirectionViaImpRecPlugin(HANDLE hProcess, char* szPluginName, ULONG_PTR AddressToTrace) { int szLenght = NULL; HMODULE hImpRecModule = NULL; ULONG_PTR fImpRecTrace = NULL; PMEMORY_CMP_HANDLER cmpModuleName; ULONG_PTR remInjectSize = (ULONG_PTR)((ULONG_PTR)&injectedRemoteLoadLibrary - (ULONG_PTR)&injectedImpRec); char szModuleName[0x1100] = {0}; char szGarbageFile[0x1100] = {0}; LPVOID cModuleName = szModuleName; ULONG_PTR NumberOfBytesWritten; InjectImpRecCodeData APIData; DWORD TracedAddress = NULL; DWORD TraceAddress = NULL; LPVOID remStringData; LPVOID remCodeData; DWORD ThreadId; HANDLE hThread; DWORD ExitCode; HANDLE FileHandle; DWORD FileSize; HANDLE FileMap; ULONG_PTR FileMapVA; if(GetModuleFileNameA(engineHandle, (LPCH)szModuleName, sizeof(szModuleName) - 0x100) > NULL) { cModuleName = (LPVOID)((ULONG_PTR)cModuleName + lstrlenA((LPCSTR)szModuleName)); cmpModuleName = (PMEMORY_CMP_HANDLER)(cModuleName); while(cmpModuleName->DataByte[0] != 0x5C) { cmpModuleName = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cmpModuleName - 1); } cmpModuleName = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cmpModuleName + 1); cmpModuleName->DataByte[0] = 0x00; lstrcpyA((LPSTR)szGarbageFile, (LPCSTR)szModuleName); lstrcatA((LPSTR)szGarbageFile, "garbage\\ImpRec.txt"); lstrcatA((LPSTR)szModuleName, "imports\\ImpRec\\"); lstrcatA((LPSTR)szModuleName, szPluginName); if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, &TraceAddress, 4, &NumberOfBytesWritten)) { if(RemoteLoadLibrary(hProcess, (char*)szModuleName, true)) { hImpRecModule = LoadLibraryA((char*)szModuleName); if(hImpRecModule != NULL) { fImpRecTrace = (ULONG_PTR)GetProcAddress(hImpRecModule, "Trace"); if(fImpRecTrace != NULL) { fImpRecTrace = fImpRecTrace - (ULONG_PTR)hImpRecModule; remCodeData = VirtualAllocEx(hProcess, NULL, remInjectSize, MEM_COMMIT, PAGE_READWRITE); remStringData = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE); RtlZeroMemory(&APIData, sizeof InjectImpRecCodeData); APIData.fTrace = fImpRecTrace + (ULONG_PTR)ImporterGetRemoteDLLBase(hProcess, hImpRecModule); APIData.AddressToTrace = (ULONG_PTR)TraceAddress; APIData.fCreateFileA = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateFileA")); APIData.fCreateFileMappingA = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateFileMappingA")); APIData.fCloseHandle = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CloseHandle")); if(WriteProcessMemory(hProcess, remCodeData, (LPCVOID)&injectedImpRec, remInjectSize, &NumberOfBytesWritten)) { WriteProcessMemory(hProcess, remStringData, &APIData, sizeof InjectImpRecCodeData, &NumberOfBytesWritten); WriteProcessMemory(hProcess, (LPVOID)((ULONG_PTR)remStringData + sizeof InjectImpRecCodeData), (LPCVOID)szGarbageFile, lstrlenA((LPSTR)szGarbageFile), &NumberOfBytesWritten); hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remCodeData, remStringData, CREATE_SUSPENDED, &ThreadId); NtSetInformationThread(hThread, ThreadHideFromDebugger, NULL, NULL); ResumeThread(hThread); WaitForSingleObject(hThread, INFINITE); if(GetExitCodeThread(hThread, &ExitCode)) { if(ExitCode != NULL) { if(MapFileEx((char*)szGarbageFile, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL)) { RtlMoveMemory(&TracedAddress, (LPVOID)FileMapVA, 4); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); } if(!DeleteFileA((LPCSTR)szGarbageFile)) { HandlerCloseAllLockHandles((char*)szGarbageFile, false, true); DeleteFileA((LPCSTR)szGarbageFile); } } } } RemoteFreeLibrary(hProcess, NULL, (char*)szModuleName, true); VirtualFreeEx(hProcess, remCodeData, NULL, MEM_RELEASE); VirtualFreeEx(hProcess, remStringData, NULL, MEM_RELEASE); } else { RemoteFreeLibrary(hProcess, NULL, (char*)szModuleName, true); } FreeLibrary(hImpRecModule); } } } } return(TracedAddress); }