Ammar
I use inline assembly
Please show your inline assembly and tell its purpose.
Nils
Please show your inline assembly and tell its purpose.
#define syscall(id) asm("mov $"#id",%rax;syscall;") ssize_t write(int fd, const void *buf, size_t count) { syscall(1); }
Mar!o
So why do want to read the value of rax again?
Nils
Yep
Nils
So why do want to read the value of rax again?
because otherwise I get a warning that the function does not return
Nils
But if I return rax gets overwritten
Ammar
You shouldn't use mov instruction, let the compiler put it with constraints.
Ammar
Wait a minute.
Mar!o
But if I return rax gets overwritten
You could do: int64_t srax; __asm { mov srax, rax } and then return srax
Nils
You could do: int64_t srax; __asm { mov srax, rax } and then return srax
alright, I didn't know I can mov into variables
Mar!o
You could do: int64_t srax; __asm { mov srax, rax } and then return srax
This is MSVC MASM assembly tough, must change it to AT&T
Mar!o
if you use GCC or Clang
Mar!o
Also x64 MSVC inline assembly only works for x32 so to do it for x64 I had to adjust many things -_-
Ammar
If you don't use the constraints to put your values to registers, the inline-assembly may broke your code, because nothing tells your compiler that you are going to use rax, rdi, rsi and rdx.
Ammar
As a rule of thumb; whenever you have a mov instruction in inline-assembly, you are very likely doing something wrong. Use constraints to place values into the correct registers before the statement executes. Do not move values around yourself. If you do so, you'll need to also represent in the constraints or clobbers the fact that the asm now modifies its arguments.
Nils
This is the correct way to do that https://godbolt.org/z/fcTGvP
what does "const int num = 1" do?
Nils
Sorry
Ammar
what does "const int num = 1" do?
For the input operand, you can put "a"(num). Meaning you set the value of rax to be num.
Ammar
Compiler generates mov eax, 1 for that part.
Ammar
Anyway, you can remove that variable and put directly to "a" constraint.
Ammar
"a"(1)
Ammar
I think you will need this guide https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Simple-Constraints.html
Ammar
This is the correct way to do that https://godbolt.org/z/fcTGvP
@tuxifan I retract this, it should have been like this https://godbolt.org/z/nxxhfa
Nils
I modified it so it fits into a macro
Ammar
I already changed that myself 😉
I am a little bit surprised you could realized that.
Ammar
Even it generates the same instructions on that code situation.
Nils
I am a little bit surprised you could realized that.
Hmm, I just see no reason why to use a varable there that's it
Ammar
I corrected the operands. Not only remove the variable.
Nils
ssize_t write(int fd, const void *buf, size_t count) { ssize_t SYSCALL(1); } Dark macro magic applied! 👍
Nils
Ahhh I see
Ammar
ssize_t my_write(int edi, const void *rsi, size_t rdx) { ssize_t ret; __asm__ volatile( "syscall" : "=a"(ret) : "D"(edi), "S"(rsi), "d"(rdx), "a"(1) : "memory" ); return ret; }
Nils
Yeah, yeah.
Nils
How is your current syscall macro btw?
#define SYSCALL(id) ret; __asm__ volatile("syscall" : "=a"(ret) : __AARGS__ "a"(id) : "memory"); return ret
Nils
As said, super-dark macro magic 😈
Nils
more than 20 probably
Mar!o
Hmm better use a inline function
Nils
Hmm better use a inline function
Inline functions behave weird here because of the primitive control flow I am using.
Nils
What is __AARGS__?
My IDE just suggested it, some builtin ig
Nils
Me neither
Ammar
#define SYSCALL(id) ret; __asm__ volatile("syscall" : "=a"(ret) : __AARGS__ "a"(id) : "memory"); return ret
But still, the problem is that nothing tells your compiler you are going to use rdi, rsi and rdx. That will cause a trouble in the future.
Nils
What are you programming? :)
a simple way to load external code into a program that I have no source code of. I just mmap() the flat binary and start execution at 0x0
Ammar
What kind of trouble?
Could be undefined behavior.
Nils
Ahh, __AARGS unpacks it automatically
Nils
It does that stuff for me it seems
Ammar
Ahh, __AARGS unpacks it automatically
Does it even put the correct constraints?
Ammar
Use gcc -E.
Nils
Use gcc -E.
It evaluates to: "D"(fd), "S"(buf), "d"(count) Is that right?
Nils
What
Ammar
Eh, I posted the link to my message though.
Ammar
looks like
Ok, go on then.
Ammar
I wonder how can it predict the correct constraints?
Nils
/app/bettergcc/bin/gcc --static -Wall -fno-builtin -fno-exceptions -fno-stack-protector -nodefaultlibs -nostartfiles ./payload/*.c -o payload.o objcopy -O binary -j .text payload.o payload.bin Does that make sense?
Nils
I wonder how can it predict the correct constraints?
Probably some non-standard function of my IDE?
Nils
Looks too dangerous to me.
It doesn't work with exceptions and protection enabled
Ammar
It doesn't work with exceptions and protection enabled
How will you execute the extracted .text section?
Ammar
Is that mmap + PROT_EXEC?