리눅스에서 코드 영역에 memcpy시 오류...해결방법은 뭘가요?

mosad34의 이미지

안녕하세요~

프로그램을 짜던중에 윈도우에서 사용중인 부분을 리눅스에 사용할 수 있도록 변환하고 있습니다.

그런데 여기서 문제가 일단 생기는 부분이

코드영역에 해당되는 주소에 memcpy로 뭘 덮어씌우거든요..

윈도우에서는 별 문제 없이 되는데

리눅스에서는 그냥 SIGSEGV 나오면서 뻗네요..

멤카피지 뭐 인자가 잘못들어가거나 그런건 아니구요

단지 목적지 주소가 코드영역이 이거든요..

리눅스에서 뭔가 메모리 보호속성이 걸려있어서 그런거 같은데...

아무리 찾아봐도 gdb로 메모리 속성보는 거나 뭐 그런게 안나와 있더라구요..

혹시나해서 찾아본 mprotect라는 함수로는 코드영역의 보호속성변경이 않된느거 같더라구용..ㅠㅠ

1. gdb로 해당 주소의 메모리 보호속성을 볼수 있는 방법이 있나요?? 뭐 쓰기만 가능 읽기만 가능 모이런거 나오는거요
2. 해당주소의 메모리 보호속성을 변경할수 있는 방법은 뭐가 있을가요..

그냥 예를들어 테스트로 코드여역에 해당되는 4001bf70이라는 주소에다 멤카피만 해도 바로 뻑나네요..

고수님들의 조언이 필요합니다... 도와주세용..ㅠㅠ

kdw2rao의 이미지

void func1(int *x) { *x = 1; }
void func2(int *x) { *x = 2; }

int main(int argc, char **argv)
{
mprotect((void *)((long) func1 & ~(getpagesize() - 1)), func2 - func1, PROT_READ|PROT_WRITE|PROT_EXEC);
memcpy(func1, func2, func2 - func1);
int x;
func1(&x);
printf("%d\n", x);
return 0;
}

mprotect() 의 1번째 인자를 page align 하시면 됩니다.

$cat /proc/PID/maps

mac040의 이미지

윈도우에서도 코드 영역은 RO 영역 아닌가요?

메모리 프로텍트 위치 관련은 코드 컴파일시 결정됩니다. (실제로는 어플리케이션이 실행될 때, 결정되나, 그것이 결정되도록 배치 및 ELF 헤더 생성은 빌드시에 이루어지죠) readelf등으로 보시면 아마 코드들은 모두 RO 영역으로 나올겁니다.

그게 정상이고, 이를 억지로 회피하는 방법은 별로 좋지 못한 방법 같은데요. .?

simpid의 이미지

해법은 모르겠고...(죄송합니다.)

자기 변경 코드는

1) 캐쉬를 부숴버리고..
2) 멀티쓰레딩 환경에 적합하지 않습니다.

라고 말씀드리고 싶네요.

mosad34의 이미지

kdw2rao 님께서 알려주신 방법으로 하니까 잘되네요^^

mprotect 사용을 저렇게 하는거였군요...

정말 정말 감사합니다!!^^

이로써 한가지 더 배웠다는 사실에 너무 기분이 좋네요..

새해복 많이 받으시고 감기조심하세요^^

mosad34의 이미지

mprotect() 의 1번째 인자를 page align 하시면 됩니다.

이 말의 의미를 잘 모르겠어요;;;
mprotect의 첫번째 인자를 저런 식으로 변경해서 넣는게 page align인거 같은데..
복사 할 함수 주소와 (page크기-1) and연산하는데..의미를 잘 모르겠네요..
좀만 더 알려주실수 있을까요??

(void *)((long) func1 & ~(getpagesize() - 1))

kaeri17의 이미지

page사이즈를 2의 power라고 샌각하고 2진수로 생각해보세요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.