2016. 12. 16. 15:44

Dos Relocation 관련 작업.

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

안녕하세요.


DOS File Format을 보시게 되면, Relocation 이란 항목이 있는데요.


이 항목은 추후 빌드된 바이너리에서 주소 번지수에 직접 변경을 가하는 항목입니다.


해당 내용은 아래와 같습니다.


링크는 제가 참조한 내용이 적혀 있는 사이트 입니다.


http://www.delorie.com/djgpp/doc/exe/

struct EXE {
  unsigned short signature; /* == 0x5a4D */
  unsigned short bytes_in_last_block;
  unsigned short blocks_in_file;
  unsigned short num_relocs;
  unsigned short header_paragraphs;
  unsigned short min_extra_paragraphs;
  unsigned short max_extra_paragraphs;
  unsigned short ss;
  unsigned short sp;
  unsigned short checksum;
  unsigned short ip;
  unsigned short cs;
  unsigned short reloc_table_offset;
  unsigned short overlay_number;
};

struct EXE_RELOC {
  unsigned short offset;
  unsigned short segment;
};

DOS 헤더 부분은 1A 까지가 overlay_number 인게 맞습니다. 


헤더 근처에 추가로 들어간 바이트는 링커에 따라서 다르거나, relocation 관련 내용입니다.


그런데 제가 사용한 컴파일러가 볼렌드 Linker를 사용하니 추가 바이트가 더 들어가는데요 내용은 아래와 같습니다.


참고 링크 http://www.ctyme.com/intr/rb-2939.htm


---Borland TLINK--- 1Ch 2 BYTEs ??? (apparently always 01h 00h) 1Eh BYTE signature FBh 1Fh BYTE TLINK version (major in high nybble, minor in low nybble) 20h 2 BYTEs ??? (v2.0 apparently always 72h 6Ah, v3.0+ seems always 6Ah 72h)


위의 내용 처럼 제가 사용한 Hello World는 위의 바이트 코드가 들어가 있네요.



0000 : 4D 5A 30 00 11 00 09 00 20 00 00 00 FF FF DB 01 

0010 : 80 00 00 00 00 00 00 00 3E 00 00 00 01 00 FB 50 

0020 : 6A 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0030 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00

0040 : 00 00 5B 00 00 00 A0 00 00 00 4C 01 00 00 18 00 

0050 : 98 01 AE 00 9B 01 AA 00 9B 01 A6 00 9B 01 6C 17

0060 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

... 


보시게 되면 20,21 에 6A 72 가 사용된게 맞네요.


그리고 추가로 relocation Pointer 형태 인데요.


위의 언급된 것처럼 offset, segment 형태로 존재 하며 시작 지점은 relocatable의 값을 토대로 해서 


4바이트씩 증가 합니다.



FILENAME:D:\DOSBOX\tc30\WORK\noname00.exe

=======HeaderInfo====================================

00h signature                           :4D 5A  

02h extrabytes                          :30 00  

04h pages                               :11 00  

06h relocations                         :09 00  

08h headersize                          :20 00  

0Ah minmemory                           :00 00  

0Ch maxmemory                           :FF FF  

0Eh initSS                              :DB 01  

10h initSP                              :80 00  

12h checksum                            :00 00  

14h initIP                              :00 00  

16h initCS                              :00 00  

18h reloctable                          :3E 00  

1Ah overlay                             :00 00  

=======Extra Info=====================================

this.headersize * 16                    :512

imagesize                               :8192

totalsize (pages-1) * 512 + extrabytes  :8240



보시게 되면 3E의 좌표에 해당 테이블의 시작 지점이고, 총 relocation 의 갯수는 9개 입니다.


그래서 4 bytes * 9 = 36 바이트를 읽어 들이면 되고 내용은 아래와 같습니다.



참고로 Code Segment는 0xd37 로 설정하고 계산한 결고 입니다.

===============Relocation Pointer===============

1 Seg:0000 Off:0001 Add:0001 PosHexData:019B ReloData:0ED2

2 Seg:0000 Off:005B Add:005B PosHexData:019B ReloData:0ED2

3 Seg:0000 Off:00A0 Add:00A0 PosHexData:019B ReloData:0ED2

4 Seg:0000 Off:014C Add:014C PosHexData:0198 ReloData:0ECF

5 Seg:0198 Off:0018 Add:1998 PosHexData:0000 ReloData:0D37

6 Seg:019B Off:00AE Add:1A5E PosHexData:0000 ReloData:0D37

7 Seg:019B Off:00AA Add:1A5A PosHexData:0000 ReloData:0D37

8 Seg:019B Off:00A6 Add:1A56 PosHexData:0000 ReloData:0D37

9 Seg:0000 Off:176C Add:176C PosHexData:0000 ReloData:0D37

==========================================


위의 relocation 관련 데이터가 코드가 메모리에 올라 간후 DS,CS 관련되서 주소가 설정 되면, 

해당 위치의 HEX 데이터를 교체 해야 합니다.


교체 할때 만약 해당 포인터의 위치의 HEX에, 더하기를 하여 바꾸면 됩니다.


그래서 PosHexData에 0xd37을 더한 결과가 RelocationData인 HEX값 이며 해당 바이너리가 로드된 포인터가 되겠습니다.


감사 합니다.