ReactOS  0.4.14-dev-608-gd495a4f
assembly.c
Go to the documentation of this file.
1 /*
2  * assembly parser
3  *
4  * Copyright 2008 James Hawkins
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <stdarg.h>
22 #include <stdio.h>
23 
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winver.h"
30 #include "bcrypt.h"
31 #include "dbghelp.h"
32 #include "ole2.h"
33 #include "fusion.h"
34 #include "corhdr.h"
35 
36 #include "fusionpriv.h"
37 #include "wine/debug.h"
38 
39 #define TableFromToken(tk) (TypeFromToken(tk) >> 24)
40 #define TokenFromTable(idx) (idx << 24)
41 
42 #define MAX_CLR_TABLES 64
43 
44 #define MD_STRINGS_BIT 0x1
45 #define MD_GUIDS_BIT 0x2
46 #define MD_BLOBS_BIT 0x4
47 
48 typedef struct tagCLRTABLE
49 {
52 } CLRTABLE;
53 
55 {
57 
61 
64 
66 
71 
75 
78 };
79 
81 {
82  DWORD offset = rva, limit;
84  WORD i;
85 
86  img = IMAGE_FIRST_SECTION(nthdrs);
87 
88  if (rva < img->PointerToRawData)
89  return rva;
90 
91  for (i = 0; i < nthdrs->FileHeader.NumberOfSections; i++)
92  {
93  if (img[i].SizeOfRawData)
94  limit = img[i].SizeOfRawData;
95  else
96  limit = img[i].Misc.VirtualSize;
97 
98  if (rva >= img[i].VirtualAddress &&
99  rva < (img[i].VirtualAddress + limit))
100  {
101  if (img[i].PointerToRawData != 0)
102  {
103  offset -= img[i].VirtualAddress;
104  offset += img[i].PointerToRawData;
105  }
106 
107  return offset;
108  }
109  }
110 
111  return 0;
112 }
113 
114 static BYTE *GetData(BYTE *pData, ULONG *pLength)
115 {
116  if ((*pData & 0x80) == 0x00)
117  {
118  *pLength = (*pData & 0x7f);
119  return pData + 1;
120  }
121 
122  if ((*pData & 0xC0) == 0x80)
123  {
124  *pLength = ((*pData & 0x3f) << 8 | *(pData + 1));
125  return pData + 2;
126  }
127 
128  if ((*pData & 0xE0) == 0xC0)
129  {
130  *pLength = ((*pData & 0x1f) << 24 | *(pData + 1) << 16 |
131  *(pData + 2) << 8 | *(pData + 3));
132  return pData + 4;
133  }
134 
135  *pLength = (ULONG)-1;
136  return 0;
137 }
138 
140 {
141  return &assembly->data[offset];
142 }
143 
144 #define MAX_TABLES_WORD 0xFFFF
145 #define MAX_TABLES_1BIT_ENCODE 32767
146 #define MAX_TABLES_2BIT_ENCODE 16383
147 #define MAX_TABLES_3BIT_ENCODE 8191
148 #define MAX_TABLES_5BIT_ENCODE 2047
149 
151 {
152  DWORD size;
153  INT tables;
154 
155  switch (TokenFromTable(index))
156  {
157  case mdtModule:
158  {
159  size = sizeof(MODULETABLE) + (assembly->stringsz - sizeof(WORD)) +
160  2 * (assembly->guidsz - sizeof(WORD));
161  break;
162  }
163  case mdtTypeRef:
164  {
165  size = sizeof(TYPEREFTABLE) + 2 * (assembly->stringsz - sizeof(WORD));
166 
167  /* ResolutionScope:ResolutionScope */
168  tables = max(assembly->tables[TableFromToken(mdtModule)].rows,
169  assembly->tables[TableFromToken(mdtModuleRef)].rows);
171  tables = max(tables, assembly->tables[TableFromToken(mdtTypeRef)].rows);
172  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
173  break;
174  }
175  case mdtTypeDef:
176  {
177  size = sizeof(TYPEDEFTABLE) + 2 * (assembly->stringsz - sizeof(WORD));
178 
179  /* Extends:TypeDefOrRef */
180  tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows,
181  assembly->tables[TableFromToken(mdtTypeRef)].rows);
182  tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows);
183  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
184 
185  size += (assembly->tables[TableFromToken(mdtFieldDef)].rows >
186  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
187  size += (assembly->tables[TableFromToken(mdtMethodDef)].rows >
188  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
189  break;
190  }
191  case mdtFieldDef:
192  {
193  size = sizeof(FIELDTABLE) + (assembly->stringsz - sizeof(WORD)) +
194  (assembly->blobsz - sizeof(WORD));
195  break;
196  }
197  case mdtMethodDef:
198  {
199  size = sizeof(METHODDEFTABLE) + (assembly->stringsz - sizeof(WORD)) +
200  (assembly->blobsz - sizeof(WORD));
201 
202  size += (assembly->tables[TableFromToken(mdtParamDef)].rows >
203  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
204  break;
205  }
206  case mdtParamDef:
207  {
208  size = sizeof(PARAMTABLE) + (assembly->stringsz - sizeof(WORD));
209  break;
210  }
211  case mdtInterfaceImpl:
212  {
213  size = sizeof(INTERFACEIMPLTABLE);
214 
215  /* Interface:TypeDefOrRef */
216  tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows,
217  assembly->tables[TableFromToken(mdtTypeRef)].rows);
218  tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows);
219  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
220  break;
221  }
222  case mdtMemberRef:
223  {
224  size = sizeof(MEMBERREFTABLE) + (assembly->stringsz - sizeof(WORD)) +
225  (assembly->blobsz - sizeof(WORD));
226 
227  /* Class:MemberRefParent */
228  tables = max(assembly->tables[TableFromToken(mdtTypeRef)].rows,
229  assembly->tables[TableFromToken(mdtModuleRef)].rows);
231  tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows);
232  tables = max(tables, assembly->tables[TableFromToken(mdtTypeDef)].rows);
233  size += (tables > MAX_TABLES_3BIT_ENCODE) ? sizeof(WORD) : 0;
234  break;
235  }
236  case 0x0B000000: /* FIXME */
237  {
238  size = sizeof(CONSTANTTABLE) + (assembly->blobsz - sizeof(WORD));
239 
240  /* Parent:HasConstant */
241  tables = max(assembly->tables[TableFromToken(mdtParamDef)].rows,
242  assembly->tables[TableFromToken(mdtFieldDef)].rows);
243  tables = max(tables, assembly->tables[TableFromToken(mdtProperty)].rows);
244  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
245  break;
246  }
247  case mdtCustomAttribute:
248  {
249  size = sizeof(CUSTOMATTRIBUTETABLE) + (assembly->blobsz - sizeof(WORD));
250 
251  /* Parent:HasCustomAttribute */
252  tables = max(assembly->tables[TableFromToken(mdtMethodDef)].rows,
253  assembly->tables[TableFromToken(mdtFieldDef)].rows);
254  tables = max(tables, assembly->tables[TableFromToken(mdtTypeRef)].rows);
255  tables = max(tables, assembly->tables[TableFromToken(mdtTypeDef)].rows);
256  tables = max(tables, assembly->tables[TableFromToken(mdtParamDef)].rows);
260  tables = max(tables, assembly->tables[TableFromToken(mdtProperty)].rows);
261  tables = max(tables, assembly->tables[TableFromToken(mdtEvent)].rows);
264  tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows);
265  tables = max(tables, assembly->tables[TableFromToken(mdtAssembly)].rows);
266  tables = max(tables, assembly->tables[TableFromToken(mdtFile)].rows);
269  size += (tables > MAX_TABLES_5BIT_ENCODE) ? sizeof(WORD) : 0;
270 
271  /* Type:CustomAttributeType */
272  tables = max(assembly->tables[TableFromToken(mdtMethodDef)].rows,
273  assembly->tables[TableFromToken(mdtMemberRef)].rows);
274  size += (tables > MAX_TABLES_3BIT_ENCODE) ? sizeof(WORD) : 0;
275  break;
276  }
277  case 0x0D000000: /* FIXME */
278  {
279  size = sizeof(FIELDMARSHALTABLE) + (assembly->blobsz - sizeof(WORD));
280 
281  /* Parent:HasFieldMarshal */
282  tables = max(assembly->tables[TableFromToken(mdtFieldDef)].rows,
283  assembly->tables[TableFromToken(mdtParamDef)].rows);
284  size += (tables > MAX_TABLES_1BIT_ENCODE) ? sizeof(WORD) : 0;
285  break;
286  }
287  case mdtPermission:
288  {
289  size = sizeof(DECLSECURITYTABLE) + (assembly->blobsz - sizeof(WORD));
290 
291  /* Parent:HasDeclSecurity */
292  tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows,
293  assembly->tables[TableFromToken(mdtMethodDef)].rows);
294  tables = max(tables, assembly->tables[TableFromToken(mdtAssembly)].rows);
295  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
296  break;
297  }
298  case 0x0F000000: /* FIXME */
299  {
300  size = sizeof(CLASSLAYOUTTABLE);
301  size += (assembly->tables[TableFromToken(mdtTypeDef)].rows >
302  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
303  break;
304  }
305  case 0x10000000: /* FIXME */
306  {
307  size = sizeof(FIELDLAYOUTTABLE);
308  size += (assembly->tables[TableFromToken(mdtFieldDef)].rows >
309  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
310  break;
311  }
312  case mdtSignature:
313  {
314  size = sizeof(STANDALONESIGTABLE) + (assembly->blobsz - sizeof(WORD));
315  break;
316  }
317  case 0x12000000: /* FIXME */
318  {
319  size = sizeof(EVENTMAPTABLE);
320  size += (assembly->tables[TableFromToken(mdtTypeDef)].rows >
321  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
322  size += (assembly->tables[TableFromToken(mdtEvent)].rows >
323  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
324  break;
325  }
326  case mdtEvent:
327  {
328  size = sizeof(EVENTTABLE) + (assembly->stringsz - sizeof(WORD));
329 
330  /* EventType:TypeDefOrRef */
331  tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows,
332  assembly->tables[TableFromToken(mdtTypeRef)].rows);
333  tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows);
334  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
335  break;
336  }
337  case 0x15000000:/* FIXME */
338  {
339  size = sizeof(PROPERTYMAPTABLE);
340  size += (assembly->tables[TableFromToken(mdtTypeDef)].rows >
341  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
342  size += (assembly->tables[TableFromToken(mdtProperty)].rows >
343  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
344  break;
345  }
346  case mdtProperty:
347  {
348  size = sizeof(PROPERTYTABLE) + (assembly->stringsz - sizeof(WORD)) +
349  (assembly->blobsz - sizeof(WORD));
350  break;
351  }
352  case 0x18000000: /* FIXME */
353  {
354  size = sizeof(METHODSEMANTICSTABLE);
355 
356  /* Association:HasSemantics */
357  tables = max(assembly->tables[TableFromToken(mdtEvent)].rows,
358  assembly->tables[TableFromToken(mdtProperty)].rows);
359  size += (tables > MAX_TABLES_1BIT_ENCODE) ? sizeof(WORD) : 0;
360 
361  size += (assembly->tables[TableFromToken(mdtMethodDef)].rows >
362  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
363  break;
364  }
365  case 0x19000000: /* FIXME */
366  {
367  size = sizeof(METHODIMPLTABLE);
368 
369  /* MethodBody:MethodDefOrRef, MethodDeclaration:MethodDefOrRef */
370  tables = max(assembly->tables[TableFromToken(mdtMethodDef)].rows,
371  assembly->tables[TableFromToken(mdtMemberRef)].rows);
372  size += (tables > MAX_TABLES_1BIT_ENCODE) ? 2 * sizeof(WORD) : 0;
373 
374  size += (assembly->tables[TableFromToken(mdtTypeDef)].rows >
375  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
376  break;
377  }
378  case mdtModuleRef:
379  {
380  size = sizeof(MODULEREFTABLE) + (assembly->stringsz - sizeof(WORD));
381  break;
382  }
383  case mdtTypeSpec:
384  {
385  size = sizeof(TYPESPECTABLE) + (assembly->blobsz - sizeof(WORD));
386  break;
387  }
388  case 0x1C000000: /* FIXME */
389  {
390  size = sizeof(IMPLMAPTABLE) + (assembly->stringsz - sizeof(WORD));
391 
392  /* MemberForwarded:MemberForwarded */
393  tables = max(assembly->tables[TableFromToken(mdtFieldDef)].rows,
394  assembly->tables[TableFromToken(mdtMethodDef)].rows);
395  size += (tables > MAX_TABLES_1BIT_ENCODE) ? sizeof(WORD) : 0;
396 
397  size += (assembly->tables[TableFromToken(mdtModuleRef)].rows >
398  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
399  break;
400  }
401  case 0x1D000000: /* FIXME */
402  {
403  size = sizeof(FIELDRVATABLE);
404  size += (assembly->tables[TableFromToken(mdtFieldDef)].rows >
405  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
406  break;
407  }
408  case mdtAssembly:
409  {
410  size = sizeof(ASSEMBLYTABLE) + 2 * (assembly->stringsz - sizeof(WORD)) +
411  (assembly->blobsz - sizeof(WORD));
412  break;
413  }
414  case 0x20000001: /* FIXME */
415  {
416  size = sizeof(ASSEMBLYPROCESSORTABLE);
417  break;
418  }
419  case 0x22000000: /* FIXME */
420  {
421  size = sizeof(ASSEMBLYOSTABLE);
422  break;
423  }
424  case mdtAssemblyRef:
425  {
426  size = sizeof(ASSEMBLYREFTABLE) + 2 * (assembly->stringsz - sizeof(WORD)) +
427  2 * (assembly->blobsz - sizeof(WORD));
428  break;
429  }
430  case 0x24000000: /* FIXME */
431  {
433  size += (assembly->tables[TableFromToken(mdtAssemblyRef)].rows >
434  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
435  break;
436  }
437  case 0x25000000: /* FIXME */
438  {
439  size = sizeof(ASSEMBLYREFOSTABLE);
440  size += (assembly->tables[TableFromToken(mdtAssemblyRef)].rows >
441  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
442  break;
443  }
444  case mdtFile:
445  {
446  size = sizeof(FILETABLE) + (assembly->stringsz - sizeof(WORD)) +
447  (assembly->blobsz - sizeof(WORD));
448  break;
449  }
450  case mdtExportedType:
451  {
452  size = sizeof(EXPORTEDTYPETABLE) + 2 * (assembly->stringsz - sizeof(WORD));
453 
454  /* Implementation:Implementation */
455  tables = max(assembly->tables[TableFromToken(mdtFile)].rows,
456  assembly->tables[TableFromToken(mdtMethodDef)].rows);
457  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
458  break;
459  }
460  case mdtManifestResource:
461  {
462  size = sizeof(MANIFESTRESTABLE) + (assembly->stringsz - sizeof(WORD));
463 
464  /* Implementation:Implementation */
465  tables = max(assembly->tables[TableFromToken(mdtFile)].rows,
466  assembly->tables[TableFromToken(mdtAssemblyRef)].rows);
467  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
468  break;
469  }
470  case 0x29000000: /* FIXME */
471  {
472  size = sizeof(NESTEDCLASSTABLE);
473  size += (assembly->tables[TableFromToken(mdtTypeDef)].rows >
474  MAX_TABLES_WORD) ? 2 * sizeof(WORD) : 0;
475  break;
476  }
477  default:
478  return 0;
479  }
480 
481  return size;
482 }
483 
485 {
486  DWORD i, count;
487  ULONG currofs;
488  ULONGLONG mask;
489 
490  currofs = offset;
491  assembly->tableshdr = assembly_data_offset(assembly, currofs);
492  if (!assembly->tableshdr)
493  return E_FAIL;
494 
495  assembly->stringsz = (assembly->tableshdr->HeapOffsetSizes & MD_STRINGS_BIT) ?
496  sizeof(DWORD) : sizeof(WORD);
497  assembly->guidsz = (assembly->tableshdr->HeapOffsetSizes & MD_GUIDS_BIT) ?
498  sizeof(DWORD) : sizeof(WORD);
499  assembly->blobsz = (assembly->tableshdr->HeapOffsetSizes & MD_BLOBS_BIT) ?
500  sizeof(DWORD) : sizeof(WORD);
501 
502  currofs += sizeof(METADATATABLESHDR);
503  assembly->numrows = assembly_data_offset(assembly, currofs);
504  if (!assembly->numrows)
505  return E_FAIL;
506 
507  memset(assembly->tables, -1, MAX_CLR_TABLES * sizeof(CLRTABLE));
508 
509  for (i = count = 0, mask = 1; i < MAX_CLR_TABLES; i++, mask <<= 1)
510  {
511  if (assembly->tableshdr->MaskValid.QuadPart & mask)
512  assembly->tables[i].rows = assembly->numrows[count++];
513  }
514  assembly->numtables = count;
515  currofs += assembly->numtables * sizeof(DWORD);
516 
517  for (i = 0, mask = 1; i < MAX_CLR_TABLES; i++, mask <<= 1)
518  {
519  if (assembly->tableshdr->MaskValid.QuadPart & mask)
520  {
521  assembly->tables[i].offset = currofs;
522  currofs += get_table_size(assembly, i) * assembly->tables[i].rows;
523  }
524  }
525 
526  return S_OK;
527 }
528 
530 {
531  METADATAHDR *metadatahdr;
532  BYTE *ptr, *dest;
533  DWORD size, ofs;
534  ULONG rva;
535 
536  rva = assembly->corhdr->MetaData.VirtualAddress;
537  ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL);
538  if (!ptr)
539  return E_FAIL;
540 
541  metadatahdr = (METADATAHDR *)ptr;
542 
543  if (!(assembly->metadatahdr = heap_alloc(sizeof(*assembly->metadatahdr)))) return E_OUTOFMEMORY;
544 
546  memcpy(assembly->metadatahdr, metadatahdr, size);
547 
548  assembly->metadatahdr->Version = (LPSTR)&metadatahdr->Version;
549 
551  ptr += FIELD_OFFSET(METADATAHDR, Version) + metadatahdr->VersionLength + 1;
552  dest = (BYTE *)assembly->metadatahdr + ofs;
553  memcpy(dest, ptr, sizeof(METADATAHDR) - ofs);
554 
555  *hdrsz = sizeof(METADATAHDR) - sizeof(LPSTR) + metadatahdr->VersionLength + 1;
556 
557  return S_OK;
558 }
559 
561 {
562  METADATASTREAMHDR *streamhdr;
563  ULONG rva, i, ofs;
564  LPSTR stream;
565  HRESULT hr;
566  DWORD hdrsz;
567  BYTE *ptr;
568 
569  hr = parse_metadata_header(assembly, &hdrsz);
570  if (FAILED(hr))
571  return hr;
572 
573  rva = assembly->corhdr->MetaData.VirtualAddress;
574  ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva + hdrsz, NULL);
575  if (!ptr)
576  return E_FAIL;
577 
578  for (i = 0; i < assembly->metadatahdr->Streams; i++)
579  {
580  streamhdr = (METADATASTREAMHDR *)ptr;
581  ofs = rva_to_offset(assembly->nthdr, rva + streamhdr->Offset);
582 
583  ptr += sizeof(METADATASTREAMHDR);
584  stream = (LPSTR)ptr;
585 
586  if (!lstrcmpA(stream, "#~"))
587  {
588  hr = parse_clr_tables(assembly, ofs);
589  if (FAILED(hr))
590  return hr;
591  }
592  else if (!lstrcmpA(stream, "#Strings") || !lstrcmpA(stream, "Strings"))
593  assembly->strings = assembly_data_offset(assembly, ofs);
594  else if (!lstrcmpA(stream, "#Blob") || !lstrcmpA(stream, "Blob"))
595  assembly->blobs = assembly_data_offset(assembly, ofs);
596 
597  ptr += ((lstrlenA(stream) + 1) + 3) & ~3; /* align on DWORD boundary */
598  }
599 
600  return S_OK;
601 }
602 
604 {
605  IMAGE_DATA_DIRECTORY *datadirs;
606 
607  assembly->nthdr = ImageNtHeader(assembly->data);
608  if (!assembly->nthdr)
609  return E_FAIL;
610 
611  if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
612  {
613  IMAGE_OPTIONAL_HEADER64 *opthdr =
614  (IMAGE_OPTIONAL_HEADER64 *)&assembly->nthdr->OptionalHeader;
615  datadirs = opthdr->DataDirectory;
616  }
617  else
618  {
619  IMAGE_OPTIONAL_HEADER32 *opthdr =
620  (IMAGE_OPTIONAL_HEADER32 *)&assembly->nthdr->OptionalHeader;
621  datadirs = opthdr->DataDirectory;
622  }
623 
624  if (!datadirs)
625  return E_FAIL;
626 
629  {
630  return E_FAIL;
631  }
632 
633  assembly->corhdr = ImageRvaToVa(assembly->nthdr, assembly->data,
635  if (!assembly->corhdr)
636  return E_FAIL;
637 
638  return S_OK;
639 }
640 
642 {
644  HRESULT hr;
645 
646  *out = NULL;
647 
648  if (!(assembly = heap_alloc_zero(sizeof(*assembly)))) return E_OUTOFMEMORY;
649 
650  assembly->path = strdupW(file);
651  if (!assembly->path)
652  {
653  hr = E_OUTOFMEMORY;
654  goto failed;
655  }
656 
659  if (assembly->hfile == INVALID_HANDLE_VALUE)
660  {
662  goto failed;
663  }
664 
666  0, 0, NULL);
667  if (!assembly->hmap)
668  {
670  goto failed;
671  }
672 
673  assembly->data = MapViewOfFile(assembly->hmap, FILE_MAP_READ, 0, 0, 0);
674  if (!assembly->data)
675  {
677  goto failed;
678  }
679 
681  if (FAILED(hr)) goto failed;
682 
684  if (FAILED(hr)) goto failed;
685 
686  *out = assembly;
687  return S_OK;
688 
689 failed:
691  return hr;
692 }
693 
695 {
696  if (!assembly)
697  return S_OK;
698 
699  heap_free(assembly->metadatahdr);
700  heap_free(assembly->path);
701  UnmapViewOfFile(assembly->data);
702  CloseHandle(assembly->hmap);
703  CloseHandle(assembly->hfile);
705 
706  return S_OK;
707 }
708 
710 {
711  int len;
712  LPWSTR cpy;
713  LPCSTR str = (LPCSTR)&assembly->strings[index];
714 
715  len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
716 
717  if ((cpy = heap_alloc(len * sizeof(WCHAR))))
718  MultiByteToWideChar(CP_ACP, 0, str, -1, cpy, len);
719 
720  return cpy;
721 }
722 
724 {
725  BYTE *ptr;
726  LONG offset;
727  DWORD stridx;
728 
729  offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
730  if (offset == -1)
731  return E_FAIL;
732 
734  if (!ptr)
735  return E_FAIL;
736 
737  ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey) + assembly->blobsz;
738  if (assembly->stringsz == sizeof(DWORD))
739  stridx = *(DWORD *)ptr;
740  else
741  stridx = *(WORD *)ptr;
742 
743  *name = assembly_dup_str(assembly, stridx);
744  if (!*name)
745  return E_OUTOFMEMORY;
746 
747  return S_OK;
748 }
749 
751 {
752  WCHAR *cpy = heap_alloc((lstrlenW(assembly->path) + 1) * sizeof(WCHAR));
753  *path = cpy;
754  if (cpy)
755  lstrcpyW(cpy, assembly->path);
756  else
757  return E_OUTOFMEMORY;
758 
759  return S_OK;
760 }
761 
763 {
764  static const WCHAR format[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
765 
766  ASSEMBLYTABLE *asmtbl;
767  LONG offset;
768 
769  *version = NULL;
770 
771  offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
772  if (offset == -1)
773  return E_FAIL;
774 
776  if (!asmtbl)
777  return E_FAIL;
778 
779  if (!(*version = heap_alloc(24 * sizeof(WCHAR))))
780  return E_OUTOFMEMORY;
781 
782  swprintf(*version, format, asmtbl->MajorVersion, asmtbl->MinorVersion,
783  asmtbl->BuildNumber, asmtbl->RevisionNumber);
784 
785  return S_OK;
786 }
787 
789 {
790  if ((assembly->corhdr->MajorRuntimeVersion == 2) && (assembly->corhdr->MinorRuntimeVersion == 0))
791  return peNone; /* .NET 1.x assembly */
792 
793  if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
794  return peAMD64; /* AMD64/IA64 assembly */
795 
796  if ((assembly->corhdr->Flags & COMIMAGE_FLAGS_ILONLY) && !(assembly->corhdr->Flags & COMIMAGE_FLAGS_32BITREQUIRED))
797  return peMSIL; /* MSIL assembly */
798 
799  return peI386; /* x86 assembly */
800 }
801 
803 {
804  return GetData(&assembly->blobs[index], size);
805 }
806 
808 {
809  ULONG i, size;
810  LONG offset;
811  BYTE hashdata[20], *pubkey, *ptr;
812  BCRYPT_ALG_HANDLE alg;
813  BYTE tokbytes[BYTES_PER_TOKEN];
814  HRESULT hr = E_FAIL;
815  LPWSTR tok;
816  DWORD idx;
817 
818  *token = NULL;
819 
820  offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
821  if (offset == -1)
822  return E_FAIL;
823 
825  if (!ptr)
826  return E_FAIL;
827 
828  ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey);
829  if (assembly->blobsz == sizeof(DWORD))
830  idx = *(DWORD *)ptr;
831  else
832  idx = *(WORD *)ptr;
833 
835 
837  return E_FAIL;
838 
839  if (BCryptHash(alg, NULL, 0, pubkey, size, hashdata, sizeof(hashdata)) != STATUS_SUCCESS)
840  {
841  hr = E_FAIL;
842  goto done;
843  }
844 
845  size = sizeof(hashdata);
846  for (i = size - 1; i >= size - 8; i--)
847  tokbytes[size - i - 1] = hashdata[i];
848 
849  if (!(tok = heap_alloc((TOKEN_LENGTH + 1) * sizeof(WCHAR))))
850  {
851  hr = E_OUTOFMEMORY;
852  goto done;
853  }
854 
855  token_to_str(tokbytes, tok);
856 
857  *token = tok;
858  hr = S_OK;
859 
860 done:
862  return hr;
863 }
864 
866 {
867  *version = assembly->metadatahdr->Version;
868  return S_OK;
869 }
870 
872 {
873  LONG offset;
874  INT i, num_rows;
875  WCHAR **ret;
876  BYTE *ptr;
877  DWORD idx;
878 
879  *count = 0;
880 
881  offset = assembly->tables[TableFromToken(mdtFile)].offset;
882  if (offset == -1)
883  return S_OK;
884 
886  if (!ptr)
887  return S_OK;
888 
889  num_rows = assembly->tables[TableFromToken(mdtFile)].rows;
890  if (num_rows <= 0)
891  return S_OK;
892 
893  if (!(ret = heap_alloc(num_rows * sizeof(WCHAR *)))) return E_OUTOFMEMORY;
894 
895  for (i = 0; i < num_rows; i++)
896  {
897  ptr += sizeof(DWORD); /* skip Flags field */
898  if (assembly->stringsz == sizeof(DWORD))
899  idx = *(DWORD *)ptr;
900  else
901  idx = *(WORD *)ptr;
902 
904  if (!ret[i])
905  {
906  for (; i >= 0; i--) heap_free(ret[i]);
907  heap_free(ret);
908  return E_OUTOFMEMORY;
909  }
910  ptr += assembly->stringsz; /* skip Name field */
911  ptr += assembly->blobsz; /* skip Hash field */
912  }
913  *count = num_rows;
914  *files = ret;
915  return S_OK;
916 }
#define MS_PRIMITIVE_PROVIDER
Definition: bcrypt.h:69
WORD RevisionNumber
Definition: fusionpriv.h:110
static DWORD rva_to_offset(IMAGE_NT_HEADERS *nthdrs, DWORD rva)
Definition: assembly.c:80
METADATAHDR * metadatahdr
Definition: assembly.c:65
static HRESULT parse_metadata_header(ASSEMBLY *assembly, DWORD *hdrsz)
Definition: assembly.c:529
HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token)
Definition: assembly.c:807
static void token_to_str(BYTE *bytes, LPWSTR str)
Definition: fusionpriv.h:470
#define max(a, b)
Definition: svc.c:63
static VOID * assembly_data_offset(ASSEMBLY *assembly, ULONG offset)
Definition: assembly.c:139
Definition: corhdr.h:41
HRESULT assembly_get_path(const ASSEMBLY *assembly, LPWSTR *path)
Definition: assembly.c:750
#define CloseHandle
Definition: compat.h:406
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
#define MD_STRINGS_BIT
Definition: assembly.c:44
struct tagEVENTTABLE EVENTTABLE
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
INT rows
Definition: assembly.c:50
#define MapViewOfFile
Definition: compat.h:410
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define MAX_CLR_TABLES
Definition: assembly.c:42
IMAGE_COR20_HEADER * corhdr
Definition: assembly.c:63
IMAGE_NT_HEADERS * nthdr
Definition: assembly.c:62
#define MAX_TABLES_WORD
Definition: assembly.c:144
static const WCHAR pubkey[]
Definition: asmname.c:68
#define CP_ACP
Definition: compat.h:99
HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version)
Definition: assembly.c:865
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE handle, DWORD flags)
Definition: bcrypt_main.c:374
HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name)
Definition: assembly.c:723
GLintptr offset
Definition: glext.h:5920
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BYTE * data
Definition: assembly.c:60
PEKIND assembly_get_architecture(ASSEMBLY *assembly)
Definition: assembly.c:788
#define TableFromToken(tk)
Definition: assembly.c:39
char * LPSTR
Definition: xmlstorage.h:182
#define lstrlenW
Definition: compat.h:415
#define E_FAIL
Definition: ddrawi.h:102
static struct _tagASSEMBLY assembly
static DWORD
Definition: assembly.c:34
int32_t INT
Definition: typedefs.h:56
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define FILE_SHARE_READ
Definition: compat.h:125
GLint limit
Definition: glext.h:10326
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
BYTE * strings
Definition: assembly.c:76
GLenum GLint GLuint mask
Definition: glext.h:6028
NTSTATUS WINAPI BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *handle, LPCWSTR id, LPCWSTR implementation, DWORD flags)
Definition: bcrypt_main.c:332
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
long LONG
Definition: pedump.c:60
static ULONG get_table_size(const ASSEMBLY *assembly, DWORD index)
Definition: assembly.c:150
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 token
Definition: glfuncs.h:210
ULONG VersionLength
Definition: fusionpriv.h:48
static PVOID ptr
Definition: dispmode.c:27
static BYTE * assembly_get_blob(ASSEMBLY *assembly, DWORD index, ULONG *size)
Definition: assembly.c:802
unsigned int idx
Definition: utils.c:41
WORD BuildNumber
Definition: fusionpriv.h:109
const WCHAR * str
DWORD blobsz
Definition: assembly.c:74
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:66
NTSTATUS WINAPI BCryptHash(BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG secretlen, UCHAR *input, ULONG inputlen, UCHAR *output, ULONG outputlen)
Definition: bcrypt_main.c:1090
#define MAX_TABLES_5BIT_ENCODE
Definition: assembly.c:148
BYTE * blobs
Definition: assembly.c:77
#define FILE_MAP_READ
Definition: compat.h:435
GLuint index
Definition: glext.h:6031
const char * LPCSTR
Definition: xmlstorage.h:183
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define OPEN_EXISTING
Definition: compat.h:434
DWORD guidsz
Definition: assembly.c:73
#define MAX_TABLES_3BIT_ENCODE
Definition: assembly.c:147
GLsizeiptr size
Definition: glext.h:5919
DWORD numtables
Definition: assembly.c:68
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLint GLvoid * img
Definition: gl.h:1956
LONG HRESULT
Definition: typedefs.h:77
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:409
uint64_t ULONGLONG
Definition: typedefs.h:65
#define swprintf(buf, format,...)
Definition: sprintf.c:56
WORD MajorVersion
Definition: fusionpriv.h:107
int JSAMPARRAY int int num_rows
Definition: jpegint.h:412
unsigned short WORD
Definition: ntddk_ex.h:93
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT parse_clr_metadata(ASSEMBLY *assembly)
Definition: assembly.c:560
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
HANDLE hfile
Definition: assembly.c:58
HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file)
Definition: assembly.c:641
int ret
PEKIND
Definition: fusion.idl:35
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
#define GENERIC_READ
Definition: compat.h:124
#define MD_GUIDS_BIT
Definition: assembly.c:45
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset)
Definition: assembly.c:484
HRESULT assembly_release(ASSEMBLY *assembly)
Definition: assembly.c:694
#define MD_BLOBS_BIT
Definition: assembly.c:46
HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version)
Definition: assembly.c:762
#define S_OK
Definition: intsafe.h:59
struct tagCLRTABLE CLRTABLE
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define lstrcpyW
Definition: compat.h:414
#define TokenFromTable(idx)
Definition: assembly.c:40
WORD MinorVersion
Definition: fusionpriv.h:108
static BYTE * GetData(BYTE *pData, ULONG *pLength)
Definition: assembly.c:114
DWORD * numrows
Definition: assembly.c:69
CLRTABLE tables[MAX_CLR_TABLES]
Definition: assembly.c:70
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
PVOID WINAPI ImageRvaToVa(_In_ PIMAGE_NT_HEADERS, _In_ PVOID, _In_ ULONG, _In_opt_ PIMAGE_SECTION_HEADER *)
HANDLE hmap
Definition: assembly.c:59
#define PAGE_READONLY
Definition: compat.h:127
DWORD stringsz
Definition: assembly.c:72
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
#define BYTES_PER_TOKEN
Definition: fusionpriv.h:466
static HRESULT parse_pe_header(ASSEMBLY *assembly)
Definition: assembly.c:603
#define MultiByteToWideChar
Definition: compat.h:100
#define CreateFileW
Definition: compat.h:408
DWORD offset
Definition: assembly.c:51
Definition: name.c:38
#define TOKEN_LENGTH
Definition: fusionpriv.h:468
LPWSTR path
Definition: assembly.c:56
unsigned int ULONG
Definition: retypes.h:1
struct nls_table * tables
Definition: nls_base.c:22
METADATATABLESHDR * tableshdr
Definition: assembly.c:67
LPSTR Version
Definition: fusionpriv.h:49
PIMAGE_NT_HEADERS WINAPI ImageNtHeader(_In_ PVOID)
static char * dest
Definition: rtl.c:135
WCHAR * LPWSTR
Definition: xmlstorage.h:184
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define UnmapViewOfFile
Definition: compat.h:411
#define BCRYPT_SHA1_ALGORITHM
Definition: bcrypt.h:74
static LPWSTR assembly_dup_str(const ASSEMBLY *assembly, DWORD index)
Definition: assembly.c:709
#define memset(x, y, z)
Definition: compat.h:39
#define MAX_TABLES_2BIT_ENCODE
Definition: assembly.c:146
#define MAX_TABLES_1BIT_ENCODE
Definition: assembly.c:145
static LPWSTR strdupW(LPCWSTR src)
Definition: assembly.c:67
HRESULT assembly_get_external_files(ASSEMBLY *assembly, LPWSTR **files, DWORD *count)
Definition: assembly.c:871
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
Definition: fci.c:126