Why doesn't frida-trace find functions in Ubuntu/GCC binaries that it finds on MacOS/Clang compiles? - frida

Here is a simple program:
int
fx(int a)
{
a += 20;
return a;
}
int
main(int argc, char *argv[])
{
return fx(fx(10));
}
I compile this on macOS (bigSur) with Clang, and trace it:
0 ✓ [11:21:19 Fri Aug 27] ~/nobackup/frida/02
% gcc -g -O0 test.c
0 ✓ [11:21:24 Fri Aug 27] ~/nobackup/frida/02
% frida-trace ./a.out -i 'a.out!*'
Instrumenting...
fx: Auto-generated handler at "/Users/pt/nobackup/frida/02/__handlers__/a.out/fx.js"
main: Auto-generated handler at "/Users/pt/nobackup/frida/02/__handlers__/a.out/main.js"
Started tracing 2 functions. Press Ctrl+C to stop.
/* TID 0x103 */
100 ms main()
100 ms | fx()
100 ms | fx()
Process terminated
1 ✗ [11:21:31 Fri Aug 27] ~/nobackup/frida/02
Perfect. It created the __handler__ JavaScript and everything.
However, I do the same thing on Ubuntu with gcc, and Frida doesn't find the functions:
pt#serval:~/frida$ gcc -g -O0 test.c
pt#serval:~/frida$ frida-trace ./a.out -i 'a.out!*'
Started tracing 0 functions. Press Ctrl+C to stop.
Process terminated
...but they are in the symbol table with objdump -t, and I can find them by walking the modules in the Frida JavaScript API.
What is the magic compiler switch I am missing? I tried visibility and export symbols with no luck.

Related

How to tranform clang .ast file to ir or bitcode file?

Apologize for my poor English.
[root#xxxx] ~
❯ clang -emit-ast aa.c
[root#xxxx] ~
❯ xxd aa.ast | head
00000000: 4350 4348 0108 0000 ce0a 0000 07c1 b3d0 CPCH............
00000010: 8cc2 2bb8 022d c8c2 2bb0 c22f 8802 2bbc ..+..-..+../..+.
00000020: c228 acc2 4312 b442 29d0 4228 9042 28d0 .(..C..B).B(.B(.
00000030: 4228 3c30 472b bc02 29d4 022b 94c2 2fb8 B(<0G+..)..+../.
I can get clang ast file with -emit-ast option
and I want to transform it to llvm ir.
But I cannot find any interface to solved it.
Anyone has suggests??
Clang AST files can be used in place of source files, so the following code works:
// main.cpp
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
> clang++ -emit-ast main.cpp -o a.ast
> clang++ a.ast -o a.out
> ./a.out
Hello, world!
Answering your question:
> clang -emit-llvm -c aa.ast

LLVM cannot find clang binary

I have just built and installed LLVM Clang 3.5.0 with compiler-rt. clang binary seems to work, but cannot build a simple test program:
$ cat hello.c
#include <stdio.h>
int main(int argc, char **argv) {
printf("Hello World\n");
return 0;
}
Building it borks with error: unable to execute command: Executable "" doesn't exist!
$ clang hello.c -o hello
error: unable to execute command: Executable "" doesn't exist!
Executable "" ? Interesting...
Debugging it further reveals that clang tries to call itself to build .o object file and then ld to link it, but does not know where itself exists apparently.
$ clang -### hello.c -o hello
clang version 3.5.0 (tags/RELEASE_350/final)
Target: x86_64-alpine-linux-musl
Thread model: posix
"" "-cc1" "-triple" "x86_64-alpine-linux-musl" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "hello.c" "-mrelocation-model" "static" "-mdisable-fp-elim" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-fuse-init-array" "-target-cpu" "x86-64" "-target-linker-version" "2.24" "-dwarf-column-info" "-resource-dir" "../lib/clang/3.5.0" "-internal-isystem" "/usr/local/include" "-internal-isystem" "../lib/clang/3.5.0/include" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdebug-compilation-dir" "/" "-ferror-limit" "19" "-fmessage-length" "158" "-mstackrealign" "-fobjc-runtime=gcc" "-fdiagnostics-show-option" "-o" "/tmp/hello-37746e.o" "-x" "c" "hello.c"
"/usr/bin/ld" "-z" "relro" "--eh-frame-hdr" "-m" "elf_x86_64" "-dynamic-linker" "/lib/ld-musl-x86_64.so.1" "-o" "hello" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../crt1.o" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../crti.o" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/crtbegin.o" "-L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3" "-L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../../x86_64-alpine-linux-musl/lib" "-L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../.." "-L/../lib" "-L/lib" "-L/usr/lib" "/tmp/hello-37746e.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/crtend.o" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../crtn.o"
When I run the first line putting /usr/bin/clang as the first item, it builds just fine:
$ /usr/bin/clang "-cc1" "-triple" "x86_64-alpine-linux-musl" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "hello.c" "-mrelocation-model" "static" "-mdisable-fp-elim" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-target-linker-version" "2.24" "-dwarf-column-info" "-resource-dir" "../lib/clang/3.5.0" "-internal-isystem" "/usr/local/include" "-internal-isystem" "../lib/clang/3.5.0/include" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdebug-compilation-dir" "/" "-ferror-limit" "19" "-fmessage-length" "158" "-mstackrealign" "-fobjc-runtime=gcc" "-fdiagnostics-show-option" "-o" "/tmp/hello-4f64bb.o" "-x" "c" "hello.c"
$
And following /usr/bin/ld is able to link it just fine resulting in:
$ ./hello
Hello World
Anny suggestions what did I screw during configure/build?
clang source analysis shows that 'clang' program on Linux uses /proc/self/exe to find out real path of its binary. I am running in chroot without /proc mounted, thus it failed.
mount -t proc proc /proc
solves the issue

LLVM/Clang use opt to show linked ll file

I had two c files and want show IR for its linked bit code
link1.c
#include "link2.h"
int main() {
int a;
int b;
foo(a,b);
return 0;
}
link2.h
#include<stdio.h>
link2.c
#include "link2.h"
void foo(int a, int b) {
printf("%d\n", a);
printf("%d\n", b);
}
I did the following command to get bc file.
clang -o0 -emit-llvm file1.c -c -o file1.bc
clang -o0 -emit-llvm file2.c -c -o file2.bc
llvm-link -o link.bc link1.bc link2.bc
When I tried lli link.bc and llvm-dis link.bc it run correctly and showed linked ll file, but when I use opt link.bc -S -o link.ll to get ll file it just reported segmentation error. Can anyone let me know what to do with opt?
It seems like it is because version compatible issue of opt. I should use a 3.5 version but turns out I was using 3.4.2.

Why two threads in NPTL have different pid in Ubuntu12.04

I tested some code in Ubuntu 12.04 LTS server x64(3.2 kernel), which I think is using NPTL.
when I run
$ getconf GNU_LIBPTHREAD_VERSION
I get
NPTL 2.15
The following is the test code. I compiled it with gcc -g -Wall -pthread
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
void *func1(void *arg)
{
printf("func1:[%d]%lu\n", getpid(), pthread_self());
for(;;);
return (void *)0;
}
int main(void)
{
printf("main:[%d]%lu\n", getpid(), pthread_self());
pthread_t tid1;
pthread_create(&tid1, NULL, func1, NULL);
void *tret = NULL;
pthread_join(tid1, &tret);
return 0;
}
when I run the program, it seems all to be expected: two threads have the same pid
$ ./a.out
main:[2107]139745753233152
func1:[2107]139745744897792
but in htop (a top like tool, you can get it by apt-get) I see this: two threads have different pid
PID Command
2108 ./a.out
2107 ./a.out
If I kill the pid 2108, the process will be killed
$ kill -9 2108
$./a.out
main:[2107]139745753233152
func1:[2107]139745744897792
Killed
And if I run the program through gdb, I can see LWP
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
main:[2183]140737354069760
[New Thread 0x7ffff77fd700 (LWP 2186)]
func1:[2183]140737345738496
I think NPTL's threads share one PID and LWP is for LinuxThreads before kernel 2.6.
The Above seems that NPTL is still using LWP under.
Am I right? I want to know the truth about NTPL and LWP.
Thanks.
The two threads do share one PID, as shown by your first example.
htop is showing you TIDs (Thread IDs) in the field marked as PID.

luajit2.0.0 -- Segmentation fault: 11

I use a simple example from http://lua-users.org/wiki/SimpleLuaApiExample to make a test. The sample can be statically linked with libluajit.a with a success, but this error message occurs when you run it:
Segmentation fault: 11
I use LuaJIT-2.0.0 released at 2012-11-08. My OS is Mac OSX Lion 10.7.5.
$ uname -a
Darwin macmatoMacBook-Pro.local 11.4.2 Darwin Kernel Version 11.4.2: Thu Aug 23 16:25:48 PDT 2012; root:xnu-1699.32.7~1/RELEASE_X86_64 x86_64
The test steps:
compile luajit-2.0.0
$ cd lj2
$ ls
COPYRIGHT Makefile README doc dynasm etc src
$ make
==== Building LuaJIT 2.0.0 ====
make -C src
DYNLINK libluajit.so
LINK luajit
OK Successfully built LuaJIT
==== Successfully built LuaJIT 2.0.0 ====
$ rm src/*.so # force to use the static version: libluajit.a
$ cd ..
compile and run the sample app
Both test.c and script.lua come from here. The folder lj2 contains the source code of the above luajit-2.0.0, just compiled successfully.
$ ls
lj2 script.lua test.c
use clang compiler
$ clang -o test test.c -I./lj2/src -L./lj2/src -lluajit
$ ./test
Segmentation fault: 11
use gcc compiler
$ gcc -o test test.c -I./lj2/src -L./lj2/src -lluajit
$ ./test
Segmentation fault: 11
But if I replace lj2/src/luajit.c with test.c, it will give me a success. This is very strange. See below:
$ cd lj2
$ make clean
$ mv src/luajit.c src/luajit.c.orig
$ cp ../test.c src/luajit.c
$ make
$ cp src/luajit ../
$ cd ..
$ ./luajit
The table the script received has:
1 2
2 4
3 6
4 8
5 10
Returning data back to C
Script returned: 30
Problem resolved. There is an section which explains how to Embedding LuaJIT in this page:
http://luajit.org/install.html
If you're building a 64 bit application on OSX which links directly or indirectly against > LuaJIT, you need to link your main executable with these flags:
-pagezero_size 10000 -image_base 100000000
Also, it's recommended to rebase all (self-compiled) shared libraries which are loaded at runtime on OSX/x64 (e.g. C extension modules for Lua). See: man rebase
Now, let me test it again:
$ clang -o test test.c -O3 -I./lj2/src -L./lj2/src -lluajit -pagezero_size 10000 -image_base 100000000
$ ./test
The table the script received has:
1 2
2 4
3 6
4 8
5 10
Returning data back to C
Script returned: 30
And valgrind returns
$ valgrind ./test
bad executable (__PAGEZERO is not 4 GB)
valgrind: ./test: cannot execute binary file
That's another question.

Resources