10진수 / 16진수 / 2진수
decimal | hexadecimal | binary |
0 | 0 | 0000 |
1 | 1 | 0001 |
2 | 2 | 0010 |
3 | 3 | 0011 |
4 | 4 | 0100 |
5 | 5 | 0101 |
6 | 6 | 0110 |
7 | 7 | 0111 |
8 | 8 | 1000 |
9 | 9 | 1001 |
10 | A | 1010 |
11 | B | 1011 |
12 | C | 1100 |
13 | D | 1101 |
14 | E | 1110 |
15 | F | 1111 |
• Unit
unit | description | range |
nibble | byte의 절반의 의미로 4bit | 16가지 경우의 수를 가진다(0 ~ 15, 0x0 ~ 0xF) |
byte | memory addressing 단위로 전통적인 8bit | 256가지의 경우의 수를 가진다(0 ~ 255, 0x00 ~ 0xFF) |
* hexideciaml 1자리 숫자로 nibble을 표현하고 2자리 숫자로 byte를 표현할 수 있음
• NBO와 HBO
ex) TCP Header에서 4660 포트 번호가 보인다. Packet Bytes Window에서 보면 0x1234로 잡힌다.
- NBO(network byte order) : 0x1234로 보인다.
- HBO(host byte order) : little endian인 경우 -> 0x3412, big endian인 경우 -> 0x1234로 보인다.
void write_4660() {
uint16_t port = 4660; // 0x1234
printf("port number = %d\n", port);
dump(&port, sizeof(port));
코드를 분석해보자.
16 bits port에 4660 값을 넣어준 값이 출력이 될 때 0x1234로 출력이 된다.
void write_0x1234() {
uint8_t network_buffer[] = { 0x12, 0x34 };
uint16_t* p = reinterpret_cast<uint16_t*>(network_buffer);
uint16_t n = *p; // TODO
printf("16 bit number=0x%x\n", n);
다음 함수는 network_buffer에 0x12, 0x34를 넣어주면 출력이 될 때는 0x3412가 된다, 해당 패킷이 출력이 될 때 리틀엔디안으로 넣어진다. 해당 출력을 0x1234로 출력하기 위해 코드를 작성해 보자.
uint16_t my_ntohs(uint16_t n) {
uint16_t n1 = (n & 0xFF00) >> 8;
//printf("%04x\n",n1);
uint16_t n2= (n & 0x00FF) << 8;
//printf("%04x\n",n2);
return n1 | n2;
}
void write_0x1234() {
uint8_t network_buffer[] = { 0x12, 0x34 };
uint16_t* p = reinterpret_cast<uint16_t*>(network_buffer);
uint16_t n = my_ntohs(*p); // TODO
printf("16 bit number=0x%x\n", n);
}
포트번호를 네트워크 바이트 순서에서 호스트 바이트 순서로 바꾸기 위해 my_ntohs 함수를 만들어준다.
함수를 작성하기 위해서는 *알고 있어 하는 부분이 있다. -> ex) AABB 가 들어있으면 비트 마스크를 씌어줘야 한다. => 0 xFF00으로 상위 1바이트를 씌어주면 AA00가 되고 0x00 FF로 하위 1바이트를 씌어주면 00BB가 된다.
위 코드에 적용을 하고 0x3400으로 나오는 부분을 비트연산을 이용해 >> 8bit 이동시켜준다.
0x0012 부분도 << 8bit 이동시켜주면 0x1234가 정상적으로 출력이 된다.
* 네트워크 바이트 순서 변환 함수
- htons : short형의 데이터, 포트번호를 호스트 바이트 순서에서 네트워크 바이트 순서로 변환
- htonl : long형의 데이터, 포트번호를 호스트 바이트 순서에서 네트워크 바이트 순서로 변환
- ntohs : short형의 데이터, 포트번호를 네트워크 바이트 순서에서 호스트 바이트 순서로 변환
- ntohl : long형의 데이터, 포트번호를 네트워크 순서에서 호스트 바이트 순서로 변환
void write_0x12345678() {
uint8_t network_buffer[] = { 0x12, 0x34, 0x56, 0x78 };
uint32_t* p = reinterpret_cast<uint32_t*>(network_buffer);
uint32_t n = my_ntohl(*p); // TODO
printf("32 bit number=0x%x\n", n);
}
이번에는 긴 데이터를 0x12345678로 출력되게 코드를 작성해 보자.
uint32_t my_ntohl(uint32_t n){
uint32_t n1 = (n & 0xFF000000) >> 24;
//printf("%08x\n",n1);
uint32_t n2 = (n & 0x00FF0000) >> 8;
//printf("%08x\n",n2);
uint32_t n3 = (n & 0x0000FF00) << 8;
//printf("%08x\n",n3);
uint32_t n4 = (n & 0x000000FF) << 24;
//printf("%08x\n",n4);
return n1|n2|n3|n4;
}
디버그 하면서 비트연산을 구했지만, 왜 24bit의 연산을 했는지 감이 안 온다,, 더 공부를 해야 할 것 같다.
=> 해결 uint32_t 는 32bit이다. 그러므로 0xFF000000 에서 FF 00 00 00 이렇게 나눠지는데 한 1개다 8bit이기 때문에 맨 끝으로 이동할려면 8bit를 3번 가야하니까 24bit이동해야한다.
'S-DEV > 네트워크 보안' 카테고리의 다른 글
Report pcap test (0) | 2023.07.18 |
---|---|
Basic header analysis (0) | 2023.07.15 |
OSI model and TCP/IP Layer (0) | 2023.07.15 |
Git (sum 실습) (0) | 2023.07.02 |