heap memory 에서 코드를 실행 실패 이슈(ARMv7 환경)
글쓴이: 송파구최고존엄 / 작성시간: 목, 2021/03/11 - 2:42오후
ARMv7,v8 환경에서 heap 메모리에서 코드를 실행하려고 합니다.
mmap을 이용해서 4바이트 할당후 casting 작업후에 실행을했더니 바로 폴트가 나버립니다.
x86, x86_64에서는 정상적으로 되는데 이게 무슨 연유에서안되는지 모르겠습니다.
cpu 입장에서는 이게 heap인지 코드섹션인지 정확히 알지못할것으로 예상이되어
당연히 x86,64가 된다면 arm도 되어야 할것이로 보이거든요
테스트 했던 코드를 첨부해봅니다.
테스트 환경 : android emulator x86, arm, arm64
using func_t = void(*)(); unsigned char test_sum[4] = {0xC0,0x03,0x5F,0xD6}; // armv8 코드 auto raw_ptr = mmap(0, 4, PROT_READ | PROT_WRITE |PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0); std::memcpy(raw_ptr, test_sum, sizeof(test_sum)); auto func = reinterpret_cast<func_t>(raw_ptr); func(); munmap(raw_ptr,4);
Forums:
이거부터 한번 해보시죠.
이거부터 한번 해보시죠.
네 실행이 가능합니다.
네 실행이 가능합니다.
아무런 보안조치가 없다면 실행가능하겠지만,
아무런 보안조치가 없다면 실행가능하겠지만,
데이터 영역에 실행코드가 있더라도 실행하지 못하도록 보안 조치가 있는것 같습니다.
리눅스는 잘 모르겠지만, 윈도우도 DEP 라고 하는게 있습니다.
https://ko.wikipedia.org/wiki/%EB%8D%B0%EC%9D%B4%ED%84%B0_%EC%8B%A4%ED%96%89_%EB%B0%A9%EC%A7%80
NX 비트(NX bit, Never eXecute bit, 실행 방지 비트)는 프로세서 명령어나 코드 또는 데이터 저장을 위한 메모리 영역을 따로 분리하는 CPU의 기술이다.
https://ko.wikipedia.org/wiki/NX_%EB%B9%84%ED%8A%B8
ARM 경우는 용어는 달라도 비슷한게 (CPU나, 커널에)있을것 같습니다.
ARM에서는 XN이라고 하죠. ARM11 시절에도
ARM에서는 XN이라고 하죠. ARM11 시절에도 있었던 물건이니까 ARMv7에는 당연히 있습니다.
https://stackoverflow.com/questions/56083538/how-do-i-know-if-arms-xn-execute-never-bit-support-is-enabled-on-my-system
댓글 감사드립니다.
내용 전부 확인하엿고 도움이 많이 됬습니다.
댓글 감사드립니다.
segmentation과 paging 문제로 보이네요
segmentation과 paging 문제로 보이네요.
x86은 segmentation, paging 둘다 사용합니다(segment register가 존재하며 주소도 segment:offset으로 표시)
ARM은 segment register가 없습니다. paging으로 다 제어합니다.
기본적으로 x86 protected mode는 segment 종류가 code와 data로 나뉘어 있어서 segment가 code일때만 실행이 가능한데, code segment와 data segment를 일부러 겹치게 하는 꼼수를 부리면 data를 code로 실행시키는게 가능하죠. 그래서 나온게 pagetable에 code 실행허가여부를 알리는 NX bit가 추가되었고 인텔이 이걸로 열심히 광고했죠. NX 켜지면 실행할려는 코드의 위치를 세그먼테이션으로 계산한 후 paging으로 물리주소 변환할때 그 페이지가 실행불가영역으로 지정된 곳이면 실행 안하고 exception 때려버리죠.
Written By the Black Knight of Destruction
댓글 달기