from FileFormat import * import Banners import pefile from TextDecorators import * from PyQt5 import QtGui, QtCore, QtWidgets import PyQt5 from cemu import * import sys, os import DisasmViewMode import fs_ntfs.fs_ntfs from fs_ntfs.fs_ntfs import ntfs class FsNtfs(FileFormat): name = 'fs_ntfs' priority = 5 lock = 0 def recognize(self, dataModel): self.dataModel = dataModel if self.dataModel.getWORD(510) != 0xAA55: # check if valid boot record return False if self.dataModel.getDWORD(3) != 0x5346544e: # check if NTFS magic return False # this will actually hit the same as mbr plugin, but this one has bigger priority return True def _encodeutf16(self, s): return '\x00'.join(s) def init(self, viewMode, parent): self._viewMode = viewMode self.MZbrush = QtGui.QBrush(QtGui.QColor(128, 0, 0)) self.INDXbrush = QtGui.QBrush(QtGui.QColor(128, 128, 0)) self.SpecialFilebrush = QtGui.QBrush(QtGui.QColor(128, 0, 128)) self.yellowPen = QtGui.QPen(QtGui.QColor(255, 255, 0)) self.greenPen = QtGui.QPen(QtGui.QColor(0, 255, 0)) self.grayBrush = QtGui.QBrush(QtGui.QColor(128, 128, 128)) self.whitePen = QtGui.QPen(QtGui.QColor(255, 255, 255)) self.textDecorator = TextDecorator(viewMode) self.textDecorator = HighlightASCII(self.textDecorator) self.textDecorator = HighlightPrefix(self.textDecorator, 'MZ', brush=self.MZbrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, 'PE\x00\x00', brush=self.MZbrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, '\x55\xAA', brush=self.MZbrush, pen=self.greenPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$MFT'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$MFTMirr'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Boot'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$LogFile'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$BadClus'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$AttrDef'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Bitmap'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Extend'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Secure'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Volume'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$UpCase'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Reparse'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Repair'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Config'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Deleted'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Repair'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Quota'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$TxfLog'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$TxfLog.blf'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$RmMetadata'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$I30'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$ObjId'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, self._encodeutf16('$Tops'), brush=self.SpecialFilebrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, 'FILE', brush=self.MZbrush, pen=self.yellowPen) self.textDecorator = HighlightPrefix(self.textDecorator, 'INDX', brush=self.INDXbrush, pen=self.greenPen) # first jump self.textDecorator = RangePen(self.textDecorator, 0, 2, pen=self.yellowPen, ignoreHighlights=True) # ntfs self.textDecorator = RangePen(self.textDecorator, 3, 8, pen=self.greenPen, ignoreHighlights=True) self.textDecorator = HighlightWideChar(self.textDecorator) self._viewMode.setTransformationEngine(self.textDecorator) # $BOOT self._viewMode.selector.addSelection((0x0B, 0x48 + 8, QtGui.QBrush(QtGui.QColor(125, 175, 150)), 0.4), type=TextSelection.SelectionType.PERMANENT) self.ntfs = fs_ntfs.fs_ntfs.ntfs.NTFS(self.dataModel) def hintDisasm(self): return DisasmViewMode.Disasm_x86_16bit def hintDisasmVA(self, offset): return offset def disasmVAtoFA(self, va): return va def getBanners(self): return [Banners.FileAddrBanner(self.dataModel, self._viewMode), Banners.TopBanner(self.dataModel, self._viewMode), Banners.BottomBanner(self.dataModel, self._viewMode)] def registerShortcuts(self, parent): self._parent = parent self.w = DialogGoto(parent, self) self._Shortcuts += [QtWidgets.QShortcut(QtGui.QKeySequence("Alt+G"), parent, self._showit, self._showit)] self._Shortcuts += [QtWidgets.QShortcut(QtGui.QKeySequence("s"), parent, self.skip_chars, self.skip_chars)] self._Shortcuts += [QtWidgets.QShortcut(QtGui.QKeySequence("e"), parent, self.skip_block, self.skip_block)] # goto $MFT self._Shortcuts += [QtWidgets.QShortcut(QtGui.QKeySequence("Alt+M"), parent, self._goto_mft, self._goto_mft)] # goto root (.) self._Shortcuts += [QtWidgets.QShortcut(QtGui.QKeySequence("Alt+R"), parent, self._goto_root, self._goto_root)] def _goto_root(self): fobj = self.ntfs.mft.get_file_record(5) if fobj: self._viewMode.selector.addSelection((fobj.offset, fobj.offset + fobj.size, QtGui.QBrush(QtGui.QColor(125, 175, 150)), 0.4), type=TextSelection.SelectionType.IF_CURSOR_IN_RANGE) self._viewMode.goTo(fobj.offset) def _goto_mft(self): fobj = self.ntfs.mft.get_file_record(0) if fobj: self._viewMode.selector.addSelection((fobj.offset, fobj.offset + fobj.size, QtGui.QBrush(QtGui.QColor(125, 175, 150)), 0.4), type=TextSelection.SelectionType.IF_CURSOR_IN_RANGE) self._viewMode.goTo(fobj.offset) def _showit(self): if not self.w.isVisible(): self.w.show() else: self.w.hide() def skip_block(self): off = self._viewMode.getCursorAbsolutePosition() x = off sizeOfData = self.dataModel.getDataSize() if x >= sizeOfData: return x = self.dataModel.getData().find(b'\x00'*8, off) if x == -1: x = off if x == off: if x < sizeOfData - 1: x += 1 self._viewMode.goTo(x) return def skip_chars(self): off = self._viewMode.getCursorAbsolutePosition() x = off + 1 sizeOfData = self.dataModel.getDataSize() if x >= sizeOfData: return # skip bytes of current value # import time BYTES = 512 # k = time.time() b = self.dataModel.getStream(off, off + 1) z = b * BYTES # compare stream of bytes z = self.dataModel.getStream(off, off+BYTES) while x < sizeOfData - BYTES and self.dataModel.getStream(x, x + BYTES) == z: x += BYTES while x < sizeOfData - 1 and self.dataModel.getBYTE(x) == ord(b): x += 1 # print time.time() - k self._viewMode.goTo(x)