Section Header


각 Section 의 속성(property)을 정의한 것이 Section Header 입니다.

section header 구조체를 보기 전에 한번 생각을 해보겠습니다.

앞서 PE 파일은 code, data, resource 등을 각각의 section 으로 나눠서 저장한다고 설명드렸습니다.
분명 PE 파일 포멧을 설계한 사람들은 어떤 장점이 있기 때문에 그랬을 겁니다.

PE 파일을 여러개의 section 구조로 만들었을때 (제가 생각하는) 장점은 바로 프로그램의 안정성입니다.

code 와 data 가 하나의 섹션으로 되어 있고 서로 뒤죽박죽 섞여 있다면, (실제로 구현이 가능하긴 합니다.)
그 복잡한은 무시하고라도 안정성에 문제가 생길 수 있습니다.

가령 문자열 data 에 값을 쓰다가 어떤 이유로 overflow 가 발생(버퍼 크기를 초과해서 입력) 했을때
바로 다음의 code (명령어) 를 그대로 덮어써버릴 것입니다. 프로그램은 그대로 뻗어 버리겠죠.

즉, code/data/resource 마다 각각의 성격(특징, 엑세스 권한)이 틀리다는 것을 알게 된 것입니다.

  • code - 실행, 읽기 권한
  • data - 비실행, 읽기, 쓰기 권한
  • resource - 비실행, 읽기 권한


그래서 PE 파일 포멧 설계자들은 비슷한 성격의 자료를 section 이라고 이름 붙인 곳에 모아두기로 결정하였고,
각각의 section 의 속성을 기술할 section header 가 필요하게 된 것입니다.
(section 의 속성에는 file/memory 에서의 시작위치, 크기, 엑세스 권한 등이 있어야 겠지요.)

이제 section header 가 무슨 역할을 하는지 이해 되셨나요?



IMAGE_SECTION_HEADER


section header 는 각 section 별 IMAGE_SECTION_HEADER 구조체의 배열로 되어있습니다. 

#define IMAGE_SIZEOF_SHORT_NAME              8

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;

    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

* 출처 : Microsoft 의 Visual C++ 에서 제공하는 winnt.h


IMAGE_SECTION_HEADER 구조체에서 알아야 할 중요 멤버는 아래와 같습니다. (나머지는 사용되지 않습니다.)

  • VirtualSize      : 메모리에서 섹션이 차지하는 크기
  • VirtualAddress   : 메모리에서 섹션의 시작 주소 (RVA)
  • SizeOfRawData    : 파일에서 섹션이 차지하는 크기
  • PointerToRawData : 파일에서 섹션의 시작 위치
  • Characteristics  : 섹션의 특징 (bit OR)


VirtualAddress 와 PointerToRawData 의 값은 아무 값이나 가질 수 없고,
각각 (IMAGE_OPTIONAL_HEADER32 에 정의된) SectionAlignment 와 FileAlignment 에 맞게 결정됩니다.

VirtualSize 와 SizeOfRawData 는 일반적으로 서로 틀린값을 가집니다.
즉, 파일에서의 섹션 크기와 메모리에 로딩된 섹션의 크기는 틀리다는 얘기가 되는 거죠.

Characteristics 는 아래 값들의 조합(bit OR)으로 이루어 집니다.

#define IMAGE_SCN_CNT_CODE                   0x00000020  // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA       0x00000040  // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA     0x00000080  // Section contains uninitialized data.
#define IMAGE_SCN_MEM_EXECUTE                0x20000000  // Section is executable.
#define IMAGE_SCN_MEM_READ                   0x40000000  // Section is readable.
#define IMAGE_SCN_MEM_WRITE                  0x80000000  // Section is writeable.


마지막으로 Name 항목에 대해서 얘기해보겠습니다.

Name 멤버는 C 언어의 문자열처럼 NULL 로 끝나지 않습니다. 또한 ASCII 값만 와야한다는 제한도 없습니다.
PE 스펙에는 섹션 Name 에 대한 어떠한 명시적인 규칙이 없기 때문에 어떠한 값을 넣어도 되고 심지어 NULL 로 채워도 됩니다.

또한 개발 도구에 따라서 섹션 이름/갯수 등이 달라집니다.

따라서 섹션의 Name 은 그냥 참고용 일뿐 어떤 정보로써 활용하기에는 100% 장담할 수 없습니다.
(데이타 섹션 이름을 ".code" 로 해도 되거든요.)


자 그러면 실제 notepad.exe 의 Section Header 배열을 살펴보죠. (총 3 개의 섹션이 있습니다.)


구조체 멤버별로 살펴보면 아래와 같습니다.

[ IMAGE_SECTION_HEADER ]

 offset   value   description
-------------------------------------------------------------------------------
000001D8 2E746578 Name (.text)
000001DC 74000000
000001E0 00007748 virtual size
000001E4 00001000 RVA
000001E8 00007800 size of raw data
000001EC 00000400 offset to raw data
000001F0 00000000 offset to relocations
000001F4 00000000 offset to line numbers
000001F8     0000 number of relocations
000001FA     0000 number of line numbers
000001FC 60000020 characteristics
                    IMAGE_SCN_CNT_CODE
                    IMAGE_SCN_MEM_EXECUTE
                    IMAGE_SCN_MEM_READ

00000200 2E646174 Name (.data)
00000204 61000000
00000208 00001BA8 virtual size
0000020C 00009000 RVA
00000210 00000800 size of raw data
00000214 00007C00 offset to raw data
00000218 00000000 offset to relocations
0000021C 00000000 offset to line numbers
00000220     0000 number of relocations
00000222     0000 number of line numbers
00000224 C0000040 characteristics
                    IMAGE_SCN_CNT_INITIALIZED_DATA
                    IMAGE_SCN_MEM_READ
                    IMAGE_SCN_MEM_WRITE

00000228 2E727372 Name (.rsrc)
0000022C 63000000
00000230 00008304 virtual size
00000234 0000B000 RVA
00000238 00008400 size of raw data
0000023C 00008400 offset to raw data
00000240 00000000 offset to relocations
00000244 00000000 offset to line numbers
00000248     0000 number of relocations
0000024A     0000 number of line numbers
0000024C 40000040 characteristics
                             IMAGE_SCN_CNT_INITIALIZED_DATA
                             IMAGE_SCN_MEM_READ




RVA to RAW



Section Header 를 잘 이해하셨다면 이제부터는 PE 파일이 메모리에 로딩되었을때
각 섹션에서 메모리의 주소(RVA)와 파일 옵셋을 잘 매핑할 수 있어야 합니다.

이러한 매핑을 일반적으로 "RVA to RAW" 라고 부릅니다.
방법은 아래와 같습니다.

1) RVA 가 속해 있는 섹션을 찾습니다.
2) 간단한 비례식을 사용해서 파일 옵셋(RAW)을 계산합니다.

IMAGE_SECTION_HEADER 구조체에 의하면 비례식은 이렇습니다.

RAW - PointerToRawData = RVA - VirtualAddress
                   RAW = RVA - VirtualAddress + PointerToRawData


간단한 퀴즈를 내보겠습니다.
아래 그림은 notepad.exe 의 File 과 Memory 에서의 모습입니다.
각각 RVA 를 계산해 보세요. (계산기 calc.exe 를 Hex 모드로 세팅하시면 계산이 편합니다.)



Q1)  RVA = 5000h 일때 File Offset = ?
A1) 먼저 해당 RVA 값이 속해 있는 섹션을 찾아야 합니다.
      => RVA 5000h 는 첫번째 섹션(".text")에 속해있습니다. (ImageBase 01000000h 를 고려하세요.)

      비례식 사용
      => RAW = 5000h(RVA) - 1000h(VirtualAddress) + 400h(PointerToRawData) = 4400h

Q2) RVA = 13314h 일때 File Offset = ?
A2) 해당 RVA 값이 속해 있는 섹션을 찾습니다.
      => 세번째 섹션(".rsrc")에 속해있습니다.

      비례식 사용
      => RAW = 13314h(RVA) - B000h(VA) + 8400h(PointerToRawData) = 10714h

Q3) RVA = ABA8h 일때 File Offset = ?
A2) 해당 RVA 값이 속해 있는 섹션을 찾습니다.
      => 두번째 섹션(".data")에 속해있습니다.

      비례식 사용
      => RAW = ABA8h(RVA) - 9000h(VA) + 7C00h(PointerToRawData) = 97A8h (X)
      => 계산 결과로 RAW = 97A8h 가 나왔지만 이 옵셋은 세번째 섹션(".rsrc")에 속해 있습니다.
           RVA 는 두번째 섹션이고, RAW 는 세번째 섹션이라면 말이 안되지요.
           이 경우에 "해당 RVA(ABA8h)에 대한 RAW 값은 정의할 수 없다" 라고 해야 합니다.
           이런 이상한 결과가 나온 이유는 위 경우에 두번째 섹션의 VirtualSize 값이 SizeOfRawData 값 보다 크기 때문입니다.

PE 파일의 섹션에는 Q3) 의 경우와 같이 VirtualSize 와 SizeOfRawData 값이 서로 틀려서 벌어지는
이상하고 재미있는(?) 일들이 많이 있습니다. (앞으로 살펴보게 될 것입니다.)




이것으로 PE Header 의 기본 구조체들에 대한 설명을 마쳤습니다.

다음에는 PE Header 의 핵심인 IAT(Import Address Table), EAT(Export Address Table) 에 대해서 공부해 보겠습니다.

(continue)



  1. 쵸밥 2009.11.26 03:50 신고 댓글주소 | 수정 | 삭제 | 댓글

    cOrE 님~ 벌써 6장을 향해 달려가고 있네요 ^^* (아 뿌듯해 ㅋ)

    질문이 하나 있어요.

    예전에 뒷장에서 Hello World! 파일을 리버싱 했던거 기억 나시죠?
    그때 "World!" 문자열을 "Reverse" 문자열로 바꿀때 Olly로 대충 끝자락 널 패딩에 데이터를 썼다가
    삑살 났었죠?

    그 때 PE header 을 보고 메모리에 올라가는 영역중에 안쓰는 곳을 골라서 Patch 해 내야 한다고.

    그래서 질문이 하나 있어요!

    제가 지금 Olly 와 이 사이트에서 얻은 PEview 를 사용중이거든요?
    윗 그림을 보면 .data area 의 시작점 01009000 (Image Base + RVA 값) 값은 Olly와 PEview 에 동일하게 표시되요.

    그런데 끝자락을 표시하는 부분이 Olly 와 PEview 가 틀리네요?

    1. Olly 의 데이터창을 보면 0100AFFF 까지 표시되요.

    2. PEview 의 .data section 을 보면 010097FF 까지로 Olly 보다 훨씬 쪼금이네요?

    3. 그런데 이번에는 계산기로 두두려보면 메모리 주소로서의 (VA) .data area 최대값은 0100ABA8 이고 . .

    4. 또 계산기를 두드려보면 파일 (RAW) 에서 메모리로 (VA) 맵핑될 수 있는 최대값은 010097FF 로 PEview 가 보여주는 수준하고 같네요?

    볼수 있는 주소의 한계를 작은 순서대로 정렬해보면 . .
    PEview 의 .data 영역 = (RAW) .data 계산기 < (VA) .data 계산기 < Ollydbg data view
    Ollydbg 가 .data area 를 .rsrc 직전까지로 제일 많이 보여주는데 . .

    우리 맘대로 "Reverse!!" 문자열을 .data area 에 집어 넣는다면 . . 그리고 파일로 패치해 낼 거라면?

    010097FF PEview 가 보여주는 수준 (RAW) 가 (VA) 에 매칭될 수 있는 최대값 안에 "Reverse!!" 문자열을 넣으면 되는건가요 ???

    • reversecore 2009.11.26 15:12 신고 댓글주소 | 수정 | 삭제

      쵸밥님, 안녕하세요.

      잠도 안주무시고 이렇게 열심히 하시다니요... @@~

      제 블로그를 아껴 주셔서 감사합니다.

      답변을 드리자면...
      PEView 에서 섹션 크기 와 실제 실행시 메모리에서 섹션 크기가 왜 틀리냐는 말씀이시죠?

      그건 바로 Section Alignment 항목 때문입니다.
      (IMAGE_OPTIONAL_HEADER 멤버)

      PE Header 의 섹션 정보에는 그 프로그램의 해당 섹션이 메모리에서 점유할 크기가 기록됩니다.

      실제 PE Loader 는 메모리를 Section Header 의 배수크기로 잡기 때문에 실제로는 더 큰값이 되는 것입니다. (효율성 때문입니다.)

      그리고 메모리에 문자열을 쓰실거면 실제 잡힌 크기 내에서 쓰시면 되고요, 파일에서 쓰실려면 적당히 빈 곳에 쓰시면 됩니다.

      감사합니다.

  2. 쵸밥 2009.11.27 00:55 신고 댓글주소 | 수정 | 삭제 | 댓글

    오 . . PE 로더의 동작에 대해서 알아봐야 겠네요 ㄷㄷ;;

  3. 메롱이 2009.11.30 02:50 신고 댓글주소 | 수정 | 삭제 | 댓글

    강좌 잘 읽다가 정말 모르는 부분이 있어서요..

    퀴즈문제(총 3문제)에서 예를 들면 RVA=13314h일때 13314 주소가 세번째 섹션에 속한다라고

    하셨는데 어떤게 세번째 섹션에 속하는지 몰라서요..

    세번째 섹션 주소 범위가 100B00h~1008304h <- 이거 맞죠?

    주소 범위를 10진수 2진수 둘다 바꿔 교해봐도 3314가 범위안에 안들어 가는거 같던데..

    제가 계산하는게 맞는지 모르겠네요..

    워낙 생초보라...ㅎㅎ;;

    수고스러우시겠지만..좀더 설명좀 해주셔용...ㅎㅎ;;

    리버싱은...마치 컴퓨터 안에서 보물찾기 하는거 같은 느낌이나서 공부 할수록 잼있네요..ㅎㅎ;;

    • ReverseCore 2009.11.30 09:08 신고 댓글주소 | 수정 | 삭제

      안녕하세요. 메롱이님.

      위 그림을 보시면 RVA 13314 는 세번째 섹션이에 속한 주소라는걸 아실 수 있습니다. (이 그림은 섹션 헤더의 정보를 기반으로 작성되었습니다.)

      세번째 섹션 범위는 아래와 같습니다.
      파일 8400 ~ 10800
      메모리 100B000 ~ 1014000

      섹션 헤더를 다시 한번 살펴보시기 바랍니다.

  4. Ezbeat 2009.12.23 17:37 신고 댓글주소 | 수정 | 삭제 | 댓글

    강의 잘 보고 있습니다 ^^
    근데 NT header라는 것이 OptionalHeader까지 인것으로 알고있는데
    마지막에 Section header까지 전부 설명하신 후에 NT header의 모든 멤버에 대해 설명을
    마쳤다고 하셔서 쫌 이상한거 같아요 ;;

    • ReverseCore 2009.12.24 02:19 신고 댓글주소 | 수정 | 삭제

      Ezbeat님, 안녕하세요.

      정확한 지적이십니다. ^^

      열심히 읽어주시고 오류를 바로 잡아 주셔서 감사합니다.

      Ezbeat님 덕분에 제 글의 완성도가 높아져서 기분 좋습니다.

      항상 감사합니다. ^^

  5. h0ney 2010.01.12 18:45 신고 댓글주소 | 수정 | 삭제 | 댓글

    제가 최근에 C# 을 사용하여 PE Viewer 를 하나 만들고 있습니다.

    분석중 파일이 Packing 이 되어있는지에 대한 여부를 확인할 때

    이리저리 궁리를 하다가 가장 효과적인 방법이 EP Section 의 Characteristics 을 살펴본 뒤

    이 값이 IMAGE_SCN_MEM_WRITE 플레그가 켜져있을 경우에는

    Packing 이 되었다고 판단하도록 만들었는데 이 부분에 대해서는

    어떻게 생각하시는지요?

    • reversecore 2010.01.13 16:22 신고 댓글주소 | 수정 | 삭제

      h0ney님, 안녕하세요.

      말씀하신대로 EP Section 에 WRITE 속성이 있다면 일단 일반적인 PE 파일은 아닐겁니다. 그렇게 만드는 컴파일러는 본적이 없구요.
      아마 패커 또는 크립터 계열로 작업된 파일일 확률이 매우 높을 겁니다.

      하지만 목표가 packing 된 파일을 찾는거라고 하시면 위 알고리즘은 100% 동작하지는 않을 겁니다.
      이유는 EP 섹션 속성을 건드리지 않는 패커도 꽤 있거든요.
      쉽게 볼 수 있는 파일은 RAR SFX 계열의 파일들입니다.

      다른 분야에서도 팩 여부를 확인하는 것은 중요합니다.
      어떤 논문들을 보면 파일의 entropy 를 확인한다고 합니다.

      저도 자세히 본건 아니라 정확한 설명은 어렵지만 쉽게 얘기해 파일의 '복잡함정도'를 측정하는 것입니다.

      압축알고리즘은 결국 자주 나타나는 패턴을 특정 작은 값으로 매핑시켜주기 때문에 0 ~ FF 의 값이 파일 전반에 걸쳐 골고루 나타날 겁니다. (일반적인 PE 파일에는 0 이 압도적으로 많지요.)

      말씀하신 방법으로도 구현해보시고, 관련해서 검색을 좀 해보시면 다양한 아이디어를 보실 수 있으실 겁니다.

      감사합니다.

  6. graythief 2010.02.21 21:04 신고 댓글주소 | 수정 | 삭제 | 댓글

    파일 오프셋을 구할 때는 그럼 저 위의 File의 offset 값과 메모리의 address 부분을 구해놓고 계산을 해야하는건가요? 그렇다면 파일마다 틀릴것인데 (섹션크기가 더 크다던지 stub 부분이 더 커진다던지 말이에요 ) 일일이 다 일단 저것을 해놓고 분석해야 하는건가요?

    • reversecore 2010.02.21 23:52 신고 댓글주소 | 수정 | 삭제

      graythief님, 안녕하세요.

      RVA <-> File Offset 변환은 보통 유틸리티를 이용합니다. PEView 나 StudPE 같은 유틸리티를 사용하시면 되구요.

      좀더 익숙해 지시면 간단한건 그냥 쉽게 변환하실 수 있습니다.

      감사합니다.

  7. 할라 2010.04.22 05:54 신고 댓글주소 | 수정 | 삭제 | 댓글

    안녕하세요~
    열심히 강좌를 보면서 학습을 하고있습니다.
    정말 볼수록 잘 쓰셧다고 감탄사가 흘러나오고 있습니다 ㅋ
    제가 필요한 부분만 추려내고 싶어도 너무 정리가 잘되있어서 결국 다보게되는..ㅋㅋ
    질문드릴께있는데요..
    특정 RVA값이 주어졌을때 그 부분을 계산하는 도중 의문점이 생겼는데요..
    저도 메모장을 peview로 열어서 각 섹션에 사이즈와 시작주소 등등을
    살펴보았는데, 이 그림 예제와 살짝다른... 곳을 발견했는데요
    첫 번째 text에서 버츄얼사이즈가 다르더군요 그러닌까 다른 섹션들도 값이
    다 틀려지는거같은데요.. 그리고 Size of RawData값들도 틀리고요.. 음.. 어째서 이런건지요??
    혹시 이게 시스템마다 다를 수도있는건가요??

    • reversecore 2010.04.23 22:56 신고 댓글주소 | 수정 | 삭제

      할라님, 칭찬 감사합니다. ^^

      질문하신대로 notepad.exe 는 OS 버전에 따라 모두 틀려집니다.
      (다른 모든 시스템 파일도 마찬가지입니다.)

      즉, OS 마다 시스템 파일 버전이 다 틀립니다.
      재빌드 해서 배포한다는 뜻이지요.

      따라서 위 그림과 다르게 보일 수 있습니다.

      감사합니다.

  8. 보름♬달★콤 2010.06.07 16:43 신고 댓글주소 | 수정 | 삭제 | 댓글

    1) VirtualSize 와 SiezOfRawData 설명에 대하여
    : 두개의 설명이 뒤바뀐것 아닌지요?
    VIrtualSize가 File 내의 Section 크기이고 SizeOfRawData가 메모리상에 올려진 setion의 크기 아닌가요? 보통의 경우 SizeOfRawData가 align배수로 roundup된 크기이더군요..
    이름도 이상하게 헷갈리게 되어있는데..

    2) 질문입니다.
    .data섹션의 경우, 이상하게 VIrtualSize보다 SizeOfRawData값이 크게 나와있는데요
    (제가 해본 결과에도 그렇게 나타나는 듯)
    이 경우는 어떻게 fiel offset을 구해야 하는지 알려주세요..
    차후에 설명해주신다고 했는데.. 어디에 써주셨는지 잘 모르겠네요...

    부탁드립니다. 수고하세요!

    • reversecore 2010.06.08 15:38 신고 댓글주소 | 수정 | 삭제

      안녕하세요~

      1) VirtualSize 가 메모리이고, SizeOfRawData 가 파일입니다.
      virtual 은 virtual address (가상메모리) 를 의미한다고 기억하시면 헷갈리지 않으실 거에요.
      SizeOfRawData 가 FileAlignment 의 배수로 된 것이 맞습니다.

      2) 둘은 1:1 매칭 되지 않기 때문에 항상 RVA 에 대한 FileOffset 을 계산할 수 있는 것은 아닙니다. 계산할 수 없는 경우도 있지요.
      예를 들어 PointerToRawData = 1000, VA = 1000 이고 SizeOfRawData = 200, VirtualSize = 400 인 경우라면...
      RVA 가 1200 보다 크다면 그에 해당되는 FileOffset 은 없는 겁니다.

      http://www.reversecore.com/22 글의 Q3) 문제를 참고하시기 바랍니다.

      감사합니다.

  9. blackjack 2010.06.28 20:44 신고 댓글주소 | 수정 | 삭제 | 댓글

    이렇게 올리는거 맞나?
    하여튼 안녕하세요. 요세 한창 리버싱 공부 중인 초짜임니다.
    질문드릴게 있는데 저 RAW계산하는게 저렇게만 봐서 잘 이해가 안갑니다.
    ImageBase 값을 참고하시라고 했는데요. 그걸 어떻게 황용하는지도 모르겠고
    그리고 예를 들어 RVA가5000h인 섹션이 어디인지 어떻게 알아내는지도 모르겟습니다 .^^

    • reversecore 2010.06.29 22:52 신고 댓글주소 | 수정 | 삭제

      안녕하세요.

      저 그림만 놓고 생각해 보시기 바랍니다.

      RVA 가 5000 인 섹션은 그림상에서 ".text" 섹션입니다.
      ImageBase 를 고려하라는 말은 저 그림이 VA 기준으로 되어 있기 때문에 ".text" 섹션의 VA 값 01001000 에서 ImageBase 값 01000000 을 빼면 결국 ".text" 섹션은 RVA 1000 에서 시작한다는 뜻입니다. (VA 01001000 에서 시작한다와 같은 말이지요.)

      설명이 좀 어렵지요? ^^

      잘 이해안가시면 다시 질문해 주세요~

  10. blackjack 2010.06.30 05:18 신고 댓글주소 | 수정 | 삭제 | 댓글

    아 이제 알겠습니다.
    RVA가5000이면 속해있는 섹션이 .text섹션이라는게
    .text섹션이 400~7C00이니까 이 안에 속해있어서 그랬군요.
    그럼 VA는 절대주소를 말하는거였잖아요?
    근데 계산 하는걸 보니까 ImageBase값을 빼준 나머지 즉 RVA로 계산해서 값을 구하네요
    그건 왜 그런가요?

    • reversecore 2010.07.03 15:00 신고 댓글주소 | 수정 | 삭제

      .text 섹션은 파일에서 400~7C00 영역이고, 메모리에서는 01001000 ~ 01009000 영역(VA)입니다.

      굳이 VA 를 RVA 로 변환해서 계산하는 이유는 Section Header 의 정보가 전부 RVA 로 되어있기 때문에 VA 를 RVA 로 변환후 계산해야 편리하기 때문입니다. (PE 헤더 정보들 대부분 RVA 로 되어있습니다.)

      PE 헤더에 RVA 만 사용하는 이유는... PE 파일이 꼭 ImageBase 에 로딩된다는 보장이 없기 때문에 RVA 로 써주는 것입니다...

      감사합니다.

  11. Vi0 2010.08.02 20:11 신고 댓글주소 | 수정 | 삭제 | 댓글

    안녕하세요
    덕분에 열심히 리버싱공부 하고있습니다
    강좌를 보다 궁금증이 생겨서 질문드리는데요

    첫번째 문제에서 RVA가 5000일때 RAW가 4400이라 구하셨는데
    RVA5000인 곳에 asdf라는 데이터가 있으면
    RAW4400이란 곳에 asdf라는 똑같은 데이터가 있다는 말..맞나요?

    또 RVA는 존재하는데 RAW는 존재하지 않는경우는
    프로그램이 실행되면서 데이터가 push된(표현이 맞나 모르겠습니다..) 경우인가요?

    • reversecore 2010.08.04 22:00 신고 댓글주소 | 수정 | 삭제

      안녕하세요.

      첫번째 질문에 대한 답변은 '네' 이구요...
      (그 영역이 메모리에 로딩되는 경우라면 말이죠.)

      두번째 질문은... 조금 난해한데요... ^^
      패커같은 경우에 특정 섹션의 파일 크기가 0 이면서 메모리 크기는 매우 큰 경우가 많습니다. 즉, 파일에서는 사용되지 않지만 메모리에서는 뭔가 사용할 필요가 있어서 예약해놓은 공간이라고 보시면 됩니다. 그대로 메모리는 할당되지요. (보통 이경우에 unpack 된 코드를 이 영역에 풀어내는 경우가 많아요.)

      감사합니다.

  12. tintin 2011.06.21 00:32 신고 댓글주소 | 수정 | 삭제 | 댓글

    안녕하세요?
    강의잘보고잇습니다^^
    강의를쭉 읽다가 제가 햇갈리는게 잇어서 질문을 합니다

    PE 파일 첫번째 강의에서

    VA (Virtual Address) 는 프로세스 가상 메모리의 절대 주소를 말하며,
    RVA (Relative Virtual Address) 는 어느 기준위치(ImageBase) 에서부터의 상대 주소를 말합니다.
    VA 와 RVA 의 관계는 아래 식과 같습니다.
    RVA + ImageBase = VA


    이렇게 말씀하셨는데요

    질문.
    이번 강의에서
    VirtualAddress : 메모리에서 섹션의 시작 주소 (RVA)
    이말은 무슨뜻인가요..?ㅠ VirtualAddress는줄여서 VA일테고
    그럼 VA = RVA ?? ,, 무지 햇갈리네요..
    혹시 메모리에서 섹션의 시작 주소 (RVA) 여기에서 오타가 나신건가요..?
    그리고 첫번째 강의에서 VA 랑 두번쨰 강의에서 VA는 같은건가요?


    아오 무슨질문을 했는지도모르겠네요 ㅎ ㅋㅋㅋ 죄송합니다

    • reversecore 2012.11.04 00:47 신고 댓글주소 | 수정 | 삭제

      여기서의 VirtualAddress 는 IMAGE_SECTION_HEADER 구조체의 멤버 변수입니다. 섹션의 메모리에서 시작 위치를 RVA 값으로 나타내지요.

      이름이 저렇게 되어 있어서 헷갈리실만 합니다.

      감사합니다.

    • 크빗 2013.08.17 08:20 신고 댓글주소 | 수정 | 삭제

      저도 같은 부분을 헷갈렸는데 이 글 보고 정확하게 짚어가네요 ㅋㅋ

  13. Bitstream0 2011.08.11 15:40 신고 댓글주소 | 수정 | 삭제 | 댓글

    'VirtualAddress : 메모리에서 섹션의 시작 주소 (RVA)' 라는 말은,

    "VirtualAddress의 값이 RVA로 표현되어 있다"는 말로 이해하시면 될 것 같습니다.

    즉, 특정 섹션의 VirtualAddress의 값이 VirtualAddress : 00001000과 같이 표현되어 있다면,

    해당 섹션의 가상메모리 상의 실제 위치(VirtualAddress)는 ImageBase + 00001000가

    되겠지요..... 지나가다가 글 남겨 봅니다.

  14. 강준성 2012.11.02 03:39 신고 댓글주소 | 수정 | 삭제 | 댓글

    RVA to RAW부분이
    이해가안되서 몇일설치다가..조금 쉽게 써봤어요..저처럼 머리나쁜사람있을까봐..

    일단 PE를 실행하면 섹션헤더를 참고해서 메모리를로드하는데 아래와같다.
    1. virtual address(rva)로 이동
    2. virtual size만큼의 크기를 할당
    3. 파일에있는 해당섹션을 메모리로 로드




    RAW = RVA - VirtualAddress + PointerToRawData 이 공식의 의미는
    PE로더가 파일의 섹션을 메모리의 섹션으로 로드하니까
    메모리가 가르키는값, 즉 RVA에서 섹션시작주소를빼고
    (이경우 메모리의 섹션시작부터 RVA가 가르키는곳까지의 크기를 뜻하게됨)
    파일섹션의 시작주소를합하는 공식
    (메모리의 크기를 구해서 파일의 시작주소를합해서
    파일의 오프셋으로 치환하는..말로는 아주 간단한 공식..)

    아 드디어 읽을수있다...ㅠㅠ
    근데 SizeofRawData(파일상 섹션의 크기)랑 Virtual Size(메모리상의 크기)가 다른이유는 전혀 이해가안가네요..

    • reversecore 2012.11.04 00:54 신고 댓글주소 | 수정 | 삭제

      안녕하세요.

      RVA -> RAW 변환은 리버스 엔지니어링에서 매우 중요한 개념입니다. 그리고 처음에는 좀 어렵게 느껴질 수 있습니다.

      지금이야 SizeOfRawData 와 VirtualSize 의 크기가 달라서 이득 볼게 별로 없습니다.

      그러나 PE가 처음 설계될 때는 HDD 가 매우 비쌌지요. 메모리는 가상 메모리 개념을 썼기 때문에 프로세스당 4GB 라고 보면 되는데요. 그당시 실제 컴퓨터 HDD 저장 공간은 10~100MB 수준이었습니다. 그래서 최대한 파일 크기를 작게 만들어야 좋았습니다. 메모리는 넉넉한 대신 파일은 팍팍하게 줄 수 있도록 자유도를 부여한 거라고 보시면 됩니다.

      지금은 패커/프로텍터에게 다양한 창의적인 기법이 가능하도록 빌미를 제공한 셈이 되었지만요... ^^~

      감사합니다.

  15. bach 2013.10.24 10:11 신고 댓글주소 | 수정 | 삭제 | 댓글

    안녕하세요,

    rva를 raw로 변환하는 과정에서

    virtual address와 pointer to rawdata 값이 필요한데,

    예제에서는 저 표를 보고 구했잖아요

    다른 파일들은 virtual address와 pointer to rawdata 값을 어떤것을 보고

    알수 있는지 궁금합니다.

    • jaehyuk 2014.02.17 13:54 신고 댓글주소 | 수정 | 삭제

      peview같은 것으로 볼 수 있고, hxd같은 hexa editor로 따라 읽어가면서 보실수 있습니다

  16. 누구에 2016.02.16 14:13 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다




Introduction


Windows 운영체제의 PE(Portable Executable) File Format 에 대해서 아주 상세히 공부해 보도록 하겠습니다.

PE format 을 공부하면서 Windows 운영체제의 가장 핵심적인 부분인
Process, Memory, DLL 등에 대한 내용을 같이 정리할 수 있습니다.



PE(Portable Executable) File Format


PE 파일의 종류는 아래와 같습니다.

  • 실행 파일 계열 : EXE, SCR
  • 라이브러리 계열 : DLL, OCX
  • 드라이버 계열 : SYS
  • 오브젝트 파일 계열 : OBJ

엄밀히 얘기하면 OBJ(오브젝트) 파일을 제외한 모든 파일들은 실행 가능한 파일 입니다.

DLL, SYS 파일등은 쉘(Explorer.exe) 에서 직접 실행 할 수는 없지만,
다른 형태의 방법(디버거, 서비스, 기타)을 이용하여 실행이 가능한 파일들입니다.

* PE 공식 스펙 에는 컴파일 결과물인 OBJ(오브젝트) 파일도 PE 파일로 간주합니다.
  하지만 OBJ 파일 자체로는 어떠한 형태의 실행도 불가능하므로 리버싱에서 관심을 가질 필요는 없습니다.


간단한 설명을 위해서 노트패드(notepad.exe) 파일을 hex editor 를 이용해서 열어보겠습니다.


<Fig. 1>

<Fig. 1> 은 notepad.exe 파일의 시작 부분이며, PE 파일의 헤더 (PE header) 부분입니다.

바로 이 PE header 에 notepad.exe 파일이 실행되기 위해 필요한 모든 정보가 적혀있습니다.

어떻게 메모리에 적재되고, 어디서부터 실행되어야 하며, 실행에 필요한 DLL 들은 어떤것들이 있고,
필요한 stack/heap 메모리의 크기를 얼마로 할지 등등...


수 많은 정보들이 PE header 에 구조체 형식으로 저장되어 있습니다.

즉, PE File Format 을 공부한다는 것은 PE header 구조체를 공부한다는 것과 같은 말입니다.



Basic Structure


일반적인 PE 파일의 기본 구조입니다. (notepad.exe)


<Fig. 2>

<Fig. 2> 는 notepad.exe 파일이 메모리에 적재(loading 또는 mapping)될 때의 모습을 나타낸 그림입니다.
많은 내용을 함축하고 있는데요, 하나씩 살펴보겠습니다.


  • DOS header 부터 Section header 까지를 PE Header, 그 밑의 Section 들을 합쳐서 PE Body 라고 합니다.

  • 파일에서는 offset 으로, 메모리에서는 VA(Virtual Address) 로 위치를 표현합니다.

  • 파일이 메모리에 로딩되면 모양이 달라집니다. (Section 의 크기, 위치 등)

  • 파일의 내용은 보통 코드(".text" 섹션), 데이타(".data" 섹션), 리소스(".rsrc") 섹션에 나뉘어서 저장됩니다.
    반드시 그런것은 아니며 개발도구(VB/VC++/Delphi/etc)와 빌드 옵션에 따라서
    섹션의 이름, 크기, 개수, 저장내용 등은 틀려집니다. 중요한 것은 섹션이 나뉘어서 저장 된다는 것입니다.

  • Section Header 에 각 Section 에 대한 파일/메모리에서의 크기, 위치, 속성 등이 정의 되어 있습니다.

  • PE Header 의 끝부분과 각 Section 들의 끝에는 NULL padding 이라고 불리우는 영역이 존재합니다.
    컴퓨터에서 파일, 메모리, 네트워크 패킷 등을 처리할 때 효율을 높이기 위해 최소 기본 단위 개념을 사용하는데,
    PE 파일에도 같은 개념이 적용된 것입니다.

  • 파일/메모리에서 섹션의 시작위치는 각 파일/메모리의 최소 기본 단위의 배수에 해당하는 위치여야 하고,
    빈 공간은 NULL 로 채워버립니다. (<Fig. 2> 를 보면 각 섹션의 시작이 이쁘게 딱딱 끊어지는 걸 볼 수 있습니다.)



VA & RVA



VA (Virtual Address) 는 프로세스 가상 메모리의 절대 주소를 말하며,
RVA (Relative Virtual Address) 는 어느 기준위치(ImageBase) 에서부터의 상대 주소를 말합니다.

VA 와 RVA 의 관계는 아래 식과 같습니다.

RVA + ImageBase = VA

PE header 내의 많은 정보는 RVA 형태로 된 것들이 많습니다.
그 이유는 PE 파일(주로 DLL)이 프로세스 가상 메모리의 특정 위치에 로딩되는 순간
이미 그 위치에 다른 PE 파일(DLL) 이 로딩 되어 있을 수 있습니다.

그럴때는 재배치(Relocation) 과정을 통해서 비어 있는 다른 위치에 로딩되어야 하는데,
만약 PE header 정보들이 VA (Virtual Address - 절대주소) 로 되어 있다면 정상적인 엑세스가 이루어지지 않을것입니다.

정보들이 RVA (Relative Virtual Address - 상대주소) 로 되어 있으면 Relocation 이 발생해도
기준위치에 대한 상대주소는 변하지 않기 때문에 아무런 문제없이 원하는 정보에 엑세스 할 수 있을 것입니다.




이어지는 강좌에서 PE Header 구조체를 하나씩 상세히 살펴보도록 하겠습니다.



(continue)



    이전 댓글 더보기
  1. 장황제 2010.01.19 18:29 신고 댓글주소 | 수정 | 삭제 | 댓글

    좋은 자료와 설명잘해주신 강의로 열심히 공부하고 있습니다!!

    정말 감사합니다~ㅋㅋ

    질문 드릴께 있는데요.

    padding의 개념이 잘 이해가 않가네여;;

    • reversecore 2010.01.21 01:56 신고 댓글주소 | 수정 | 삭제

      장황제님, 안녕하세요.

      PE 파일의 padding 개념에 대해서 궁금하시군요.


      패딩은 '기본단위' 를 맞추기 위해서 추가하는 덤 이라고 보시면 됩니다.

      이러한 '기본단위' 개념은 컴퓨터 뿐만 아니라 일상 생활에서도 많이 볼 수 있습니다.
      가령 귤을 (많이) 보관할 때는 낱개로 보관하는것이 아니고 박스에 담아서 창고에 보관하지요. 그때 박스가 바로 '기본단위' 인 것입니다. 귤이 몇개라고 하지 않고 귤박스가 몇개라고 말을 합니다.

      왜냐구요? 편하니까요. 귤박스가 아주 많아지면 보관 창고를 더 늘려야 하고, 그때는 귤이 몇박스라고 하지 않고 귤이 창고 몇개에 보관되어 있다라고 할 수 있습니다.

      이러한 '기본단위' 개념은 컴퓨터 설계에도 그대로 녹아 있어서 메모리, 하드디스크 등에도 적용되어 있습니다. (하드디스크가 섹터단위로 구분된다고 들어보셨지요?)

      마찬가지로 PE File Format 의 '섹션'에도 '기본단위(크기)' 개념이 적용되어 있습니다.

      제가 프로그래밍한 코드가 (기계어로 컴파일되어) 크기가 100 byte 밖에 안된다고 하더라도, 만약 섹션의 기본단위가 400h(1000d) byte 라면 코드 섹션의 크기는 1000d 가 되는 것입니다.

      100 byte 코드가 채워지고 남은 900 byte 의 영역에는 그냥 0 으로 채워지게 되고, 이를 padding 이라고 하는 것입니다.

      메모리도 같은 개념이 적용됩니다. (보통 파일보다는 단위 크기가 좀 더 크지요.)

      PE 파일에서 padding 은 누가 어떻게 만들까요?
      네, 당연히 개발도구(VC++, VB, etc) 에서 PE 파일 생성시 자신의 옵션에 따라서 결정됩니다. ^^


      만약 잘 이해 안되시면 다시 질문해 주세요~

      감사합니다.

  2. 장황제 2010.01.21 21:48 신고 댓글주소 | 수정 | 삭제 | 댓글

    와..읽으면서..웃음이 나옵니다..ㅋㅋ

    이해가 퐉왔습니다~;;

    정말 개념만 보면 쉬운거였네요..ㅋㅋ

    이해하기 쉽게 알려주셔서 감사합니다~

    • ReverseCore 2010.01.21 22:47 신고 댓글주소 | 수정 | 삭제

      장황제님, 안녕하세요.

      이해가 잘 되셨다니 다행입니다.

      사실 저렇게 귤을 보관하면 검색(찾기)이 편리해 집니다.
      "몇번 창고 몇번 박스내의 몇번 귤" 하면 되니까요.

      즉, 대량의 데이타를 보관할 때 묶어서 보관하면 정리도 잘되고 검색도 쉬워지는 장점이 있지요.

      감사합니다.

  3. 장황제 2010.01.30 10:45 신고 댓글주소 | 수정 | 삭제 | 댓글

    이번에는 패딩사이즈질문좀 드릴께요..ㅠ

    파일에 패딩하고 메모리에 로드되었을때의 패딩 크기가 알고싶어서요.

    저는 만약 sectionalignment에서 ox00001000이면 4096바이트의 배수가 되는거고.

    filealignment가 ox00002000 이면 8192바이트의 배수가 된다고 생각을 했는데....

    제가 잘못생각하고 있는건가요??

    • reversecore 2010.01.31 23:19 신고 댓글주소 | 수정 | 삭제

      장황제님, 안녕하세요.

      패딩크기 말씀이시죠?

      실제 코드(데이타) 의 크기를 각 alignment 에 맞게 확장시켜 주기 때문에 그때 그때 달라집니다.

      그리고 각 섹션의 크기는 장황제님 말씀대로 입니다.

      보통 file alignment 는 0x200, 0x400, 0x1000 이 많이 쓰입니다.
      Section Alignment 는 0x1000 이 많이 쓰이구요.

      감사합니다.

  4. tanosi 2010.04.06 01:02 신고 댓글주소 | 수정 | 삭제 | 댓글

    머리속에 '파밧' 하고 개념이 잘 서는 포스팅을 보고 놀랐습니다.
    출간 준비중 이라고 하시니 기대됩니다~~
    최근 나온 리버스엔지니어링 역분석 구조와 원리 라는책을 보고 PE 에서 딱 막혔는데, 다시한번 달리게 되었습니다.
    많은 도움이 되고 있습니다~~

  5. 할라 2010.04.15 22:29 신고 댓글주소 | 수정 | 삭제 | 댓글

    리버싱 입문에 들어서는 할라라고 합니다^^;;
    요즘 리버싱이 재밌어지려고 하는 찰라에
    많은걸 학습해야 하는걸 깨닫고 관련된 자료를 찾아다니는 찰나에
    이런 좋은 글을 발견했네요 ㅎㅎ
    괜찮으시면 이 글을 토대로 제가 따로 글을 올려놓고 싶은데
    괜찮나요?^^;

    아무튼 여기서 많은 걸 배워갑니다^^

    • reversecore 2010.04.15 23:42 신고 댓글주소 | 수정 | 삭제

      할라님, 안녕하세요. ^^

      저의 저작권 정책만 지켜주시면
      여기서 배우신 내용을 가지고 본인의 글을 쓰시는건
      아무런 문제가 없습니다.

      감사합니다.

  6. 할라 2010.04.19 16:39 신고 댓글주소 | 수정 | 삭제 | 댓글

    음.. 저기 VA/RVA 부분에서요
    VA와 RVA에 관계를 보시면
    RVA + ImageBase = VA라고 되어있는데요
    +가 맞나요??? -아닌가요???

    • reversecore 2010.04.19 23:01 신고 댓글주소 | 수정 | 삭제

      + 가 맞습니다.

      RVA 의 의미가 Relative Virtual Address (to ImageBase) 이거든요.

      따라서 VA = RVA + ImageBase 이고,
      RVA = VA - ImageBase 이지요.

      감사합니다.

  7. kvirus 2010.05.27 10:39 신고 댓글주소 | 수정 | 삭제 | 댓글

    책으로 출판하시는군요...
    꼭 소장하겠습니다!!!
    기대되네요 :)

  8. MyKim 2010.06.17 23:47 신고 댓글주소 | 수정 | 삭제 | 댓글

    이렇게 체계적으로 잘 정리된 내용이라니 ...
    참 좋은 내용를 제공해 주셔서 감사합니다.
    또한 박수와 격려를 보내드립니다.
    그런데 언제 책이 출간되나요 ?
    빨리 사서 공부해야 겠습니다....

    Have reverence for God, and obey his commands, because this is all that man was created for. (Ecclesia 12:13)

  9. 박두현 2010.08.09 19:02 신고 댓글주소 | 수정 | 삭제 | 댓글

    Fig2. 그림을 사용하고 싶습니다.
    프로그램 실행에 관해서 블로깅을 하고 있는데
    Fig2 그림이 너무나 필요합니다.
    물론 출처는 남기겠습니다.

    • reversecore 2010.08.10 12:43 신고 댓글주소 | 수정 | 삭제

      안녕하세요.

      가져가시기 전에 먼저 문의해 주셔서 감사합니다. ^^

      이글의 제일 처음 댓글을 보시면 showtime 님께서 동일한 문의를 주셨는데요.

      그쪽에 제가 답변 달아놓은 대로만 지켜주시면 사용하실 수 있도록 해드리겠습니다.

      감사합니다.

  10. maruhun 2010.08.11 23:55 신고 댓글주소 | 수정 | 삭제 | 댓글

    pe구조에 궁금한점있어서 문의드립니다.

    인터넷으로찾아보았지만 시원한 대답이 없어서 이렇게문의 드립니다.

    페이징 파일이란 가상메모리라고 알고있습니다. 그럼 페이지는 CPU가 엑세스하는 메모리인가요?

    그리고 공부를 하다보니깐 처음에 CPU가 메모리를 vitual address를 발생시킨다고 하는데

    cpu는 가상주소밖에 모르는건가요?

    실제 주소 번지(가상주소)=이미지 로드 시작 번지+RVA 인데

    실제 주소 번지가(가상주소)<----메모리 주소이면 실제주소는 어딘지..

    VAS,MMF,VMM 등 찾아보고 연습장에 내용이랑 찾아놓았지만 연결이 되지를 않습니다..

    간단하게 연결만 시켜주셨으면 감사하겠습니다..

    • reversecore 2010.08.15 22:48 신고 댓글주소 | 수정 | 삭제

      CPU 는 하드웨어이고 컴퓨터의 두뇌 역할이지요.
      따라서 메모리를 직접 access 할 수 있습니다.

      내부적으로 치열하게 물리메모리<->가상메모리 변환을 통해 정확한 주소에 접근할 수 있습니다.

      물리주소에 접근하는걸 궁금하시는게 아니라면...

      위의 설명은 이렇게 이해하시면 됩니다.

      PE 파일이 실행되면 프로세스가 생성되는데,
      프로세스는 4 GB 의 가상메모리를 할당 받고 그중 하위 2GB 를 유저영역으로 사용할 수 있습니다.

      이 프로세스 가상 메모리 주소를 표시할 때 VA 로 나타냅니다.

      음... 어떻게 이해가 되시는지요...

      궁금하신 내용은 또 질문 올려주세요~

      감사합니다.

  11. pe공부 2011.01.01 10:52 신고 댓글주소 | 수정 | 삭제 | 댓글

    리버스코어님 제가 PE포맷에 대해서 공부하다가 의문점이 생겨서 질문드립니다.
    ------------------------------------------------------------------------------------------------
    현재 PE파일포맷형식이 A라고 하면(현재 PE구조)
    PE파일포맷형식을 다른 형식인 B로 만들어도 되는가?(물론,프로그램이 실행해야할 필수정보는 있다.)
    WIN32 OS들은 모두 B형식을 인식할수있다고 치자

    • reversecore 2011.01.03 01:04 신고 댓글주소 | 수정 | 삭제

      안녕하세요.

      네, 말씀하신 대로 가능합니다.

      packer 류의 프로그램이 바로 정확하게 그 일을 수행하고 있지요.

      감사합니다.

  12. 금빛 star 2011.04.27 11:54 신고 댓글주소 | 수정 | 삭제 | 댓글

    좋은 자료에 감사드립니다.
    근데. 가상메모리->물리메모리변환은 누가 해주는가요? OS인가요?
    무식한넘. 감히 질문합니다요.

  13. wjsdlfdhkd 2011.05.01 20:14 신고 댓글주소 | 수정 | 삭제 | 댓글

    wjsdlfdhkd@nate.com 네이트온친추좀 해주세요 ㅠ

  14. PE 2011.05.18 11:43 신고 댓글주소 | 수정 | 삭제 | 댓글

    제가 PE관련하여 발표를 하게 되었습니다.

    ppt자료에 그림을 쓰고 싶습니다.

    사용해도 되는지 먼저 문의 드립니다.

  15. cropin 2011.05.30 01:28 신고 댓글주소 | 수정 | 삭제 | 댓글

    제가 리버싱입문한지 얼마안되서 죄송한데
    offset과 address의 차이점이 무엇인지 설명해주실수 있나요?...

    • reversecore 2011.06.03 22:22 신고 댓글주소 | 수정 | 삭제

      안녕하세요.

      둘 다 거의 같은 개념인데요... 보통 리버싱에서는 아래와 같이 사용됩니다.

      offset 은 어떤 기준점에서 떨어진 거리(변위)를 나타내며 주로 파일내의 위치를 표현할 때 사용합니다. (상대 거리를 나타낼 때 주로 사용됨)

      address 는 주로 메모리의 절대 주소를 나타낼 때 사용됩니다. (절대 주소를 나타낼 때 주로 사용됨)

      감사합니다.

  16. 금강이 2011.09.19 16:43 신고 댓글주소 | 수정 | 삭제 | 댓글

    안녕하세요 요즘은 하루하루 방문해서 조금씩 공부하고 있습니다. ㅎㅎ
    사내에서 스터디 같은걸 하는데 PE 관련 교육을 하려고 합니다. 그림2번 PPT 파일에 사용해도 될지요?

  17. 2012.02.03 11:06 신고 댓글주소 | 수정 | 삭제 | 댓글

    조금 햇갈리는게 있는데 각 널패딩은 하위주소(그림에서 윗부분)에 종속되는건가요? 그러니까 각각의 헤더 및 섹션들의 널패딩은 그 아래부분인건가요?

  18. 라마르틴 2013.02.26 17:00 신고 댓글주소 | 수정 | 삭제 | 댓글

    dllinjection 먼저 읽고 pe구조 몰라서 읽었는데 역시 깔끔합니다. 그동안 몰랐던 것들이 머릿속에서 깔끔하게 정리되는 느낌.

  19. 이정민 2014.10.27 12:20 신고 댓글주소 | 수정 | 삭제 | 댓글

    안녕하세요.
    글을 읽다가 궁금한 점이 하나 생겨서 여쭤봅니다.
    RVA 와 VA에 대해서
    DLL파일 같은 경우 이미 그 위치에 다른 파일이있다면
    재배치 과정을 통해 다른 위치로 로딩되어야 하는데
    VA주소로 되어있다면 정상적인 접근이 안된다는게 이해가 안되는데요,

    첫번째로는
    각 프로세스마다 독립된 가상메모리를 사용하는데
    어떻게 메모리 주소가 겹칠 수 있는지를 모르겠고,

    두번째로는
    RVA 주소든 VA 주소든 하나의 고유한 메모리 주소인데
    VA주소로는 왜 접근이 안되는건지 모르겠습니다.

  20. 코딩하는 경제학도 2017.02.03 08:09 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다





티스토리 툴바