Tuesday, April 17, 2007
Perl 펄] 헥사 뷰어, 헥사 덤프 만들기 소스 코드; Hex Viewer, File Dump
펄로 헥사 뷰어 (Hex Viewer) 를 만드는 코드입니다. C가 섞이지 않은 순수한 펄로 제작되었습니다. 16바이트씩 읽지만 속도는 빠른 편입니다. 수천 바이트씩 한꺼번에 읽는 소스도 있긴 있는데 너무 복잡하고, 속도도 이것과 똑같았습니다.
아래 펄 코드에 보면, 문자를 화면에 즉시 출력하지 않고, $output 이라는 변수에 차곡차곡 넣어서 한꺼번에 출력합니다. 이러니 속도가 아주 빨라졌습니다.
파일명: example.pl
(※ 스크롤 박스 사용법: 박스 안을 마우스로 클릭한 후, 키보드의 좌우 화살표키를 누르면 양옆으로 움직일 수 있습니다. 박스에서 다시 나오려면, 박스 바깥의 아무곳이나 클릭하면 됩니다.)
실행 결과 화면:
클릭한후옆으로스크롤가능
example.pl Example.class > out.txt
이렇게 하면 out.txt 라는 파일로 출력 결과가 저장됩니다.
위에서 Example.class 란, 뷰어로 볼 아무 이름의 파일을 의미합니다.
참고: ▶▶ [QnA] 헥사 에디터란? 좋은 헥사 에디터(Hex Editor)는? : WinHex
아래 펄 코드에 보면, 문자를 화면에 즉시 출력하지 않고, $output 이라는 변수에 차곡차곡 넣어서 한꺼번에 출력합니다. 이러니 속도가 아주 빨라졌습니다.
파일을 헥사로 출력 프로그램 소스 코드
파일명: example.pl
(※ 스크롤 박스 사용법: 박스 안을 마우스로 클릭한 후, 키보드의 좌우 화살표키를 누르면 양옆으로 움직일 수 있습니다. 박스에서 다시 나오려면, 박스 바깥의 아무곳이나 클릭하면 됩니다.)
#!/usr/bin/perl
use strict; use warnings;
die "파일명을 입력하세요\n" if $#ARGV == -1;
my $offset = 0; # 번지 변수
my ($buf16, $buf16Len, @buf16Array, $output);
open(IN, "<", $ARGV[0]) or die "$!\n"; # 파일 오픈
binmode(IN); # 파일 모드를, 이진모드로 전환
while ($buf16Len = read(IN, $buf16, 16)) { # 파일을 16바이트씩 읽기
$output = sprintf("%08X: ", $offset); # Offset (번지) 출력
@buf16Array = unpack "C*", $buf16; # 문자열 형식의 버퍼를, 바이트 배열로 변환
for (my $i = 0; $i < $buf16Len; $i++) { # 헥사 부분의 헥사 값 16개 출력 (8개씩 2부분으로)
$output .= " " if ($i == 8); # 8개씩 분리
$output .= sprintf("%02X ", $buf16Array[$i]); # 헥사 값 출력
}
# 한 줄이 16 바이트가 되지 않을 때, 헥사 부분과 문자 부분 사이에 공백들 삽입
for (my $i = 0; $i <= (16 - $buf16Len) * 3; $i++) { $output .= " "; }
$output .= " " if ($buf16Len < 9); # 한줄이 9바이트보다 적을 때는 한칸 더 삽입
for (my $i = 0; $i < $buf16Len; $i++) { # 문자 구역 출력
if ($buf16Array[$i] >= 0x20 && $buf16Array[$i] <= 0x7E) { # 특수 문자 아니면 그대로 출력
$output .= sprintf("%c", $buf16Array[$i]);
} else { $output .= "."; } # 특수문자, 그래픽문자 등은 마침표로 출력
}
$offset += 16; # 번지 값을 16 증가
print $output, "\n"; # 수시로 출력하는 것보다, 하나의 문자열로 모조리 합쳐서 출력하는 것이 2배쯤 빠름
}
printf("%08X: ", $offset) if ($offset == 0); # 0바이트 파일일 경우 처리
close IN; # 파일 닫기
use strict; use warnings;
die "파일명을 입력하세요\n" if $#ARGV == -1;
my $offset = 0; # 번지 변수
my ($buf16, $buf16Len, @buf16Array, $output);
open(IN, "<", $ARGV[0]) or die "$!\n"; # 파일 오픈
binmode(IN); # 파일 모드를, 이진모드로 전환
while ($buf16Len = read(IN, $buf16, 16)) { # 파일을 16바이트씩 읽기
$output = sprintf("%08X: ", $offset); # Offset (번지) 출력
@buf16Array = unpack "C*", $buf16; # 문자열 형식의 버퍼를, 바이트 배열로 변환
for (my $i = 0; $i < $buf16Len; $i++) { # 헥사 부분의 헥사 값 16개 출력 (8개씩 2부분으로)
$output .= " " if ($i == 8); # 8개씩 분리
$output .= sprintf("%02X ", $buf16Array[$i]); # 헥사 값 출력
}
# 한 줄이 16 바이트가 되지 않을 때, 헥사 부분과 문자 부분 사이에 공백들 삽입
for (my $i = 0; $i <= (16 - $buf16Len) * 3; $i++) { $output .= " "; }
$output .= " " if ($buf16Len < 9); # 한줄이 9바이트보다 적을 때는 한칸 더 삽입
for (my $i = 0; $i < $buf16Len; $i++) { # 문자 구역 출력
if ($buf16Array[$i] >= 0x20 && $buf16Array[$i] <= 0x7E) { # 특수 문자 아니면 그대로 출력
$output .= sprintf("%c", $buf16Array[$i]);
} else { $output .= "."; } # 특수문자, 그래픽문자 등은 마침표로 출력
}
$offset += 16; # 번지 값을 16 증가
print $output, "\n"; # 수시로 출력하는 것보다, 하나의 문자열로 모조리 합쳐서 출력하는 것이 2배쯤 빠름
}
printf("%08X: ", $offset) if ($offset == 0); # 0바이트 파일일 경우 처리
close IN; # 파일 닫기
실행 결과 화면:
클릭한후옆으로스크롤가능
D:\Z>example.pl
파일명을 입력하세요
D:\Z>example.pl Example.class
00000000: CA FE BA BE 00 00 00 31 00 43 0A 00 0A 00 1C 08 .......1.C......
00000010: 00 1D 07 00 1E 07 00 1F 0A 00 04 00 20 0A 00 03 ............ ...
00000020: 00 21 0A 00 03 00 22 09 00 23 00 24 08 00 25 07 .!...."..#.$..%.
00000030: 00 26 0A 00 27 00 28 0A 00 29 00 2A 08 00 2B 0A .&..'.(..).*..+.
00000040: 00 2C 00 2D 0A 00 03 00 2E 0A 00 29 00 2F 07 00 .,.-.......)./..
00000050: 30 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 0...<init>...()V
00000060: 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 ...Code...LineNu
00000070: 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 6E mberTable...main
00000080: 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F ...([Ljava/lang/
00000090: 53 74 72 69 6E 67 3B 29 56 01 00 0A 45 78 63 65 String;)V...Exce
000000A0: 70 74 69 6F 6E 73 07 00 31 01 00 0A 53 6F 75 72 ptions..1...Sour
000000B0: 63 65 46 69 6C 65 01 00 0C 45 78 61 6D 70 6C 65 ceFile...Example
000000C0: 2E 6A 61 76 61 0C 00 12 00 13 01 00 08 74 65 73 .java........tes
000000D0: 74 2E 62 69 6E 01 00 17 6A 61 76 61 2F 69 6F 2F t.bin...java/io/
000000E0: 44 61 74 61 49 6E 70 75 74 53 74 72 65 61 6D 01 DataInputStream.
000000F0: 00 17 6A 61 76 61 2F 69 6F 2F 46 69 6C 65 49 6E ..java/io/FileIn
00000100: 70 75 74 53 74 72 65 61 6D 0C 00 12 00 32 0C 00 putStream....2..
00000110: 12 00 33 0C 00 34 00 35 07 00 36 0C 00 37 00 38 ..3..4.5..6..7.8
00000120: 01 00 05 25 30 32 58 0A 01 00 10 6A 61 76 61 2F ...%02X....java/
00000130: 6C 61 6E 67 2F 4F 62 6A 65 63 74 07 00 39 0C 00 lang/Object..9..
00000140: 3A 00 3B 07 00 3C 0C 00 3D 00 3E 01 00 28 25 6E :.;..<..=.>..(%n
00000150: 25 6E 25 6E 5B 25 64 20 EB B0 94 EC 9D B4 ED 8A %n%n[%d ........
00000160: B8 EB A5 BC 20 EC 9D BD EC 96 B4 EC 84 9C 20 EC .... ......... .
00000170: B6 9C EB A0 A5 5D 07 00 3F 0C 00 3A 00 40 0C 00 .....]..?..:.@..
00000180: 41 00 13 0C 00 42 00 13 01 00 07 45 78 61 6D 70 A....B.....Examp
00000190: 6C 65 01 00 13 6A 61 76 61 2F 69 6F 2F 49 4F 45 le...java/io/IOE
000001A0: 78 63 65 70 74 69 6F 6E 01 00 15 28 4C 6A 61 76 xception...(Ljav
000001B0: 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 a/lang/String;)V
000001C0: 01 00 18 28 4C 6A 61 76 61 2F 69 6F 2F 49 6E 70 ...(Ljava/io/Inp
000001D0: 75 74 53 74 72 65 61 6D 3B 29 56 01 00 04 72 65 utStream;)V...re
000001E0: 61 64 01 00 05 28 5B 42 29 49 01 00 10 6A 61 76 ad...([B)I...jav
000001F0: 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 a/lang/System...
00000200: 6F 75 74 01 00 15 4C 6A 61 76 61 2F 69 6F 2F 50 out...Ljava/io/P
00000210: 72 69 6E 74 53 74 72 65 61 6D 3B 01 00 0E 6A 61 rintStream;...ja
00000220: 76 61 2F 6C 61 6E 67 2F 42 79 74 65 01 00 07 76 va/lang/Byte...v
00000230: 61 6C 75 65 4F 66 01 00 13 28 42 29 4C 6A 61 76 alueOf...(B)Ljav
00000240: 61 2F 6C 61 6E 67 2F 42 79 74 65 3B 01 00 13 6A a/lang/Byte;...j
00000250: 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 ava/io/PrintStre
00000260: 61 6D 01 00 06 66 6F 72 6D 61 74 01 00 3C 28 4C am...format..<(L
00000270: 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 java/lang/String
00000280: 3B 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A ;[Ljava/lang/Obj
00000290: 65 63 74 3B 29 4C 6A 61 76 61 2F 69 6F 2F 50 72 ect;)Ljava/io/Pr
000002A0: 69 6E 74 53 74 72 65 61 6D 3B 01 00 11 6A 61 76 intStream;...jav
000002B0: 61 2F 6C 61 6E 67 2F 49 6E 74 65 67 65 72 01 00 a/lang/Integer..
000002C0: 16 28 49 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 49 .(I)Ljava/lang/I
000002D0: 6E 74 65 67 65 72 3B 01 00 05 63 6C 6F 73 65 01 nteger;...close.
000002E0: 00 07 70 72 69 6E 74 6C 6E 00 21 00 11 00 0A 00 ..println.!.....
000002F0: 00 00 00 00 02 00 01 00 12 00 13 00 01 00 14 00 ................
00000300: 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 ...........*....
00000310: 00 00 00 01 00 15 00 00 00 06 00 01 00 00 00 03 ................
00000320: 00 09 00 16 00 17 00 02 00 14 00 00 00 C1 00 07 ................
00000330: 00 07 00 00 00 75 12 02 4C 11 04 00 BC 08 4D 03 .....u..L.....M.
00000340: 36 04 BB 00 03 59 BB 00 04 59 2B B7 00 05 B7 00 6....Y...Y+.....
00000350: 06 3A 05 19 05 2C B6 00 07 59 3E 9E 00 2F 03 36 .:...,...Y>../.6
00000360: 06 15 06 1D A2 00 23 B2 00 08 12 09 04 BD 00 0A ......#.........
00000370: 59 03 2C 15 06 33 B8 00 0B 53 B6 00 0C 57 84 04 Y.,..3...S...W..
00000380: 01 84 06 01 A7 FF DD A7 FF CC B2 00 08 12 0D 04 ................
00000390: BD 00 0A 59 03 15 04 B8 00 0E 53 B6 00 0C 57 19 ...Y......S...W.
000003A0: 05 B6 00 0F B2 00 08 B6 00 10 B1 00 00 00 01 00 ................
000003B0: 15 00 00 00 3A 00 0E 00 00 00 06 00 03 00 07 00 ....:...........
000003C0: 09 00 09 00 0C 00 0B 00 1D 00 0D 00 28 00 0E 00 ............(...
000003D0: 31 00 0F 00 48 00 10 00 4B 00 0E 00 51 00 12 00 1...H...K...Q...
000003E0: 54 00 15 00 69 00 16 00 6E 00 18 00 74 00 19 00 T...i...n...t...
000003F0: 18 00 00 00 04 00 01 00 19 00 01 00 1A 00 00 00 ................
00000400: 02 00 1B ...
D:\Z>
D:\Z>example.pl Example.class > out.txt
D:\Z>
파일명을 입력하세요
D:\Z>example.pl Example.class
00000000: CA FE BA BE 00 00 00 31 00 43 0A 00 0A 00 1C 08 .......1.C......
00000010: 00 1D 07 00 1E 07 00 1F 0A 00 04 00 20 0A 00 03 ............ ...
00000020: 00 21 0A 00 03 00 22 09 00 23 00 24 08 00 25 07 .!...."..#.$..%.
00000030: 00 26 0A 00 27 00 28 0A 00 29 00 2A 08 00 2B 0A .&..'.(..).*..+.
00000040: 00 2C 00 2D 0A 00 03 00 2E 0A 00 29 00 2F 07 00 .,.-.......)./..
00000050: 30 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 0...<init>...()V
00000060: 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 ...Code...LineNu
00000070: 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 6E mberTable...main
00000080: 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F ...([Ljava/lang/
00000090: 53 74 72 69 6E 67 3B 29 56 01 00 0A 45 78 63 65 String;)V...Exce
000000A0: 70 74 69 6F 6E 73 07 00 31 01 00 0A 53 6F 75 72 ptions..1...Sour
000000B0: 63 65 46 69 6C 65 01 00 0C 45 78 61 6D 70 6C 65 ceFile...Example
000000C0: 2E 6A 61 76 61 0C 00 12 00 13 01 00 08 74 65 73 .java........tes
000000D0: 74 2E 62 69 6E 01 00 17 6A 61 76 61 2F 69 6F 2F t.bin...java/io/
000000E0: 44 61 74 61 49 6E 70 75 74 53 74 72 65 61 6D 01 DataInputStream.
000000F0: 00 17 6A 61 76 61 2F 69 6F 2F 46 69 6C 65 49 6E ..java/io/FileIn
00000100: 70 75 74 53 74 72 65 61 6D 0C 00 12 00 32 0C 00 putStream....2..
00000110: 12 00 33 0C 00 34 00 35 07 00 36 0C 00 37 00 38 ..3..4.5..6..7.8
00000120: 01 00 05 25 30 32 58 0A 01 00 10 6A 61 76 61 2F ...%02X....java/
00000130: 6C 61 6E 67 2F 4F 62 6A 65 63 74 07 00 39 0C 00 lang/Object..9..
00000140: 3A 00 3B 07 00 3C 0C 00 3D 00 3E 01 00 28 25 6E :.;..<..=.>..(%n
00000150: 25 6E 25 6E 5B 25 64 20 EB B0 94 EC 9D B4 ED 8A %n%n[%d ........
00000160: B8 EB A5 BC 20 EC 9D BD EC 96 B4 EC 84 9C 20 EC .... ......... .
00000170: B6 9C EB A0 A5 5D 07 00 3F 0C 00 3A 00 40 0C 00 .....]..?..:.@..
00000180: 41 00 13 0C 00 42 00 13 01 00 07 45 78 61 6D 70 A....B.....Examp
00000190: 6C 65 01 00 13 6A 61 76 61 2F 69 6F 2F 49 4F 45 le...java/io/IOE
000001A0: 78 63 65 70 74 69 6F 6E 01 00 15 28 4C 6A 61 76 xception...(Ljav
000001B0: 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 a/lang/String;)V
000001C0: 01 00 18 28 4C 6A 61 76 61 2F 69 6F 2F 49 6E 70 ...(Ljava/io/Inp
000001D0: 75 74 53 74 72 65 61 6D 3B 29 56 01 00 04 72 65 utStream;)V...re
000001E0: 61 64 01 00 05 28 5B 42 29 49 01 00 10 6A 61 76 ad...([B)I...jav
000001F0: 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 a/lang/System...
00000200: 6F 75 74 01 00 15 4C 6A 61 76 61 2F 69 6F 2F 50 out...Ljava/io/P
00000210: 72 69 6E 74 53 74 72 65 61 6D 3B 01 00 0E 6A 61 rintStream;...ja
00000220: 76 61 2F 6C 61 6E 67 2F 42 79 74 65 01 00 07 76 va/lang/Byte...v
00000230: 61 6C 75 65 4F 66 01 00 13 28 42 29 4C 6A 61 76 alueOf...(B)Ljav
00000240: 61 2F 6C 61 6E 67 2F 42 79 74 65 3B 01 00 13 6A a/lang/Byte;...j
00000250: 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 ava/io/PrintStre
00000260: 61 6D 01 00 06 66 6F 72 6D 61 74 01 00 3C 28 4C am...format..<(L
00000270: 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 java/lang/String
00000280: 3B 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A ;[Ljava/lang/Obj
00000290: 65 63 74 3B 29 4C 6A 61 76 61 2F 69 6F 2F 50 72 ect;)Ljava/io/Pr
000002A0: 69 6E 74 53 74 72 65 61 6D 3B 01 00 11 6A 61 76 intStream;...jav
000002B0: 61 2F 6C 61 6E 67 2F 49 6E 74 65 67 65 72 01 00 a/lang/Integer..
000002C0: 16 28 49 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 49 .(I)Ljava/lang/I
000002D0: 6E 74 65 67 65 72 3B 01 00 05 63 6C 6F 73 65 01 nteger;...close.
000002E0: 00 07 70 72 69 6E 74 6C 6E 00 21 00 11 00 0A 00 ..println.!.....
000002F0: 00 00 00 00 02 00 01 00 12 00 13 00 01 00 14 00 ................
00000300: 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 ...........*....
00000310: 00 00 00 01 00 15 00 00 00 06 00 01 00 00 00 03 ................
00000320: 00 09 00 16 00 17 00 02 00 14 00 00 00 C1 00 07 ................
00000330: 00 07 00 00 00 75 12 02 4C 11 04 00 BC 08 4D 03 .....u..L.....M.
00000340: 36 04 BB 00 03 59 BB 00 04 59 2B B7 00 05 B7 00 6....Y...Y+.....
00000350: 06 3A 05 19 05 2C B6 00 07 59 3E 9E 00 2F 03 36 .:...,...Y>../.6
00000360: 06 15 06 1D A2 00 23 B2 00 08 12 09 04 BD 00 0A ......#.........
00000370: 59 03 2C 15 06 33 B8 00 0B 53 B6 00 0C 57 84 04 Y.,..3...S...W..
00000380: 01 84 06 01 A7 FF DD A7 FF CC B2 00 08 12 0D 04 ................
00000390: BD 00 0A 59 03 15 04 B8 00 0E 53 B6 00 0C 57 19 ...Y......S...W.
000003A0: 05 B6 00 0F B2 00 08 B6 00 10 B1 00 00 00 01 00 ................
000003B0: 15 00 00 00 3A 00 0E 00 00 00 06 00 03 00 07 00 ....:...........
000003C0: 09 00 09 00 0C 00 0B 00 1D 00 0D 00 28 00 0E 00 ............(...
000003D0: 31 00 0F 00 48 00 10 00 4B 00 0E 00 51 00 12 00 1...H...K...Q...
000003E0: 54 00 15 00 69 00 16 00 6E 00 18 00 74 00 19 00 T...i...n...t...
000003F0: 18 00 00 00 04 00 01 00 19 00 01 00 1A 00 00 00 ................
00000400: 02 00 1B ...
D:\Z>
D:\Z>example.pl Example.class > out.txt
D:\Z>
example.pl Example.class > out.txt
이렇게 하면 out.txt 라는 파일로 출력 결과가 저장됩니다.
위에서 Example.class 란, 뷰어로 볼 아무 이름의 파일을 의미합니다.
참고: ▶▶ [QnA] 헥사 에디터란? 좋은 헥사 에디터(Hex Editor)는? : WinHex
tag: perl
Perl | 펄
<< Home