15 May
2014
Posted in: 코드
By    No Comments

덤프의 색깔을 찾아서…


덤프의 색깔을 찾아서…
by 신영진(YoungJin Shin), codewiz at gmail.com, @codemaru, http://www.jiniya.net

덤프 이미지 분석은 내가 갑~ 왼쪽에 그림이 덤프 이미지입니다.

화욜날 간만에 댓글의 reinhard, zoops 횽들을 만나서 술을 한 잔 했습니다. 그러면서 이런저런 이야기를 하는데 reinhard 님께서 드미트리옹께서 크래시 덤프의 이미지를 만들어서 재미를 보고 계셨다는 이야기를 해주시더군요. 제가 또 드미트리옹과 페친 아니겠습니까? 드미트리옹의 책도 다 샀는데 눈 뜬 장님이었더군요. 책 표지 자체가 크래시 덤프 이미지였다는 사실을 알고는 충격과 공포에 빠졌습니다. 역시 사람은 아는만큼 보인다는 옛 이야기가 다 헛말이 아니었습니다. 핡~

그래서 저도 해봤습니다. 제가 가진 게임 덤프 파일 중에 하나를 돌려보았지요. 가운데 텅 빈 공간이 웬지 무한한 우주 공간에서 찰나의 순간을 살다가는 인간이라는 존재의 한없는 고독함을 나타내 주고 있는듯한 느낌입니다 ㅋㅋㅋ~

crash

한 게임의 크래시 덤프

글을 보고는 바이너리를 이미지로 변환을 어떻게 하시는지 궁금해 하시는 분들이 계시는 듯 하여 소스 코드도 같이 올려드립니다. 지난 번에 작업한 스크립트 파일은 앞에 비트맵 헤더 붙이고 귀찮아서 뒤에다 0으로 전부 패딩을 넣었었는데요, 이번 버전은 비트맵 의도대로 중간 중간에 패딩을 넣도록 한 버전입니다. bin2img.py input.tar output.bmp 하시면 됩니다.

'''

	Copyright (c) 2014 YoungJin Shin <codewiz@gmail.com>

	bin2img.py input.tar output.bmp

'''

import math
import struct
import sys

BPP = 24
BPP_BYTES = BPP / 8
BMP_HDR_SIZE = 14
DIB_HDR_SIZE = 40
DPI = 2835

def GetImageFileSize(sz):
	px = int(math.ceil(sz / float(BPP_BYTES)))
	wpx = int(math.ceil(math.sqrt(px)))

	xbytes = int(math.floor((wpx * BPP + 31) / 32.0) * 4)
	return (wpx * xbytes, wpx, wpx, xbytes)

def GetBmpHeader(sz, w, h):
	return struct.pack('=BBLHHLLLLHHLLLLLL'
						, 0x42
						, 0x4d
						, sz + BMP_HDR_SIZE + DIB_HDR_SIZE
						, 0
						, 0
						, BMP_HDR_SIZE + DIB_HDR_SIZE
						, DIB_HDR_SIZE
						, w
						, h
						, 1
						, BPP 
						, 0
						, sz
						, DPI
						, DPI
						, 0
						, 0)

def GetPadBuffer(sz):
	pad = ''
	for x in range(sz):
		pad += struct.pack('=B', 0)

	return pad

def BinaryToImage(bin_path, img_path):
	inf = open(bin_path, 'rb')
	buffer = inf.read()
	inf.close()

	buffer_size = len(buffer)

	fsz, w, h, wbytes_pad = GetImageFileSize(buffer_size)

	hdr = GetBmpHeader(fsz, w, h)

	outf = open(img_path, 'wb')
	outf.write(hdr)

	wbytes = w * BPP_BYTES
	pad_size = wbytes_pad - wbytes

	pos = 0
	for i in range(h):
		remain = buffer_size - pos
		if remain < wbytes:
			pad_size = wbytes_pad - remain

		outf.write(buffer[pos : pos + wbytes])

		outf.write(GetPadBuffer(pad_size))
		
		pos += wbytes

	outf.close()

if __name__ == "__main__":
	BinaryToImage(sys.argv[1], sys.argv[2])


  • 트랙백 주소: http://www.jiniya.net/wp/archives/13168/trackback

관련 글