elf 형식의 바이너리 실행 파일을 malloc을 통해 로드 한후 실행시키기

cider22c의 이미지

간단한 라이브러리를 쓰는 파일 하나를 만듭니다.
########## a.c ############
#include

int main(){
printf("test!\n");
return 0;
}
###########################

그리고 컴파일 합니다. gcc a.c -> 그 결과물은 물론 a.out 이겠지요.

물론 a.out을 실행시키면 잘 됩니다. test!

다음은 이 파일을 로드 하는 로더 파일을 만듭니다.

########### load.c #############
fout = fopen("a.out","rb");
unsigned char *c = (unsigned char*)mmap(NULL, file_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
fread(ptr, 1, file_size, fout);
memcpy(c, ptr, 11546);

이제 C에는 a.out의 내용이 담겨져 있습니다.

a.out의 헤더를 분석해서 엔트리 포인트를 구합니다. 메인 함수의 위치를 구하여 c의 위치부터 off_set을 더합니다.
main_fun = (int (*)(void))(c + (hdr->e_entry) - 0x8048000 + 0xB0);

여기서 0x8048000은 가장주소의 시작이고 hdr->e_entry는 start의 위치입니다. 그리고 0xB0는 entry : start 부터 main 까지의 off_set 입니다. 따라서 main_fun 는 현재 정확히 main을 가르킵니다.

main_fun()으로 실행을 시키면 세그멘테이션 오류가 발생합니다. 당연히 위의 계산이 틀린듯 보이지만 그렇지 않습니다.

실제 a.out에서 printf() 라인만 삭제하고(다이나믹 링킹을 사용하지 않는다면) return 30; 으로 고친다음에

컴파일 새로 해서
int c = main_fun();
printf("%d",c);

해보면 30이 찍힙니다. 즉 실행이 된다는겁니다.

그래서 elf 를 분석해 보았습니다.

main에서 printf를 부르면 plt로 가고 plt에서 GOT+4와 GOT+8를 실행시키는데 이 GOT+4와 GOT+8은

심볼을 해석하는 코드와 해당 루틴에 대한 위치가 들어있다고 합니다. 그런데 이 정보는 로드 타임에 다이나믹 링커에 의해

값이 정해지기 때문에 malloc에 의해서는 이 값을 바꿀수가 없습니다. 그럼 일단 malloc으로 데이타를 로드 한 다음

그 위치까지 가서 binary rewriting을 해야 한다는 결론에 이르렀는데 .. 그 다음이 문제인것이..

다이나믹 링커에 대한 정보가 너무 부족해서 어떻게 그 GOT+4 와 GOT+8을 쓰는지도 잘 모르겠고

실제 이런 방식이 맞는지도 의심이 듭니다.

가장 원천적으로는 이런 malloc으로 표준 C 라이브러릴 쓰는 stub 코드의 실행이 가능한지도 의심이 듭니다.

저와 비슷한 고민을 하신분들이 있으시면 도움을 받았으면 합니다!

끝까지 읽어주셔셔 감사합니다.

grassman의 이미지

아래 내용을 참조하시기 바랍니다.

http://www.linuxforums.org/misc/understanding_elf_using_readelf_and_objdump_3.html

dynamic linking을 사용하고 있을 때는 dynamic linker가 수행하는 일을 로딩한 프로그램에서 수행해 줘야 합니다. GOT에 주소가 초기화 되어 있지 않을 것이므로 참조하는 주소 부분에 현재의 호출 함수에 대한 주소를 입력해 줘야 제대로 동작합니다. 예를 들어 printf라고 한다면 현재의 프로그램에서 printf 함수의 주소를 강제로 GOT 영역에 넣어주면 됩니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.