diff --git a/Scylla/DumpMemoryGui.cpp b/Scylla/DumpMemoryGui.cpp index dde9712..a3c3e7d 100644 --- a/Scylla/DumpMemoryGui.cpp +++ b/Scylla/DumpMemoryGui.cpp @@ -1,547 +1,552 @@ #include "DumpMemoryGui.h" #include "Architecture.h" #include "ProcessAccessHelp.h" #include #include "PeParser.h" WCHAR DumpMemoryGui::protectionString[100]; const WCHAR DumpMemoryGui::MemoryUndefined[] = L"UNDEF"; const WCHAR DumpMemoryGui::MemoryUnknown[] = L"UNKNOWN"; const WCHAR * DumpMemoryGui::MemoryStateValues[] = {L"COMMIT",L"FREE",L"RESERVE"}; const WCHAR * DumpMemoryGui::MemoryTypeValues[] = {L"IMAGE",L"MAPPED",L"PRIVATE"}; const WCHAR * DumpMemoryGui::MemoryProtectionValues[] = {L"EXECUTE",L"EXECUTE_READ",L"EXECUTE_READWRITE",L"EXECUTE_WRITECOPY",L"NOACCESS",L"READONLY",L"READWRITE",L"WRITECOPY",L"GUARD",L"NOCACHE",L"WRITECOMBINE"}; DumpMemoryGui::DumpMemoryGui() { dumpedMemory = 0; dumpedMemorySize = 0; deviceNameResolver = new DeviceNameResolver(); } DumpMemoryGui::~DumpMemoryGui() { if (dumpedMemory) { delete [] dumpedMemory; } if (deviceNameResolver) { delete deviceNameResolver; } memoryList.clear(); } BOOL DumpMemoryGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam) { DoDataExchange(); // attach controls DlgResize_Init(true, true); addColumnsToMemoryList(ListMemorySelect); displayMemoryList(ListMemorySelect); forceDump = false; DoDataExchange(DDX_LOAD); EditMemoryAddress.SetValue(ProcessAccessHelp::targetImageBase); EditMemorySize.SetValue((DWORD)ProcessAccessHelp::targetSizeOfImage); CenterWindow(); return TRUE; } void DumpMemoryGui::addColumnsToMemoryList(CListViewCtrl& list) { list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); list.InsertColumn(COL_ADDRESS, L"Address", LVCFMT_CENTER); list.InsertColumn(COL_SIZE, L"Size", LVCFMT_CENTER); list.InsertColumn(COL_FILENAME, L"File", LVCFMT_LEFT); list.InsertColumn(COL_PESECTION, L"PE Section", LVCFMT_LEFT); list.InsertColumn(COL_TYPE, L"Type", LVCFMT_CENTER); list.InsertColumn(COL_PROTECTION, L"Protection", LVCFMT_CENTER); list.InsertColumn(COL_STATE, L"State", LVCFMT_CENTER); list.InsertColumn(COL_MAPPED_FILE, L"Mapped File", LVCFMT_LEFT); } void DumpMemoryGui::displayMemoryList(CListViewCtrl& list) { int count = 0; WCHAR temp[20]; list.DeleteAllItems(); getMemoryList(); std::vector::const_iterator iter; for( iter = memoryList.begin(); iter != memoryList.end(); iter++ , count++) { swprintf_s(temp, PRINTF_DWORD_PTR_FULL, iter->address); list.InsertItem(count,temp); swprintf_s(temp, L"%08X", iter->size); list.SetItemText(count, COL_SIZE, temp); list.SetItemText(count, COL_FILENAME, iter->filename); list.SetItemText(count, COL_PESECTION, iter->peSection); if (iter->state == MEM_FREE) { list.SetItemText(count, COL_TYPE, MemoryUndefined); } else { list.SetItemText(count, COL_TYPE, getMemoryTypeString(iter->type)); } if ( (iter->state == MEM_RESERVE) || (iter->state == MEM_FREE) ) { list.SetItemText(count, COL_PROTECTION, MemoryUndefined); } else { list.SetItemText(count, COL_PROTECTION, getMemoryProtectionString(iter->protect)); } list.SetItemText(count, COL_STATE, getMemoryStateString(iter->state)); list.SetItemText(count, COL_MAPPED_FILE, iter->mappedFilename); list.SetItemData(count, (DWORD_PTR)&(*iter)); } list.SetColumnWidth(COL_ADDRESS, LVSCW_AUTOSIZE_USEHEADER); list.SetColumnWidth(COL_SIZE, LVSCW_AUTOSIZE_USEHEADER); list.SetColumnWidth(COL_FILENAME, LVSCW_AUTOSIZE_USEHEADER); list.SetColumnWidth(COL_PESECTION, LVSCW_AUTOSIZE_USEHEADER); list.SetColumnWidth(COL_TYPE, LVSCW_AUTOSIZE_USEHEADER); list.SetColumnWidth(COL_PROTECTION, LVSCW_AUTOSIZE_USEHEADER); list.SetColumnWidth(COL_STATE, LVSCW_AUTOSIZE_USEHEADER); list.SetColumnWidth(COL_MAPPED_FILE, LVSCW_AUTOSIZE_USEHEADER); } const WCHAR * DumpMemoryGui::getMemoryTypeString(DWORD value) { switch(value) { case MEM_IMAGE: return MemoryTypeValues[TYPE_IMAGE]; case MEM_MAPPED: return MemoryTypeValues[TYPE_MAPPED]; case MEM_PRIVATE: return MemoryTypeValues[TYPE_PRIVATE]; default: return MemoryUnknown; } } const WCHAR * DumpMemoryGui::getMemoryStateString(DWORD value) { switch(value) { case MEM_COMMIT: return MemoryStateValues[STATE_COMMIT]; case MEM_FREE: return MemoryStateValues[STATE_FREE]; case MEM_RESERVE: return MemoryStateValues[STATE_RESERVE]; default: return MemoryUnknown; } } WCHAR * DumpMemoryGui::getMemoryProtectionString(DWORD value) { protectionString[0] = 0; if (value & PAGE_GUARD) { wcscpy_s(protectionString, MemoryProtectionValues[PROT_GUARD]); wcscat_s(protectionString, L" | "); value ^= PAGE_GUARD; } if (value & PAGE_NOCACHE) { wcscpy_s(protectionString, MemoryProtectionValues[PROT_NOCACHE]); wcscat_s(protectionString, L" | "); value ^= PAGE_NOCACHE; } if (value & PAGE_WRITECOMBINE) { wcscpy_s(protectionString, MemoryProtectionValues[PROT_WRITECOMBINE]); wcscat_s(protectionString, L" | "); value ^= PAGE_WRITECOMBINE; } switch(value) { case PAGE_EXECUTE: { wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE]); break; } case PAGE_EXECUTE_READ: { wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE_READ]); break; } case PAGE_EXECUTE_READWRITE: { wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE_READWRITE]); break; } case PAGE_EXECUTE_WRITECOPY: { wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE_WRITECOPY]); break; } case PAGE_NOACCESS: { wcscat_s(protectionString, MemoryProtectionValues[PROT_NOACCESS]); break; } case PAGE_READONLY: { wcscat_s(protectionString, MemoryProtectionValues[PROT_READONLY]); break; } case PAGE_READWRITE: { wcscat_s(protectionString, MemoryProtectionValues[PROT_READWRITE]); break; } case PAGE_WRITECOPY: { wcscat_s(protectionString, MemoryProtectionValues[PROT_WRITECOPY]); break; } default: { wcscat_s(protectionString, MemoryUnknown); } } return protectionString; } LRESULT DumpMemoryGui::OnListMemoryColumnClicked(NMHDR* pnmh) { NMLISTVIEW* list = (NMLISTVIEW*)pnmh; int column = list->iSubItem; if(column == prevColumn) { ascending = !ascending; } else { prevColumn = column; ascending = true; } // lo-byte: column, hi-byte: sort-order ListMemorySelect.SortItems(&listviewCompareFunc, MAKEWORD(column, ascending)); return 0; } LRESULT DumpMemoryGui::OnListMemoryClick(NMHDR* pnmh) { int index = ListMemorySelect.GetSelectionMark(); if (index != -1) { selectedMemory = (Memory *)ListMemorySelect.GetItemData(index); if (selectedMemory) { updateAddressAndSize(selectedMemory); } } return 0; } void DumpMemoryGui::OnOK(UINT uNotifyCode, int nID, CWindow wndCtl) { DoDataExchange(DDX_SAVE); if (EditMemoryAddress.GetValue() == 0 || EditMemorySize.GetValue() == 0) { wndCtl.MessageBoxW(L"Textbox is empty!",L"Error",MB_ICONERROR); } else { if (dumpMemory()) { EndDialog(1); } else { wndCtl.MessageBoxW(L"Reading memory from process failed",L"Error",MB_ICONERROR); } } } void DumpMemoryGui::OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl) { EndDialog(0); } void DumpMemoryGui::updateAddressAndSize( Memory * selectedMemory ) { EditMemoryAddress.SetValue(selectedMemory->address); EditMemorySize.SetValue(selectedMemory->size); } int DumpMemoryGui::listviewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { const Memory * module1 = (Memory *)lParam1; const Memory * module2 = (Memory *)lParam2; int column = LOBYTE(lParamSort); bool ascending = (HIBYTE(lParamSort) == TRUE); int diff = 0; switch(column) { case COL_ADDRESS: diff = module1->address < module2->address ? -1 : 1; break; case COL_SIZE: diff = module1->size < module2->size ? -1 : 1; break; case COL_FILENAME: diff = _wcsicmp(module1->filename, module2->filename); break; case COL_PESECTION: diff = _wcsicmp(module1->peSection, module2->peSection); break; case COL_TYPE: diff = module1->type < module2->type ? -1 : 1; break; case COL_PROTECTION: diff = module1->protect < module2->protect ? -1 : 1; break; case COL_STATE: diff = _wcsicmp(getMemoryStateString(module1->state), getMemoryStateString(module2->state)); //diff = module1->state < module2->state ? -1 : 1; break; case COL_MAPPED_FILE: diff = _wcsicmp(module1->mappedFilename, module2->mappedFilename); break; } return ascending ? diff : -diff; } void DumpMemoryGui::getMemoryList() { DWORD_PTR address = 0; MEMORY_BASIC_INFORMATION memBasic = {0}; Memory memory; HMODULE * hMods = 0; WCHAR target[MAX_PATH]; if (memoryList.empty()) { memoryList.reserve(20); } else { memoryList.clear(); } memory.filename[0] = 0; memory.peSection[0] = 0; memory.mappedFilename[0] = 0; while(VirtualQueryEx(ProcessAccessHelp::hProcess,(LPCVOID)address,&memBasic,sizeof(memBasic))) { memory.address = (DWORD_PTR)memBasic.BaseAddress; memory.type = memBasic.Type; memory.state = memBasic.State; memory.size = (DWORD)memBasic.RegionSize; memory.protect = memBasic.Protect; if (memory.type == MEM_MAPPED || memory.type == MEM_IMAGE) { if (!getMappedFilename(&memory)) { memory.mappedFilename[0] = 0; } } memoryList.push_back(memory); memory.mappedFilename[0] = 0; address += memBasic.RegionSize; } DWORD numHandles = ProcessAccessHelp::getModuleHandlesFromProcess(ProcessAccessHelp::hProcess, &hMods); if (numHandles == 0) { return; } for (DWORD i = 0; i < numHandles; i++) { if (GetModuleFileNameExW(ProcessAccessHelp::hProcess, hMods[i], target, _countof(target))) { setModuleName((DWORD_PTR)hMods[i],target); setAllSectionNames((DWORD_PTR)hMods[i],target); } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"getMemoryList :: GetModuleFileNameExW failed 0x%X", GetLastError()); #endif } } delete [] hMods; } void DumpMemoryGui::setSectionName(DWORD_PTR sectionAddress, DWORD sectionSize, const WCHAR * sectionName) { bool found = false; std::vector::const_iterator iter; for( iter = memoryList.begin(); iter != memoryList.end(); iter++) { if (!found) { if ( (iter->address <= sectionAddress) && (sectionAddress < (iter->address + iter->size)) ) { if (wcslen(iter->peSection) == 0) { wcscpy_s((WCHAR *)iter->peSection, _countof(iter->peSection), sectionName); } else { wcscat_s((WCHAR *)iter->peSection, _countof(iter->peSection), L"|"); wcscat_s((WCHAR *)iter->peSection, _countof(iter->peSection), sectionName); } found = true; } } else { if ((sectionSize+sectionAddress) < iter->address) { break; } if (wcslen(iter->peSection) == 0) { wcscpy_s((WCHAR *)iter->peSection, _countof(iter->peSection), sectionName); } else { wcscat_s((WCHAR *)iter->peSection, _countof(iter->peSection), L"|"); wcscat_s((WCHAR *)iter->peSection, _countof(iter->peSection), sectionName); } } } } void DumpMemoryGui::setModuleName(DWORD_PTR moduleBase, const WCHAR * moduleName) { bool found = false; std::vector::const_iterator iter; //get filename const WCHAR* slash = wcsrchr(moduleName, L'\\'); if(slash) { moduleName = slash+1; } for( iter = memoryList.begin(); iter != memoryList.end(); iter++) { if (iter->address == moduleBase) { found = true; } if (found) { if (iter->type == MEM_IMAGE) { wcscpy_s((WCHAR *)iter->filename, MAX_PATH, moduleName); } else { break; } } } } void DumpMemoryGui::setAllSectionNames( DWORD_PTR moduleBase, WCHAR * moduleName ) { WCHAR sectionNameW[IMAGE_SIZEOF_SHORT_NAME + 1] = {0}; PeParser peFile(moduleName); if (peFile.isValidPeFile()) { std::vector & listSectionHeader = peFile.getSectionHeaderList(); for (WORD i = 0; i < peFile.getNumberOfSections(); i++) { peFile.getSectionNameUnicode(i, sectionNameW, _countof(sectionNameW)); setSectionName(moduleBase + listSectionHeader[i].sectionHeader.VirtualAddress, listSectionHeader[i].sectionHeader.Misc.VirtualSize, sectionNameW); } } else { MessageBox(moduleName,L"Not a valid PE -> This should never happen",MB_ICONERROR); } } bool DumpMemoryGui::dumpMemory() { DWORD_PTR address = EditMemoryAddress.GetValue(); dumpedMemorySize = EditMemorySize.GetValue(); swprintf_s(dumpFilename,TEXT("MEM_")TEXT(PRINTF_DWORD_PTR_FULL_S)TEXT("_")TEXT("%08X"),address,dumpedMemorySize); dumpedMemory = new BYTE[dumpedMemorySize]; if (dumpedMemory) { if (forceDump) { return ProcessAccessHelp::readMemoryPartlyFromProcess(address,dumpedMemorySize,dumpedMemory); } else { return ProcessAccessHelp::readMemoryFromProcess(address,dumpedMemorySize,dumpedMemory); } } else { return false; } } bool DumpMemoryGui::getMappedFilename( Memory* memory ) { WCHAR filename[MAX_PATH] = {0}; if (GetMappedFileNameW(ProcessAccessHelp::hProcess, (LPVOID)memory->address, filename, _countof(filename)) > 0) { - return deviceNameResolver->resolveDeviceLongNameToShort(filename, memory->mappedFilename); + if (!deviceNameResolver->resolveDeviceLongNameToShort(filename, memory->mappedFilename)) + { + wcscpy_s(memory->mappedFilename, filename); + } + + return true; } return false; } diff --git a/Scylla/ProcessAccessHelp.cpp b/Scylla/ProcessAccessHelp.cpp index a11048b..8a7a613 100644 --- a/Scylla/ProcessAccessHelp.cpp +++ b/Scylla/ProcessAccessHelp.cpp @@ -1,935 +1,942 @@ #include "ProcessAccessHelp.h" #include "Scylla.h" #include "NativeWinApi.h" #include "PeParser.h" HANDLE ProcessAccessHelp::hProcess = 0; ModuleInfo * ProcessAccessHelp::selectedModule; DWORD_PTR ProcessAccessHelp::targetImageBase = 0; DWORD_PTR ProcessAccessHelp::targetSizeOfImage = 0; DWORD_PTR ProcessAccessHelp::maxValidAddress = 0; std::vector ProcessAccessHelp::moduleList; //target process module list std::vector ProcessAccessHelp::ownModuleList; //own module list _DInst ProcessAccessHelp::decomposerResult[MAX_INSTRUCTIONS]; unsigned int ProcessAccessHelp::decomposerInstructionsCount = 0; _CodeInfo ProcessAccessHelp::decomposerCi = {0}; _DecodedInst ProcessAccessHelp::decodedInstructions[MAX_INSTRUCTIONS]; unsigned int ProcessAccessHelp::decodedInstructionsCount = 0; BYTE ProcessAccessHelp::fileHeaderFromDisk[PE_HEADER_BYTES_COUNT]; //#define DEBUG_COMMENTS bool ProcessAccessHelp::openProcessHandle(DWORD dwPID) { if (dwPID > 0) { if (hProcess) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"openProcessHandle :: There is already a process handle, HANDLE %X", hProcess); #endif return false; } else { //hProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE, 0, dwPID); //if (!NT_SUCCESS(NativeWinApi::NtOpenProcess(&hProcess,PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE,&ObjectAttributes, &cid))) hProcess = NativeOpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_SUSPEND_RESUME|PROCESS_TERMINATE, dwPID); if (hProcess) { return true; } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"openProcessHandle :: Failed to open handle, PID %X", dwPID); #endif return false; } } } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"openProcessHandle :: Wrong PID, PID %X", dwPID); #endif return false; } } HANDLE ProcessAccessHelp::NativeOpenProcess(DWORD dwDesiredAccess, DWORD dwProcessId) { HANDLE hProcess = 0; CLIENT_ID cid = {0}; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS ntStatus = 0; InitializeObjectAttributes(&ObjectAttributes, 0, 0, 0, 0); cid.UniqueProcess = (HANDLE)dwProcessId; ntStatus = NativeWinApi::NtOpenProcess(&hProcess,dwDesiredAccess,&ObjectAttributes, &cid); if (NT_SUCCESS(ntStatus)) { return hProcess; } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"NativeOpenProcess :: Failed to open handle, PID %X Error 0x%X", dwProcessId, NativeWinApi::RtlNtStatusToDosError(ntStatus)); #endif return 0; } } void ProcessAccessHelp::closeProcessHandle() { if (hProcess) { CloseHandle(hProcess); hProcess = 0; } moduleList.clear(); targetImageBase = 0; selectedModule = 0; } bool ProcessAccessHelp::readMemoryPartlyFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer) { DWORD_PTR addressPart = 0; DWORD_PTR readBytes = 0; DWORD_PTR bytesToRead = 0; MEMORY_BASIC_INFORMATION memBasic = {0}; bool returnValue = false; if (!hProcess) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryPartlyFromProcess :: hProcess == NULL"); #endif return returnValue; } if (!readMemoryFromProcess(address, size, dataBuffer)) { addressPart = address; do { if (!VirtualQueryEx(ProcessAccessHelp::hProcess,(LPCVOID)addressPart,&memBasic,sizeof(memBasic))) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryPartlyFromProcess :: Error VirtualQueryEx %X %X err: %u", addressPart,size, GetLastError()); #endif break; } bytesToRead = memBasic.RegionSize; if ( (readBytes+bytesToRead) > size) { bytesToRead = size - readBytes; } if (memBasic.State == MEM_COMMIT) { if (!readMemoryFromProcess(addressPart, bytesToRead, (LPVOID)((DWORD_PTR)dataBuffer + readBytes))) { break; } } else { ZeroMemory((LPVOID)((DWORD_PTR)dataBuffer + readBytes),bytesToRead); } readBytes += bytesToRead; addressPart += memBasic.RegionSize; } while (readBytes < size); if (readBytes == size) { returnValue = true; } } else { returnValue = true; } return returnValue; } bool ProcessAccessHelp::writeMemoryToProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer) { SIZE_T lpNumberOfBytesWritten = 0; if (!hProcess) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryFromProcess :: hProcess == NULL"); #endif return false; } return (WriteProcessMemory(hProcess,(LPVOID)address, dataBuffer, size,&lpNumberOfBytesWritten) != FALSE); } bool ProcessAccessHelp::readMemoryFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer) { SIZE_T lpNumberOfBytesRead = 0; DWORD dwProtect = 0; bool returnValue = false; if (!hProcess) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryFromProcess :: hProcess == NULL"); #endif return returnValue; } if (!ReadProcessMemory(hProcess, (LPVOID)address, dataBuffer, size, &lpNumberOfBytesRead)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory %X %X err: %u", address, size, GetLastError()); #endif if (!VirtualProtectEx(hProcess, (LPVOID)address, size, PAGE_READWRITE, &dwProtect)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryFromProcess :: Error VirtualProtectEx %X %X err: %u", address,size, GetLastError()); #endif returnValue = false; } else { if (!ReadProcessMemory(hProcess, (LPVOID)address, dataBuffer, size, &lpNumberOfBytesRead)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory %X %X err: %u", address, size, GetLastError()); #endif returnValue = false; } else { returnValue = true; } VirtualProtectEx(hProcess, (LPVOID)address, size, dwProtect, &dwProtect); } } else { returnValue = true; } if (returnValue) { if (size != lpNumberOfBytesRead) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory read %d bytes requested %d bytes", lpNumberOfBytesRead, size); #endif returnValue = false; } else { returnValue = true; } } return returnValue; } bool ProcessAccessHelp::decomposeMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startAddress) { ZeroMemory(&decomposerCi, sizeof(_CodeInfo)); decomposerCi.code = dataBuffer; decomposerCi.codeLen = (int)bufferSize; decomposerCi.dt = dt; decomposerCi.codeOffset = startAddress; decomposerInstructionsCount = 0; if (distorm_decompose(&decomposerCi, decomposerResult, sizeof(decomposerResult)/sizeof(decomposerResult[0]), &decomposerInstructionsCount) == DECRES_INPUTERR) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"decomposeMemory :: distorm_decompose == DECRES_INPUTERR"); #endif return false; } else { return true; } } bool ProcessAccessHelp::disassembleMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startOffset) { // Holds the result of the decoding. _DecodeResult res; // next is used for instruction's offset synchronization. // decodedInstructionsCount holds the count of filled instructions' array by the decoder. decodedInstructionsCount = 0; _OffsetType offset = startOffset; res = distorm_decode(offset, dataBuffer, (int)bufferSize, dt, decodedInstructions, MAX_INSTRUCTIONS, &decodedInstructionsCount); /* for (unsigned int i = 0; i < decodedInstructionsCount; i++) { #ifdef SUPPORT_64BIT_OFFSET printf("%0*I64x (%02d) %-24s %s%s%s\n", dt != Decode64Bits ? 8 : 16, decodedInstructions[i].offset, decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p); #else printf("%08x (%02d) %-24s %s%s%s\n", decodedInstructions[i].offset, decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p); #endif }*/ if (res == DECRES_INPUTERR) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"disassembleMemory :: res == DECRES_INPUTERR"); #endif return false; } else if (res == DECRES_SUCCESS) { //printf("disassembleMemory :: res == DECRES_SUCCESS\n"); return true; } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"disassembleMemory :: res == %d", res); #endif return true; //not all instructions fit in buffer } } DWORD_PTR ProcessAccessHelp::findPattern(DWORD_PTR startOffset, DWORD size, BYTE * pattern, const char * mask) { DWORD pos = 0; size_t searchLen = strlen(mask) - 1; for(DWORD_PTR retAddress = startOffset; retAddress < startOffset + size; retAddress++) { if( *(BYTE*)retAddress == pattern[pos] || mask[pos] == '?' ) { if(mask[pos+1] == 0x00) { return (retAddress - searchLen); } pos++; } else { pos = 0; } } return 0; } bool ProcessAccessHelp::readHeaderFromCurrentFile(const WCHAR * filePath) { return readHeaderFromFile(fileHeaderFromDisk, sizeof(fileHeaderFromDisk), filePath); } LONGLONG ProcessAccessHelp::getFileSize(const WCHAR * filePath) { LONGLONG fileSize = 0; HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if (hFile != INVALID_HANDLE_VALUE) { fileSize = getFileSize(hFile); CloseHandle(hFile); } return fileSize; } LONGLONG ProcessAccessHelp::getFileSize(HANDLE hFile) { LARGE_INTEGER lpFileSize = {0}; if ((hFile != INVALID_HANDLE_VALUE) && (hFile != 0)) { if (!GetFileSizeEx(hFile, &lpFileSize)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"ProcessAccessHelp::getFileSize :: GetFileSizeEx failed %u", GetLastError()); #endif return 0; } else { return lpFileSize.QuadPart; } } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"ProcessAccessHelp::getFileSize hFile invalid"); #endif return 0; } } bool ProcessAccessHelp::readMemoryFromFile(HANDLE hFile, LONG offset, DWORD size, LPVOID dataBuffer) { DWORD lpNumberOfBytesRead = 0; DWORD retValue = 0; DWORD dwError = 0; if (hFile != INVALID_HANDLE_VALUE) { retValue = SetFilePointer(hFile, offset, NULL, FILE_BEGIN); dwError = GetLastError(); if ((retValue == INVALID_SET_FILE_POINTER) && (dwError != NO_ERROR)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryFromFile :: SetFilePointer failed error %u", dwError); #endif return false; } else { if (ReadFile(hFile, dataBuffer, size, &lpNumberOfBytesRead, 0)) { return true; } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryFromFile :: ReadFile failed - size %d - error %u", size, GetLastError()); #endif return false; } } } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readMemoryFromFile :: hFile invalid"); #endif return false; } } bool ProcessAccessHelp::writeMemoryToNewFile(const WCHAR * file,DWORD size, LPCVOID dataBuffer) { HANDLE hFile = CreateFile(file, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); if (hFile != INVALID_HANDLE_VALUE) { bool resultValue = writeMemoryToFile(hFile,0,size,dataBuffer); CloseHandle(hFile); return resultValue; } else { return false; } } bool ProcessAccessHelp::writeMemoryToFile(HANDLE hFile, LONG offset, DWORD size, LPCVOID dataBuffer) { DWORD lpNumberOfBytesWritten = 0; DWORD retValue = 0; DWORD dwError = 0; if ((hFile != INVALID_HANDLE_VALUE) && dataBuffer) { retValue = SetFilePointer(hFile, offset, NULL, FILE_BEGIN); dwError = GetLastError(); if ((retValue == INVALID_SET_FILE_POINTER) && (dwError != NO_ERROR)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"writeMemoryToFile :: SetFilePointer failed error %u", dwError); #endif return false; } else { if (WriteFile(hFile, dataBuffer, size, &lpNumberOfBytesWritten, 0)) { return true; } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"writeMemoryToFile :: WriteFile failed - size %d - error %u", size, GetLastError()); #endif return false; } } } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"writeMemoryToFile :: hFile invalid"); #endif return false; } } bool ProcessAccessHelp::writeMemoryToFileEnd(HANDLE hFile, DWORD size, LPCVOID dataBuffer) { DWORD lpNumberOfBytesWritten = 0; DWORD retValue = 0; if ((hFile != INVALID_HANDLE_VALUE) && (hFile != 0)) { SetFilePointer(hFile, 0, 0, FILE_END); if (WriteFile(hFile, dataBuffer, size, &lpNumberOfBytesWritten, 0)) { return true; } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"writeMemoryToFileEnd :: WriteFile failed - size %d - error %u", size, GetLastError()); #endif return false; } } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"writeMemoryToFileEnd :: hFile invalid"); #endif return false; } } bool ProcessAccessHelp::readHeaderFromFile(BYTE * buffer, DWORD bufferSize, const WCHAR * filePath) { DWORD lpNumberOfBytesRead = 0; LONGLONG fileSize = 0; DWORD dwSize = 0; bool returnValue = 0; HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if( hFile == INVALID_HANDLE_VALUE ) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"readHeaderFromFile :: INVALID_HANDLE_VALUE %u", GetLastError()); #endif returnValue = false; } else { fileSize = getFileSize(hFile); if (fileSize > 0) { if (fileSize > bufferSize) { dwSize = bufferSize; } else { dwSize = (DWORD)(fileSize - 1); } returnValue = readMemoryFromFile(hFile, 0, dwSize, buffer); } CloseHandle(hFile); } return returnValue; } LPVOID ProcessAccessHelp::createFileMappingViewRead(const WCHAR * filePath) { return createFileMappingView(filePath, GENERIC_READ, PAGE_READONLY | SEC_IMAGE, FILE_MAP_READ); } LPVOID ProcessAccessHelp::createFileMappingViewFull(const WCHAR * filePath) { return createFileMappingView(filePath, GENERIC_ALL, PAGE_EXECUTE_READWRITE, FILE_MAP_ALL_ACCESS); } LPVOID ProcessAccessHelp::createFileMappingView(const WCHAR * filePath, DWORD accessFile, DWORD flProtect, DWORD accessMap) { HANDLE hFile = CreateFile(filePath, accessFile, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if( hFile == INVALID_HANDLE_VALUE ) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"createFileMappingView :: INVALID_HANDLE_VALUE %u", GetLastError()); #endif return NULL; } HANDLE hMappedFile = CreateFileMapping(hFile, NULL, flProtect, 0, 0, NULL); CloseHandle(hFile); if( hMappedFile == NULL ) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"createFileMappingView :: hMappedFile == NULL"); #endif return NULL; } if (GetLastError() == ERROR_ALREADY_EXISTS) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"createFileMappingView :: GetLastError() == ERROR_ALREADY_EXISTS"); #endif return NULL; } LPVOID addrMappedDll = MapViewOfFile(hMappedFile, accessMap, 0, 0, 0); if( addrMappedDll == NULL ) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"createFileMappingView :: addrMappedDll == NULL"); #endif CloseHandle(hMappedFile); return NULL; } CloseHandle(hMappedFile); return addrMappedDll; } DWORD ProcessAccessHelp::getProcessByName(const WCHAR * processName) { DWORD dwPID = 0; HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32W pe32; pe32.dwSize = sizeof(PROCESSENTRY32W); if( !Process32FirstW( hProcessSnap, &pe32 ) ) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"getProcessByName :: Error getting first Process"); #endif CloseHandle( hProcessSnap ); return 0; } do { if(!_wcsicmp(pe32.szExeFile, processName)) { dwPID = pe32.th32ProcessID; break; } } while(Process32NextW(hProcessSnap, &pe32)); CloseHandle(hProcessSnap); return dwPID; } bool ProcessAccessHelp::getProcessModules(HANDLE hProcess, std::vector &moduleList) { ModuleInfo module; WCHAR filename[MAX_PATH*2] = {0}; DWORD cbNeeded = 0; bool retVal = false; DeviceNameResolver deviceNameResolver; moduleList.reserve(20); EnumProcessModules(hProcess, 0, 0, &cbNeeded); HMODULE* hMods=(HMODULE*)malloc(cbNeeded*sizeof(HMODULE)); if (hMods) { if(EnumProcessModules(hProcess, hMods, cbNeeded, &cbNeeded)) { for(unsigned int i = 1; i < (cbNeeded/sizeof(HMODULE)); i++) //skip first module! { module.modBaseAddr = (DWORD_PTR)hMods[i]; module.modBaseSize = (DWORD)getSizeOfImageProcess(hProcess, module.modBaseAddr); module.isAlreadyParsed = false; module.parsing = false; filename[0] = 0; module.fullPath[0] = 0; if (GetMappedFileNameW(hProcess, (LPVOID)module.modBaseAddr, filename, _countof(filename)) > 0) { if (!deviceNameResolver.resolveDeviceLongNameToShort(filename, module.fullPath)) { - MessageBoxW(0, filename, L"Cannot resolve this path!", MB_ICONERROR); + if (!GetModuleFileNameExW(hProcess, (HMODULE)module.modBaseAddr, module.fullPath, _countof(module.fullPath))) + { + wcscpy_s(module.fullPath, filename); + } } } + else + { + GetModuleFileNameExW(hProcess, (HMODULE)module.modBaseAddr, module.fullPath, _countof(module.fullPath)); + } moduleList.push_back(module); } retVal = true; } free(hMods); } return retVal; } bool ProcessAccessHelp::getMemoryRegionFromAddress(DWORD_PTR address, DWORD_PTR * memoryRegionBase, SIZE_T * memoryRegionSize) { MEMORY_BASIC_INFORMATION memBasic; if (VirtualQueryEx(hProcess,(LPCVOID)address,&memBasic,sizeof(MEMORY_BASIC_INFORMATION)) != sizeof(MEMORY_BASIC_INFORMATION)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"getMemoryRegionFromAddress :: VirtualQueryEx error %u", GetLastError()); #endif return false; } else { *memoryRegionBase = (DWORD_PTR)memBasic.BaseAddress; *memoryRegionSize = memBasic.RegionSize; return true; } } bool ProcessAccessHelp::getSizeOfImageCurrentProcess() { DWORD_PTR newSizeOfImage = getSizeOfImageProcess(ProcessAccessHelp::hProcess, ProcessAccessHelp::targetImageBase); if (newSizeOfImage != 0) { ProcessAccessHelp::targetSizeOfImage = newSizeOfImage; return true; } else { return false; } } SIZE_T ProcessAccessHelp::getSizeOfImageProcess(HANDLE processHandle, DWORD_PTR moduleBase) { SIZE_T sizeOfImage = 0, sizeOfImageNative = 0; MEMORY_BASIC_INFORMATION lpBuffer = {0}; sizeOfImageNative = getSizeOfImageProcessNative(processHandle, moduleBase); if (sizeOfImageNative) { return sizeOfImageNative; } WCHAR filenameOriginal[MAX_PATH*2] = {0}; WCHAR filenameTest[MAX_PATH*2] = {0}; GetMappedFileNameW(processHandle, (LPVOID)moduleBase, filenameOriginal, _countof(filenameOriginal)); do { moduleBase = (DWORD_PTR)((SIZE_T)moduleBase + lpBuffer.RegionSize); sizeOfImage += lpBuffer.RegionSize; if (!VirtualQueryEx(processHandle, (LPCVOID)moduleBase, &lpBuffer, sizeof(MEMORY_BASIC_INFORMATION))) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"getSizeOfImageProcess :: VirtualQuery failed %X", GetLastError()); #endif lpBuffer.Type = 0; sizeOfImage = 0; } GetMappedFileNameW(processHandle, (LPVOID)moduleBase, filenameTest, _countof(filenameTest)); if (_wcsicmp(filenameOriginal,filenameTest) != 0)//problem: 2 modules without free space { break; } } while (lpBuffer.Type == MEM_IMAGE); //if (sizeOfImage != sizeOfImageNative) //{ // WCHAR temp[1000] = {0}; // wsprintfW(temp, L"0x%X sizeofimage\n0x%X sizeOfImageNative", sizeOfImage, sizeOfImageNative); // MessageBoxW(0, temp, L"Test", 0); //} return sizeOfImage; } DWORD ProcessAccessHelp::getEntryPointFromFile(const WCHAR * filePath) { PeParser peFile(filePath, false); return peFile.getEntryPoint(); } bool ProcessAccessHelp::createBackupFile(const WCHAR * filePath) { size_t fileNameLength = wcslen(filePath) + 5; //.bak + null BOOL retValue = 0; WCHAR * backupFile = new WCHAR[fileNameLength]; wcscpy_s(backupFile, fileNameLength, filePath); wcscat_s(backupFile, fileNameLength, L".bak"); retValue = CopyFile(filePath, backupFile, FALSE); if (!retValue) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"createBackupFile :: CopyFile failed with error 0x%X", GetLastError()); #endif } delete [] backupFile; return retValue != 0; } DWORD ProcessAccessHelp::getModuleHandlesFromProcess(const HANDLE hProcess, HMODULE ** hMods) { DWORD count = 30; DWORD cbNeeded = 0; bool notEnough = true; *hMods = new HMODULE[count]; do { if (!EnumProcessModules(hProcess, *hMods, count * sizeof(HMODULE), &cbNeeded)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"getModuleHandlesFromProcess :: EnumProcessModules failed count %d", count); #endif delete [] *hMods; return 0; } if ((count * sizeof(HMODULE)) < cbNeeded) { delete [] *hMods; count = cbNeeded / sizeof(HMODULE); *hMods = new HMODULE[count]; } else { notEnough = false; } } while (notEnough); return cbNeeded / sizeof(HMODULE); } void ProcessAccessHelp::setCurrentProcessAsTarget() { ProcessAccessHelp::hProcess = GetCurrentProcess(); } bool ProcessAccessHelp::suspendProcess() { if (NativeWinApi::NtSuspendProcess) { if (NT_SUCCESS( NativeWinApi::NtSuspendProcess(ProcessAccessHelp::hProcess) )) { return true; } } return false; } bool ProcessAccessHelp::resumeProcess() { if (NativeWinApi::NtResumeProcess) { if (NT_SUCCESS( NativeWinApi::NtResumeProcess(ProcessAccessHelp::hProcess) )) { return true; } } return false; } bool ProcessAccessHelp::terminateProcess() { if (NativeWinApi::NtTerminateProcess) { if (NT_SUCCESS( NativeWinApi::NtTerminateProcess(ProcessAccessHelp::hProcess, 0) )) { return true; } } return false; } bool ProcessAccessHelp::isPageExecutable( DWORD Protect ) { if (Protect & PAGE_NOCACHE) Protect ^= PAGE_NOCACHE; if (Protect & PAGE_GUARD) Protect ^= PAGE_GUARD; 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; } } SIZE_T ProcessAccessHelp::getSizeOfImageProcessNative( HANDLE processHandle, DWORD_PTR moduleBase ) { MEMORY_REGION_INFORMATION memRegion = {0}; SIZE_T retLen = 0; if (NativeWinApi::NtQueryVirtualMemory(processHandle, (PVOID)moduleBase, MemoryRegionInformation, &memRegion, sizeof(MEMORY_REGION_INFORMATION), &retLen) == STATUS_SUCCESS) { return memRegion.RegionSize; } return 0; } diff --git a/Scylla/ProcessLister.cpp b/Scylla/ProcessLister.cpp index 223c4fb..044cf3e 100644 --- a/Scylla/ProcessLister.cpp +++ b/Scylla/ProcessLister.cpp @@ -1,292 +1,295 @@ #include "ProcessLister.h" #include "SystemInformation.h" #include "Logger.h" #include "ProcessAccessHelp.h" #include //#define DEBUG_COMMENTS def_IsWow64Process ProcessLister::_IsWow64Process = 0; std::vector& ProcessLister::getProcessList() { return processList; } bool ProcessLister::isWindows64() { #ifdef _WIN64 //compiled 64bit application return true; #else //32bit exe, check wow64 BOOL bIsWow64 = FALSE; //not available in all windows operating systems //Minimum supported client: Windows Vista, Windows XP with SP2 //Minimum supported server: Windows Server 2008, Windows Server 2003 with SP1 if (_IsWow64Process) { _IsWow64Process(GetCurrentProcess(), &bIsWow64); if (bIsWow64 != FALSE) { return true; } else { return false; } } else { return false; } #endif } //only needed in windows xp DWORD ProcessLister::setDebugPrivileges() { DWORD err = 0; HANDLE hToken = 0; TOKEN_PRIVILEGES Debug_Privileges = {0}; if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Debug_Privileges.Privileges[0].Luid)) { return GetLastError(); } if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { err = GetLastError(); if(hToken) CloseHandle(hToken); return err; } Debug_Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; Debug_Privileges.PrivilegeCount = 1; AdjustTokenPrivileges(hToken, false, &Debug_Privileges, 0, NULL, NULL); CloseHandle(hToken); return GetLastError(); } /************************************************************************/ /* Check if a process is 32 or 64bit */ /************************************************************************/ ProcessType ProcessLister::checkIsProcess64(HANDLE hProcess) { BOOL bIsWow64 = FALSE; if (!hProcess) { return PROCESS_MISSING_RIGHTS; } if (!isWindows64()) { //32bit win can only run 32bit process return PROCESS_32; } _IsWow64Process(hProcess, &bIsWow64); if (bIsWow64 == FALSE) { //process not running under wow return PROCESS_64; } else { //process running under wow -> 32bit return PROCESS_32; } } bool ProcessLister::getAbsoluteFilePath(HANDLE hProcess, Process * process) { WCHAR processPath[MAX_PATH]; bool retVal = false; wcscpy_s(process->fullPath, L"Unknown path"); if(!hProcess) { //missing rights return false; } if (GetProcessImageFileNameW(hProcess, processPath, _countof(processPath)) > 0) { if (!deviceNameResolver->resolveDeviceLongNameToShort(processPath, process->fullPath)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"getAbsoluteFilePath :: resolveDeviceLongNameToShort failed with path %s", processPath); #endif //some virtual volumes - MessageBoxW(0, processPath, L"Cannot resolve this path!", MB_ICONERROR); + if (GetModuleFileNameExW(hProcess, 0, process->fullPath, _countof(process->fullPath)) != 0) + { + retVal = true; + } } else { retVal = true; } } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"getAbsoluteFilePath :: GetProcessImageFileName failed %u", GetLastError()); #endif if (GetModuleFileNameExW(hProcess, 0, process->fullPath, _countof(process->fullPath)) != 0) { retVal = true; } } return retVal; } std::vector& ProcessLister::getProcessListSnapshotNative() { ULONG retLength = 0; ULONG bufferLength = 1; PSYSTEM_PROCESS_INFORMATION pBuffer = (PSYSTEM_PROCESS_INFORMATION)malloc(bufferLength); PSYSTEM_PROCESS_INFORMATION pIter; if (!processList.empty()) { //clear elements, but keep reversed memory processList.clear(); } else { //first time, reserve memory processList.reserve(34); } if (NativeWinApi::NtQuerySystemInformation(SystemProcessInformation, pBuffer, bufferLength, &retLength) == STATUS_INFO_LENGTH_MISMATCH) { free(pBuffer); bufferLength = retLength + sizeof(SYSTEM_PROCESS_INFORMATION); pBuffer = (PSYSTEM_PROCESS_INFORMATION)malloc(bufferLength); if (!pBuffer) return processList; if (NativeWinApi::NtQuerySystemInformation(SystemProcessInformation, pBuffer, bufferLength, &retLength) != STATUS_SUCCESS) { return processList; } } else { return processList; } pIter = pBuffer; while(TRUE) { if (pIter->UniqueProcessId > (HANDLE)4) //small filter { handleProcessInformationAndAddToList(pIter); } if (pIter->NextEntryOffset == 0) { break; } else { pIter = (PSYSTEM_PROCESS_INFORMATION)((DWORD_PTR)pIter + (DWORD_PTR)pIter->NextEntryOffset); } } std::reverse(processList.begin(), processList.end()); //reverse process list free(pBuffer); return processList; } void ProcessLister::handleProcessInformationAndAddToList( PSYSTEM_PROCESS_INFORMATION pProcess ) { Process process; WCHAR tempProcessName[MAX_PATH*2] = {0}; process.PID = (DWORD)pProcess->UniqueProcessId; HANDLE hProcess = ProcessAccessHelp::NativeOpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, process.PID); if (hProcess) { ProcessType processType = checkIsProcess64(hProcess); #ifdef _WIN64 if (processType == PROCESS_64) #else if (processType == PROCESS_32) #endif { process.sessionId = pProcess->SessionId; memcpy(tempProcessName, pProcess->ImageName.Buffer, pProcess->ImageName.Length); wcscpy_s(process.filename, tempProcessName); getAbsoluteFilePath(hProcess, &process); process.pebAddress = getPebAddressFromProcess(hProcess); getProcessImageInformation(hProcess, &process); processList.push_back(process); } CloseHandle(hProcess); } } void ProcessLister::getProcessImageInformation( HANDLE hProcess, Process* process ) { DWORD_PTR readImagebase = 0; process->imageBase = 0; process->imageSize = 0; if (hProcess && process->pebAddress) { PEB_CURRENT * peb = (PEB_CURRENT *)process->pebAddress; if (ReadProcessMemory(hProcess, &peb->ImageBaseAddress, &readImagebase, sizeof(DWORD_PTR), 0)) { process->imageBase = readImagebase; process->imageSize = (DWORD)ProcessAccessHelp::getSizeOfImageProcess(hProcess, process->imageBase); } } } DWORD_PTR ProcessLister::getPebAddressFromProcess( HANDLE hProcess ) { if (hProcess) { ULONG RequiredLen = 0; void * PebAddress = 0; PROCESS_BASIC_INFORMATION myProcessBasicInformation[5] = {0}; if(NativeWinApi::NtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, sizeof(PROCESS_BASIC_INFORMATION), &RequiredLen) == STATUS_SUCCESS) { PebAddress = (void*)myProcessBasicInformation->PebBaseAddress; } else { if(NativeWinApi::NtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, RequiredLen, &RequiredLen) == STATUS_SUCCESS) { PebAddress = (void*)myProcessBasicInformation->PebBaseAddress; } } return (DWORD_PTR)PebAddress; } return 0; } diff --git a/Scylla/Scylla.h b/Scylla/Scylla.h index f10c9af..23b90e5 100644 --- a/Scylla/Scylla.h +++ b/Scylla/Scylla.h @@ -1,35 +1,35 @@ #pragma once #include "ConfigurationHolder.h" #include "PluginLoader.h" #include "ProcessLister.h" #include "Logger.h" #define APPNAME_S "Scylla" -#define APPVERSION_S "v0.9.5" +#define APPVERSION_S "v0.9.5b" #define APPVERSIONDWORD 0x00009500 #define DONATE_BTC_ADDRESS "1GmVrhWwUhwLohaCLP4SKV5kkz8rd16N8h" #define APPNAME TEXT(APPNAME_S) #define APPVERSION TEXT(APPVERSION_S) class Scylla { public: static void initAsGuiApp(); static void initAsDll(); static ConfigurationHolder config; static PluginLoader plugins; static ProcessLister processLister; static FileLog debugLog; static ListboxLog windowLog; private: static const WCHAR DEBUG_LOG_FILENAME[]; };