3

I have an object file (for which I don't have access to the source).

For good reasons, I need to duplicate a call path. For example, this object file might have the following symbols:

_FuncA _FuncB _FuncC

_FuncA calls _FuncB, which in turns calls _FuncC. FuncC might increment a global variable defined in the C source code counter.

I want to modify this object file and duplicate _FuncA, _FuncB, and _FuncC.

The result would be an object file with the following symbols:

_FuncA _FuncB _FuncC _FuncA_copy _FuncB_copy _FuncC_copy

_FuncA_copy would need to call _FuncB_copy, which in turns calls _FuncC_copy. And I need _FuncC_copy to still reference the same global variable counter and increment it.

What I have so far:

It seems like the objcopy command will let you add new symbols using the flag --add-symbol <name>=[<section>:]<value>[,<flags>].

This seems like it would help me create _FuncA_copy, _FuncB_copy, _FuncC_copy. But is there anyway to modify the function call inside _FuncA_copy to _FuncB to go to _FuncB_copy instead?

Is there a better way to do this?

Ajay
  • 2,078
  • 1
  • 15
  • 13
  • 1
    I think it would help to understand why you want to do this. The [linker `--wrap` option](https://stackoverflow.com/q/13961774/10396) may help solve the real problem – AShelly Nov 29 '18 at 22:31
  • The question is an ask for the tool to do the job, not a programming question. As such, it is off-topic. – SergeyA Nov 29 '18 at 22:37
  • 2
    Disagree. This is a request for help with a non-standard way to create an executable program. – AShelly Nov 29 '18 at 22:39
  • @AShelly Thanks, that post on `--wrap` does look helpful, I'll see if that helps. As for the reason. This object file is being translated to machine code by a separate tool. I need to translate `_FuncA` in two slightly different ways in the same output binary. The tool would require having two separate copies of `FuncA`. I actually do have access to the source files, but I can't really make copies of the functions in the source code as the code base extremely large and there are more than 3 functions that I need to do this for. It seems like patching it on the object file would be the easiest. – Ajay Nov 29 '18 at 22:49
  • Looking at that post `--wrap` and the weaken & globalize method do not work as they would, for example, redirect the reference to `_FuncB` in `_FuncA` and `_FuncA_copy` to `_FuncB_copy` because they redirect all reference. I need to selectively only redirect the reference to inside `_FuncA_copy` to `_FuncB` to go to `_FuncB_copy`. – Ajay Nov 29 '18 at 23:09
  • 4
    What about creating a `.s` file (via `-S`). They're much easier to parse. Then, manipulate/duplicate/morph the asm code. Then, finish the compile. This is on the same level of difficulty [or less] than trying to patch a binary to duplicate a function with a different name. – Craig Estey Nov 29 '18 at 23:19

1 Answers1

4

The solution I found is writing an LLVM Pass shared module that can plugin to LLVM's optimizer tool which takes in a bytecode object and outputs a bytecode object.

http://llvm.org/docs/WritingAnLLVMPass.html

A LLVM pass is a custom optimizer that you can create, and within it you can have the optimizer loop over all function symbols and rename them as you wish and it updates all of the references to that function.

Ajay
  • 2,078
  • 1
  • 15
  • 13