I feel naughty

1
2
3
4
5
6
7
void foo(){ /*...*/ }

void bar(){}

//...

copy_to_remote_process((const void *)foo, (uintptr_t)bar - (uintptr_t)foo);
The worst part? It works!
Last edited on
Naughty sun god!

I feel like this is the kind of thing that could explode if the compiler/linker decide to get creative with how the functions are laid out in the binary, to improve locality and whatnot.

-Albatross
Yup. But hey, if it saves me having to write two versions of foo() in Assembly (one for each bitness), I honestly don't care.
What's this code for and why's it naughty??
closed account (4w0o1hU5)
It's purpose is commendable, however.

@zapshe you've marked c++ as one of your skills
Last edited on
I wonder if there's a setting to force the compiler to lay out the instruction memory in the contiguous way you're using it.
@zapshe you've marked c++ as one of your skills

A shame you didn't put "asshole" as one of yours. Was practically half asleep when I first saw it.
What's this code for and why's it naughty??
To inject a DLL into another process, you need some bootstrapping code so that you can a) have some entry point to create a new thread in that process, and b) do any initialization required by that DLL.
It's naughty because the language provides no guarantees about the memory layout of functions. There's no guarantee that the entirety of foo() will be between &foo and &bar, or that &bar > &foo. Actually, I had to tweak the compiler settings because it kept inserting a stack guard that pointed to an address outside the function.

I wonder if there's a setting to force the compiler to lay out the instruction memory in the contiguous way you're using it.
That sure would be cool. Without such guarantees the only way to write the above properly would be to analyze the generated code by disassembling it so that you can find all the possible bits that belong to that function. And obviously if the compiler has the great idea to do jmp eax anywhere, the problem becomes much, much harder.
Thanks for the details!
I feel naughty

You should, you miscreant coder!
Honestly, though, you usually don’t need to worry too much about the exact size of your functions when injecting a process. The size of the functions is often much smaller than the available data space being injected...

That said, this is something that is not uncommon in low-level C programming to determine the size of a function. Just mind your compiler’s default optimizations. (IIRC, both GCC and MSVC need no adjustment by default.)
Dang, all this programming dirty talk....
Honestly, though, you usually don’t need to worry too much about the exact size of your functions when injecting a process.
Hmm... I suppose I could copy the entire section of the caller into the remote process. I hadn't thought of that.
1
2
3
4
5
6
auto base_address = get_caller_module_base_address();
auto module_size = get_caller_module_size();
assert(base_address <= foo && foo < base_address + module_size);
auto offset = foo - base_address;
auto remote_address = copy_to_remote_process(base_address, module_size);
create_remote_thread(remote_address + offset);
Last edited on
You should live on the edge.
Just don't get cut, the edge can be rather sharp.
I wonder if there's a setting to force the compiler to lay out the instruction memory in the contiguous way you're using it.


I think you can program the linker to do that for you. At least if you're using GNU ld (or gold, maybe). But I don't know the details.
Assuming a GNU toolchain...

Compiler:
https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Variable-Attributes.html
Say for example
1
2
static void __attribute__((section(".copycode")) foo ( ) {
}


Linker:
https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_19.html
Something like this, but you may need to tweak things.
Put all the functions marked as copycode together in one linker section, and define a couple of symbols (which you can then extern from your source code) to tell you how much to copy.
1
2
3
4
5
6
7
SECTIONS {
  .copycode :
     {
        zzzFooCopyBegin = .;
    *(.copycode)
        zzzFooCopyEnd = .;
    }
Topic archived. No new replies allowed.