-2

Need I specify the address of the char array opcodes (&opcodes)? I'm casting to a void pointer, then I see indeed specify again the address (fp points address to opcodes -> points to opcodes).

char opcodes[] = "\x41\x41...";

void main()
{
    void(*fp) (void);
    fp = (void *)&opcodes; // opcodes or &opcodes
    fp();
}
Joe
  • 307
  • 5
  • 14
  • 4
    The C standard does not make any guarantees for code like this. – EOF Jul 22 '15 at 18:00
  • 5
    A function pointer and a void* are distinct (incompatible) types, use inline assembly –  Jul 22 '15 at 18:02
  • basically your question is if a function pointer is a simple pointer or actually a double pointer in disguise? – Dleep Jul 22 '15 at 18:02
  • opcodes makes more sense than &opcodes, but the address itself should be the same and since you are casting it to a different pointer type, the type of the address also shouldn't matter. – JSF Jul 22 '15 at 18:04
  • Check out this post: http://stackoverflow.com/questions/31504984/executing-shellcode-segmentation-fault?noredirect=1#comment50975960_31504984 . Might help. – Petr Skocik Jul 22 '15 at 18:07
  • 4
    The compiler and/or runtime may place the data in `opcodes` in memory that is marked 'not executable'. You may not be able to do what you're attempting to do. It's all inherently unportable. – Jonathan Leffler Jul 22 '15 at 18:07
  • C does not define behavior for converting a void pointer or an object pointer to a function pointer, therefore your program exhibits undefined behavior, even if it never performs a function call via the converted pointer. – John Bollinger Jul 22 '15 at 18:11
  • 2
    C may be compiled for Harvard architectures. – EOF Jul 22 '15 at 18:20
  • @DieterLücking Inline assembly and the opcodes are the same. – Joe Jul 22 '15 at 18:21
  • @JSF I'm confused with what you said... I'm asking in the thread if I'm pointing to an address that is a pointer to opcodes or if I'm pointing directly to opcodes. – Joe Jul 22 '15 at 18:21
  • @PSkocik This isn't my question. – Joe Jul 22 '15 at 18:22
  • @JonathanLeffler I disable the protection in the compilation. – Joe Jul 22 '15 at 18:22
  • @JohnBollinger Must I use an int? And I call the function in the last line, fp(); – Joe Jul 22 '15 at 18:28
  • 1
    @Joe, Sorry, inline assembly is something the compiler/assembler handles and makes part of the executable code. The 'opcodes' is just some data in the heap. (usually not allowed to execute on the heap) – user3629249 Jul 22 '15 at 18:30
  • @Joe, either way (with or without the &) you are pointing directly to the opcodes. There is no pointer to pointer involved. I just double checked with gcc -S of your code with and without the & that doesn't matter. The generated code (.s file) is identical with or without the & in the C source code. – JSF Jul 22 '15 at 18:30
  • @JSF I know the compiler optimize the executable, but I insist, I want know what I'm doing. – Joe Jul 22 '15 at 18:48
  • 1
    @Joe, no, using `int` changes nothing. C does not provide any defined way to execute data. As others have suggested, this is what inline assembly is for, if your compiler provides such a facility. – John Bollinger Jul 22 '15 at 18:51
  • Cast to `void(*)()`. – fuz Jul 22 '15 at 18:51
  • @Joe, I had optimization off. This is not an optimization I am describing. The meaning of your code really is the same with or without that &. &opcodes does not imply the creation of a temporary holding the address opcodes. opcodes itself is an address and &opcodes is that same address but with a weird type. – JSF Jul 22 '15 at 18:54
  • @JohnBollinger lol, in all systems the exploits are made with C and opcodes :/ But ok... strange – Joe Jul 22 '15 at 18:55
  • @Joe yes, they are. And they all are built upon undefined behavior. – The Paramagnetic Croissant Jul 22 '15 at 18:56
  • 2
    @Joe, C does not provide any *defined* way. Exploits that follow the route you describe rely on triggering undefined behavior that in practice happens to favor the attacker at least some of the time. That doesn't make them reliable. It does make such vectors something that compilers and operating systems try to disable, which is an independent reason why you should not rely on executing data as code. – John Bollinger Jul 22 '15 at 18:59
  • @Joe [This](https://stackoverflow.com/questions/18476002/execute-binary-machine-code-from-c) might be useful if you're using GCC. However, this is very compiler specific. – Alyssa Haroldsen Jul 22 '15 at 19:01
  • Ok, guys. It's a bad practice. This runs but you say the standard don't accept this. Ok, it's useful, but I'm asking another issue. – Joe Jul 22 '15 at 19:34

1 Answers1

1

Perhaps.

The C standard nor the C++ standard have an answer to this. For both of them, it's Undefined Behavior. It might vary from implementation to implementation, if it's even possible.

If you give us a specific compiler, we might be able to answer it.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • I would say they very well have an answer: **don't do it!** They just call it a bit more friendly: _undefined behaviour_. And, no: UB does not vary, that would be _implementation defined_. Once UB is invoked, there is no use in investigating further. – too honest for this site Jul 22 '15 at 20:05