챕터3 kernel.asm 파일에
db 0x66
db 0x67
db 0xEA
dd PM_Start
dw SysCodeSelector
이 부분을
;db 0x66
;db 0x67
[bits 32]
db 0xEA
dd PM_Start
dw SysCodeSelector
이런식으로 바꾸면 왜 실행이 안될까 하는 부분이 있었는데요
생각을 해봤는데 제 생각은 이렇습니다
(사견이므로 틀릴 수도 있습니다)
[bits 32]는 컴파일러가 16비트용으로 작성된 코드를 자동으로 prefix를 붙여 32비트용으로 바꾸는 역할을 합니다
그런데 위의 코드는 컴파일러가 알아들을 수 있는 어셈블리 명령이 아닌
db를 이용해 기계어 바이트 코드를 직접 입력하였습니다
따라서 컴파일러 입장에서는 저게 jmp명령인지 사용자가 데이터를 저장해둔 건지 알 방법이 없죠
그래서 prefix를 붙이지 않고 0xEA라는 코드를 그대로 사용하는 것 같습니다
디스어셈블 하지 않고 헥사코드를 보면 아래 [bits 32]를 넣은 코드는
EA230000000800
이런식으로 나옵니다
prefix가 붙지 않더라구요
반면 첫번째 코드는
6667EA250000000800
이런식으로 맨 앞에 66과67이 붙습니다
그리고 책에 나온대로 jmp명령을 사용하여 jmp dword SysCodeSelector:PM_Start를 이용하면
66EA240000000800
이런 코드가 생깁니다 (67은 없어도 되는듯)
그래서
db 0x66
db 0xEA
dd PM_Start
dw SysCodeSelector
이렇게 적었더니 이것도 실행이 되더라구요
헥사코드는 66EA240000000800 로 jmp dword SysCodeSelector:PM_Start를 이용했을때와 완전히 동일한 코드가 나왔습니다
왜 67이 없어도 되는지는 잘 모르겠네요 ㅎㅎ
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
공지 | [공지] 커널 스터디 관련 Q&A 게시판 입니다. [5] | woos | 2016.04.09 | 2197 |
1485 | First.S, Second.S 분석한 자료 | 도영주 | 2013.08.03 | 1441 |
1484 | kernel 에서 실행 순서 관련 문서 | 도영주 | 2013.08.03 | 1880 |
1483 | 오늘 스터디 시간에 잠깐 찾은 second.S 분석 pdf [1] | 제한재 | 2013.07.27 | 1841 |
1482 | lilo 분석 참고 자료 | 시갈 | 2013.07.27 | 1463 |
1481 | 헷갈리는 주소, 포인터 연산에 대하여 정리( #, (), [] ) [2] | 시대유감 | 2013.07.20 | 3164 |
1480 | Register 관련 몇 가지 정리. | 도영주 | 2013.07.16 | 3244 |
1479 | 처음 어셈블리 해보시는데 할만하세요? [4] | 백창우 | 2013.07.08 | 1891 |
1478 | SVN 사용법 정리 [2] | 시대유감 | 2013.06.30 | 2135 |
1477 | 회식사진 투척합니다. [5] | 김택훈 | 2013.06.30 | 2291 |
1476 | 7장 소스1 | 시갈 | 2013.06.22 | 1415 |
1475 | 분석 관련 자료 [3] | 백창우 | 2013.06.15 | 1849 |
1474 | 리눅스 커널 분석 환경 [3] | 시대유감 | 2013.06.10 | 2023 |
» | 오늘 풀리지 않은 문제 관련 [1] | 이경욱 | 2013.06.02 | 3305 |
1472 | OS 커널의 구조와 원리 실습 방법 [1] | 시갈 | 2013.05.26 | 5696 |
1471 | 제안사항 입니다. [2] | 강정근 | 2013.05.07 | 3193 |
1470 | ELF 파일 포맷 정리 [6] | 도영주 | 2013.05.04 | 11544 |
1469 | TOZ 신청방법 아시는분?! [4] | 강정근 | 2013.04.29 | 2724 |
1468 | 안녕하세요. 빠른진행을 위해 어플로 접근성을 높여보아요^^ [1] | Napoleon | 2013.04.22 | 3583 |
1467 | 교제 및 장소(투표 종료) [14] | 조유준 | 2013.04.22 | 3838 |
1466 | 반갑습니다. 이성미입니다. [1] | 이성미 | 2013.04.22 | 3396 |
.
이 책은 약간 꼬아놓은 부분 때문에 많이 헷갈리게 하는 것 같습니다.
Intel Architecture Developer Manual을 살펴보니
66H는 operand-size prefix이고, 67H는 source-size prefix입니다.
JMP는 operand, source 형태가 아닌, operand만 가지고 있는 명령어 이기 때문에, 66으로만 해주어도 위의 명령을 해석하는 데에는 아무런 문제가 없는 것 같습니다.
우리가 이전 주 스터디에서
[bits 32]
db 0xEA
dd PM_Start
dw SysCodeSelector
를 하면 될 것 같다고 했었는데, 안되는 이유는 결과를 보면 EA[23000000]0800으로 해석이 안되고,
EA23000000으로 해석이 되어 jmp 0x0:0x23으로 해석이 되어 잘못된 주소를 가리키게 되어 그런 것 입니다.
JMP SysCodeSelector:PM_Start의 원래 원형은 JMP CS:EIP인걸로 책에 나옵니다.
JMP CS(16):EIP(32)는 EA[32][16]으로 변경됩니다.
JMP는 여러 가지로 해석이 됩니다. FF, E8, E9, EA 등등으로 JMP방법에 따라서 해석된 기계어 코드가 다릅니다.
EA는 2가지로 존재하는데, EA cd, EA cp입니다.
EA cd는 뒤에 4byte를 읽어온다는 의미이고, EA cp는 뒤에 6byte를 읽어온다는 의미 입니다.
EA cd = JMP ptr16:16이고, EA cp = JMP ptr16:32입니다.
66이 없으면 EA cd로 해석이 되고, 66이 있으면 EA cp로 해석이 되는 것으로 보입니다.
이는 EA는 jmp자체를 해석한 결과이기 때문에, [bits] 지시자와 관계없이, cp로 해석하려면 반드시 66이라는 값이 앞에 필요하다는 것입니다. 그렇지 않으면 cd로 해석하게 될 것이니까요.
우리가 [BITS ]지시자를 EA를 해석할 때, 16bit주소를 32bit으로 만들어줄 것이라고 생각했기 때문에 잘못 생각하게 된 원인인 것 같습니다.
해결하는데 시간이 꽤 걸렸는데, 정리가 되고 나니 날이 샜네요.ㅠㅠ
샌드위치 데이라서 미리 휴가를 내고 쉬는 날이어서 다행입니다.