-Added a warning message when entries typical of packed files are found in the import table
-Offsets are now shown when printing out information about a PE's headers/contents. Both absolute within the file and relative to the structure's start
-Fixed a bug parsing import table entries

git-svn-id: http://pefile.googlecode.com/svn/trunk@75 8842bc4e-7134-0410-8230-5dc5194fb5c1
diff --git a/pefile.py b/pefile.py
index 43fb2fc..7abd05c 100644
--- a/pefile.py
+++ b/pefile.py
@@ -663,6 +663,12 @@
         return ''.join( self.text )
 
 
+STRUCT_SIZEOF_TYPES = {
+    'x': 1, 'c': 1, 'b': 1, 'B': 1, 
+    'h': 2, 'H': 2, 
+    'i': 4, 'I': 4, 'l': 4, 'L': 4, 'f': 4,
+    'q': 8, 'Q': 8, 'd': 8,
+    's': 1 }
 
 class Structure:
     """Prepare structure object to extract members from data.
@@ -678,6 +684,7 @@
         self.__keys__ = []
         #self.values = {}
         self.__format_length__ = 0
+        self.__field_offsets__ = dict()
         self.__set_format__(format[1])
         self.__all_zeroes__ = False
         self.__unpacked_data_elms__ = None
@@ -691,6 +698,13 @@
     def __get_format__(self):
         return self.__format__
         
+    def get_field_absolute_offset(self, field_name):
+        """Return the offset within the field for the requested field in the structure."""
+        return self.__file_offset__ + self.__field_offsets__[field_name]
+
+    def get_field_relative_offset(self, field_name):
+        """Return the offset within the structure for the requested field."""
+        return self.__field_offsets__[field_name]
     
     def get_file_offset(self):
         return self.__file_offset__
@@ -703,9 +717,18 @@
         
         return self.__all_zeroes__
                 
+    def sizeof_type(self, t):
+        count = 1
+        _t = t
+        if t[0] in string.digits:
+            # extract the count
+            count = int( ''.join([d for d in t if d in string.digits]) )
+            _t = ''.join([d for d in t if d not in string.digits])
+        return STRUCT_SIZEOF_TYPES[_t] * count
     
     def __set_format__(self, format):
         
+        offset = 0
         for elm in format:
             if ',' in elm:
                 elm_type, elm_name = elm.split(',', 1)
@@ -719,6 +742,10 @@
                         occ_count = search_list.count(elm_name)
                         elm_name = elm_name+'_'+str(occ_count)
                     names.append(elm_name)
+                    self.__field_offsets__[elm_name] = offset
+
+                offset += self.sizeof_type(elm_type)
+
                 # Some PE header structures have unions on them, so a certain
                 # value might have different names, so each key has a list of
                 # all the possible members referring to the data.
@@ -807,7 +834,9 @@
                 else:
                     val_str = ''.join(filter(lambda c:c != '\0', str(val)))
                 
-                dump.append('%-30s %s' % (key+':', val_str))
+                dump.append('0x%-8X 0x%-3X %-30s %s' % (
+                    self.__field_offsets__[key] + self.__file_offset__, 
+                    self.__field_offsets__[key], key+':', val_str))
         
         return dump
 
@@ -3022,6 +3051,22 @@
                         imports = import_data,
                         dll = dll))
         
+        suspicious_imports = set([ 'LoadLibrary', 'GetProcAddress' ])
+        suspicious_imports_count = 0
+        total_symbols = 0
+        for imp_dll in import_descs:
+            for symbol in imp_dll.imports:
+                for suspicious_symbol in suspicious_imports:
+                    if symbol and symbol.name and symbol.name.startswith( suspicious_symbol ):
+                        suspicious_imports_count += 1
+                        break
+                total_symbols += 1
+        if suspicious_imports_count == len(suspicious_imports) and total_symbols < 20:
+            self.__warnings.append(
+                'Imported symbols contain entries typical of packed executables.' )
+            
+            
+        
         return import_descs
 
     
@@ -3073,6 +3118,7 @@
             imp_ord = None
             imp_hint = None
             imp_name = None
+            name_offset = None
             hint_name_table_rva = None
             
             if table[idx].AddressOfData: