I feel naughty

Aug 28, 2019 at 11:43pm
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 Aug 29, 2019 at 3:23am
Aug 28, 2019 at 11:49pm
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
Aug 29, 2019 at 3:23am
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.
Aug 29, 2019 at 3:43am
What's this code for and why's it naughty??
Aug 29, 2019 at 5:56am
closed account (4w0o1hU5)
It's purpose is commendable, however.

@zapshe you've marked c++ as one of your skills
Last edited on Aug 29, 2019 at 12:10pm
Aug 29, 2019 at 2:22pm
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.
Aug 29, 2019 at 3:54pm
@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.
Aug 29, 2019 at 4:02pm
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.
Aug 29, 2019 at 4:55pm
Thanks for the details!
Aug 29, 2019 at 6:26pm
I feel naughty

You should, you miscreant coder!
Aug 30, 2019 at 2:55am
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.)
Aug 30, 2019 at 3:04am
Dang, all this programming dirty talk....
Aug 30, 2019 at 3:20am
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 Aug 30, 2019 at 3:21am
Aug 30, 2019 at 4:18am
You should live on the edge.
Aug 30, 2019 at 4:29am
Just don't get cut, the edge can be rather sharp.
Aug 30, 2019 at 5:08am
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.
Aug 30, 2019 at 12:53pm
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.