MCPcopy Create free account
hub / github.com/clementgallet/libTAS / write_tramp_function

Function write_tramp_function

src/library/hookpatch.cpp:492–688  ·  view source on GitHub ↗

Fill into pTramp the function pointer of the built trampoline function. * This function contains the first instructions of original function, * where some instructions needs a modification, and a jump * to the remaining instructions of original function. */

Source from the content-addressed store, hash-verified

490 * to the remaining instructions of original function.
491 */
492static bool write_tramp_function(const void *orig_fun, void **pTramp)
493{
494 static unsigned char* currentTrampAddr = nullptr;
495
496 currentTrampAddr = static_cast<unsigned char*>(allocate_nearby_segment(currentTrampAddr, orig_fun));
497
498 if (!currentTrampAddr) {
499 *pTramp = nullptr;
500 return false;
501 }
502
503 *pTramp = currentTrampAddr;
504
505 const unsigned char* pOrig = static_cast<const unsigned char*>(orig_fun);
506
507 /* Overwrite the trampoline function */
508 LOG(LL_DEBUG, LCF_HOOK, " Building our trampoline function in %p", currentTrampAddr);
509
510 /* Write each instruction of the original function that we will overwrite,
511 * and update instructions with relative addresses. Our trampoline function
512 * is written in an address that is at most 32-bit away from the original
513 * function, so that for instructions with 32-bit relative address can be
514 * updated in place.
515 * Our trampoline will look like that:
516 * orig_instr1
517 * ...
518 * orig_instrN
519 * ff 25 00 00 00 00 jmp *(%rip)
520 * ad dr re ss to or ig fn address to orig function offset by N bytes
521 *
522 * For the short jump instructions, we change the offset
523 * to jump to another jump instruction
524 * orig_instr1
525 * 7e of jne 0xof
526 * orig_instrN
527 * ff 25 00 00 00 00 jmp *(%rip)
528 * ad dr re ss to or ig fn address to orig function offset by N bytes
529 * ad dr re ss to ju mp 01 address to orig called function 01
530 */
531
532 int cur_offset = 0;
533 std::list<jmp_info> jmp_list;
534 instr_info instr;
535
536 while (cur_offset < JMP_INSTR_LEN) {
537 /* Transcribe each instruction, and update the occasionnal relative address */
538 int instr_len = instruction_length(pOrig + cur_offset, &instr);
539
540 /* Print instruction */
541 std::ostringstream oss_orig;
542 for (int off = cur_offset; off < cur_offset + instr_len; off++) {
543 oss_orig << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(*(pOrig + off)) << " ";
544 }
545 LOG(LL_DEBUG, LCF_HOOK, " Found instruction %s", oss_orig.str().c_str());
546
547 // Case where modRM with offset relative to the current instruction
548 // pointer value. We need to change the offset in place
549 bool relative_rip = instr.has_modRM &&

Callers 1

hook_patch_addrFunction · 0.85

Calls 5

allocate_nearby_segmentFunction · 0.85
instruction_lengthFunction · 0.85
c_strMethod · 0.45
beginMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected