일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- GEF
- 지훈현서
- tool
- vmware 반응 속도
- 공유 라이브러리는 왜 항상 같은 순서로 맵핑 될까?
- 개발
- vhdx 파일 복구
- 임베디드 시스템 해킹
- c++
- python3.11 설치
- GDB
- pip 에러 해결
- 리커버릿
- python3.11 pip
- DYNAMIC Section
- pwntools
- z3 signed 이슈
- python
- Recoverit
- 실시간로깅
- VSCode C++ 표준 버전 수정
- std::cerr
- wsl2 복구
- OpenAI 개발
- docker
- Python.h: No such file or directory
- Windows 부팅 오류
- pwn
- Python3
- Seccomp bypass
- Today
- Total
OZ1NG의 뽀나블(Pwnable)
[C/C++] 구조체 bitfield 멤버 변수 선언 ( ':' ) 본문
[*] tcmalloc 코드를 분석하다가 Span 구조체의 멤버 변수 선언부에 `:`으로 신기하게 변수가 선언된 부분이 있어서 찾아보다가 알게된 bitfield에 대해 정리해봤따.
[*] bitfield?
C/C++ 구조체에 있는 문법으로 특정 변수의 크기를 비트 단위로 정할 때 사용한다.
struct {
unsigned int a : 16;
unsigned int b : 16;
unsigned short c;
} typedef test;
위와 같이 선언한다면 a와 b 변수는 원래는 4바이트의 크기를 갖는 unsigned int 형이지만 16비트로 크기 제한을 걸었기
때문에 실제로는 2바이트의 크기만을 갖게 된다. (근데 타입은 유지함..)
이 경우 a와 b 변수는 unsigned short int 형으로 변환된다.
비트 단위는 2^n 단위로 설정할 수 있다.
[*] 사용 목적
struct {
unsigned int a : 2;
unsigned int b : 1;
} typedef test;
예를 들어 2비트 또는 1비트만 필요한 변수라면 위와 같이 선언하여 메모리 낭비를 최소로 만들 수 있다. (극한의 효율...)
[*] 테스트 코드
// unsigned int refcount : 16; 이런 문법 테스트
#include <stdio.h>
#include <stdlib.h>
#define type(x) _Generic((x), \
_Bool: "_Bool", unsigned char: "unsigned char", \
char: "char", signed char: "signed char", \
short int: "short int", unsigned short int: "unsigned short int", \
int: "int", unsigned int: "unsigned int", \
long int: "long int", unsigned long int: "unsigned long int", \
long long int: "long long int", unsigned long long int: "unsigned long long int", \
float: "float", double: "double", \
long double: "long double", char *: "char *", \
void *: "void *", int *: "int *", \
default: "unknown")
struct {
unsigned int a : 16;
unsigned int b : 16;
unsigned short c;
} typedef test;
struct {
unsigned int a : 16;
unsigned short c;
unsigned int b : 16;
} typedef test2;
struct {
unsigned short c;
unsigned int a : 16;
unsigned int b : 16;
} typedef test3;
int main(){
test *buf = malloc(sizeof(test));
test2 *buf2 = malloc(sizeof(test2));
test3 *buf3 = malloc(sizeof(test3));
buf->a = 0x1111;
buf->b = 0x2222;
buf->c = 0x3333;
buf2->a = 0x1111;
buf2->b = 0x2222;
buf2->c = 0x3333;
buf3->a = 0x1111;
buf3->b = 0x2222;
buf3->c = 0x3333;
// break point
printf("value : %p, type : %s\n", buf->a, type(buf->a));
return 0;
}
oz1ng@LAPTOP-6F0C4A2N:/mnt/c/Users/ghdxo/Desktop/oz1ng_Lab/tcmalloc/test$ ./colon_test
value : 0x1111, type : unsigned short int
[*] 메모리 확인
pwndbg> x/20gx 0x405290
0x405290: 0x0000000000000000 0x0000000000000021
0x4052a0: 0x0000333322221111 0x0000000000000000
0x4052b0: 0x0000000000000000 0x0000000000000021
0x4052c0: 0x0000222233331111 0x0000000000000000
0x4052d0: 0x0000000000000000 0x0000000000000021
0x4052e0: 0x0000222211113333 0x0000000000000000
0x4052f0: 0x0000000000000000 0x0000000000020d11
0x405300: 0x0000000000000000 0x0000000000000000
0x405310: 0x0000000000000000 0x0000000000000000
0x405320: 0x0000000000000000 0x0000000000000000
테스트 코드에서 break point 부분까지 실행 후 buf, buf2, buf3의 값을 확인한 모습이다.
unsigned int형이지만 실제로는 unsigned short int와 똑같이 작동하는 것을 볼 수 있다.
[*] 주의
- sizeof의 인자로 비트 필드 변수는 들어갈 수 없다.
[*] 참고
- https://stackoverflow.com/questions/4706584/what-does-this-mean-in-c-int-a16
what does this mean in c int a:16;?
Possible Duplicate: What does 'unsigned temp:3' mean? please what does this notation mean int a:16; I found it is code like this and it does compile. struct name { int ...
stackoverflow.com
'Tips' 카테고리의 다른 글
[C++] 클래스 생성자의 첫 번째 인자 (0) | 2022.07.19 |
---|---|
[C++] new operator 정적 할당(된 곳에 변수 할당) (0) | 2022.07.19 |
[C/C++] Capstone 라이브러리 (disassembly 라이브러리) (0) | 2022.07.18 |
[Python3] 인코딩 범위 무시하고 순수 바이트 값으로 디코딩 하기 (bytes.decode(errors="surrogateescape")) (0) | 2022.07.14 |
[Tips] PIE 보호 기법이 걸려 경우 gdb 디버깅 - gef (0) | 2022.07.14 |