메모리 덤프 등에서 긁은 GUID 값을 그대로 검색하면 byte ordering 에 의해 원하는 결과가 나오지 않습니다. 그렇다고 0x10 이나 되는 GUID 를 손으로 수정하기도 눈알 빠지는 일이고요. little endian으로 저장된 GUID 를 검색하기 쉽게 big endian으로 변환해주는 파이썬 스크립트 입니다. 실행하고 명령창에 메모리에서 복사한 값을 붙여 넣는 식으로 동작합니다.
GUID 구조체를 선언해두고 구조체에 이쁘게 값을 집어넣고 빼고 하는 식으로 동작하기에 어마어마하게 느립니다. with as 문을 사용해봤습니다. 중요한 부분은 # convert string to binaryData
주석 아래가 전부입니다. 자동으로 컴포넌트, 인터페이스명 까지 긁어오면 좋겠지만 시간 나는대로 추가하겠습니다.
# -*- coding:utf8 -*-
import re
import struct
import binascii
from ctypes import *
class HexToGuid:
def __init__(self, inputVal):
"""
메모리에서 긁어온 16진수 문자열값의 길이를 검증하고
byte ordering 을 변경하여
검색하기 쉽게 저장해둔다
typedef struct _GUID { // GUID 구조체 원형
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
:param inputVal:
"""
class GUID(Structure):
_field_ = [
('Data1', c_uint32),
('Data2', c_uint16),
('Data3', c_uint16),
('Data4', c_char * 8)
]
self.guid = GUID()
self.guidStr = ''
self.clsidStr = ''
hexStr = self.getHexStr(inputVal)
if hexStr is None:
raise ValueError
else:
self.initGuid(hexStr)
self.guidStr = self.getGuidStr()
self.clsidStr = self.getClsidStr()
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
return
def getHexStr(self, inputVal):
"""
IDA나 메모리 덤프에서 긁어온 GUID 로 의심되는 HEX 값 문자열을
빈칸 등 불필요한 문자를 삭제하고 GUID 에 맞는 길이인지 검증한 후 리턴한다.
맞지 않을경우 None 리턴
:param inputVal: IDA 나 기타 덤프에서 긁어온 HEX 값
:return: HEX 만 추출한 문자열
"""
# return Value
hexStr = None
# Remove redundant characters
redundants = '[\s\{\}\-\_]'
replaceTo = ''
inputVal = re.sub(redundants, replaceTo, inputVal)
# validate input value
guidPattern = '[a-fA-F0-9]{32}'
match = re.match(guidPattern, inputVal)
if match is not None:
hexStr = match.group(0)
return hexStr
def initGuid(self, hexStr):
"""
LittleEndian 방식으로 기록된 메모리덤프를 갖고 GUID 구조체를 읽어온다
:param hexStr: HEX값으로 이뤄진 연속된 문자열
"""
# convert string to binaryData
hexBinary = bytearray.fromhex(hexStr)
self.guid.Data1, self.guid.Data2, self.guid.Data3, self.guid.Data4 = struct.unpack('<LHH8s', hexBinary)
def getGuidStr(self):
"""
GUID 구조체를 읽기 편하게 반환한다
:return: GUID 문자열값
"""
# .decode('utf-8)' stands for removing b''
guid = self.guid
output = '%08x-%04x-%04x-%s' % (guid.Data1, guid.Data2, guid.Data3,
binascii.hexlify(guid.Data4).decode('utf-8'))
return output
def getClsidStr(self):
"""
GUID 구조체를 읽기 편하게 반환한다
CLSID 와 GUID 는 표현 형태만 다를뿐 같은 값
:return: CLSID 문자열값
"""
# .decode('utf-8)' stands for removing b''
guid = self.guid
output = '%08x-%04x-%04x-%s-%s' % (guid.Data1, guid.Data2, guid.Data3,
binascii.hexlify(guid.Data4[0:2]).decode('utf-8'),
binascii.hexlify(guid.Data4[2:]).decode('utf-8'))
return output
def main():
while True:
inputVal = input('\nType desired hex data : ')
try:
with HexToGuid(inputVal) as htg:
print('Google This!!!')
print(' GUID FORM : %s' % htg.guidStr)
print(' CLSID FORM : %s' % htg.clsidStr)
except ValueError:
print('Invalid hex value - %s' % inputVal)
if __name__ == '__main__':
main()
1 Comment