[pwnable with C++] string 객체의 구조
string 메모리 구조
/*nothing*/
#include <string>
#include <iostream>
using namespace std;
int main() {
string* test = new string();
getline(cin, *test);
return 0;
}
코드는 이렇게 짜놓고 대충 메모리 구조만 봤다.
이 상태에서 처음엔 값을 0x10이하의 길이로 주고 힙을 한 번 봤음.
(input : ipwnipwn\n)
pwndbg> x/24gx 0x613c10
0x613c10: 0x0000000000000000 0x0000000000000031
0x613c20: 0x0000000000613c30 0x0000000000000008
0x613c30: 0x6e7770696e777069 0x0000000000000000
0x613c40: 0x0000000000000000 0x0000000000000411
0x613c50: 0x6e7770696e777069 0x000000000000000a
0x613c60: 0x0000000000000000 0x0000000000000000
0x613c70: 0x0000000000000000 0x0000000000000000
0x613c80: 0x0000000000000000 0x0000000000000000
0x613c90: 0x0000000000000000 0x0000000000000000
0x613ca0: 0x0000000000000000 0x0000000000000000
0x613cb0: 0x0000000000000000 0x0000000000000000
0x613cc0: 0x0000000000000000 0x0000000000000000
이것만 봐도 많은 걸 알 수 있음
/*nothing*/
struct string {
char *str;
__int64 size;
char buf[0x10];
}
대충 이런 구조로 이뤄져 있음. (객체의 메모리 구조를 따라서 struct
로 표현한 것)
그리고 str
은 buf
의 주소를 가리킨다는 것도 알 수 있음.
또 버퍼링 하기 위해서 입력받은 값도 힙 할당해서 거기에 받는다는 것도 알 수 있음. (뒤에 이어붙여진 힙을 보면 알 수 있다.)
이제 0x10보다 더 긴 값을 넣어줘보겠음.
당연히 원래 제 위치(buf
)에 0x10보다 긴 값을 넣으면 bof
가 발생하니까 그렇게 구현하진 않겠지?
(input : AAAAAAAAAAAAAAAAAAAAAAA...)
대충 때려박음
갑자기 왜 md 문법으로 메모리 보여주다가 사진을 쓰냐면 parseheap
기능 땜에 글자가 안 이쁘게 짤려서 그렇다.
여튼 parseheap
기능으로 힙을 보면 벌써부터 힙이 더럽다. 그 말은 즉 이래저래 여러 작업들을 거친다는 걸 알 수 있음.
이건 getline
함수 내부 구현을 봐야하는 거라 귀찮으므로 패스. 나중에 보자.
보면 size
는 입력받은 크기만큼 제대로 변경 되어있는 걸 알 수 있고, str
은 입력받은 값이 복사된 그 주소가 박힌다.
그리고 buf + 8
쪽을 보면 일단 buf
에 입력값을 쓰는 것 같긴 한데, 일련의 작업을 거쳐서 buf
쪽에만 값을 어떤 값으로 초기화 해주는 것 같다.
끗
결론
/*nothing*/
struct string {
char *str;
__int64 size;
union{
something...;
char buf[0x10];
}
}
위의 형태로 구현되어 있는듯~!