DWORD get_hdrs_size(BYTE* payload) { if (payload == NULL) return false; bool is64b = is64bit(payload); BYTE* payload_nt_hdr = get_nt_hrds(payload); if (payload_nt_hdr == NULL) { printf("Invalid payload: %p\n", payload); return false; } IMAGE_FILE_HEADER *fileHdr = NULL; DWORD hdrsSize = 0; if (is64b) { IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr; fileHdr = &(payload_nt_hdr64->FileHeader); hdrsSize = payload_nt_hdr64->OptionalHeader.SizeOfHeaders; } else { IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr; fileHdr = &(payload_nt_hdr32->FileHeader); hdrsSize = payload_nt_hdr32->OptionalHeader.SizeOfHeaders; } return hdrsSize; }
LPVOID get_sec_ptr(BYTE* payload) { if (payload == NULL) return NULL; bool is64b = is64bit(payload); BYTE* payload_nt_hdr = get_nt_hrds(payload); if (payload_nt_hdr == NULL) { printf("Invalid payload: %p\n", payload); return NULL; } IMAGE_FILE_HEADER *fileHdr = NULL; LPVOID secptr = NULL; if (is64b) { IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr; fileHdr = &(payload_nt_hdr64->FileHeader); secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr64->OptionalHeader) + fileHdr->SizeOfOptionalHeader); } else { IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr; fileHdr = &(payload_nt_hdr32->FileHeader); secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr32->OptionalHeader) + fileHdr->SizeOfOptionalHeader); } return secptr; }
bool update_image_base(BYTE* payload, PVOID destImageBase) { bool is64b = is64bit(payload); //update image base in the written content: BYTE* payload_nt_hdr = get_nt_hrds(payload); if (payload_nt_hdr == NULL) { return false; } if (is64b) { IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr; payload_nt_hdr64->OptionalHeader.ImageBase = (ULONGLONG)destImageBase; } else { IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr; payload_nt_hdr32->OptionalHeader.ImageBase = (DWORD)destImageBase; } return true; }
IMAGE_DATA_DIRECTORY* get_pe_directory(PVOID pe_buffer, DWORD dir_id) { if (dir_id >= IMAGE_NUMBEROF_DIRECTORY_ENTRIES) return NULL; BYTE* nt_headers = get_nt_hrds((BYTE*)pe_buffer); if (nt_headers == NULL) return NULL; IMAGE_DATA_DIRECTORY* peDir = NULL; if (is64bit((BYTE*)pe_buffer)) { IMAGE_NT_HEADERS64* nt_headers64 = (IMAGE_NT_HEADERS64*)nt_headers; peDir = &(nt_headers64->OptionalHeader.DataDirectory[dir_id]); } else { IMAGE_NT_HEADERS32* nt_headers64 = (IMAGE_NT_HEADERS32*)nt_headers; peDir = &(nt_headers64->OptionalHeader.DataDirectory[dir_id]); } if (peDir->VirtualAddress == NULL) { return NULL; } return peDir; }
WORD get_sec_number(BYTE* payload) { if (payload == NULL) return 0; bool is64b = is64bit(payload); BYTE* payload_nt_hdr = get_nt_hrds(payload); if (payload_nt_hdr == NULL) { printf("Invalid payload: %p\n", payload); return 0; } IMAGE_FILE_HEADER *fileHdr = NULL; LPVOID secptr = NULL; if (is64b) { IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr; fileHdr = &(payload_nt_hdr64->FileHeader); } else { IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr; fileHdr = &(payload_nt_hdr32->FileHeader); } return fileHdr->NumberOfSections; }
void CMainFrame::OnButtonSelectprocess() { CMFCRibbonButton* pButton = (CMFCRibbonButton*)m_wndRibbonBar.FindByID( ID_BUTTON_SELECTPROCESS ); CRect pos = pButton->GetRect( ); ClientToScreen( &pos ); CMenu menu; menu.CreatePopupMenu( ); ClearProcMenuItems( ); HANDLE ProcessList = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, NULL ); if (ProcessList != INVALID_HANDLE_VALUE) { PROCESSENTRY32 ProcInfo; ProcInfo.dwSize = sizeof( PROCESSENTRY32 ); BOOL rp = Process32First( ProcessList, &ProcInfo ); bool bSkip = false; while( rp == TRUE ) { // Are we filtering out processes if ( gbFilterProcesses ) { for ( int i = 0; i < sizeof( CommonProcesses ) / sizeof( CommonProcesses[0] ) ; i ++ ) { if ( strcmp( ProcInfo.szExeFile, CommonProcesses[i].c_str( ) ) == 0 ) { //printf( "True %s\n", ProcInfo.szExeFile ); bSkip = true; } } } if ( bSkip ) { bSkip = false; rp = Process32Next(ProcessList,&ProcInfo); continue; } HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, false, ProcInfo.th32ProcessID ); if ( hProcess ) { if ( is64bit( hProcess ) ) { char filename[1024]; DWORD len = sizeof(filename); GetModuleFileNameEx(hProcess,NULL,filename,1024); SHFILEINFO sfi; SHGetFileInfo(filename,FILE_ATTRIBUTE_NORMAL,&sfi,sizeof(SHFILEINFO),SHGFI_ICON | SHGFI_USEFILEATTRIBUTES); CBitmap* pBitmap = new CBitmap; CProcessMenuInfo Item; Item.ProcessId = ProcInfo.th32ProcessID; Item.pBitmap = pBitmap; CClientDC clDC(this); CDC dc;dc.CreateCompatibleDC(&clDC); int cx = 16;int cy = 16; pBitmap->CreateCompatibleBitmap(&clDC,cx,cy); CBitmap* pOldBmp = dc.SelectObject(pBitmap); dc.FillSolidRect(0,0,cx,cy,GetSysColor(COLOR_3DFACE)); ::DrawIconEx(dc.GetSafeHdc(),0,0,sfi.hIcon,cx,cy,0,NULL,DI_NORMAL); dc.SelectObject( pOldBmp ); dc.DeleteDC(); DWORD MsgID = WM_PROCESSMENU + ProcMenuItems.size(); menu.AppendMenu( MF_STRING | MF_ENABLED, MsgID , ProcInfo.szExeFile ); menu.SetMenuItemBitmaps(MsgID, MF_BYCOMMAND,pBitmap,pBitmap); ProcMenuItems.push_back(Item); } CloseHandle(hProcess); } rp = Process32Next(ProcessList,&ProcInfo); } CloseHandle(ProcessList); } menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_HORNEGANIMATION,pos.left,pos.bottom,this); }
bool sections_virtual_to_raw(BYTE* payload, SIZE_T payload_size, OUT BYTE* destAddress, OUT SIZE_T *raw_size_ptr) { if (payload == NULL) return false; bool is64b = is64bit(payload); BYTE* payload_nt_hdr = get_nt_hrds(payload); if (payload_nt_hdr == NULL) { printf("Invalid payload: %p\n", payload); return false; } IMAGE_FILE_HEADER *fileHdr = NULL; DWORD hdrsSize = 0; LPVOID secptr = NULL; if (is64b) { IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*) payload_nt_hdr; fileHdr = &(payload_nt_hdr64->FileHeader); hdrsSize = payload_nt_hdr64->OptionalHeader.SizeOfHeaders; secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr64->OptionalHeader) + fileHdr->SizeOfOptionalHeader); } else { IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*) payload_nt_hdr; fileHdr = &(payload_nt_hdr32->FileHeader); hdrsSize = payload_nt_hdr32->OptionalHeader.SizeOfHeaders; secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr32->OptionalHeader) + fileHdr->SizeOfOptionalHeader); } if (!validate_ptr(payload, payload_size, payload, hdrsSize)) { return false; } //copy payload's headers: memcpy(destAddress, payload, hdrsSize); //copy all the sections, one by one: printf("Coping sections:\n"); SIZE_T raw_end = 0; for (WORD i = 0; i < fileHdr->NumberOfSections; i++) { PIMAGE_SECTION_HEADER next_sec = (PIMAGE_SECTION_HEADER)((ULONGLONG)secptr + (IMAGE_SIZEOF_SECTION_HEADER * i)); if (!validate_ptr(payload, payload_size, next_sec, IMAGE_SIZEOF_SECTION_HEADER)) { return false; } LPVOID section_mapped = (BYTE*) payload + next_sec->VirtualAddress; LPVOID section_raw_ptr = destAddress + next_sec->PointerToRawData; SIZE_T sec_size = next_sec->SizeOfRawData; raw_end = next_sec->SizeOfRawData + next_sec->PointerToRawData; if (next_sec->VirtualAddress + sec_size >= payload_size) { printf("[!] Virtual section size is out ouf bounds: %lx\n", sec_size); sec_size = SIZE_T(payload_size - next_sec->VirtualAddress); printf("[!] Truncated to maximal size: %lx\n", sec_size); } if (next_sec->VirtualAddress >= payload_size && sec_size != 0) { printf("[-] VirtualAddress of section is out ouf bounds: %lx\n", static_cast<SIZE_T>(next_sec->VirtualAddress)); return false; } if (next_sec->PointerToRawData + sec_size >= payload_size) { printf("[-] Raw section size is out ouf bounds: %lx\n", sec_size); return false; } printf("[+] %s to: %p\n", next_sec->Name, section_raw_ptr); memcpy(section_raw_ptr, section_mapped, sec_size); } if (raw_end > payload_size) raw_end = payload_size; if (raw_size_ptr != NULL) { (*raw_size_ptr) = raw_end; } return true; }