xref: /reactos/sdk/lib/rossym/pe.c (revision 53221834)
1 #define NTOSAPI
2 #include <ntifs.h>
3 #include <ndk/ntndk.h>
4 #include <reactos/rossym.h>
5 #include "rossympriv.h"
6 #include <ntimage.h>
7 
8 #define NDEBUG
9 #include <debug.h>
10 
11 #include "dwarf.h"
12 #include "pe.h"
13 #include "rossympriv.h"
14 
15 PeSect *pesection(Pe *pe, const char *name)
16 {
17 	int i;
18 	ANSI_STRING WantName;
19 	RtlInitAnsiString(&WantName, name);
20 	DPRINT("Searching for section %s\n", name);
21 	for (i = 0; i < pe->nsections; i++) {
22 		PANSI_STRING AnsiString = ANSI_NAME_STRING(&pe->sect[i]);
23 		if (WantName.Length == AnsiString->Length &&
24 			!memcmp(AnsiString->Buffer, name, WantName.Length)) {
25 			DPRINT("Found %s (%d) @ %x (%x)\n", name, i,
26 				   ((PCHAR)pe->imagebase)+pe->sect[i].VirtualAddress,
27 				   pe->sect[i].SizeOfRawData);
28 			return &pe->sect[i];
29 		}
30 	}
31 	DPRINT("%s not found\n", name);
32 	return nil;
33 }
34 
35 u16int peget2(const unsigned char *ptr) {
36 	return *((u16int*)ptr);
37 }
38 
39 u32int peget4(const unsigned char *ptr) {
40 	return *((u32int*)ptr);
41 }
42 
43 u64int peget8(const unsigned char *ptr) {
44 	return *((u64int*)ptr);
45 }
46 
47 int readn(void *filectx, char *buffer, ulong size) {
48 	return RosSymReadFile(filectx, buffer, size);
49 }
50 
51 int seek(void *filectx, ulong position, int origin) {
52 	assert(origin == 0);
53 	return RosSymSeekFile(filectx, position);
54 }
55 
56 static int
57 readblock(void *fd, DwarfBlock *b, ulong off, ulong len)
58 {
59 	b->data = malloc(len);
60 	if(b->data == nil)
61 		return -1;
62 	if(!seek(fd, off, 0) || !readn(fd, (char *)b->data, len)){
63 		free(b->data);
64 		b->data = nil;
65 		return -1;
66 	}
67 	b->len = len;
68 	return 0;
69 }
70 
71 int
72 loaddisksection(Pe *pe, char *name, DwarfBlock *b)
73 {
74 	PeSect *s;
75 	if((s = pesection(pe, name)) == nil)
76 		return -1;
77 	return readblock(pe->fd, b, s->PointerToRawData, s->SizeOfRawData);
78 }
79 
80 int
81 loadmemsection(Pe *pe, char *name, DwarfBlock *b)
82 {
83 	PeSect *s;
84 
85 	if((s = pesection(pe, name)) == nil)
86 		return -1;
87 	DPRINT("Loading section %s (ImageBase %x RVA %x)\n", name, pe->fd, s->VirtualAddress);
88 	b->data = RosSymAllocMem(s->SizeOfRawData);
89 	b->len = s->SizeOfRawData;
90 	PCHAR DataSource = ((char *)pe->fd) + s->VirtualAddress;
91 	DPRINT("Copying to %x from %x (%x)\n", DataSource, b->data, b->len);
92 	RtlCopyMemory(b->data, DataSource, s->SizeOfRawData);
93 
94 	return s->SizeOfRawData;
95 }
96 
97 void *RosSymAllocMemZero(ulong size, ulong count) {
98 	void *res = RosSymAllocMem(size * count);
99 	if (res) memset(res, 0, size * count);
100 	return res;
101 }
102 
103 int GetStrnlen(const char *string, int maxlen) {
104 	int i;
105 	for (i = 0; i < maxlen && string[i]; i++);
106 	return i;
107 }
108 
109 void pefree(Pe *pe) {
110 	int i;
111 	for (i = 0; i < pe->nsections; i++) {
112 		RtlFreeAnsiString(ANSI_NAME_STRING(&pe->sect[i]));
113 	}
114 	for (i = 0; i < pe->nsymbols; i++) {
115 		free(pe->symtab[i].name);
116 	}
117 	free(pe->symtab);
118 	free(pe->sect);
119 	free(pe);
120 }
121 
122 void xfree(void *v) {
123 	if (v) RosSymFreeMem(v);
124 }
125 
126 ulong pefindrva(struct _IMAGE_SECTION_HEADER *SectionHeaders, int NumberOfSections, ulong TargetPhysical) {
127 	int i;
128 	DPRINT("Finding RVA for Physical %x\n", TargetPhysical);
129 	for (i = 0; i < NumberOfSections; i++) {
130 		DPRINT("Section %d name %s Raw %x Virt %x\n",
131 			   i,
132 			   ANSI_NAME_STRING(&SectionHeaders[i])->Buffer,
133 			   SectionHeaders[i].PointerToRawData,
134 			   SectionHeaders[i].VirtualAddress);
135 		if (TargetPhysical >= SectionHeaders[i].PointerToRawData &&
136 			TargetPhysical < SectionHeaders[i].PointerToRawData + SectionHeaders[i].SizeOfRawData) {
137 			DPRINT("RVA %x\n", TargetPhysical - SectionHeaders[i].PointerToRawData + SectionHeaders[i].VirtualAddress);
138 			return TargetPhysical - SectionHeaders[i].PointerToRawData + SectionHeaders[i].VirtualAddress;
139 		}
140 	}
141 	return nil;
142 }
143