diff --git a/Scylla/IATReferenceScan.cpp b/Scylla/IATReferenceScan.cpp index 1a5ad03..b6763c7 100644 --- a/Scylla/IATReferenceScan.cpp +++ b/Scylla/IATReferenceScan.cpp @@ -1,437 +1,464 @@ #include "IATReferenceScan.h" #include "Scylla.h" #include "Architecture.h" //#define DEBUG_COMMENTS int IATReferenceScan::numberOfFoundDirectImports() { return (int)iatDirectImportList.size(); } 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; iatReferenceList.clear(); iatDirectImportList.clear(); iatReferenceList.reserve(200); 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::iterator iter = iatReferenceList.begin(); iter != iatReferenceList.end(); iter++) // { // patchReferenceInMemory(&(*iter)); // } //} // //void IATReferenceScan::patchNewIatBaseFile(DWORD_PTR newIatBaseAddress) //{ // NewIatAddressVA = newIatBaseAddress; // // for (std::vector::iterator iter = iatReferenceList.begin(); iter != iatReferenceList.end(); iter++) // { // patchReferenceInFile(&(*iter)); // } //} void IATReferenceScan::patchDirectImportsMemory() { for (std::vector::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) { - findDirectIatReference(instruction); + findDirectIatReferenceCallJmp(instruction); + findDirectIatReferenceMov(instruction); } } 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; #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; } } -void IATReferenceScan::findDirectIatReference( _DInst * instruction ) +void IATReferenceScan::findDirectIatReferenceCallJmp( _DInst * instruction ) { #ifdef DEBUG_COMMENTS _DecodedInst inst; #endif IATReference ref; ref.targetPointer = 0; 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.addressVA = (DWORD_PTR)instruction->addr; ref.targetAddressInIat = (DWORD_PTR)INSTRUCTION_GET_TARGET(instruction); if ((ref.targetAddressInIat < ImageBase) || (ref.targetAddressInIat > (ImageBase+ImageSize))) //call/JMP outside pe image { - if (isAddressValidMemory(ref.targetAddressInIat)) + if (isAddressValidImageMemory(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, INSTRUCTION_GET_TARGET(instruction)); #endif iatDirectImportList.push_back(ref); } } } } } -bool IATReferenceScan::isAddressValidMemory( DWORD_PTR address ) +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); + 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::patchReferenceInFile( IATReference * ref ) -{ - DWORD_PTR newIatAddressPointer = (ref->targetPointer - IatAddressVA) + NewIatAddressRVA + standardImageBase; - - DWORD patchBytes = 0; - -#ifdef _WIN64 - patchBytes = (DWORD)(newIatAddressPointer - (ref->addressVA - ImageBase + standardImageBase) - 6); -#else - patchBytes = newIatAddressPointer; -#endif - - -} - void IATReferenceScan::patchDirectImportInMemory( IATReference * ref ) { DWORD patchBytes = 0; BYTE patchPreBytes[2]; ref->targetPointer = lookUpIatForPointer(ref->targetAddressInIat); 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; } 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::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 + standardImageBase) - 6); + 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); - Scylla::debugLog.log(L"address %X old %X new %X",ref->addressVA, ref->targetPointer, newIatAddressPointer); + 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::findDirectIatReferenceMov( _DInst * instruction ) +{ +#ifdef DEBUG_COMMENTS + _DecodedInst inst; +#endif + + IATReference ref; + ref.targetPointer = 0; + ref.type = IAT_REFERENCE_DIRECT_MOV; - memory += patchOffset + 2; - //Scylla::debugLog.log(L"%X %X %X %X %X %X",memory[0],memory[1],memory[2],memory[3],memory[4],memory[5] ); - + if (instruction->size >= 5 && instruction->opcode == I_MOV) + { + //MOV REGISTER, 0xFFFFFFFF + if (instruction->ops[0].type == O_REG && instruction->ops[1].type == O_IMM) + { + ref.targetAddressInIat = (DWORD_PTR)instruction->imm.qword; + ref.addressVA = (DWORD_PTR)instruction->addr; - *((DWORD *)memory) = patchBytes; + if (ref.targetAddressInIat > 0x000FFFFF && ref.targetAddressInIat != (DWORD_PTR)-1) + { + if ((ref.targetAddressInIat < ImageBase) || (ref.targetAddressInIat > (ImageBase+ImageSize))) + { + if (isAddressValidImageMemory(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, INSTRUCTION_GET_TARGET(instruction)); +#endif + iatDirectImportList.push_back(ref); + } + } + } + } } -} \ No newline at end of file +} diff --git a/Scylla/IATReferenceScan.h b/Scylla/IATReferenceScan.h index 4d3c8a2..1c1d746 100644 --- a/Scylla/IATReferenceScan.h +++ b/Scylla/IATReferenceScan.h @@ -1,103 +1,104 @@ #pragma once #include #include "ProcessAccessHelp.h" #include "PeParser.h" enum IATReferenceType { IAT_REFERENCE_PTR_JMP, IAT_REFERENCE_PTR_CALL, IAT_REFERENCE_DIRECT_JMP, - IAT_REFERENCE_DIRECT_CALL + IAT_REFERENCE_DIRECT_CALL, + IAT_REFERENCE_DIRECT_MOV }; class IATReference { public: DWORD_PTR addressVA; //Address of reference DWORD_PTR targetPointer; //Place inside IAT DWORD_PTR targetAddressInIat; //WIN API? IATReferenceType type; }; class IATReferenceScan { public: IATReferenceScan() { IatAddressVA = 0; IatSize = 0; ImageBase = 0; ImageSize = 0; iatBackup = 0; ScanForDirectImports = false; ScanForNormalImports = true; } ~IATReferenceScan() { iatReferenceList.clear(); iatDirectImportList.clear(); if (iatBackup) { free(iatBackup); } } bool ScanForDirectImports; bool ScanForNormalImports; void startScan(DWORD_PTR imageBase, DWORD imageSize, DWORD_PTR iatAddress, DWORD iatSize); //void patchNewIatBaseMemory(DWORD_PTR newIatBaseAddress); //void patchNewIatBaseFile(DWORD_PTR newIatBaseAddress); void patchNewIat(DWORD_PTR stdImagebase, DWORD_PTR newIatBaseAddress, PeParser * peParser); void patchDirectImportsMemory(); int numberOfFoundDirectImports(); private: DWORD_PTR NewIatAddressRVA; DWORD_PTR IatAddressVA; DWORD IatSize; DWORD_PTR ImageBase; DWORD ImageSize; - DWORD_PTR standardImageBase; DWORD_PTR * iatBackup; std::vector iatReferenceList; std::vector iatDirectImportList; bool isPageExecutable( DWORD Protect ); void scanMemoryPage( PVOID BaseAddress, SIZE_T RegionSize ); void analyzeInstruction( _DInst * instruction ); void findNormalIatReference( _DInst * instruction ); void getIatEntryAddress( IATReference* ref ); - void findDirectIatReference( _DInst * instruction ); - bool isAddressValidMemory( DWORD_PTR address ); + void findDirectIatReferenceCallJmp( _DInst * instruction ); + bool isAddressValidImageMemory( DWORD_PTR address ); void patchReferenceInMemory( IATReference * ref ); void patchReferenceInFile( IATReference* ref ); void patchDirectImportInMemory( IATReference * iter ); DWORD_PTR lookUpIatForPointer( DWORD_PTR addr ); + void findDirectIatReferenceMov( _DInst * instruction ); }; /* PE64 ---------- 000000013FF82D87 FF15 137C0A00 CALL QWORD [RIP+0xA7C13] Result: 000000014002A9A0 000000013F65C952 FF25 F8EA0B00 JMP QWORD [RIP+0xBEAF8] Result: 000000013F71B450 PE32 ---------- 0120FFA5 FF15 8C6D2601 CALL DWORD [0x01266D8C] 0120FF52 FF25 D4722601 JMP DWORD [0x012672D4] */ diff --git a/Scylla/ProcessAccessHelp.h b/Scylla/ProcessAccessHelp.h index 0c1d9db..2f309ec 100644 --- a/Scylla/ProcessAccessHelp.h +++ b/Scylla/ProcessAccessHelp.h @@ -1,226 +1,227 @@ #pragma once #include #include #include /************************************************************************/ /* distorm */ /************************************************************************/ #include +#include // The number of the array of instructions the decoder function will use to return the disassembled instructions. // Play with this value for performance... #define MAX_INSTRUCTIONS (200) /************************************************************************/ class ApiInfo; class ModuleInfo { public: WCHAR fullPath[MAX_PATH]; DWORD_PTR modBaseAddr; DWORD modBaseSize; bool isAlreadyParsed; bool parsing; /* for iat rebuilding with duplicate entries: ntdll = low priority kernelbase = low priority SHLWAPI = low priority kernel32 = high priority priority = 1 -> normal/high priority priority = 0 -> low priority */ int priority; std::vector apiList; ModuleInfo() { modBaseAddr = 0; modBaseSize = 0; priority = 1; isAlreadyParsed = false; parsing = false; } const WCHAR * getFilename() const { const WCHAR* slash = wcsrchr(fullPath, L'\\'); if(slash) { return slash+1; } return fullPath; } }; class ApiInfo { public: char name[MAX_PATH]; WORD hint; DWORD_PTR va; DWORD_PTR rva; WORD ordinal; bool isForwarded; ModuleInfo * module; }; class ProcessAccessHelp { public: static HANDLE hProcess; //OpenProcess handle to target process static DWORD_PTR targetImageBase; static DWORD_PTR targetSizeOfImage; static DWORD_PTR maxValidAddress; static ModuleInfo * selectedModule; static std::vector moduleList; //target process module list static std::vector ownModuleList; //own module list static const size_t PE_HEADER_BYTES_COUNT = 2000; static BYTE fileHeaderFromDisk[PE_HEADER_BYTES_COUNT]; //for decomposer static _DInst decomposerResult[MAX_INSTRUCTIONS]; static unsigned int decomposerInstructionsCount; static _CodeInfo decomposerCi; //distorm :: Decoded instruction information. static _DecodedInst decodedInstructions[MAX_INSTRUCTIONS]; static unsigned int decodedInstructionsCount; #ifdef _WIN64 static const _DecodeType dt = Decode64Bits; #else static const _DecodeType dt = Decode32Bits; #endif /* * Open a new process handle */ static bool openProcessHandle(DWORD dwPID); static HANDLE NativeOpenProcess(DWORD dwDesiredAccess, DWORD dwProcessId); static void closeProcessHandle(); /* * Get all modules from a process */ static bool getProcessModules(DWORD dwPID, std::vector &moduleList); /* * file mapping view with different access level */ static LPVOID createFileMappingViewRead(const WCHAR * filePath); static LPVOID createFileMappingViewFull(const WCHAR * filePath); /* * Create a file mapping view of a file */ static LPVOID createFileMappingView(const WCHAR * filePath, DWORD accessFile, DWORD flProtect, DWORD accessMap); /* * Read memory from target process */ static bool readMemoryFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer); static bool writeMemoryToProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer); /* * Read memory from target process and ignore no data pages */ static bool readMemoryPartlyFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer); /* * Read memory from file */ static bool readMemoryFromFile(HANDLE hFile, LONG offset, DWORD size, LPVOID dataBuffer); /* * Write memory to file */ static bool writeMemoryToFile(HANDLE hFile, LONG offset, DWORD size, LPCVOID dataBuffer); /* * Write memory to new file */ static bool writeMemoryToNewFile(const WCHAR * file,DWORD size, LPCVOID dataBuffer); /* * Write memory to file end */ static bool writeMemoryToFileEnd(HANDLE hFile, DWORD size, LPCVOID dataBuffer); /* * Disassemble Memory */ static bool disassembleMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startOffset); static bool decomposeMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startAddress); /* * Search for pattern */ static DWORD_PTR findPattern(DWORD_PTR startOffset, DWORD size, BYTE * pattern, const char * mask); /* * Get process ID by process name */ static DWORD getProcessByName(const WCHAR * processName); /* * Get memory region from address */ static bool getMemoryRegionFromAddress(DWORD_PTR address, DWORD_PTR * memoryRegionBase, SIZE_T * memoryRegionSize); /* * Read PE Header from file */ static bool readHeaderFromFile(BYTE * buffer, DWORD bufferSize, const WCHAR * filePath); static bool readHeaderFromCurrentFile(const WCHAR * filePath); /* * Get real sizeOfImage value */ static SIZE_T getSizeOfImageProcess(HANDLE processHandle, DWORD_PTR moduleBase); /* * Get real sizeOfImage value current process */ static bool getSizeOfImageCurrentProcess(); static LONGLONG getFileSize(HANDLE hFile); static LONGLONG getFileSize(const WCHAR * filePath); static DWORD getEntryPointFromFile(const WCHAR * filePath); static bool createBackupFile(const WCHAR * filePath); static DWORD getModuleHandlesFromProcess(const HANDLE hProcess, HMODULE ** hMods ); static void setCurrentProcessAsTarget(); static bool suspendProcess(); static bool resumeProcess(); static bool terminateProcess(); };