Page Menu
Home
desp's stash
Search
Configure Global Search
Log In
Files
F352054
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
23 KB
Subscribers
None
View Options
diff --git a/Scylla/IATReferenceScan.cpp b/Scylla/IATReferenceScan.cpp
index 9795953..9d560be 100644
--- a/Scylla/IATReferenceScan.cpp
+++ b/Scylla/IATReferenceScan.cpp
@@ -1,767 +1,767 @@
#include "IATReferenceScan.h"
#include "Scylla.h"
#include "Architecture.h"
#include <set>
//#define DEBUG_COMMENTS
FileLog IATReferenceScan::directImportLog(L"Scylla_direct_imports.log");
int IATReferenceScan::numberOfFoundDirectImports()
{
return (int)iatDirectImportList.size();
}
int IATReferenceScan::numberOfFoundUniqueDirectImports()
{
std::set<DWORD_PTR> apiPointers;
for (std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference * ref = &(*iter);
apiPointers.insert(ref->targetAddressInIat);
}
return (int)apiPointers.size();
}
int IATReferenceScan::numberOfDirectImportApisNotInIat()
{
std::set<DWORD_PTR> apiPointers;
for (std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference * ref = &(*iter);
if (ref->targetPointer == 0)
{
apiPointers.insert(ref->targetAddressInIat);
}
}
return (int)apiPointers.size();
}
int IATReferenceScan::getSizeInBytesOfJumpTableInSection()
{
return (numberOfFoundUniqueDirectImports() * 6); //for x86 and x64 the same size, FF25 00000000
}
void IATReferenceScan::startScan(DWORD_PTR imageBase, DWORD imageSize, DWORD_PTR iatAddress, DWORD iatSize)
{
MEMORY_BASIC_INFORMATION memBasic = {0};
IatAddressVA = iatAddress;
IatSize = iatSize;
ImageBase = imageBase;
ImageSize = imageSize;
if (ScanForNormalImports)
{
iatReferenceList.clear();
iatReferenceList.reserve(200);
}
if (ScanForDirectImports)
{
iatDirectImportList.clear();
iatDirectImportList.reserve(50);
}
DWORD_PTR section = imageBase;
do
{
if (!VirtualQueryEx(ProcessAccessHelp::hProcess, (LPCVOID)section, &memBasic, sizeof(MEMORY_BASIC_INFORMATION)))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"VirtualQueryEx failed %d", GetLastError());
#endif
break;
}
else
{
if (isPageExecutable(memBasic.Protect))
{
//do read and scan
scanMemoryPage(memBasic.BaseAddress, memBasic.RegionSize);
}
}
section = (DWORD_PTR)((SIZE_T)section + memBasic.RegionSize);
} while (section < (imageBase + imageSize));
}
//void IATReferenceScan::patchNewIatBaseMemory(DWORD_PTR newIatBaseAddress)
//{
// NewIatAddressVA = newIatBaseAddress;
//
// for (std::vector<IATReference>::iterator iter = iatReferenceList.begin(); iter != iatReferenceList.end(); iter++)
// {
// patchReferenceInMemory(&(*iter));
// }
//}
//
//void IATReferenceScan::patchNewIatBaseFile(DWORD_PTR newIatBaseAddress)
//{
// NewIatAddressVA = newIatBaseAddress;
//
// for (std::vector<IATReference>::iterator iter = iatReferenceList.begin(); iter != iatReferenceList.end(); iter++)
// {
// patchReferenceInFile(&(*iter));
// }
//}
void IATReferenceScan::patchDirectImportsMemory( bool junkByteAfterInstruction )
{
JunkByteAfterInstruction = junkByteAfterInstruction;
for (std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
patchDirectImportInMemory(&(*iter));
}
}
bool IATReferenceScan::isPageExecutable( DWORD Protect )
{
if (Protect & PAGE_NOCACHE) Protect ^= PAGE_NOCACHE;
if (Protect & PAGE_WRITECOMBINE) Protect ^= PAGE_WRITECOMBINE;
switch(Protect)
{
case PAGE_EXECUTE:
{
return true;
}
case PAGE_EXECUTE_READ:
{
return true;
}
case PAGE_EXECUTE_READWRITE:
{
return true;
}
case PAGE_EXECUTE_WRITECOPY:
{
return true;
}
default:
return false;
}
}
void IATReferenceScan::scanMemoryPage( PVOID BaseAddress, SIZE_T RegionSize )
{
BYTE * dataBuffer = (BYTE *)calloc(RegionSize, 1);
BYTE * currentPos = dataBuffer;
int currentSize = (int)RegionSize;
DWORD_PTR currentOffset = (DWORD_PTR)BaseAddress;
_DecodeResult res;
unsigned int instructionsCount = 0, next = 0;
if (!dataBuffer)
return;
if (ProcessAccessHelp::readMemoryFromProcess((DWORD_PTR)BaseAddress, RegionSize, (LPVOID)dataBuffer))
{
while (1)
{
ZeroMemory(&ProcessAccessHelp::decomposerCi, sizeof(_CodeInfo));
ProcessAccessHelp::decomposerCi.code = currentPos;
ProcessAccessHelp::decomposerCi.codeLen = currentSize;
ProcessAccessHelp::decomposerCi.dt = ProcessAccessHelp::dt;
ProcessAccessHelp::decomposerCi.codeOffset = currentOffset;
instructionsCount = 0;
res = distorm_decompose(&ProcessAccessHelp::decomposerCi, ProcessAccessHelp::decomposerResult, sizeof(ProcessAccessHelp::decomposerResult)/sizeof(ProcessAccessHelp::decomposerResult[0]), &instructionsCount);
if (res == DECRES_INPUTERR)
{
break;
}
for (unsigned int i = 0; i < instructionsCount; i++)
{
if (ProcessAccessHelp::decomposerResult[i].flags != FLAG_NOT_DECODABLE)
{
analyzeInstruction(&ProcessAccessHelp::decomposerResult[i]);
}
}
if (res == DECRES_SUCCESS) break; // All instructions were decoded.
else if (instructionsCount == 0) break;
next = (unsigned long)(ProcessAccessHelp::decomposerResult[instructionsCount-1].addr - ProcessAccessHelp::decomposerResult[0].addr);
if (ProcessAccessHelp::decomposerResult[instructionsCount-1].flags != FLAG_NOT_DECODABLE)
{
next += ProcessAccessHelp::decomposerResult[instructionsCount-1].size;
}
currentPos += next;
currentOffset += next;
currentSize -= next;
}
}
free(dataBuffer);
}
void IATReferenceScan::analyzeInstruction( _DInst * instruction )
{
if (ScanForNormalImports)
{
findNormalIatReference(instruction);
}
if (ScanForDirectImports)
{
findDirectIatReferenceMov(instruction);
#ifndef _WIN64
findDirectIatReferenceCallJmp(instruction);
findDirectIatReferenceLea(instruction);
findDirectIatReferencePush(instruction);
#endif
}
}
void IATReferenceScan::findNormalIatReference( _DInst * instruction )
{
#ifdef DEBUG_COMMENTS
_DecodedInst inst;
#endif
IATReference ref;
if (META_GET_FC(instruction->meta) == FC_CALL || META_GET_FC(instruction->meta) == FC_UNC_BRANCH)
{
if (instruction->size >= 5)
{
if (META_GET_FC(instruction->meta) == FC_CALL)
{
ref.type = IAT_REFERENCE_PTR_CALL;
}
else
{
ref.type = IAT_REFERENCE_PTR_JMP;
}
ref.addressVA = (DWORD_PTR)instruction->addr;
ref.instructionSize = instruction->size;
#ifdef _WIN64
if (instruction->flags & FLAG_RIP_RELATIVE)
{
#ifdef DEBUG_COMMENTS
distorm_format(&ProcessAccessHelp::decomposerCi, instruction, &inst);
Scylla::debugLog.log(PRINTF_DWORD_PTR_FULL L" " PRINTF_DWORD_PTR_FULL L" %S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, (DWORD_PTR)instruction->addr, ImageBase, inst.mnemonic.p, inst.operands.p, instruction->ops[0].type, instruction->size, INSTRUCTION_GET_RIP_TARGET(instruction));
#endif
if (INSTRUCTION_GET_RIP_TARGET(instruction) >= IatAddressVA && INSTRUCTION_GET_RIP_TARGET(instruction) < (IatAddressVA + IatSize))
{
ref.targetPointer = INSTRUCTION_GET_RIP_TARGET(instruction);
getIatEntryAddress(&ref);
//Scylla::debugLog.log(L"iat entry "PRINTF_DWORD_PTR_FULL,ref.targetAddressInIat);
iatReferenceList.push_back(ref);
}
}
#else
if (instruction->ops[0].type == O_DISP)
{
//jmp dword ptr || call dword ptr
#ifdef DEBUG_COMMENTS
distorm_format(&ProcessAccessHelp::decomposerCi, instruction, &inst);
Scylla::debugLog.log(PRINTF_DWORD_PTR_FULL L" " PRINTF_DWORD_PTR_FULL L" %S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, (DWORD_PTR)instruction->addr, ImageBase, inst.mnemonic.p, inst.operands.p, instruction->ops[0].type, instruction->size, instruction->disp);
#endif
if (instruction->disp >= IatAddressVA && instruction->disp < (IatAddressVA + IatSize))
{
ref.targetPointer = (DWORD_PTR)instruction->disp;
getIatEntryAddress(&ref);
//Scylla::debugLog.log(L"iat entry "PRINTF_DWORD_PTR_FULL,ref.targetAddressInIat);
iatReferenceList.push_back(ref);
}
}
#endif
}
}
}
void IATReferenceScan::getIatEntryAddress( IATReference * ref )
{
if (!ProcessAccessHelp::readMemoryFromProcess(ref->targetPointer, sizeof(DWORD_PTR), &ref->targetAddressInIat))
{
ref->targetAddressInIat = 0;
}
}
bool IATReferenceScan::isAddressValidImageMemory( DWORD_PTR address )
{
MEMORY_BASIC_INFORMATION memBasic = {0};
if (!VirtualQueryEx(ProcessAccessHelp::hProcess, (LPCVOID)address, &memBasic, sizeof(MEMORY_BASIC_INFORMATION)))
{
return false;
}
return (memBasic.Type == MEM_IMAGE && isPageExecutable(memBasic.Protect));
}
void IATReferenceScan::patchReferenceInMemory( IATReference * ref )
{
DWORD_PTR newIatAddressPointer = ref->targetPointer - IatAddressVA + NewIatAddressRVA;
DWORD patchBytes = 0;
#ifdef _WIN64
patchBytes = (DWORD)(newIatAddressPointer - ref->addressVA - 6);
#else
patchBytes = newIatAddressPointer;
#endif
ProcessAccessHelp::writeMemoryToProcess(ref->addressVA + 2, sizeof(DWORD), &patchBytes);
}
void IATReferenceScan::patchDirectImportInMemory( IATReference * ref )
{
DWORD patchBytes = 0;
BYTE patchPreBytes[2];
if (ref->targetPointer)
{
patchPreBytes[0] = 0xFF;
if (ref->type == IAT_REFERENCE_DIRECT_CALL) //FF15
{
patchPreBytes[1] = 0x15;
}
else if (ref->type == IAT_REFERENCE_DIRECT_JMP) //FF25
{
patchPreBytes[1] = 0x25;
}
else
{
return;
}
if (!JunkByteAfterInstruction)
{
ref->addressVA -= 1;
}
ProcessAccessHelp::writeMemoryToProcess(ref->addressVA, 2, patchPreBytes);
#ifdef _WIN64
patchBytes = (DWORD)(ref->targetPointer - ref->addressVA - 6);
#else
patchBytes = ref->targetPointer;
#endif
ProcessAccessHelp::writeMemoryToProcess(ref->addressVA + 2, sizeof(DWORD), &patchBytes);
}
}
DWORD_PTR IATReferenceScan::lookUpIatForPointer( DWORD_PTR addr )
{
if (!iatBackup)
{
iatBackup = (DWORD_PTR *)calloc(IatSize + sizeof(DWORD_PTR), 1);
if (!iatBackup)
{
return 0;
}
if (!ProcessAccessHelp::readMemoryFromProcess(IatAddressVA, IatSize, iatBackup))
{
free(iatBackup);
iatBackup = 0;
return 0;
}
}
for (int i = 0; i < ((int)IatSize / (int)sizeof(DWORD_PTR));i++)
{
if (iatBackup[i] == addr)
{
return (DWORD_PTR)&iatBackup[i] - (DWORD_PTR)iatBackup + IatAddressVA;
}
}
return 0;
}
void IATReferenceScan::patchNewIat(DWORD_PTR stdImagebase, DWORD_PTR newIatBaseAddress, PeParser * peParser)
{
NewIatAddressRVA = newIatBaseAddress;
DWORD patchBytes = 0;
for (std::vector<IATReference>::iterator iter = iatReferenceList.begin(); iter != iatReferenceList.end(); iter++)
{
IATReference * ref = &(*iter);
DWORD_PTR newIatAddressPointer = (ref->targetPointer - IatAddressVA) + NewIatAddressRVA + stdImagebase;
#ifdef _WIN64
patchBytes = (DWORD)(newIatAddressPointer - (ref->addressVA - ImageBase + stdImagebase) - 6);
#else
patchBytes = newIatAddressPointer;
#endif
DWORD_PTR patchOffset = peParser->convertRVAToOffsetRelative(ref->addressVA - ImageBase);
int index = peParser->convertRVAToOffsetVectorIndex(ref->addressVA - ImageBase);
BYTE * memory = peParser->getSectionMemoryByIndex(index);
DWORD memorySize = peParser->getSectionMemorySizeByIndex(index);
if (memorySize < (DWORD)(patchOffset + 6))
{
Scylla::debugLog.log(L"Error - Cannot fix IAT reference RVA: " PRINTF_DWORD_PTR_FULL, ref->addressVA - ImageBase);
}
else
{
memory += patchOffset + 2;
*((DWORD *)memory) = patchBytes;
}
//Scylla::debugLog.log(L"address %X old %X new %X",ref->addressVA, ref->targetPointer, newIatAddressPointer);
}
}
void IATReferenceScan::printDirectImportLog()
{
IATReferenceScan::directImportLog.log(L"------------------------------------------------------------");
IATReferenceScan::directImportLog.log(L"ImageBase " PRINTF_DWORD_PTR_FULL L" ImageSize %08X IATAddress " PRINTF_DWORD_PTR_FULL L" IATSize 0x%X", ImageBase, ImageSize, IatAddressVA, IatSize);
int count = 0;
bool isSuspect = false;
for (std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference * ref = &(*iter);
ApiInfo * apiInfo = apiReader->getApiByVirtualAddress(ref->targetAddressInIat, &isSuspect);
count++;
WCHAR * type = L"U";
if (ref->type == IAT_REFERENCE_DIRECT_CALL)
{
type = L"CALL";
}
else if (ref->type == IAT_REFERENCE_DIRECT_JMP)
{
type = L"JMP";
}
else if (ref->type == IAT_REFERENCE_DIRECT_MOV)
{
type = L"MOV";
}
else if (ref->type == IAT_REFERENCE_DIRECT_PUSH)
{
type = L"PUSH";
}
else if (ref->type == IAT_REFERENCE_DIRECT_LEA)
{
type = L"LEA";
}
IATReferenceScan::directImportLog.log(L"%04d AddrVA " PRINTF_DWORD_PTR_FULL L" Type %s Value " PRINTF_DWORD_PTR_FULL L" IatRefPointer " PRINTF_DWORD_PTR_FULL L" Api %s %S", count, ref->addressVA, type, ref->targetAddressInIat, ref->targetPointer,apiInfo->module->getFilename(), apiInfo->name);
}
IATReferenceScan::directImportLog.log(L"------------------------------------------------------------");
}
void IATReferenceScan::findDirectIatReferenceCallJmp( _DInst * instruction )
{
IATReference ref;
if (META_GET_FC(instruction->meta) == FC_CALL || META_GET_FC(instruction->meta) == FC_UNC_BRANCH)
{
if ((instruction->size >= 5) && (instruction->ops[0].type == O_PC)) //CALL/JMP 0x00000000
{
if (META_GET_FC(instruction->meta) == FC_CALL)
{
ref.type = IAT_REFERENCE_DIRECT_CALL;
}
else
{
ref.type = IAT_REFERENCE_DIRECT_JMP;
}
ref.targetAddressInIat = (DWORD_PTR)INSTRUCTION_GET_TARGET(instruction);
checkMemoryRangeAndAddToList(&ref, instruction);
}
}
}
void IATReferenceScan::findDirectIatReferenceMov( _DInst * instruction )
{
IATReference ref;
ref.type = IAT_REFERENCE_DIRECT_MOV;
if (instruction->opcode == I_MOV)
{
#ifdef _WIN64
if (instruction->size >= 7) //MOV REGISTER, 0xFFFFFFFFFFFFFFFF
#else
if (instruction->size >= 5) //MOV REGISTER, 0xFFFFFFFF
#endif
{
if (instruction->ops[0].type == O_REG && instruction->ops[1].type == O_IMM)
{
ref.targetAddressInIat = (DWORD_PTR)instruction->imm.qword;
checkMemoryRangeAndAddToList(&ref, instruction);
}
}
}
}
void IATReferenceScan::findDirectIatReferencePush( _DInst * instruction )
{
IATReference ref;
ref.type = IAT_REFERENCE_DIRECT_PUSH;
if (instruction->size >= 5 && instruction->opcode == I_PUSH)
{
ref.targetAddressInIat = (DWORD_PTR)instruction->imm.qword;
checkMemoryRangeAndAddToList(&ref, instruction);
}
}
void IATReferenceScan::findDirectIatReferenceLea( _DInst * instruction )
{
IATReference ref;
ref.type = IAT_REFERENCE_DIRECT_LEA;
if (instruction->size >= 5 && instruction->opcode == I_LEA)
{
if (instruction->ops[0].type == O_REG && instruction->ops[1].type == O_DISP) //LEA EDX, [0xb58bb8]
{
ref.targetAddressInIat = (DWORD_PTR)instruction->disp;
checkMemoryRangeAndAddToList(&ref, instruction);
}
}
}
void IATReferenceScan::checkMemoryRangeAndAddToList( IATReference * ref, _DInst * instruction )
{
#ifdef DEBUG_COMMENTS
_DecodedInst inst;
#endif
if (ref->targetAddressInIat > 0x000FFFFF && ref->targetAddressInIat != (DWORD_PTR)-1)
{
if ((ref->targetAddressInIat < ImageBase) || (ref->targetAddressInIat > (ImageBase+ImageSize))) //outside pe image
{
//if (isAddressValidImageMemory(ref->targetAddressInIat))
{
bool isSuspect = false;
if (apiReader->getApiByVirtualAddress(ref->targetAddressInIat, &isSuspect) != 0)
{
ref->addressVA = (DWORD_PTR)instruction->addr;
ref->instructionSize = instruction->size;
ref->targetPointer = lookUpIatForPointer(ref->targetAddressInIat);
#ifdef DEBUG_COMMENTS
distorm_format(&ProcessAccessHelp::decomposerCi, instruction, &inst);
Scylla::debugLog.log(PRINTF_DWORD_PTR_FULL L" " PRINTF_DWORD_PTR_FULL L" %S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL,(DWORD_PTR)instruction->addr, ImageBase, inst.mnemonic.p, inst.operands.p, instruction->ops[0].type, instruction->size, ref->targetAddressInIat);
#endif
iatDirectImportList.push_back(*ref);
}
}
}
}
}
void IATReferenceScan::patchDirectJumpTableEntry(DWORD_PTR targetIatPointer, DWORD_PTR stdImagebase, DWORD directImportsJumpTableRVA, PeParser * peParser, BYTE * jmpTableMemory, DWORD newIatBase )
{
DWORD patchBytes = 0;
for (std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference * ref = &(*iter);
//only one jmp in table for different direct imports with same iat address
if (ref->targetPointer == targetIatPointer)
{
//patch dump
DWORD patchOffset = (DWORD)peParser->convertRVAToOffsetRelative(ref->addressVA - ImageBase);
int index = peParser->convertRVAToOffsetVectorIndex(ref->addressVA - ImageBase);
BYTE * memory = peParser->getSectionMemoryByIndex(index);
DWORD memorySize = peParser->getSectionMemorySizeByIndex(index);
DWORD sectionRVA = peParser->getSectionAddressRVAByIndex(index);
if (ref->type == IAT_REFERENCE_DIRECT_CALL || ref->type == IAT_REFERENCE_DIRECT_JMP)
{
#ifndef _WIN64
if (ref->instructionSize == 5)
{
patchBytes = directImportsJumpTableRVA - (ref->addressVA - ImageBase) - 5;
patchDirectImportInDump32(1, 5, patchBytes, memory, memorySize, false, patchOffset, sectionRVA);
}
#endif
}
else if (ref->type == IAT_REFERENCE_DIRECT_PUSH || ref->type == IAT_REFERENCE_DIRECT_MOV)
{
#ifndef _WIN64
if (ref->instructionSize == 5) //for x86
{
patchBytes = directImportsJumpTableRVA + stdImagebase;
patchDirectImportInDump32(1, 5, patchBytes, memory, memorySize, true, patchOffset, sectionRVA);
}
#else
if (ref->instructionSize == 10) //for x64
{
DWORD_PTR patchBytes64 = directImportsJumpTableRVA + stdImagebase;
patchDirectImportInDump64(2, 10, patchBytes64, memory, memorySize, true, patchOffset, sectionRVA);
}
#endif
}
else if (ref->type == IAT_REFERENCE_DIRECT_LEA)
{
#ifndef _WIN64
if (ref->instructionSize == 6)
{
patchBytes = directImportsJumpTableRVA + stdImagebase;
patchDirectImportInDump32(2, 6, patchBytes, memory, memorySize, true, patchOffset, sectionRVA);
}
#endif
}
}
}
}
void IATReferenceScan::patchDirectJumpTable( DWORD_PTR stdImagebase, DWORD directImportsJumpTableRVA, PeParser * peParser, BYTE * jmpTableMemory, DWORD newIatBase )
{
std::set<DWORD_PTR> apiPointers;
for (std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference * ref = &(*iter);
apiPointers.insert(ref->targetPointer);
}
DWORD patchBytes;
for (std::set<DWORD_PTR>::iterator apiIter = apiPointers.begin(); apiIter != apiPointers.end(); apiIter++)
{
DWORD_PTR refTargetPointer = *apiIter;
if (newIatBase) //create new iat in section
{
refTargetPointer = (*apiIter - IatAddressVA) + newIatBase + ImageBase;
}
//create jump table in section
DWORD_PTR newIatAddressPointer = refTargetPointer - ImageBase + stdImagebase;
#ifdef _WIN64
patchBytes = (DWORD)(newIatAddressPointer - (directImportsJumpTableRVA + stdImagebase) - 6);
#else
- patchBytes = newIatAddressPointer; //dont forget relocation here
- directImportLog.log(L"Relocation direct imports fix: Base RVA %08X Offset %04X Type IMAGE_REL_BASED_HIGHLOW", (directImportsJumpTableRVA + 2) & 0xFFFFF000, (directImportsJumpTableRVA + 2) & 0x00000FFF);
+ patchBytes = newIatAddressPointer;
+ DWORD relocOffset = (directImportsJumpTableRVA + 2);
+ directImportLog.log(L"Relocation direct imports fix: Base RVA %08X Type HIGHLOW Offset %04X RelocTableEntry %04X", relocOffset & 0xFFFFF000, relocOffset & 0x00000FFF, (IMAGE_REL_BASED_HIGHLOW << 12) + (relocOffset & 0x00000FFF));
#endif
jmpTableMemory[0] = 0xFF;
jmpTableMemory[1] = 0x25;
*((DWORD *)&jmpTableMemory[2]) = patchBytes;
patchDirectJumpTableEntry(*apiIter, stdImagebase, directImportsJumpTableRVA, peParser, jmpTableMemory, newIatBase);
jmpTableMemory += 6;
directImportsJumpTableRVA += 6;
}
-
-
-
}
void IATReferenceScan::patchDirectImportInDump32( int patchPreFixBytes, int instructionSize, DWORD patchBytes, BYTE * memory, DWORD memorySize, bool generateReloc, DWORD patchOffset, DWORD sectionRVA )
{
if (memorySize < (DWORD)(patchOffset + instructionSize))
{
Scylla::debugLog.log(L"Error - Cannot fix direct import reference RVA: %X", sectionRVA + patchOffset);
}
else
{
memory += patchOffset + patchPreFixBytes;
if (generateReloc)
{
- directImportLog.log(L"Relocation direct imports fix: Base RVA %08X Offset %04X Type IMAGE_REL_BASED_HIGHLOW", (sectionRVA + patchOffset + patchPreFixBytes) & 0xFFFFF000, (sectionRVA + patchOffset+ patchPreFixBytes) & 0x00000FFF);
+ DWORD relocOffset = sectionRVA + patchOffset+ patchPreFixBytes;
+ directImportLog.log(L"Relocation direct imports fix: Base RVA %08X Type HIGHLOW Offset %04X RelocTableEntry %04X", relocOffset & 0xFFFFF000, relocOffset & 0x00000FFF, (IMAGE_REL_BASED_HIGHLOW << 12) + (relocOffset & 0x00000FFF));
}
*((DWORD *)memory) = patchBytes;
}
}
void IATReferenceScan::patchDirectImportInDump64( int patchPreFixBytes, int instructionSize, DWORD_PTR patchBytes, BYTE * memory, DWORD memorySize, bool generateReloc, DWORD patchOffset, DWORD sectionRVA )
{
if (memorySize < (DWORD)(patchOffset + instructionSize))
{
Scylla::debugLog.log(L"Error - Cannot fix direct import reference RVA: %X", sectionRVA + patchOffset);
}
else
{
memory += patchOffset + patchPreFixBytes;
if (generateReloc)
{
- directImportLog.log(L"Relocation direct imports fix: Base RVA %08X Offset %04X Type IMAGE_REL_BASED_DIR64", (sectionRVA + patchOffset + patchPreFixBytes) & 0xFFFFF000, (sectionRVA + patchOffset+ patchPreFixBytes) & 0x00000FFF);
+ DWORD relocOffset = sectionRVA + patchOffset+ patchPreFixBytes;
+ directImportLog.log(L"Relocation direct imports fix: Base RVA %08X Type DIR64 Offset %04X RelocTableEntry %04X", relocOffset & 0xFFFFF000, relocOffset & 0x00000FFF, (IMAGE_REL_BASED_DIR64 << 12) + (relocOffset & 0x00000FFF));
}
*((DWORD_PTR *)memory) = patchBytes;
}
}
DWORD IATReferenceScan::addAdditionalApisToList()
{
std::set<DWORD_PTR> apiPointers;
for (std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference * ref = &(*iter);
if (ref->targetPointer == 0)
{
apiPointers.insert(ref->targetAddressInIat);
}
}
DWORD_PTR iatAddy = IatAddressVA + IatSize;
DWORD newIatSize = IatSize;
bool isSuspect = false;
for (std::set<DWORD_PTR>::iterator apiIter = apiPointers.begin(); apiIter != apiPointers.end(); apiIter++)
{
for (std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference * ref = &(*iter);
if (ref->targetPointer == 0 && ref->targetAddressInIat == *apiIter)
{
ref->targetPointer = iatAddy;
ApiInfo * apiInfo = apiReader->getApiByVirtualAddress(ref->targetAddressInIat, &isSuspect);
apiReader->addFoundApiToModuleList(iatAddy, apiInfo, true, isSuspect);
}
}
iatAddy += sizeof(DWORD_PTR);
newIatSize += sizeof(DWORD_PTR);
}
return newIatSize;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, May 27, 3:08 AM (1 d, 9 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
f5/12/5f8913a0291264cefc149343681c
Attached To
rSCY Scylla
Event Timeline
Log In to Comment