c++2022. 10. 29. 14:18

 

 

아래 링크의 Android Asan 빌드 방식을 이해하기 위해 이번 테스트를 진행한다.

https://source.android.com/docs/security/test/asan

 

 

Windows의 toolchain인 mingw64 package에서는 -fsanitize=address를 지원하지 않는다. ( -lasan lib이 존재하지 않음.)

환경)

WSL 에서 clang++을 이용해서 테스트를 아래의 명령어로 간단하게 진행한다.

 

목표) 

clang으로 빌드할 때, -fsanitize=address 를 포함하는 executable과 shared lib의 결합에 어떤 영향을 주는지 확인.

 

테스트에 사용될 libfoo.so 및 libfoo_san.so에 사용된 foo_san.cc의 내용은 heap-buffer-overflow를 발생하도록 작성되었다.

SUMMARY: AddressSanitizer: heap-buffer-overflow (libfoo_san.so+0x12a9) in foo()

#foo_san.cc

#include <iostream>


void foo(){

        std::cout<<"foo_san"<<std::endl;
        char *ptr=(char*) malloc(1);
        ptr[2]='a';

}



#main.cc
#include <iostream>
#include "foo.h"

int main(){
        char*ptr = (char*)malloc(1);
        foo();
        ptr[2] ='b';
        return 0;
}

 

#libfoo.so 및 libfoo_san.so 빌드

 

clang++ -shared -o libfoo.so foo_san.cc

clang++ -shared -fsanitize=address -o libfoo_san.so foo_san.cc

 

 

위 두가지 so를 이용하여 main.cc를 두가지 옵션으로 각각 호출 해본다.

 

test1) 일반 실행 파일 + 일반 shared lib

heap-buffer-overflow에 대한 아무런 오류를 출력해주지 않는다.

$clang++ main.cc libfoo.so -Wl,-rpath,.

 

jayce@DESKTOP-J8A6E99:/mnt/d/wsl/asan_test/shared_lib$ ./a.out
foo_san

 

 

test2) asan 실행 파일 + asan shared lib

아래와 같이 libfoo_san.so의 문제를 예쁘게 출력해 준다.

$clang++ main.cc -fsanitize=address libfoo_san.so -Wl,-rpath,.

jayce@DESKTOP-J8A6E99:/mnt/d/wsl/asan_test/shared_lib$ ./a.out
foo_san
=================================================================
==5530==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000032 at pc 0x7fc4c3f932aa bp 0x7fff5e90be00 sp 0x7fff5e90bdf8
WRITE of size 1 at 0x602000000032 thread T0
    #0 0x7fc4c3f932a9 in foo() (libfoo_san.so+0x12a9)
    #1 0x4c6b21 in main (/mnt/d/wsl/asan_test/shared_lib/a.out+0x4c6b21)
    #2 0x7fc4c3a3a082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
    #3 0x41c36d in _start (/mnt/d/wsl/asan_test/shared_lib/a.out+0x41c36d)

0x602000000032 is located 1 bytes to the right of 1-byte region [0x602000000030,0x602000000031)
allocated by thread T0 here:
    #0 0x494aad in malloc (/mnt/d/wsl/asan_test/shared_lib/a.out+0x494aad)
    #1 0x7fc4c3f93260 in foo() (libfoo_san.so+0x1260)
    #2 0x4c6b21 in main (/mnt/d/wsl/asan_test/shared_lib/a.out+0x4c6b21)
    #3 0x7fc4c3a3a082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)

SUMMARY: AddressSanitizer: heap-buffer-overflow (libfoo_san.so+0x12a9) in foo()
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 01 fa fa fa[01]fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==5530==ABORTING

 

 

test3)  일반 실행 파일 + asan shared lib

asan 옵션을 가지고 compile된 so의 경우, 일반 executable과 linking이 불가능하다.

so 생성 시, asan 에 대한 symbol이 추가되기 때문.

따라서 asan 빌드된 library를 device의 일반 library에 replace하여 Asan 기능 활성화는 불가능다.

$clang++ main.cc libfoo_san.so -Wl,-rpath,.

jayce@DESKTOP-J8A6E99:/mnt/d/wsl/asan_test/shared_lib$ clang++ main.cc libfoo_san.so -Wl,-rpath,.
/usr/bin/ld: libfoo_san.so: undefined reference to `__asan_register_globals'
/usr/bin/ld: libfoo_san.so: undefined reference to `__asan_unregister_globals'
/usr/bin/ld: libfoo_san.so: undefined reference to `__asan_init'
/usr/bin/ld: libfoo_san.so: undefined reference to `__asan_report_store1'
/usr/bin/ld: libfoo_san.so: undefined reference to `__asan_after_dynamic_init'
/usr/bin/ld: libfoo_san.so: undefined reference to `__asan_version_mismatch_check_v8'
/usr/bin/ld: libfoo_san.so: undefined reference to `__asan_before_dynamic_init'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
jayce@DESKTOP-J8A6E99:/mnt/d/wsl/asan_test/shared_lib$
jayce@DESKTOP-J8A6E99:/mnt/d/wsl/asan_test/shared_lib$ objdump -t libfoo_san.so  | grep asan
00000000000012c0 l     F .text  0000000000000021              asan.module_ctor
00000000000012f0 l     F .text  0000000000000017              asan.module_dtor
0000000000000000         *UND*  0000000000000000              __asan_register_globals
0000000000000000         *UND*  0000000000000000              __asan_unregister_globals
0000000000000000         *UND*  0000000000000000              __asan_init
0000000000000000         *UND*  0000000000000000              __asan_report_store1
0000000000000000         *UND*  0000000000000000              __asan_after_dynamic_init
0000000000000000         *UND*  0000000000000000              __asan_version_mismatch_check_v8
0000000000000000         *UND*  0000000000000000              __asan_before_dynamic_init
jayce@DESKTOP-J8A6E99:/mnt/d/wsl/asan_test/shared_lib$

 

test4) 반대로 asan executable의 경우, 일반 lib과 linking에 문제가 없다. 다만 lib에서의 heap-buffer-overflow를 잡아내지 못한다. (executable 자체의 디버깅을 위한 asan 활성화는 target device의 library를 신경쓰지 않고 활성화가 가능함을 의미)

 

$clang++ main.cc -fsanitize=address libfoo.so -Wl,-rpath,.

jayce@DESKTOP-J8A6E99:/mnt/d/wsl/asan_test/shared_lib$ ./a.out
foo_san
=================================================================
==5538==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000012 at pc 0x0000004c6b67 bp 0x7ffd4a61e960 sp 0x7ffd4a61e958
WRITE of size 1 at 0x602000000012 thread T0
    #0 0x4c6b66 in main (/mnt/d/wsl/asan_test/shared_lib/a.out+0x4c6b66)
    #1 0x7f6619ee9082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
    #2 0x41c36d in _start (/mnt/d/wsl/asan_test/shared_lib/a.out+0x41c36d)

0x602000000012 is located 1 bytes to the right of 1-byte region [0x602000000010,0x602000000011)
allocated by thread T0 here:
    #0 0x494aad in malloc (/mnt/d/wsl/asan_test/shared_lib/a.out+0x494aad)
    #1 0x4c6b18 in main (/mnt/d/wsl/asan_test/shared_lib/a.out+0x4c6b18)
    #2 0x7f6619ee9082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/mnt/d/wsl/asan_test/shared_lib/a.out+0x4c6b66) in main
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa[01]fa fa fa 01 fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==5538==ABORTING

 

참조: 

https://stackoverflow.com/questions/33519085/cannot-specify-multiple-rpath-in-eclipse-cdt

https://stackoverflow.com/questions/25160245/clang-linking-with-a-so-file

'c++' 카테고리의 다른 글

map vs unorderedmap 성능 차이  (0) 2022.11.02
undef 활용, log message 출력  (0) 2019.10.02
lambda expression on capture  (0) 2018.06.29
Posted by easy16
android2022. 10. 25. 23:22

 

 

 

persist.logd.size.main (Settings app)?

persist.logd.size.system

https://medium.com/@roperluo.me/android-logd-log-principle-4739bc78cb4b

ro.logd.size(BoardConfig.mk)?

logcat size 관련

http://androidxref.com/9.0.0_r3/xref/system/core/liblog/properties.c#600

 

logcat 버퍼 종류

http://egloos.zum.com/furmuwon/v/11335434

'android' 카테고리의 다른 글

android omx IL architecture  (0) 2022.11.03
logcat option 활용  (0) 2022.10.25
dumpsys package 참조  (0) 2022.09.11
Android 12 : cfi check fail 회피 방법  (1) 2022.06.30
sendevent로 Linux keyevent 전송 방법  (0) 2022.04.01
Posted by easy16
android2022. 10. 25. 22:38

 

/system/bin/logcat -v threadtime -f [출력파일명] -r [파일순환할 크기 kbytes] -n [몇개의 파일로] -s [TAG명]:[출력레벨]...

 

ex)

/system/bin/logcat -v threadtime -f /sdcard/logcat -r 10000 -n 10 -s bt_btif:W bt_a2dp:W bt_btif:W;

 

옵션

다음 표는 logcat의 명령줄 옵션을 설명합니다.

옵션설명
-b <buffer> 보기 위한 대체 로그 버퍼를 로드합니다(예: events 또는 radio). main, system  crash 버퍼 세트가 기본적으로 사용됩니다. 대체 로그 버퍼 보기를 참조하세요.
-c, --clear 선택한 버퍼를 지우고(플러시하고) 종료합니다. 기본 버퍼 세트는 main, system, crash입니다. 모든 버퍼를 지우려면 -b all -c를 사용합니다.
-e <expr>, --regex=<expr> 로그 메시지가 <expr>과 일치하는 줄만 출력합니다. 여기서 <expr>은 정규 표현식입니다.
-m <count>, --max-count=<count> <count>개 줄을 출력한 후 종료합니다. --regex와의 페어링용이지만 자체적으로도 작동합니다.
--print --regex  --max-count와 페어링하면 콘텐츠가 정규식 필터를 우회할 수 있지만, 여전히 올바른 일치 숫자에서 중지합니다.
-d 로그를 화면에 덤프하고 종료합니다.
-f <filename> 로그 메시지 출력을 <filename>에 씁니다. 기본값은 stdout입니다.
-g, --buffer-size 지정된 로그 버퍼의 크기를 출력하고 종료합니다.
-n <count> 순환되는 로그의 최대 수를 <count>로 설정합니다. 기본값은 4입니다. -r 옵션이 필요합니다.
-r <kbytes> <kbytes> 출력마다 로그 파일을 순환시킵니다. 기본값은 16입니다. -f 옵션이 필요합니다.
-s 모든 태그의 우선순위를 'silent'로 설정하는 필터 표현식 '*:S'와 동일하며, 콘텐츠를 추가하는 필터 표현식 목록 앞에 두기 위해 사용합니다. 자세한 내용은 로그 출력 필터링 섹션을 참고하세요.
-v <format> 로그 메시지의 출력 형식을 설정합니다. 기본값은 threadtime 형식입니다. 지원되는 형식의 목록은 로그 출력 형식 제어 섹션을 참조하세요.
-D, --dividers 각 로그 버퍼 간의 구분선을 출력합니다.
-c 전체 로그를 플러시하고(지우고) 종료합니다.
-t <count> 가장 최근의 줄 수만 출력합니다. 이 옵션은 -d 기능을 포함합니다.
-t '<time>' 지정된 시간 이후 가장 최근의 줄을 출력합니다. 이 옵션은 -d 기능을 포함합니다. 공백이 있는 매개변수에 따옴표를 사용하는 방법에 관한 자세한 내용은 -P 옵션을 참조하세요.
 
-T <count> 지정된 시간 이후 가장 최근의 줄 수를 출력합니다. 이 옵션은 -d 기능을 포함하지 않습니다.
-T '<time>' 지정된 시간 이후 가장 최근의 줄을 출력합니다. 이 옵션은 -d 기능을 포함하지 않습니다. 공백이 있는 매개변수에 따옴표를 사용하는 방법에 관한 자세한 내용은 -P 옵션을 참조하세요.
 
-L, --last 마지막 재부팅 전에 로그를 덤프합니다.
-B, --binary 로그를 바이너리로 출력합니다.
-S, --statistics 로그 스패머를 식별하고 타겟팅할 수 있도록 통계를 출력에 포함합니다.
-G <size> 로그 링 버퍼의 크기를 설정합니다. K 또는 M을 끝에 추가하여 KB나 MB를 표시합니다.
-p, --prune 다음과 같이 허용 목록과 차단 목록을 출력(읽기)하고 인수를 사용하지 않습니다.
 
-P '<list> ...'
--prune '<list> ...' -P '<allowlist_and_denylist>'
허용 목록과 차단 목록을 작성(설정)하여 특정 목적에 맞게 로깅 콘텐츠를 조정합니다. 허용 목록과 차단 목록 항목의 혼합 콘텐츠를 제공합니다. 여기서 <allowlist> 또는 <denylist>는 UID, UID/PID 또는 PID가 될 수 있습니다. Logcat 통계(logcat -S)의 안내에 따라 다음과 같은 목적으로 허용 목록 및 차단 목록을 조정할 수 있습니다.
  • UID 선택을 통해 특정 로깅 콘텐츠에 가장 긴 수명을 부여합니다.
  • 사용자(UID) 또는 프로세스(PID)가 이러한 리소스를 사용하지 못하도록 하여 로그 콘텐츠의 범위를 늘리므로 진단 중인 문제를 더 잘 파악할 수 있습니다.
기본적으로 로깅 시스템은 로그 통계에서 최악의 위반자를 자동 차단하여 동적으로 새로운 로그 메시지의 공간을 만듭니다. 휴리스틱이 고갈되면 시스템은 가장 오래된 항목을 잘라내어 새 메시지를 위한 공간을 확보합니다.
허용 목록을 추가하면 AID(Android Identification Number)가 보호되어 프로세스의 AID 및 GID가 위반자로 선언되는 것을 방지하며, 차단 목록을 추가하면 최악의 위반자로 간주되기 전에 공간을 확보할 수 있습니다. 잘라내기를 얼마나 적극적으로 할지 선택할 수 있습니다. 또한, 각 로그 버퍼의 가장 오래된 항목에서만 콘텐츠를 삭제하도록 잘라내기를 해제할 수도 있습니다.
따옴표
adb logcat은 따옴표를 유지하지 않으므로 다음과 같은 구문으로 허용 목록과 차단 목록을 지정합니다.
 
다음 예에서는 PID 32676 및 UID 675로 허용 목록을 지정하고, PID 32677 및 UID 897로 차단 목록을 지정합니다. 더 빠른 잘라내기를 위해 차단 목록의 PID 32677에 가중치가 적용됩니다.
 
허용 목록 및 차단 목록에 사용할 수 있는 다른 명령어 변형은 다음과 같습니다.
 
--pid=<pid> ... 지정된 PID의 로그만 출력합니다.
--wrap 두 시간 동안 절전 모드일 때 또는 버퍼가 래핑하려고 할 때 중 하나가 먼저 발생하는 경우 about-to-wrap wakeup을 제공하여 폴링의 효율성을 높입니다.

출처 : https://developer.android.com/studio/command-line/logcat?hl=ko 

'android' 카테고리의 다른 글

android omx IL architecture  (0) 2022.11.03
logger size 변경 관련  (0) 2022.10.25
dumpsys package 참조  (0) 2022.09.11
Android 12 : cfi check fail 회피 방법  (1) 2022.06.30
sendevent로 Linux keyevent 전송 방법  (0) 2022.04.01
Posted by easy16