1# coding=utf-8
2# Copyright 2018 Sascha Schirra
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are met:
6#
7# 1. Redistributions of source code must retain the above copyright notice, this
8# list of conditions and the following disclaimer.
9#
10# 2. Redistributions in binary form must reproduce the above copyright notice,
11# this list of conditions and the following disclaimer in the documentation
12# and/or other materials provided with the distribution.
13#
14# 3. Neither the name of the copyright holder nor the names of its contributors
15# may be used to endorse or promote products derived from this software without
16# specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" A ND
19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28from ropper.printer.printer import *
29from ropper.loaders.pe import *
30from filebytes.pe import *
31import datetime
32
33
34class PEPrinter(FileDataPrinter):
35
36    @classmethod
37    def validType(cls):
38        return Type.PE
39
40    def printInformation(self, binary):
41
42        self.__printImageHeaders(binary)
43        self.__printOptionalHeaders(binary)
44
45    def __printImageHeaders(self, pefile):
46        fh = pefile._binary.imageNtHeaders.header.FileHeader
47        data = [
48            (cstr('Characteristics', Color.BLUE),
49                cstr(self._toHex(fh.Characteristics), Color.WHITE)),
50            (cstr('Machine', Color.BLUE),
51                cstr(pe.IMAGE_FILE_MACHINE[fh.Machine], Color.WHITE)),
52            (cstr('NumberOfSections', Color.BLUE),
53                cstr((fh.NumberOfSections), Color.WHITE)),
54            (cstr('PointerToSymbolTable', Color.BLUE),
55                cstr(self._toHex(fh.PointerToSymbolTable, pefile.arch.addressLength), Color.WHITE)),
56            (cstr('SizeOfOptionalHeader', Color.BLUE),
57                cstr((fh.SizeOfOptionalHeader), Color.WHITE)),
58            (cstr('TimeDateStamp', Color.BLUE),
59                cstr((datetime.datetime.fromtimestamp(
60                    fh.TimeDateStamp
61                    ).strftime('%Y-%m-%d %H:%M:%S')), Color.WHITE))
62        ]
63
64        self._printTable('Image Headers', (cstr('Name',Color.LIGHT_GRAY), cstr('Value',Color.LIGHT_GRAY)), data)
65
66    def __printOptionalHeaders(self, pefile):
67        oh = pefile._binary.imageNtHeaders.header.OptionalHeader
68        addressLength = pefile.arch.addressLength
69        data = [
70            (cstr('AddressOfEntryPoint', Color.BLUE),
71                cstr(self._toHex(oh.AddressOfEntryPoint, addressLength), Color.WHITE)),
72            (cstr('BaseOfCode', Color.BLUE),
73                cstr(self._toHex(oh.BaseOfCode, addressLength), Color.WHITE)),
74            (cstr('CheckSum', Color.BLUE),
75                cstr(self._toHex(oh.CheckSum,4), Color.WHITE)),
76            (cstr('DllCharacteristics', Color.BLUE),
77                cstr(self._toHex(oh.DllCharacteristics,2), Color.WHITE)),
78            (cstr('FileAlignment', Color.BLUE),
79                cstr(self._toHex(oh.FileAlignment,4), Color.WHITE)),
80            (cstr('ImageBase', Color.BLUE),
81                cstr(self._toHex(oh.ImageBase, addressLength), Color.WHITE)),
82            (cstr('LoaderFlags', Color.BLUE),
83                cstr(self._toHex(oh.LoaderFlags,4), Color.WHITE)),
84            (cstr('Magic', Color.BLUE),
85                cstr(self._toHex(oh.Magic,4), Color.WHITE)),
86            (cstr('MajorImageVersion', Color.BLUE),
87                cstr(self._toHex(oh.MajorImageVersion,2), Color.WHITE)),
88            (cstr('MajorLinkerVersion', Color.BLUE),
89                cstr(self._toHex(oh.MajorLinkerVersion,2), Color.WHITE)),
90            (cstr('MajorOperatingSystemVersion', Color.BLUE),
91                cstr(self._toHex(oh.MajorOperatingSystemVersion,2), Color.WHITE)),
92            (cstr('MajorSubsystemVersion', Color.BLUE),
93                cstr(self._toHex(oh.MajorSubsystemVersion,2), Color.WHITE)),
94            (cstr('MinorImageVersion', Color.BLUE),
95                cstr(self._toHex(oh.MinorImageVersion,2), Color.WHITE)),
96            (cstr('NumberOfRvaAndSizes', Color.BLUE),
97                cstr(self._toHex(oh.NumberOfRvaAndSizes,4), Color.WHITE)),
98            (cstr('SectionAlignment', Color.BLUE),
99                cstr(self._toHex(oh.SectionAlignment,4), Color.WHITE)),
100            (cstr('SizeOfCode', Color.BLUE),
101                cstr(self._toHex(oh.SizeOfCode,4), Color.WHITE)),
102            (cstr('SizeOfHeaders', Color.BLUE),
103                cstr(self._toHex(oh.SizeOfHeaders,4), Color.WHITE)),
104            (cstr('SizeOfHeapCommit', Color.BLUE),
105                cstr(self._toHex(oh.SizeOfHeapCommit,4), Color.WHITE)),
106            (cstr('SizeOfHeapReserve', Color.BLUE),
107                cstr(self._toHex(oh.SizeOfHeapReserve,4), Color.WHITE)),
108            (cstr('SizeOfImage', Color.BLUE),
109                cstr(self._toHex(oh.SizeOfImage,4), Color.WHITE)),
110            (cstr('SizeOfInitializedData', Color.BLUE),
111                cstr(self._toHex(oh.SizeOfInitializedData,4), Color.WHITE)),
112            (cstr('SizeOfStackCommit', Color.BLUE),
113                cstr(self._toHex(oh.SizeOfStackCommit,4), Color.WHITE)),
114            (cstr('SizeOfStackReserve', Color.BLUE),
115                cstr(self._toHex(oh.SizeOfStackReserve,4), Color.WHITE)),
116            (cstr('SizeOfUninitializedData', Color.BLUE),
117                cstr(self._toHex(oh.SizeOfUninitializedData,4), Color.WHITE)),
118            (cstr('Subsystem', Color.BLUE),
119                cstr(self._toHex(oh.Subsystem,4), Color.WHITE)),
120            (cstr('Win32VersionValue', Color.BLUE),
121                cstr(self._toHex(oh.Win32VersionValue,4), Color.WHITE))
122        ]
123
124        self._printTable('Image Optional Headers', (cstr('Name', Color.LIGHT_GRAY), cstr('Value',Color.LIGHT_GRAY)), data)
125
126    def printDllCharacteristics(self, pefile):
127        dllc = pefile._binary.imageNtHeaders.header.OptionalHeader.DllCharacteristics
128        yes = cstr('Yes', Color.YELLOW)
129        no = cstr('NO', Color.GREEN)
130        data = [
131            (cstr('DynamicBase', Color.BLUE), yes if (
132                dllc & ImageDllCharacteristics.DYNAMIC_BASE) > 0 else no),
133            (cstr('ForceIntegrity', Color.BLUE), yes if (
134                dllc & ImageDllCharacteristics.FORCE_INTEGRITY) > 0 else no),
135            (cstr('NxCompat', Color.BLUE), yes if (
136                dllc & ImageDllCharacteristics.NX_COMPAT) > 0 else no),
137            (cstr('No Isolation', Color.BLUE), yes if (
138                dllc & ImageDllCharacteristics.NO_ISOLATION) > 0 else no),
139            (cstr('No SEH', Color.BLUE), yes if (dllc & ImageDllCharacteristics.NO_SEH)
140             > 0 else no),
141            (cstr('No Bind', Color.BLUE), yes if (dllc & ImageDllCharacteristics.NO_BIND)
142             > 0 else no),
143            (cstr('WdmDriver', Color.BLUE), yes if (
144                dllc & ImageDllCharacteristics.WDM_DRIVER) > 0 else no),
145            (cstr('ControlFLowGuard', Color.BLUE), yes if (
146                dllc & ImageDllCharacteristics.CONTROL_FLOW_GUARD) > 0 else no),
147            (cstr('TerminalServerAware', Color.BLUE), yes if (
148                dllc & ImageDllCharacteristics.TERMINAL_SERVER_AWARE) > 0 else no)
149        ]
150
151        self._printTable('DllCharacteristics', (cstr('Name', Color.LIGHT_GRAY), cstr('Value', Color.LIGHT_GRAY)), data)
152
153    def printEntryPoint(self, binary):
154        self._printLine(self._toHex(binary.entryPoint, binary.arch.addressLength))
155
156    def printImageBase(self, binary):
157        self._printLine(
158            self._toHex(binary.imageBase, binary.arch.addressLength))
159
160    def printImports(self, pefile):
161        imports = pefile._binary.dataDirectory[pe.ImageDirectoryEntry.IMPORT]
162        if imports:
163            data = []
164            for descriptorData in imports:
165                for function in descriptorData.importAddressTable:
166                    if function.ordinal:
167                        data.append((cstr(descriptorData.dllName, Color.BLUE),
168                                cstr(self._toHex(pefile._binary.imageBase + function.rva,pefile.arch.addressLength), Color.CYAN),
169                                cstr(hex(function.ordinal), Color.LIGHT_GRAY),
170                                cstr('', Color.WHITE)))
171                    else:
172                        data.append((cstr(descriptorData.dllName, Color.BLUE),
173                                cstr(self._toHex(pefile._binary.imageBase+function.rva,pefile.arch.addressLength), Color.CYAN),
174                                cstr(hex(function.importByName.hint) if function.importByName else '', Color.LIGHT_GRAY),
175                                cstr(function.importByName.name if function.importByName else '', Color.WHITE)))
176
177            self._printTable(
178                'Imports', (cstr('DLL', Color.LIGHT_GRAY), cstr('Address', Color.LIGHT_GRAY), cstr('Hint/Ordinal', Color.LIGHT_GRAY), cstr('Function', Color.LIGHT_GRAY)), data)
179        else:
180            print('No imports!')
181
182    def printSections(self, pefile):
183
184        data = []
185        for section in pefile._binary.sections:
186            data.append((cstr(section.header.Name, Color.BLUE),
187                        cstr(self._toHex(section.header.VirtualAddress,pefile.arch.addressLength), Color.CYAN),
188                        cstr(self._toHex(section.header.SizeOfRawData), Color.LIGHT_GRAY),
189                        cstr(self._toHex(section.header.PointerToRawData,pefile.arch.addressLength), Color.WHITE),
190                        cstr(self._toHex(section.header.PointerToRelocations,pefile.arch.addressLength), Color.LIGHT_GRAY),
191                        cstr(self._toHex(section.header.NumberOfRelocations), Color.WHITE),))
192
193        self._printTable(
194            'Section Header', (cstr('Name', Color.LIGHT_GRAY), cstr('VAddr', Color.LIGHT_GRAY), cstr('RawDataSize', Color.LIGHT_GRAY), cstr('RawDataPtr', Color.LIGHT_GRAY), cstr('RelocPtr', Color.LIGHT_GRAY), cstr('NrOfReloc', Color.LIGHT_GRAY)), data)
195
196
197    def printArchitecture(self, binary):
198        self._printLine(str(binary.arch))
199
200    def printFileType(self, binary):
201        self._printLine(str(binary.type))
202