Create a new entry at the sections header.
| 199 | |
| 200 | // Create a new entry at the sections header. |
| 201 | BOOL cobf::create_shellcode_section(PIMAGE_SECTION_HEADER& sh_sec, DWORD& funs_rva) |
| 202 | { |
| 203 | // Get the sections. |
| 204 | PIMAGE_DOS_HEADER dos_hdr = (PIMAGE_DOS_HEADER)this->pe_rawf.data(); |
| 205 | PIMAGE_NT_HEADERS nt_hdrs = (PIMAGE_NT_HEADERS)&this->pe_rawf.data()[dos_hdr->e_lfanew]; |
| 206 | |
| 207 | // Verify the existence of a new section. |
| 208 | if (nt_hdrs->OptionalHeader.SizeOfHeaders < dos_hdr->e_lfanew + sizeof(nt_hdrs->Signature) + |
| 209 | sizeof(nt_hdrs->FileHeader) + nt_hdrs->FileHeader.SizeOfOptionalHeader + |
| 210 | ((size_t)nt_hdrs->FileHeader.NumberOfSections + 1) * sizeof(IMAGE_SECTION_HEADER)) |
| 211 | return FALSE; |
| 212 | |
| 213 | // Get the section of the shellcode. |
| 214 | sh_sec = (PIMAGE_SECTION_HEADER)&this->pe_rawf[dos_hdr->e_lfanew + |
| 215 | sizeof(nt_hdrs->Signature) + sizeof(nt_hdrs->FileHeader) + |
| 216 | nt_hdrs->FileHeader.SizeOfOptionalHeader + nt_hdrs->FileHeader.NumberOfSections * |
| 217 | sizeof(IMAGE_SECTION_HEADER)]; |
| 218 | |
| 219 | // Set the shellcode section properties. |
| 220 | PIMAGE_SECTION_HEADER prev_sec = sh_sec - 1; |
| 221 | sh_sec->Name[0] = '.'; sh_sec->Name[1] = 'c'; |
| 222 | sh_sec->Name[2] = 'o'; sh_sec->Name[3] = 'b'; |
| 223 | sh_sec->Name[4] = 'f'; sh_sec->Name[5] = '\0'; |
| 224 | sh_sec->Name[6] = '\0'; sh_sec->Name[7] = '\0'; |
| 225 | sh_sec->NumberOfLinenumbers = 0; |
| 226 | sh_sec->NumberOfRelocations = 0; |
| 227 | sh_sec->PointerToRelocations = 0; |
| 228 | sh_sec->PointerToLinenumbers = 0; |
| 229 | sh_sec->Misc.VirtualSize = 0; |
| 230 | sh_sec->SizeOfRawData = shellcode::shellcode_size + sizeof(shellcode::shellcodes_funs); |
| 231 | sh_sec->PointerToRawData = prev_sec->PointerToRawData + prev_sec->SizeOfRawData; |
| 232 | sh_sec->VirtualAddress = prev_sec->VirtualAddress + prev_sec->Misc.VirtualSize + |
| 233 | nt_hdrs->OptionalHeader.SectionAlignment - (prev_sec->Misc.VirtualSize % |
| 234 | nt_hdrs->OptionalHeader.SectionAlignment); |
| 235 | sh_sec->Characteristics = IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; |
| 236 | nt_hdrs->FileHeader.NumberOfSections++; |
| 237 | |
| 238 | // Set the section info. |
| 239 | DWORD sh_sec_offset = (DWORD)((PBYTE)sh_sec - this->pe_rawf.data()); |
| 240 | |
| 241 | // Resize the whole pe. |
| 242 | this->pe_rawf.resize(this->pe_rawf.size() + sh_sec->SizeOfRawData + |
| 243 | sizeof(shellcode::shellcodes_funs)); |
| 244 | sh_sec = (PIMAGE_SECTION_HEADER)(this->pe_rawf.data() + sh_sec_offset); |
| 245 | funs_rva = sh_sec->VirtualAddress + shellcode::shellcode_size; |
| 246 | |
| 247 | // Copy the shellcode and the table. |
| 248 | memcpy_s(this->pe_rawf.data() + sh_sec->PointerToRawData, sh_sec->SizeOfRawData, |
| 249 | shellcode::shellcode_start, shellcode::shellcode_size); |
| 250 | memcpy_s(this->pe_rawf.data() + sh_sec->PointerToRawData + shellcode::shellcode_size, |
| 251 | sizeof(shellcode::shellcodes_funs), shellcode::shellcodes_funs, |
| 252 | sizeof(shellcode::shellcodes_funs)); |
| 253 | |
| 254 | // Updating the functions offsets. |
| 255 | PDWORD p_sh_funs = (PDWORD)(this->pe_rawf.data() + sh_sec->PointerToRawData + shellcode::shellcode_size); |
| 256 | for (size_t idx = 0; idx < sizeof(shellcode::shellcodes_funs) / sizeof(*shellcode::shellcodes_funs); idx++) |
| 257 | { |
| 258 | // Update the offset. |