bool CAttachMemory::attachASProtect() { if (m_pExeNTHdr == NULL) return false; PIMAGE_SECTION_HEADER pDataSect = GetSectionHeader(2); DWORD dwDataAddress = m_pExeNTHdr->OptionalHeader.ImageBase + pDataSect->VirtualAddress; BYTE p; ::CopyMemory(&p, reinterpret_cast<LPCVOID>(dwDataAddress), sizeof(BYTE)); while (1) { BYTE q; ::CopyMemory(&q, reinterpret_cast<LPCVOID>(dwDataAddress), sizeof(BYTE)); if (p != q) break; else p = q; ::Sleep(0x10); } return true; }
int CPEInfo::RvaToOffSet(DWORD dwRva) { int dwSectionNum=GetImageNTHeader()->FileHeader.NumberOfSections; PIMAGE_SECTION_HEADER pSectionHeader=GetSectionHeader(); for(int i = 0;i < dwSectionNum; i++) { DWORD dwSectionAlign=Align(pSectionHeader[i].Misc.VirtualSize,GetImageNTHeader()->OptionalHeader.SectionAlignment); DWORD dwSectionStart = pSectionHeader[i].VirtualAddress; //注意最后要减1,因为dwSectionAlign求得的是内存中整个节区的大小 //即:dwSectionEnd-dwSectionStart+1=dwSectionAlign DWORD dwSectionEnd = dwSectionStart+dwSectionAlign-1; if(dwRva>=dwSectionStart && dwRva<dwSectionEnd)//落在此节区内 { DWORD dwOffSet=dwRva-dwSectionStart; //如果此RVA是节区在内存中对齐补0的空白数据, //那么在文件中应该没有对应的数据 //属于无效的RVA return dwOffSet<pSectionHeader[i].SizeOfRawData? pSectionHeader[i].PointerToRawData+dwOffSet : -1; } } return -1; }
void * CELFFile::GetSectionPtr(int section_index,size_t offset) { if (section_index >= GetSectionCount()) return NULL; Elf32_Shdr * shdr = GetSectionHeader(section_index); return shdr->sh_offset + reinterpret_cast<char *>(GetImage()) + offset; }
void * CELFFile::GetSectionData(int section_index,size_t * _size) { if (section_index >= GetSectionCount()) return NULL; Elf32_Shdr * shdr = GetSectionHeader(section_index); *_size = shdr->sh_size; return shdr->sh_offset + reinterpret_cast<char *>(GetImage()); }
long CELFFile::GetSectionVa(int section_index,size_t offset) { if (section_index >= GetSectionCount()) return NULL; Elf32_Shdr * shdr = GetSectionHeader(section_index); return shdr->sh_addr + offset; }
DWORD CAttachMemory::GetCodeAddress(LPBYTE lpData, size_t Length) { if (m_pExeNTHdr == NULL) return 0; PIMAGE_SECTION_HEADER pTextSect = GetSectionHeader(0); DWORD dwTextAddress = m_pExeNTHdr->OptionalHeader.ImageBase + pTextSect->VirtualAddress; return SearchAddress(dwTextAddress, pTextSect->Misc.VirtualSize, lpData, Length); }
DWORD CAttachMemory::SearchData(LPCTSTR lpTargetString) { if (m_pExeNTHdr == NULL) return 0; PIMAGE_SECTION_HEADER pDataSect = GetSectionHeader(2); DWORD dwDataAddress = m_pExeNTHdr->OptionalHeader.ImageBase + pDataSect->VirtualAddress; DWORD dwTargetAddress = SearchAddress(dwDataAddress, pDataSect->Misc.VirtualSize, lpTargetString); return dwTargetAddress; }
void * CELFFile::VaToPtr(long va) { for (int i = 0; i < GetSectionCount();i++) { Elf32_Shdr *shdr = GetSectionHeader(i); if (va <= shdr->sh_addr + shdr->sh_size && va >= shdr->sh_addr) { return GetImage() + shdr->sh_offset + (va - shdr->sh_addr); } } return NULL; }
DWORD CAttachMemory::GetCallAddress(DWORD shift) { if (m_pExeNTHdr == NULL) return 0; BYTE code[5]; code[0] = 0xE8; *reinterpret_cast<DWORD*>(code+1) = shift; PIMAGE_SECTION_HEADER pTextSect = GetSectionHeader(0); DWORD dwTextAddress = m_pExeNTHdr->OptionalHeader.ImageBase + pTextSect->VirtualAddress; return SearchAddress(dwTextAddress, pTextSect->Misc.VirtualSize, code, 0x05) + 0x05 + shift; }
long CELFFile::GetNewSectionBase() { long max = 0; for (int i = 0; i < GetSectionCount(); i++) { Elf32_Shdr* section_header = GetSectionHeader(i); if (max < section_header->sh_addr + section_header->sh_size) { max = section_header->sh_addr + section_header->sh_size; } } max = 0x1000-(max %0x1000) + max; max = max + (sizeof(Elf32_Shdr) * (GetSectionCount() + 1)) + size; return max; }
long CELFFile::GetSectionMinAddress() { long max = 0; unsigned long min = -1; for (int i = 0; i < GetSectionCount(); i++) { Elf32_Shdr* section_header = GetSectionHeader(i); if (max < section_header->sh_addr + section_header->sh_size) { max = section_header->sh_addr + section_header->sh_size; } if (min < (unsigned long)(section_header->sh_addr) && section_header->sh_addr != 0) { min = section_header->sh_addr; } } return min; }
DWORD CAttachMemory::SearchCode(LPBYTE lpData, size_t Length, int shift) { if (m_pExeNTHdr == NULL) return 0; PIMAGE_SECTION_HEADER pTextSect = GetSectionHeader(0); DWORD dwTextAddress = m_pExeNTHdr->OptionalHeader.ImageBase + pTextSect->VirtualAddress; DWORD dwAddress = SearchAddress(dwTextAddress, pTextSect->Misc.VirtualSize, lpData, Length) + shift; if (dwAddress == 0) return 0; DWORD dwOldProtect, dwTargetAddress; ::VirtualProtect(reinterpret_cast<LPVOID>(dwAddress), sizeof(DWORD), PAGE_READWRITE, &dwOldProtect); ::CopyMemory(&dwTargetAddress, reinterpret_cast<LPCVOID>(dwAddress), sizeof(DWORD)); ::VirtualProtect(reinterpret_cast<LPVOID>(dwAddress), sizeof(DWORD), dwOldProtect, &dwOldProtect); return dwTargetAddress; }
PUCHAR CPEInfo::GetSectionNameByRva(DWORD dwRva) { int dwSectionNum=GetImageNTHeader()->FileHeader.NumberOfSections; PIMAGE_SECTION_HEADER pSectionHeader=GetSectionHeader(); for(int i = 0;i < dwSectionNum; i++) { DWORD dwSectionAlign=Align(pSectionHeader[i].Misc.VirtualSize,GetImageNTHeader()->OptionalHeader.SectionAlignment); DWORD dwSectionStart = pSectionHeader[i].VirtualAddress; //注意最后要减1,因为dwSectionAlign求得的是内存中整个节区的大小 //即:dwSectionEnd-dwSectionStart+1=dwSectionAlign DWORD dwSectionEnd = dwSectionStart+dwSectionAlign-1; if(dwRva>=dwSectionStart && dwRva<=dwSectionEnd)//落在此节区内 { return (PUCHAR)(pSectionHeader+i); } } return NULL; }
void CELFFile::AddSegmentSection(char * new_section_name,size_t new_section_size,long new_section_flag) { printf("new base:%x\n",GetNewSegmentSectionBase() ); long new_section_addr = GetNewSegmentSectionBase(); Elf32_Phdr * new_phdr_header = AddProgramHeader(); new_phdr_header->p_align = 0x1000;//new_section_size + (0x1000 - (new_section_size % 0x1000)); new_phdr_header->p_filesz = new_section_size; new_phdr_header->p_memsz = new_section_size; new_phdr_header->p_offset = size; new_phdr_header->p_flags = new_section_flag;//PF_X|PF_W|PF_R; new_phdr_header->p_vaddr = new_section_addr; new_phdr_header->p_type = PT_LOAD; new_phdr_header->p_paddr = new_section_addr; //asm("int3"); ReallocImage(size+new_section_size); return ; if (buffer == NULL || new_section_size == 0) return; size_t old_size = size; Elf32_Shdr * t_shdr_header = GetFirstSectionHeader() + GetSectionCount(); if (reinterpret_cast<size_t>(t_shdr_header) - reinterpret_cast<size_t>(GetImage()) == old_size) { ReallocImage(size + new_section_size + sizeof(Elf32_Shdr)); } else { ReallocImage(size + new_section_size ); } Elf32_Ehdr * elf_header = GetElfHeader(); Elf32_Shdr * string_section_header = GetSectionHeader( elf_header->e_shstrndx ); size_t str_table_last_offset = string_section_header->sh_size + string_section_header->sh_offset; char * new_string_begin_addr = reinterpret_cast<char*>(GetImage()) + str_table_last_offset; strcpy(new_string_begin_addr,new_section_name); string_section_header->sh_size += strlen(new_section_name); //Elf32_Shdr * new_shdr_header = GetSectionHeader(GetSectionCount() - 1); //Elf32_Shdr * new_shdr_header = GetSectionHeader(0) + GetSectionCount(); //printf ("last section:%s\n",GetStringTableStr( new_shdr_header->sh_name)); Elf32_Shdr * new_shdr_header = reinterpret_cast<Elf32_Shdr*>( (elf_header->e_shoff + reinterpret_cast<Elf32_Off>(GetImage()))); new_shdr_header += GetSectionCount(); //new_shdr_header++; printf("Elf32_Shdr Size:%x\n",sizeof(Elf32_Shdr)); if (reinterpret_cast<size_t>(new_shdr_header) - reinterpret_cast<size_t>(GetImage()) == old_size) { new_shdr_header->sh_offset = old_size + sizeof(Elf32_Shdr); } else { new_shdr_header->sh_offset = old_size; } printf("offset :%x\n",reinterpret_cast<size_t>(new_shdr_header) - reinterpret_cast<size_t>(GetImage())); new_shdr_header->sh_name = str_table_last_offset - string_section_header->sh_offset; printf ("last section:%s\n",GetStringTableStr( new_shdr_header->sh_name)); new_shdr_header->sh_addr = GetNewSectionBase(); new_shdr_header->sh_size = new_section_size; printf("size :%#x\n",new_shdr_header->sh_size); new_shdr_header->sh_flags = new_section_flag; //new_shdr_header->sh_offset = old_size; new_shdr_header->sh_type = 1; new_shdr_header->sh_link = 0; new_shdr_header->sh_info = 0; new_shdr_header->sh_addralign = 16; new_shdr_header->sh_entsize = 0; ++elf_header->e_shnum; /* Elf32_Phdr * new_phdr_header = GetProgramHeader(GetProgramCount() - 1); new_phdr_header++; printf("new_phdr_header offset:%#x\n",(size_t)new_phdr_header - (size_t)GetImage()); new_phdr_header->p_align = 0x1000;//new_section_size + (0x1000 - (new_section_size % 0x1000)); new_phdr_header->p_filesz = new_section_size; new_phdr_header->p_memsz = new_section_size; new_phdr_header->p_offset = new_shdr_header->sh_offset; new_phdr_header->p_flags = 5; new_phdr_header->p_vaddr = new_shdr_header->sh_addr; new_phdr_header->p_type = 1; new_phdr_header->p_paddr = new_phdr_header->p_vaddr; elf_header->e_phnum += 1;*/ }
void CELFFile::AddSection(char * new_section_name,size_t new_section_size,long new_section_flag) { if (buffer == NULL || new_section_size == 0) return; size_t old_size = size; Elf32_Shdr * t_shdr_header = GetFirstSectionHeader() + GetSectionCount(); if (reinterpret_cast<size_t>(t_shdr_header) - reinterpret_cast<size_t>(GetImage()) == old_size) { ReallocImage(size + new_section_size + sizeof(Elf32_Shdr)); } else { ReallocImage(size + new_section_size ); } Elf32_Ehdr * elf_header = GetElfHeader(); Elf32_Shdr * string_section_header = GetSectionHeader( elf_header->e_shstrndx ); size_t str_table_last_offset = string_section_header->sh_size + string_section_header->sh_offset; char * new_string_begin_addr = reinterpret_cast<char*>(GetImage()) + str_table_last_offset; strcpy(new_string_begin_addr,new_section_name); string_section_header->sh_size += strlen(new_section_name); //Elf32_Shdr * new_shdr_header = GetSectionHeader(GetSectionCount() - 1); //Elf32_Shdr * new_shdr_header = GetSectionHeader(0) + GetSectionCount(); //printf ("last section:%s\n",GetStringTableStr( new_shdr_header->sh_name)); Elf32_Shdr * new_shdr_header = reinterpret_cast<Elf32_Shdr*>( (elf_header->e_shoff + reinterpret_cast<Elf32_Off>(GetImage()))); new_shdr_header += GetSectionCount(); //new_shdr_header++; printf("Elf32_Shdr Size:%x\n",sizeof(Elf32_Shdr)); if (reinterpret_cast<size_t>(new_shdr_header) - reinterpret_cast<size_t>(GetImage()) == old_size) { new_shdr_header->sh_offset = old_size + sizeof(Elf32_Shdr); } else { new_shdr_header->sh_offset = old_size; } printf("offset :%x\n",reinterpret_cast<size_t>(new_shdr_header) - reinterpret_cast<size_t>(GetImage())); new_shdr_header->sh_name = str_table_last_offset - string_section_header->sh_offset; printf ("last section:%s\n",GetStringTableStr( new_shdr_header->sh_name)); new_shdr_header->sh_addr = GetNewSectionBase(); new_shdr_header->sh_size = new_section_size; printf("size :%#x\n",new_shdr_header->sh_size); new_shdr_header->sh_flags = new_section_flag; //new_shdr_header->sh_offset = old_size; new_shdr_header->sh_type = 1; new_shdr_header->sh_link = 0; new_shdr_header->sh_info = 0; new_shdr_header->sh_addralign = 16; new_shdr_header->sh_entsize = 0; ++elf_header->e_shnum; }
char * CELFFile::GetStringTableStr(int str_offset) { Elf32_Ehdr * elf_header = GetElfHeader(); Elf32_Shdr * section_header = GetSectionHeader( elf_header->e_shstrndx ); return reinterpret_cast<char*>(GetImage()) + section_header->sh_offset + str_offset; }
Elf32_Shdr * CELFFile::GetFirstSectionHeader() { return GetSectionHeader(0); }
// Returns a pointer to code section header IMAGE_SECTION_HEADER* GetCodeSectionHeader() { return GetSectionHeader(".text"); }