mirror of https://github.com/x64dbg/TitanEngine
1525 lines
76 KiB
C++
1525 lines
76 KiB
C++
#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)(DWORD_PTR)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)(DWORD_PTR)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)(DWORD_PTR)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)(DWORD_PTR)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)(DWORD_PTR)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);
|
|
} |