ABOUT ME

I will trust that the dots will somehow connect in your future.

Today
Yesterday
Total
  • gcc & LD_PRELOAD & 동적 라이브러리 & makefile -2
    Linux Basic 2024. 4. 29. 00:15

     

    앞에서 배운 동적 라이브러리와 LD_PRELOAD를 이용해서 곱하기를 나누기로 변경하는 재미있는 놀이를 해볼 생각이다.

     

    1. 파일 준비

     

    아래 처럼 4개의 파일을 만들어 준다.

    div.h, div.c, mul.h, mul.c

    //div.c
    #include <stdio.h>
    
    int div(int b)
    {
        int a;
    
        for(a = 1; a < 10; a++) {
    	    printf("%d / %d = %d\n", b, a, a / b);
        }
    
        return 0;
    }
    
    //div.h
    int div(int b);
    
    //mul.c
    #include <stdio.h>
    
    int mul(int b)
    {
        int a;
    
        for(a = 1; a < 10; a++) {
    	    printf("%d * %d = %d\n", b, a, a * b);
        }
    
        return 0;
    }
    
    //mul.h
    int mul(int b);

     

     

    https://m.blog.naver.com/whtie5500/221692793640

     

    [C] pthread란? pthread예제

    오늘은 pthread입니다! 아마 운영체제시간에 배울텐데요~ 저는 운영체제수업시간에 배웠거든요! 흠 오늘은 ...

    blog.naver.com

     

    위 사이트를 참조해서 thread 를 수정해서 만들었다.

     

    2. thread 파일 생성

     

    일반적으로 thread를 사용할때 동적라이브러를 많이 사용해서 구조를 비슷하게 가져가봤다.

    // libthread_func.c
    #include <pthread.h>
    #include <stdio.h>
    #include "mul.h"
    
    void* thread_function(void* arg) {
        printf("Thread function from dynamic library\n");
    
        pid_t pid; //process id
        pthread_t tid; // thread id
    
        pid = getpid(); //4
        tid = pthread_self();
    
        char* thread_name = (char *)arg;
        int i = 0;
        int b;
    
        printf("출력할 단의 숫자를 입력해 주세요");
        scanf("%d", &b);    
        mul(b);    
    
        printf("thread name : %s, tid : %x, pid : %u\n", thread_name, (unsigned int)tid, (unsigned int)pid); //5
    
    
        return NULL;
    }

     

    //libthread_func.h
    void* thread_function(void* arg);

     

    아래 동적 라이브러리를 쓰기 위해서 libthread_func.h 해더를 참조해서 함수를 호출하는 식으로 했다.

    //main.c
    #include <stdio.h>
    #include <pthread.h>
    #include <dlfcn.h> // 동적 라이브러리 관련 헤더 파일
    #include "libthread_func.h"
    
    int main() {
        pthread_t thread_id;
        void* lib_handle;
        char p1[] = "thread_1";
    
        // 스레드 생성 및 실행
        if (pthread_create(&thread_id, NULL, thread_function, (void*)p1)) {
            fprintf(stderr, "Error creating thread\n");
            dlclose(lib_handle);
            return 1;
        }
    
        // 스레드가 종료될 때까지 대기
        pthread_join(thread_id, NULL);
    
        return 0;
    }

     

     

    이제 준비가 끝났으니 차례대로 빌드해서 실행 시켜보자!

     

    3. Makefile 파일 생성

    CC = gcc
    LDFLAGS = -fPIC
    EXE = main
    CFLAGS = -shared
    OBJS = *.so *.o
    
    main.o : main.c
    	$(CC) -c $< $(LDFLAGS)
    
    libthread_func.o : libthread_func.c
    	$(CC) -c $< $(LDFLAGS)
    
    mul.o : mul.c
    	$(CC) -c $< $(LDFLAGS)	
    
    div.o : div.c
    	$(CC) -c $< $(LDFLAGS)	
    
    mul_hook.o : mul_hook.c
    	$(CC) -o $@ -c $< $(LDFLAGS)
    
    $(EXE): main.o mul.o libthread_func.o mul_hook.o div.o
    	$(CC) $(CFLAGS) -o mul_hook.so mul_hook.o $(LDFLAGS)
    	$(CC) $(CFLAGS) -o libthread_func.so libthread_func.o mul.o div.o $(LDFLAGS)
    	$(CC) -o $(EXE) $< -L./ -lthread_func
    
    clean:
    	rm -f $(OBJS) $(EXE)

     

    아래처럼 작성 후 make main을 치고 main파일 치면 아래와 같이 나올 것이다.

     

    4. 실행

    $./main
    Thread function from dynamic library
    출력할 단의 숫자를 입력해 주세요5
    5 * 1 = 5
    5 * 2 = 10
    5 * 3 = 15
    5 * 4 = 20
    5 * 5 = 25
    5 * 6 = 30
    5 * 7 = 35
    5 * 8 = 40
    5 * 9 = 45
    thread name : thread_1, tid : d31ff640, pid : 9074

     

    이제 hook함수를 만들어서 곱셈을 나눗셈으로 변경해보자.

     

    //mul_hook.c
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <dlfcn.h>
    #include <time.h>
     
    int mul(int b)
    {
        clock_t start, end;
        double cpu_time_used;
        int c;
    
        int (*new_mul)(int b);
        new_mul = dlsym(RTLD_NEXT, "div");
    
        c = new_mul(b);
    
        return c;
    }

     

     

    5. hook 연습

    내가 위에서 동적 라이브러리 만들때 아래처럼 div.o로 추가 했기때문에 찾을 수 있다.

    $(CC) $(CFLAGS) -o libthread_func.so libthread_func.o mul.o div.o $(LDFLAGS)

     

    아래처럼 곱셉이 나눗셈으로 변경된것을 확인할 수 있다.

    $LD_PRELOAD=${PWD}/mul_hook.so ./main
    Thread function from dynamic library
    출력할 단의 숫자를 입력해 주세요5
    5 / 1 = 0
    5 / 2 = 0
    5 / 3 = 0
    5 / 4 = 0
    5 / 5 = 1
    5 / 6 = 1
    5 / 7 = 1
    5 / 8 = 1
    5 / 9 = 1
    thread name : thread_1, tid : 361ff640, pid : 9218

     

    6. Makefile 최적화

     

    더 최적화를 할 수 있지만 아래 처럼 object 파일 생성만 줄여도 많이 줄어든다.

    CC = gcc
    LDFLAGS = -fPIC
    EXE = main
    CFLAGS = -shared
    OBJS = *.so *.o
    SRC_DIR = ./
    
    SRCS = $(notdir $(wildcard $(SRC_DIR)/*.c))
    OBJECTS = $(SRCS:.c=.o)
    
    $(EXE): $(OBJECTS) 
    	@echo $(OBJECTS)
    	$(CC) $(CFLAGS) -o mul_hook.so mul_hook.o $(LDFLAGS)
    	$(CC) $(CFLAGS) -o libthread_func.so libthread_func.o mul.o div.o $(LDFLAGS)
    	$(CC) -o $(EXE) main.o -L./ -lthread_func
    
    clean:
    	rm -f $(OBJS) $(EXE)

     

    더 자세한 설명은 아래 두 사이트를 참조하면 된다.

     

    7. CMake적용

     

    일반적으로 Makefile 보다는 CMakeLists.txt을 만들어서 많이 사용한다.

    위 예제를 Cmake버전으로 변경해보자.

    cmake_minimum_required(VERSION 3.0)
    project(hook_example)
    add_compile_options(-fPIC)
    
    
    # 실행 파일 빌드
    add_executable(main main.c)
    
    # 곱셈 연산 후킹 라이브러리 빌드
    add_library(mul_hook SHARED mul_hook.c )
    add_library(thread_func SHARED libthread_func.c mul.c div.c)
    
    
    # 실행 파일에 링크
    target_link_libraries(main thread_func)

     

    cmake ..

    make

    ./main

     LD_PRELOAD=${PWD}/libmul_hook.so ./main

     

    https://modoocode.com/311

     

    씹어먹는 C++ - <19 - 1. Make 사용 가이드 (Makefile 만들기)>

    모두의 코드 씹어먹는 C++ - <19 - 1. Make 사용 가이드 (Makefile 만들기)> 작성일 : 2020-06-10 이 글은 85879 번 읽혔습니다. 에 대해서 다루어 보겠습니다. 안녕하세요. 이번 강좌 부터는 씹어먹는 C++ 시리

    modoocode.com

     

    https://blog.naver.com/komixer_die/30154063239

     

    Makefile 지원 함수 몇 가지. (subst, wildcard, patsubst, notdir)

    Makefile 에서는 다양한 함수를 지원 하는데요. 몇 가지 알아보고 정리하고자 합니다.   먼저 subst ...

    blog.naver.com

     

    반응형

    'Linux Basic' 카테고리의 다른 글

    리눅스에서 압축 풀때  (3) 2024.07.25
    sftp server 설정  (0) 2024.05.15
    gcc & 정적 라이브러리 & 동적 라이브러리 & makefile - 1  (0) 2024.04.27
    cmake on linux  (0) 2023.09.17
    onnx docker 사용하기  (0) 2023.07.16
Designed by Tistory.