본문 바로가기

S-DEV/네트워크 보안

Byte order

728x90

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