Add the shellcode entry as a callback.
| 461 | |
| 462 | // Add the shellcode entry as a callback. |
| 463 | BOOL cobf::add_shellcode_entry(PIMAGE_SECTION_HEADER& sh_sec, DWORD entry) |
| 464 | { |
| 465 | // Get the headers. |
| 466 | PIMAGE_DOS_HEADER dos_hdr = (PIMAGE_DOS_HEADER)this->pe_rawf.data(); |
| 467 | PIMAGE_NT_HEADERS nt_hdrs = (PIMAGE_NT_HEADERS)&this->pe_rawf.data()[dos_hdr->e_lfanew]; |
| 468 | |
| 469 | // Build the array of addresses. |
| 470 | vector<PVOID> tls_cbs = { (PVOID)(nt_hdrs->OptionalHeader.ImageBase + entry) }; |
| 471 | vector<BYTE> tls_data; |
| 472 | |
| 473 | // Get the table. |
| 474 | PIMAGE_TLS_DIRECTORY p_tls; size_t tls_size; |
| 475 | if (!this->get_data_table(IMAGE_DIRECTORY_ENTRY_TLS, (PVOID*)&p_tls, tls_size)) |
| 476 | { |
| 477 | // Cannot verify the tls table. |
| 478 | return FALSE; |
| 479 | }; |
| 480 | |
| 481 | // The tls directory can be existing or not. |
| 482 | if (p_tls) |
| 483 | { |
| 484 | // Get the offset to the array. |
| 485 | DWORD tls_cbs_off = (DWORD)(p_tls->AddressOfCallBacks - nt_hdrs->OptionalHeader.ImageBase); |
| 486 | if (!this->rva_to_offset(tls_cbs_off, tls_cbs_off)) return FALSE; |
| 487 | |
| 488 | // Adding the availible callbacks. |
| 489 | PVOID* p_tls_cbs = (PVOID*)&this->pe_rawf[tls_cbs_off]; |
| 490 | |
| 491 | // Insert and remove the old pointer. |
| 492 | do { tls_cbs.push_back(*p_tls_cbs); |
| 493 | } while (*p_tls_cbs && (*p_tls_cbs++ = NULL, TRUE)); |
| 494 | |
| 495 | // Removing the old array and pointer. |
| 496 | p_tls->AddressOfCallBacks = nt_hdrs->OptionalHeader.ImageBase + sh_sec->VirtualAddress + |
| 497 | sh_sec->SizeOfRawData; |
| 498 | } |
| 499 | else |
| 500 | { |
| 501 | // Building a new tls directory. |
| 502 | IMAGE_TLS_DIRECTORY tls_dir = { 0 }; DWORD index = 0; |
| 503 | tls_dir.AddressOfIndex = nt_hdrs->OptionalHeader.ImageBase + sh_sec->VirtualAddress + |
| 504 | sh_sec->SizeOfRawData + sizeof(tls_dir); |
| 505 | tls_dir.AddressOfCallBacks = tls_dir.AddressOfIndex + sizeof(index); |
| 506 | |
| 507 | // Build up the bytes array. |
| 508 | tls_data.insert(tls_data.end(), (PBYTE)&tls_dir, (PBYTE)&tls_dir + sizeof(tls_dir)); |
| 509 | tls_data.insert(tls_data.end(), (PBYTE)&index, (PBYTE)&index + sizeof(index)); |
| 510 | tls_cbs.push_back(NULL); |
| 511 | |
| 512 | // Point to the new table. |
| 513 | nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS] = { |
| 514 | sh_sec->VirtualAddress + sh_sec->SizeOfRawData, |
| 515 | (DWORD)(sizeof(tls_dir) + sizeof(index) + tls_cbs.size() * sizeof(PVOID)) |
| 516 | }; |
| 517 | }; |
| 518 | |
| 519 | // Writing to the shellcode section. |
| 520 | DWORD sh_sec_offset = (DWORD)((PBYTE)sh_sec - this->pe_rawf.data()); |
no test coverage detected