Better handling of conflicting section information between
SizeOfRawData and VirtualSize.

diff --git a/server/mapping.c b/server/mapping.c
index 5826fef..81e4806 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -116,11 +116,25 @@
     return NULL;
 }
 
+/* return the size of the memory mapping of a given section */
+static inline unsigned int get_section_map_size( const IMAGE_SECTION_HEADER *sec )
+{
+    if (!sec->Misc.VirtualSize) return ROUND_SIZE( sec->SizeOfRawData );
+    else return ROUND_SIZE( sec->Misc.VirtualSize );
+}
+
+/* return the size of the file mapping of a given section */
+static inline unsigned int get_section_filemap_size( const IMAGE_SECTION_HEADER *sec )
+{
+    if (!sec->Misc.VirtualSize) return sec->SizeOfRawData;
+    else return min( sec->SizeOfRawData, ROUND_SIZE( sec->Misc.VirtualSize ) );
+}
+
 /* allocate and fill the temp file for a shared PE image mapping */
 static int build_shared_mapping( struct mapping *mapping, int fd,
                                  IMAGE_SECTION_HEADER *sec, unsigned int nb_sec )
 {
-    unsigned int i, max_size, total_size;
+    unsigned int i, size, max_size, total_size;
     off_t shared_pos, read_pos, write_pos;
     char *buffer = NULL;
     int shared_fd;
@@ -134,9 +148,9 @@
         if ((sec[i].Characteristics & IMAGE_SCN_MEM_SHARED) &&
             (sec[i].Characteristics & IMAGE_SCN_MEM_WRITE))
         {
-            unsigned int size = ROUND_SIZE( sec[i].Misc.VirtualSize );
+            size = get_section_filemap_size( &sec[i] );
             if (size > max_size) max_size = size;
-            total_size += size;
+            total_size += get_section_map_size( &sec[i] );
         }
     }
     if (!(mapping->shared_size = total_size)) return 1;  /* nothing to do */
@@ -159,10 +173,11 @@
         if (!(sec[i].Characteristics & IMAGE_SCN_MEM_SHARED)) continue;
         if (!(sec[i].Characteristics & IMAGE_SCN_MEM_WRITE)) continue;
         write_pos = shared_pos;
-        shared_pos += ROUND_SIZE( sec[i].Misc.VirtualSize );
-        if (!sec[i].PointerToRawData || !sec[i].SizeOfRawData) continue;
+        shared_pos += get_section_map_size( &sec[i] );
         read_pos = sec[i].PointerToRawData;
-        toread = sec[i].SizeOfRawData;
+        size = get_section_filemap_size( &sec[i] );
+        if (!read_pos || !size) continue;
+        toread = size;
         while (toread)
         {
             long res = pread( fd, buffer + sec[i].SizeOfRawData - toread, toread, read_pos );
@@ -170,8 +185,7 @@
             toread -= res;
             read_pos += res;
         }
-        if (pwrite( shared_fd, buffer, sec[i].SizeOfRawData, write_pos ) != sec[i].SizeOfRawData)
-            goto error;
+        if (pwrite( shared_fd, buffer, size, write_pos ) != size) goto error;
     }
     free( buffer );
     return 1;