ReactOS  0.4.15-dev-2361-g32428a3
pefixup.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <typedefs.h>
#include <pecoff.h>
#include "../../dll/win32/dbghelp/compat.h"
Include dependency graph for pefixup.c:

Go to the source code of this file.

Enumerations

enum  fixup_mode {
  MODE_LOADCONFIG, MODE_KERNELDRIVER, MODE_WDMDRIVER, MODE_KERNELDLL,
  MODE_KERNEL
}
 

Functions

voidrva_to_ptr (unsigned char *buffer, PIMAGE_NT_HEADERS nt_header, DWORD rva)
 
static void error (const char *message,...)
 
static void fix_checksum (unsigned char *buffer, long len, PIMAGE_NT_HEADERS nt_header)
 
static int add_loadconfig (unsigned char *buffer, PIMAGE_NT_HEADERS nt_header)
 
static int driver_fixup (int mode, unsigned char *buffer, PIMAGE_NT_HEADERS nt_header)
 
static void print_usage (void)
 
int main (int argc, char **argv)
 

Variables

static const charg_ApplicationName
 
static const charg_Target
 

Enumeration Type Documentation

◆ fixup_mode

Enumerator
MODE_LOADCONFIG 
MODE_KERNELDRIVER 
MODE_WDMDRIVER 
MODE_KERNELDLL 
MODE_KERNEL 

Definition at line 27 of file pefixup.c.

Function Documentation

◆ add_loadconfig()

static int add_loadconfig ( unsigned char buffer,
PIMAGE_NT_HEADERS  nt_header 
)
static

Definition at line 81 of file pefixup.c.

82 {
84  PIMAGE_EXPORT_DIRECTORY export_directory;
85 
87  if (export_dir->Size != 0)
88  {
89  export_directory = rva_to_ptr(buffer, nt_header, export_dir->VirtualAddress);
90  if (export_directory != NULL)
91  {
92  DWORD *name_ptr, *function_ptr, n;
93  WORD *ordinal_ptr;
94 
95  name_ptr = rva_to_ptr(buffer, nt_header, export_directory->AddressOfNames);
96  ordinal_ptr = rva_to_ptr(buffer, nt_header, export_directory->AddressOfNameOrdinals);
97  function_ptr = rva_to_ptr(buffer, nt_header, export_directory->AddressOfFunctions);
98 
99  for (n = 0; n < export_directory->NumberOfNames; n++)
100  {
101  const char* name = rva_to_ptr(buffer, nt_header, name_ptr[n]);
102  if (!strcmp(name, "_load_config_used"))
103  {
104  PIMAGE_DATA_DIRECTORY load_config_dir;
105  DWORD load_config_rva = function_ptr[ordinal_ptr[n]];
106  DWORD* load_config_ptr = rva_to_ptr(buffer, nt_header, load_config_rva);
107 
108  /* Update the DataDirectory pointer / size
109  The first entry of the LOAD_CONFIG struct is the size, use that as DataDirectory.Size */
111  load_config_dir->VirtualAddress = load_config_rva;
112  load_config_dir->Size = *load_config_ptr;
113 
114  return 0;
115  }
116  }
117 
118  error("Export '_load_config_used' not found\n");
119  }
120  else
121  {
122  error("Invalid rva for export directory\n");
123  }
124  }
125  else
126  {
127  error("No export directory\n");
128  }
129 
130  return 1;
131 }
void * rva_to_ptr(unsigned char *buffer, PIMAGE_NT_HEADERS nt_header, DWORD rva)
Definition: pefixup.c:36
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
DWORD AddressOfNameOrdinals
Definition: compat.h:167
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
static export_section_t export_dir
Definition: data.c:448
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define NULL
Definition: types.h:112
Definition: name.c:38
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static IMAGE_NT_HEADERS32 nt_header
Definition: data.c:36
static void error(const char *message,...)
Definition: pefixup.c:53

Referenced by main().

◆ driver_fixup()

static int driver_fixup ( int  mode,
unsigned char buffer,
PIMAGE_NT_HEADERS  nt_header 
)
static

Definition at line 133 of file pefixup.c.

134 {
135  /* GNU LD just doesn't know what a driver is, and has notably no idea of paged vs non-paged sections */
136  for (unsigned i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
137  {
139 
140  /* LD puts alignment crap that nobody asked for */
142 
143  /* LD overdoes it and puts the initialized flag everywhere */
144  if (Section->Characteristics & IMAGE_SCN_CNT_CODE)
146 
147  /* For some reason, .rsrc is made writable by windres */
148  if (strncasecmp((char*)Section->Name, ".rsrc", 5) == 0)
149  {
151  continue;
152  }
153 
154  /* Known sections which can be discarded */
155  if (strncasecmp((char*)Section->Name, "INIT", 4) == 0)
156  {
158  continue;
159  }
160 
161  /* Known sections which can be paged */
162  if ((strncasecmp((char*)Section->Name, "PAGE", 4) == 0)
163  || (strncasecmp((char*)Section->Name, ".rsrc", 5) == 0)
164  || (strncasecmp((char*)Section->Name, ".edata", 6) == 0)
165  || (strncasecmp((char*)Section->Name, ".reloc", 6) == 0))
166  {
167  continue;
168  }
169 
170  /* If it's discardable, don't set the flag */
172  continue;
173 
175  }
176 
177  return 0;
178 }
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
#define IMAGE_SCN_ALIGN_MASK
Definition: pecoff.h:56
#define strncasecmp
Definition: fake.h:10
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: ntimage.h:231
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define IMAGE_SCN_CNT_CODE
Definition: ntimage.h:230
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IMAGE_SCN_MEM_NOT_PAGED
Definition: ntimage.h:237
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
static IMAGE_NT_HEADERS32 nt_header
Definition: data.c:36
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235

Referenced by main().

◆ error()

static void error ( const char message,
  ... 
)
static

Definition at line 53 of file pefixup.c.

54 {
55  va_list args;
56 
57  fprintf(stderr, "%s ERROR: '%s': ", g_ApplicationName, g_Target);
58 
61  va_end(args);
62 }
Definition: tftpd.h:59
#define args
Definition: format.c:66
static const char * g_Target
Definition: pefixup.c:25
Definition: match.c:390
static const char * g_ApplicationName
Definition: pefixup.c:24
#define va_end(ap)
Definition: acmsvcex.h:90
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
char * va_list
Definition: acmsvcex.h:78
va_start(ap, x)
FILE * stderr

Referenced by add_loadconfig(), and main().

◆ fix_checksum()

static void fix_checksum ( unsigned char buffer,
long  len,
PIMAGE_NT_HEADERS  nt_header 
)
static

Definition at line 64 of file pefixup.c.

65 {
66  unsigned int checksum = 0;
67  long n;
68 
70 
71  for (n = 0; n < len; n += 2)
72  {
73  checksum += *(unsigned short *)(buffer + n);
74  checksum = (checksum + (checksum >> 16)) & 0xffff;
75  }
76 
77  checksum += len;
79 }
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
GLenum GLsizei len
Definition: glext.h:6722
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
static IMAGE_NT_HEADERS32 nt_header
Definition: data.c:36

Referenced by main().

◆ main()

int main ( int argc  ,
char **  argv 
)

Definition at line 193 of file pefixup.c.

194 {
195  FILE* file;
196  long len;
197  unsigned char *buffer;
199  int result = 1;
200  enum fixup_mode mode;
201 
202  g_ApplicationName = argv[0];
203 
204  if (argc != 3)
205  {
206  print_usage();
207  return 1;
208  }
209 
210  if (strcmp(argv[1], "--loadconfig") == 0)
211  {
213  }
214  else if (strcmp(argv[1], "--kernelmodedriver") == 0)
215  {
217  }
218  else if (strcmp(argv[1], "--wdmdriver") == 0)
219  {
221  }
222  else if (strcmp(argv[1], "--kerneldll") == 0)
223  {
225  }
226  else if (strcmp(argv[1], "--kernel") == 0)
227  {
228  mode = MODE_KERNEL;
229  }
230  else
231  {
232  print_usage();
233  return 1;
234  }
235 
236  g_Target = argv[2];
237 
238  /* Read the whole file to memory. */
239  file = fopen(g_Target, "r+b");
240  if (!file)
241  {
242  fprintf(stderr, "%s ERROR: Can't open '%s'.\n", g_ApplicationName, g_Target);
243  return 1;
244  }
245 
246  fseek(file, 0, SEEK_END);
247  len = ftell(file);
248  if (len < sizeof(IMAGE_DOS_HEADER))
249  {
250  fclose(file);
251  error("Image size too small to be a PE image\n");
252  return 1;
253  }
254 
255  /* Add one byte extra for the case where the input file size is odd.
256  We rely on this in our crc calculation */
257  buffer = calloc(len + 1, 1);
258  if (buffer == NULL)
259  {
260  fclose(file);
261  error("Not enough memory available: (Needed %u bytes).\n", len + 1);
262  return 1;
263  }
264 
265  /* Read the whole input file into a buffer */
266  fseek(file, 0, SEEK_SET);
267  fread(buffer, 1, len, file);
268 
269  /* Check the headers and save pointers to them. */
272  {
274 
276 
278  {
279  if (mode == MODE_LOADCONFIG)
281  else
283 
284  if (!result)
285  {
286  /* Success. Fix checksum and write to file */
288 
289  /* We could 'optimize by only writing the changed parts, but keep it simple for now */
290  fseek(file, 0, SEEK_SET);
291  fwrite(buffer, 1, len, file);
292  }
293  }
294  else
295  {
296  error("Invalid PE signature: %x\n", nt_header->Signature);
297  }
298  }
299  else
300  {
301  error("Invalid DOS signature: %x\n", dos_header->e_magic);
302  }
303 
304  free(buffer);
305  fclose(file);
306 
307  return result;
308 }
static int argc
Definition: ServiceArgs.c:12
static int driver_fixup(int mode, unsigned char *buffer, PIMAGE_NT_HEADERS nt_header)
Definition: pefixup.c:133
GLuint64EXT * result
Definition: glext.h:11304
fixup_mode
Definition: pefixup.c:27
static const char * g_Target
Definition: pefixup.c:25
static void print_usage(void)
Definition: pefixup.c:182
#define free
Definition: debug_ros.c:5
GLuint buffer
Definition: glext.h:5915
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
#define argv
Definition: mplay32.c:18
static const char * g_ApplicationName
Definition: pefixup.c:24
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
struct _IMAGE_DOS_HEADER * PIMAGE_DOS_HEADER
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
#define SEEK_SET
Definition: jmemansi.c:26
static IMAGE_DOS_HEADER dos_header
Definition: data.c:13
const char file[]
Definition: icontest.c:11
GLenum GLsizei len
Definition: glext.h:6722
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
GLenum mode
Definition: glext.h:6217
static void fix_checksum(unsigned char *buffer, long len, PIMAGE_NT_HEADERS nt_header)
Definition: pefixup.c:64
static int add_loadconfig(unsigned char *buffer, PIMAGE_NT_HEADERS nt_header)
Definition: pefixup.c:81
#define NULL
Definition: types.h:112
#define calloc
Definition: rosglue.h:14
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define SEEK_END
Definition: cabinet.c:27
static IMAGE_NT_HEADERS32 nt_header
Definition: data.c:36
static void error(const char *message,...)
Definition: pefixup.c:53
PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS
Definition: ntddk_ex.h:187
Definition: fci.c:126

◆ print_usage()

static void print_usage ( void  )
static

Definition at line 182 of file pefixup.c.

183 {
184  printf("Usage: %s <mode> <filename>\n", g_ApplicationName);
185  printf("Where <mode> is on of the following:\n");
186  printf(" --loadconfig Fix the LOAD_CONFIG directory entry\n");
187  printf(" --kernelmodedriver Fix code and data sections for driver images\n");
188  printf(" --wdmdriver Fix code and data sections for WDM drivers\n");
189  printf(" --kerneldll Fix code and data sections for Kernel-Mode DLLs\n");
190  printf(" --kernel Fix code and data sections for kernels\n");
191 }
static const char * g_ApplicationName
Definition: pefixup.c:24
#define printf
Definition: config.h:203

Referenced by main().

◆ rva_to_ptr()

void* rva_to_ptr ( unsigned char buffer,
PIMAGE_NT_HEADERS  nt_header,
DWORD  rva 
)

Definition at line 36 of file pefixup.c.

37 {
38  unsigned int i;
40 
41  for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++, section_header++)
42  {
43  if (rva >= section_header->VirtualAddress &&
44  rva < section_header->VirtualAddress + section_header->Misc.VirtualSize)
45  {
46  return buffer + rva - section_header->VirtualAddress + section_header->PointerToRawData;
47  }
48  }
49 
50  return NULL;
51 }
GLuint buffer
Definition: glext.h:5915
DWORD PointerToRawData
Definition: pedump.c:290
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
union _IMAGE_SECTION_HEADER::@1552 Misc
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
static IMAGE_NT_HEADERS32 nt_header
Definition: data.c:36

Referenced by add_loadconfig().

Variable Documentation

◆ g_ApplicationName

const char* g_ApplicationName
static

Definition at line 24 of file pefixup.c.

Referenced by error(), main(), and print_usage().

◆ g_Target

const char* g_Target
static

Definition at line 25 of file pefixup.c.

Referenced by error(), and main().