flat assembler
Message board for the users of flat assembler.

Index > Linux > How to check if libc.so is loaded properly?

Author
Thread Post new topic Reply to topic
tianboh



Joined: 07 Jul 2023
Posts: 10
tianboh 30 Aug 2023, 08:18
Hi, I am studying how to interact between assembly and C source code, but it seems that libc.so didn't load properly. Here is a minimal reproducible snippet.

C source code driver.c:
Code:
#include <stdio.h>
#include <stdlib.h>

extern int _c0_main();

/* The main function, which calls _c0_main */
int main() {
  printf("%d\n", _c0_main());
  exit(0);
}

int print_int(int n) {
  fprintf(stderr, "%d\n", n);
  return 0;
}
    

Assembly code assem.s:
Code:
        .text
        .globl _c0_main
_c0_main:
        push %rbp
        movq %rsp, %rbp
        subq $24, %rsp
        movq %rbx, -8(%rbp)
        movq %r12, -16(%rbp)
        movq %r13, -24(%rbp)
        movq %r14, %r12
        movq %r15, %rbx
        movl $1, %eax
        movl %eax, %edi
        call print_int
        movl $0, %ecx
        movl %ecx, %eax
        movq %rbx, %r15
        movq %r12, %r14
        movq -24(%rbp), %r13
        movq -16(%rbp), %r12
        movq -8(%rbp), %rbx
        movq %rbp, %rsp
        popq %rbp
        ret
    

So basically, the driver provide print_int and calls assembly. The assembly calls function provided by driver.

You can compile, link and execute by
Code:
gcc driver.c -o driver.o
gcc -g -m64 -no-pie driver.o assemb.s -o toy.exe
./toy.exe
    

However, this will lead to seg fault. The backtrace is
Code:
#0  0x00007ffff7c09e98 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff7c06d24 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff7bf1c6a in fprintf () from /lib/x86_64-linux-gnu/libc.so.6
#3  0x00000000004011a2 in print_int ()
#4  0x00000000004011cf in _c0_main () at assemb.s:14
#5  0x0000000000401158 in main ()
    

It seems that this toy cannot execute fprintf properly.

I am running this snippet on Ubuntu 20.04, with gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2).

Any suggestions would be grateful!
Post 30 Aug 2023, 08:18
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 30 Aug 2023, 09:42
Changing the AT&T code to fasm
Code:
format elf64

extrn   print_int
public  _c0_main

_c0_main:
        push    rbp
        mov     rbp,rsp
        sub     rsp,24
        mov     [rbp-8],rbx
        mov     [rbp-16],r12
        mov     [rbp-24],r13
        mov     r12,r14
        mov     rbx,r15
        mov     eax,1
        mov     edi,eax
        call    print_int
        mov     ecx,0
        mov     eax,ecx
        mov     r15,rbx
        mov     r14,r12
        mov     r13,[rbp-24]
        mov     r12,[rbp-16]
        mov     rbx,[rbp-8]
        mov     rsp,rbp
        pop     rbp
        ret    
Compiling with
Code:
fasm tianboh.asm tianboh.asm.o && gcc -c tianboh.c -o tianboh.c.o && gcc -g -m64 tianboh.asm.o tianboh.c.o -o tianboh && ./tianboh    
It works on my machine.
Code:
flat assembler  version 1.73.31  (16384 kilobytes memory)
1 passes, 624 bytes.
1
0    
Post 30 Aug 2023, 09:42
View user's profile Send private message Visit poster's website Reply with quote
tianboh



Joined: 07 Jul 2023
Posts: 10
tianboh 30 Aug 2023, 10:03
Thank you for your reply!

I tried to use fasm format, but still get seg fault.

Code:
fasm tianboh.asm tianboh.asm.o
    

works fine, it shows
Code:
flat assembler  version 1.73.22  (16384 kilobytes memory)
1 passes, 624 bytes.
    

but the execution of final objective file still fails.

Any ideas? I feel its not related to assembly syntax.
Post 30 Aug 2023, 10:03
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 30 Aug 2023, 10:54
You can try eliminating the separate linker step. I have no idea if that makes any difference.
Code:
fasm tianboh.asm tianboh.asm.o && gcc tianboh.c tianboh.asm.o -o tianboh && ./tianboh    
Post 30 Aug 2023, 10:54
View user's profile Send private message Visit poster's website Reply with quote
tianboh



Joined: 07 Jul 2023
Posts: 10
tianboh 30 Aug 2023, 11:23
You are right, this result in the same seg fault.

I also try plain C program and it works fine, so the libraries is good. Are C and assembly use the same libc.so?

Code:
#include <stdio.h>
#include <stdlib.h>

int print_int(int n)
{
    fprintf(stderr, "%d\n", n);
    return 0;
}

int main()
{
    print_int(1);
    exit(0);
}

    
Post 30 Aug 2023, 11:23
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 30 Aug 2023, 11:30
I'm not very familiar with the internal c calling convention. But your ASM code looks "weird".

The lack of stack alignment to 0 mod 16 might be an issue?
The corruption of RDI might be an issue?
Post 30 Aug 2023, 11:30
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 30 Aug 2023, 11:32
I would simplify the asm code like this:
Code:
format elf64

extrn   print_int
public  _c0_main

_c0_main:
        push    rdi
        mov     edi,1
        call    print_int
        pop     rdi
        ret    
Post 30 Aug 2023, 11:32
View user's profile Send private message Visit poster's website Reply with quote
tianboh



Joined: 07 Jul 2023
Posts: 10
tianboh 30 Aug 2023, 11:53
AWESOME!!! You are genius!!! After adding push and pop %RDI, it is working now.

I am curious though, why do we need to push and pop %RDI around function call? I thought we only need to pass the first parameter before function call.

Plus, I heard alignment before, but don't know how to follow it. How do you find out the ASM is not aligned?
Post 30 Aug 2023, 11:53
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 30 Aug 2023, 11:56
I suspect the alignment is the real culprit. Probably RDI is of no consequence.

So pushing ANY register will probably work, it's main purpose is to align the stack to 0 mod 16. Try it with another register and see what happens.
Post 30 Aug 2023, 11:56
View user's profile Send private message Visit poster's website Reply with quote
tianboh



Joined: 07 Jul 2023
Posts: 10
tianboh 30 Aug 2023, 11:59
Yes, the alignment is the real culprit. I changed RDI to R9, and it works as well.

Why push and pop can help align the stack? Is there any other way to achieve it?
Post 30 Aug 2023, 11:59
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 30 Aug 2023, 12:06
You can also use sub/add
Code:
_c0_main:
        sub     rsp,8
        mov     edi,1
        call    print_int
        add     rsp,8
        ret    
Post 30 Aug 2023, 12:06
View user's profile Send private message Visit poster's website Reply with quote
tianboh



Joined: 07 Jul 2023
Posts: 10
tianboh 30 Aug 2023, 12:08
I see, this should be faster. Thank you for your help! Have a good one!
Post 30 Aug 2023, 12:08
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 30 Aug 2023, 12:12
tianboh wrote:
I see, this should be faster.
Not necessarily. You would need to time it to see.

It uses mores code bytes, so the code cache is stressed more. It also modifies the flags so there may be hazards created that block some other processing. Plus the stack can be specially handled in some CPUs so that basic push/pop can perform extremely well.

Test it to make sure you get what you expect.
Post 30 Aug 2023, 12:12
View user's profile Send private message Visit poster's website Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 767
tthsqe 30 Aug 2023, 13:54
tianboh, as you can see, you have to be careful when mentioning speed around revolution. Also, it looks like revo's libc is probably old and not using sse/avx aligned instructions while yours is. Hence the difference.
Post 30 Aug 2023, 13:54
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 30 Aug 2023, 13:58
tthsqe wrote:
tianboh, as you can see, you have to be careful when mentioning speed around revolution.
Smile

'tis better to be informed than to blindly assume.
Post 30 Aug 2023, 13:58
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2545
Furs 31 Aug 2023, 13:28
I mean in this case the difference is not measurable so just go with what's smaller: push/pop.
Post 31 Aug 2023, 13:28
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 31 Aug 2023, 13:45
I also don't understand why calling c printf would be in time critical code. Confused IMO it shouldn't be in there.

If it is important to make it perform really well then make your own print code and avoid all the overheads of call/ret, and all the extra bloat of printf being a comprehensive function instead of being pared down to just the few things the code needs it to do.
Post 31 Aug 2023, 13:45
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.