modify relocation function
@@ -1,3 +1,11 @@ | ||
1 | +2010-05-29 Kazuki Iwamoto <iwm@maid.org> | |
2 | + | |
3 | + * version 2.2.3 | |
4 | + | |
5 | +2010-05-26 Kazuki Iwamoto <iwm@maid.org> | |
6 | + | |
7 | + * misc/peimage.c: modify relocation function | |
8 | + | |
1 | 9 | 2010-02-09 Kazuki IWAMOTO <iwm@maid.org> |
2 | 10 | |
3 | 11 | * version 2.2.2 |
@@ -24,42 +24,73 @@ | ||
24 | 24 | * ja:PEイメージ関数 * |
25 | 25 | * * |
26 | 26 | ******************************************************************************/ |
27 | -/* ja:PEイメージを検証する | |
27 | +/* ja:PEイメージの仮想相対アドレスをファイルオフセットに変換する | |
28 | + image,PEイメージ(ヘッダ) | |
29 | + address,仮想相対アドレス | |
30 | + RET,ファイルオフセット,-1:エラー */ | |
31 | +gint | |
32 | +peimage_file_address_to_offset (const guint8 *image, | |
33 | + const guint32 address) | |
34 | +{ | |
35 | + gint offset = -1; | |
36 | + | |
37 | + if (image) | |
38 | + { | |
39 | + gint i; | |
40 | + guint16 sections; | |
41 | + ImageSectionHeader *ish; | |
42 | + | |
43 | + sections = pe_ifh_get_number_of_sections (image); | |
44 | + ish = pe_image_section_header (image); | |
45 | + for (i = 0; i < sections; i++) | |
46 | + { | |
47 | + if (ish_get_virtual_address (ish) <= address | |
48 | + && address < ish_get_virtual_address (ish) | |
49 | + + ish_get_virtual_size (ish)) | |
50 | + { | |
51 | + offset = address - ish_get_virtual_address (ish) | |
52 | + + ish_get_pointer_to_raw_data (ish); | |
53 | + break; | |
54 | + } | |
55 | + ish++; | |
56 | + } | |
57 | + } | |
58 | + return offset; | |
59 | +} | |
60 | + | |
61 | + | |
62 | +/* ja:PEイメージのファイルオフセットを仮想相対アドレスに変換する | |
28 | 63 | image,PEイメージ(ヘッダ) |
29 | - length,バイト数 | |
30 | - RET,TRUE:正常終了,FALSE:エラー */ | |
31 | -gboolean | |
32 | -peimage_file_is_valid (const guint8 *image, | |
33 | - const gssize length) | |
64 | + offset,ファイルオフセット | |
65 | + RET,仮想相対アドレス,-1:エラー */ | |
66 | +guint32 | |
67 | +peimage_file_offset_to_address (const guint8 *image, | |
68 | + const gint offset) | |
34 | 69 | { |
35 | - gint i, count; | |
36 | - gssize leng = 0; | |
37 | - const ImageSectionHeader *ish; | |
70 | + guint32 address = (guint32)-1; | |
38 | 71 | |
39 | - if (!image || length < sizeof (ImageDosHeader) | |
40 | - || pe_idh_get_magic (image) != PEIMAGE_DOS_SIGNATURE | |
41 | - || length < pe_idh_get_lfanew (image) + sizeof (guint32) | |
42 | - + sizeof (ImageFileHeader) + sizeof (ImageOptionalHeader) | |
43 | - || pe_get_signature (image) != PEIMAGE_NT_SIGNATURE | |
44 | - || pe_ifh_get_machine (image) != PEIMAGE_FILE_MACHINE_I386 | |
45 | - || pe_ifh_get_size_of_optional_header (image) | |
46 | - != sizeof (ImageOptionalHeader) | |
47 | - || pe_ioh_get_magic (image) != PEIMAGE_NT_OPTIONAL_HDR_MAGIC | |
48 | - || length < peimage_file_header_bytes (image)) | |
49 | - return FALSE; | |
50 | - ish = pe_image_section_header (image); | |
51 | - count = pe_ifh_get_number_of_sections (image); | |
52 | - for (i = 0; i < count; i++) | |
72 | + if (image) | |
53 | 73 | { |
54 | - gssize size; | |
74 | + gint i; | |
75 | + guint16 sections; | |
76 | + ImageSectionHeader *ish; | |
55 | 77 | |
56 | - size = ish_get_virtual_address (ish) | |
57 | - + MAX (ish_get_virtual_size (ish), ish_get_size_of_raw_data (ish)); | |
58 | - if (leng < size) | |
59 | - leng = size; | |
60 | - ish++; | |
78 | + sections = pe_ifh_get_number_of_sections (image); | |
79 | + ish = pe_image_section_header (image); | |
80 | + for (i = 0; i < sections; i++) | |
81 | + { | |
82 | + if (ish_get_pointer_to_raw_data (ish) <= offset | |
83 | + && offset < ish_get_pointer_to_raw_data (ish) | |
84 | + + ish_get_size_of_raw_data (ish)) | |
85 | + { | |
86 | + address = offset - ish_get_pointer_to_raw_data (ish) | |
87 | + + ish_get_virtual_address (ish); | |
88 | + break; | |
89 | + } | |
90 | + ish++; | |
91 | + } | |
61 | 92 | } |
62 | - return leng <= pe_ioh_get_size_of_image (image); | |
93 | + return address; | |
63 | 94 | } |
64 | 95 | |
65 | 96 |
@@ -91,49 +122,61 @@ | ||
91 | 122 | return NULL; |
92 | 123 | } |
93 | 124 | length = idh_get_lfanew (image) + sizeof (guint32) |
94 | - + sizeof (ImageFileHeader) + sizeof (ImageOptionalHeader); | |
95 | - image = g_realloc (image, length); | |
96 | - length -= sizeof (ImageDosHeader); | |
97 | - if (!image || fileio_read (fio, image + sizeof (ImageDosHeader), length) | |
98 | - != length | |
99 | - || pe_get_signature (image) != PEIMAGE_NT_SIGNATURE | |
100 | - || pe_ifh_get_machine (image) != PEIMAGE_FILE_MACHINE_I386 | |
101 | - || pe_ifh_get_size_of_optional_header (image) | |
102 | - != sizeof (ImageOptionalHeader) | |
103 | - || pe_ioh_get_magic (image) != PEIMAGE_NT_OPTIONAL_HDR_MAGIC) | |
125 | + + sizeof (ImageFileHeader); | |
126 | + if (length > sizeof (ImageDosHeader)) | |
104 | 127 | { |
128 | + image = g_realloc (image, length); | |
129 | + length -= sizeof (ImageDosHeader); | |
130 | + if (!image || fileio_read (fio, image + sizeof (ImageDosHeader), length) | |
131 | + != length) | |
132 | + { | |
133 | + g_free (image); | |
134 | + fileio_close (fio); | |
135 | + return NULL; | |
136 | + } | |
137 | + length += sizeof (ImageDosHeader); | |
138 | + } | |
139 | + else | |
140 | + { | |
141 | + length = sizeof (ImageDosHeader); | |
142 | + } | |
143 | + if (pe_get_signature (image) != PEIMAGE_NT_SIGNATURE | |
144 | + || pe_ifh_get_machine (image) != PEIMAGE_FILE_MACHINE_I386) | |
145 | + { | |
105 | 146 | g_free (image); |
106 | 147 | fileio_close (fio); |
107 | 148 | return NULL; |
108 | 149 | } |
109 | - number_of_sections = pe_ifh_get_number_of_sections (image); | |
110 | 150 | header_bytes = peimage_file_header_bytes (image); |
111 | - size_of_image = pe_ioh_get_size_of_image (image); | |
112 | 151 | image = g_realloc (image, header_bytes); |
113 | - ish = pe_image_section_header (image); | |
114 | - length = sizeof (ImageSectionHeader) * number_of_sections; | |
115 | - if (!image || fileio_read (fio, ish, length) != length) | |
152 | + header_bytes -= length; | |
153 | + if (!image || fileio_read (fio, image + length, header_bytes) != header_bytes | |
154 | + || pe_get_signature (image) != PEIMAGE_NT_SIGNATURE | |
155 | + || pe_ifh_get_machine (image) != PEIMAGE_FILE_MACHINE_I386 | |
156 | + || pe_ioh_get_magic (image) != PEIMAGE_NT_OPTIONAL_HDR_MAGIC) | |
116 | 157 | { |
117 | 158 | g_free (image); |
118 | 159 | fileio_close (fio); |
119 | 160 | return NULL; |
120 | 161 | } |
162 | + header_bytes += length; | |
163 | + number_of_sections = pe_ifh_get_number_of_sections (image); | |
121 | 164 | length = 0; |
165 | + ish = pe_image_section_header (image); | |
122 | 166 | for (i = 0; i < number_of_sections; i++) |
123 | 167 | { |
124 | - gssize size; | |
168 | + gssize leng; | |
125 | 169 | |
126 | - size = ish_get_virtual_address (ish) + MAX (ish_get_virtual_size (ish), | |
127 | - ish_get_size_of_raw_data (ish)); | |
128 | - if (length < size) | |
129 | - length = size; | |
170 | + leng = ish_get_virtual_address (ish) + ish_get_virtual_size (ish); | |
171 | + if (length < leng) | |
172 | + length = leng; | |
130 | 173 | ish++; |
131 | 174 | } |
175 | + size_of_image = pe_ioh_get_size_of_image (image); | |
132 | 176 | if (length > size_of_image) |
133 | 177 | { |
134 | - g_free (image); | |
135 | - fileio_close (fio); | |
136 | - return NULL; | |
178 | + size_of_image = length; | |
179 | + pe_ioh_set_size_of_image (image, size_of_image); | |
137 | 180 | } |
138 | 181 | image = g_realloc (image, size_of_image); |
139 | 182 | if (!image) |
@@ -141,32 +184,25 @@ | ||
141 | 184 | fileio_close (fio); |
142 | 185 | return NULL; |
143 | 186 | } |
144 | - ish = pe_image_section_header (image); | |
145 | 187 | length = pe_ioh_get_size_of_headers (image); |
146 | 188 | g_memset (image + length, 0, size_of_image - length); |
147 | - length -= header_bytes; | |
148 | - if (fileio_read (fio, image + header_bytes, length) != length) | |
189 | + if (length > header_bytes) | |
149 | 190 | { |
150 | - g_free (image); | |
151 | - fileio_close (fio); | |
152 | - return NULL; | |
153 | - } | |
154 | - for (i = 0; i < number_of_sections; i++) | |
155 | - { | |
156 | - length = ish_get_size_of_raw_data (ish); | |
157 | - if (fileio_seek (fio, ish_get_pointer_to_raw_data (ish), | |
158 | - FILEIO_SEEK_SET) < 0 | |
159 | - || fileio_read (fio, image + ish_get_virtual_address (ish), length) | |
160 | - != length) | |
191 | + length -= header_bytes; | |
192 | + if (fileio_read (fio, image + header_bytes, length) != length) | |
161 | 193 | { |
162 | 194 | g_free (image); |
163 | 195 | fileio_close (fio); |
164 | 196 | return NULL; |
165 | 197 | } |
166 | - if (ish_get_virtual_size (ish) > length) | |
167 | - length = ish_get_virtual_size (ish); | |
168 | - ish_set_virtual_size (ish, length); | |
169 | - ish_set_size_of_raw_data (ish, length); | |
198 | + } | |
199 | + ish = pe_image_section_header (image); | |
200 | + for (i = 0; i < number_of_sections; i++) | |
201 | + { | |
202 | + if (fileio_seek (fio, ish_get_pointer_to_raw_data (ish), | |
203 | + FILEIO_SEEK_SET) >= 0) | |
204 | + fileio_read (fio, image + ish_get_virtual_address (ish), | |
205 | + MIN (ish_get_virtual_size (ish), ish_get_size_of_raw_data (ish))); | |
170 | 206 | ish++; |
171 | 207 | } |
172 | 208 | if (!fileio_close (fio)) |
@@ -188,17 +224,21 @@ | ||
188 | 224 | if (image && delta != 0 && pe_ioh_get_data_directory_size (image, |
189 | 225 | PEIMAGE_DIRECTORY_ENTRY_BASERELOC)) |
190 | 226 | { |
191 | - const ImageBaseRelocation *ibr; | |
227 | + guint32 address, size; | |
192 | 228 | |
193 | - for (ibr = pe_image_base_relocation (image); | |
194 | - ibr_get_virtual_address (ibr); | |
195 | - ibr = (const ImageBaseRelocation *)((const guint8 *)ibr | |
196 | - + ibr_get_size_of_block (ibr))) | |
229 | + size = pe_ioh_get_size_of_image (image); | |
230 | + address = pe_ioh_get_data_directory_virtual_address (image, | |
231 | + PEIMAGE_DIRECTORY_ENTRY_BASERELOC); | |
232 | + while (address + sizeof (ImageBaseRelocation) <= size) | |
197 | 233 | { |
198 | 234 | gint i, count; |
199 | - guint32 address; | |
235 | + guint32 base; | |
236 | + ImageBaseRelocation *ibr; | |
200 | 237 | |
201 | - address = ibr_get_virtual_address (ibr); | |
238 | + ibr = (ImageBaseRelocation *)(image + address); | |
239 | + base = ibr_get_virtual_address (ibr); | |
240 | + if (base == 0 || address + ibr_get_size_of_block (ibr) > size) | |
241 | + break; | |
202 | 242 | count = (ibr_get_size_of_block (ibr) - sizeof (guint32) * 2) |
203 | 243 | / sizeof (guint16); |
204 | 244 | for (i = 0; i < count; i++) |
@@ -206,14 +246,16 @@ | ||
206 | 246 | guint16 typeoffset; |
207 | 247 | |
208 | 248 | typeoffset = ibr_get_type_offset (ibr, i); |
209 | - if (((typeoffset >> 12) & 0xf) == PEIMAGE_REL_BASED_HIGHLOW) | |
249 | + if (((typeoffset >> 12) & 0xf) == PEIMAGE_REL_BASED_HIGHLOW | |
250 | + && base + (typeoffset & 0xfff) <= size) | |
210 | 251 | { |
211 | 252 | guint32 *p; |
212 | 253 | |
213 | - p = (guint32 *)(image + address + (typeoffset & 0xfff)); | |
254 | + p = (guint32 *)(image + base + (typeoffset & 0xfff)); | |
214 | 255 | *p = GUINT32_TO_LE (GUINT32_FROM_LE (*p) + delta); |
215 | 256 | } |
216 | 257 | } |
258 | + address += ibr_get_size_of_block (ibr); | |
217 | 259 | } |
218 | 260 | } |
219 | 261 | } |
@@ -232,27 +274,54 @@ | ||
232 | 274 | if (image && pe_ioh_get_data_directory_size (image, |
233 | 275 | PEIMAGE_DIRECTORY_ENTRY_EXPORT)) |
234 | 276 | { |
235 | - gint i, count; | |
236 | - const guint16 *ordinals; | |
237 | - const guint32 *functions, *names; | |
277 | + guint32 address, size; | |
238 | 278 | const ImageExportDirectory *ied; |
239 | 279 | |
240 | - ied = pe_image_export_directory (image); | |
241 | - functions = (const guint32 *)(image | |
280 | + size = pe_ioh_get_size_of_image (image); | |
281 | + address = pe_ioh_get_data_directory_virtual_address (image, | |
282 | + PEIMAGE_DIRECTORY_ENTRY_EXPORT); | |
283 | + ied = (const ImageExportDirectory *)(image + address); | |
284 | + if (address + sizeof (ImageExportDirectory) <= size | |
285 | + && ied_get_address_of_functions (ied) | |
286 | + + ied_get_number_of_functions (ied) * sizeof (guint32) <= size | |
287 | + && ied_get_address_of_names (ied) | |
288 | + + ied_get_number_of_names (ied) * sizeof (guint32) <= size | |
289 | + && ied_get_address_of_name_ordinals (ied) | |
290 | + + ied_get_number_of_names (ied) * sizeof (guint16) <= size) | |
291 | + { | |
292 | + gint i; | |
293 | + const guint16 *ordinals; | |
294 | + const guint32 *functions, *names; | |
295 | + | |
296 | + functions = (const guint32 *)(image | |
242 | 297 | + ied_get_address_of_functions (ied)); |
243 | - names = (const guint32 *)(image | |
298 | + names = (const guint32 *)(image | |
244 | 299 | + ied_get_address_of_names (ied)); |
245 | - ordinals = (const guint16 *)(image | |
300 | + ordinals = (const guint16 *)(image | |
246 | 301 | + ied_get_address_of_name_ordinals (ied)); |
247 | - count = ied_get_number_of_names (ied); | |
248 | - for (i = 0; i < count; i++) | |
249 | - if (g_strcmp ((const gchar *)(image + GUINT32_FROM_LE (names[i])), | |
250 | - name) == 0) | |
251 | - { | |
252 | - func = image | |
253 | - + GUINT32_FROM_LE (functions[GUINT16_FROM_LE (ordinals[i])]); | |
254 | - break; | |
255 | - } | |
302 | + for (i = 0; i < ied_get_number_of_names (ied); i++) | |
303 | + { | |
304 | + gint j; | |
305 | + | |
306 | + address = GUINT32_FROM_LE (names[i]); | |
307 | + for (j = 0; address + j < size | |
308 | + && image[address + j] != '\0' && name[j] != '\0' | |
309 | + && image[address + j] == name[j]; j++); | |
310 | + if (address + j < size && image[address + j] == name[j]) | |
311 | + { | |
312 | + gint index; | |
313 | + | |
314 | + index = GUINT16_FROM_LE (ordinals[i]); | |
315 | + if (index < ied_get_number_of_functions (ied)) | |
316 | + { | |
317 | + address = GUINT32_FROM_LE (functions[index]); | |
318 | + if (address < size) | |
319 | + func = image + address; | |
320 | + } | |
321 | + break; | |
322 | + } | |
323 | + } | |
324 | + } | |
256 | 325 | } |
257 | 326 | return func; |
258 | 327 | } |
@@ -271,15 +340,30 @@ | ||
271 | 340 | if (image && pe_ioh_get_data_directory_size (image, |
272 | 341 | PEIMAGE_DIRECTORY_ENTRY_EXPORT)) |
273 | 342 | { |
274 | - gint index; | |
275 | - const guint32 *functions; | |
343 | + guint32 address, size; | |
276 | 344 | const ImageExportDirectory *ied; |
277 | 345 | |
278 | - ied = pe_image_export_directory (image); | |
279 | - functions = (const guint32 *)(image + ied_get_address_of_functions (ied)); | |
280 | - index = ordinal - ied_get_base (ied); | |
281 | - if (index < ied_get_number_of_functions (ied)) | |
282 | - proc = image + GUINT32_FROM_LE (functions[index]); | |
346 | + size = pe_ioh_get_size_of_image (image); | |
347 | + address = pe_ioh_get_data_directory_virtual_address (image, | |
348 | + PEIMAGE_DIRECTORY_ENTRY_EXPORT); | |
349 | + ied = (const ImageExportDirectory *)(image + address); | |
350 | + if (address + sizeof (ImageExportDirectory) <= size | |
351 | + && ied_get_address_of_functions (ied) | |
352 | + + ied_get_number_of_functions (ied) * sizeof (guint32) <= size) | |
353 | + { | |
354 | + gint index; | |
355 | + const guint32 *functions; | |
356 | + | |
357 | + functions = (const guint32 *)(image | |
358 | + + ied_get_address_of_functions (ied)); | |
359 | + index = ordinal - ied_get_base (ied); | |
360 | + if (index < ied_get_number_of_functions (ied)) | |
361 | + { | |
362 | + address = GUINT32_FROM_LE (functions[index]); | |
363 | + if (address < size) | |
364 | + proc = image + address; | |
365 | + } | |
366 | + } | |
283 | 367 | } |
284 | 368 | return proc; |
285 | 369 | } |
@@ -299,7 +383,9 @@ | ||
299 | 383 | PEIMAGE_DIRECTORY_ENTRY_RESOURCE)) |
300 | 384 | { |
301 | 385 | gchar **element; |
386 | + guint32 size; | |
302 | 387 | |
388 | + size = pe_ioh_get_size_of_image (image); | |
303 | 389 | element = g_strsplit (key[0] == '/' ? key + 1 : key, "/", G_MAXINT); |
304 | 390 | if (element) |
305 | 391 | { |
@@ -316,24 +402,42 @@ | ||
316 | 402 | |
317 | 403 | ird = (const ImageResourceDirectory *)(image + address + offset); |
318 | 404 | irde = (const ImageResourceDirectoryEntry *)(ird + 1); |
405 | + if (address + offset + sizeof (ImageResourceDirectory) > size) | |
406 | + break; | |
319 | 407 | count = ird_get_number_of_named_entries (ird) |
320 | 408 | + ird_get_number_of_id_entries (ird); |
409 | + if (address + offset + sizeof (ImageResourceDirectory) | |
410 | + + count * sizeof (ImageResourceDirectoryEntry) > size) | |
411 | + break; | |
321 | 412 | for (j = 0; j < count; j++) |
322 | 413 | { |
323 | 414 | gboolean result; |
324 | - gchar *name; | |
415 | + gchar *name = NULL; | |
325 | 416 | |
326 | 417 | if (irde_get_id (irde) & 0x80000000) |
327 | 418 | { |
328 | - gchar *utf8str; | |
329 | - const ImageResourceDirStringU *irdsu; | |
419 | + guint32 offset; | |
330 | 420 | |
331 | - irdsu = (const ImageResourceDirStringU *)(image + address | |
332 | - + (irde_get_id (irde) & 0x7fffffff)); | |
333 | - utf8str = g_utf16_to_utf8 (irdsu_get_name_string (irdsu), | |
421 | + offset = address + (irde_get_id (irde) & 0x7fffffff); | |
422 | + if (offset + sizeof (guint16) <= size) | |
423 | + { | |
424 | + const ImageResourceDirStringU *irdsu; | |
425 | + | |
426 | + irdsu = (const ImageResourceDirStringU *) | |
427 | + (image + offset); | |
428 | + if (sizeof (guint16) | |
429 | + + irdsu_get_length (irdsu) * sizeof (gunichar2) | |
430 | + <= size) | |
431 | + { | |
432 | + gchar *utf8str; | |
433 | + | |
434 | + utf8str = g_utf16_to_utf8 | |
435 | + (irdsu_get_name_string (irdsu), | |
334 | 436 | irdsu_get_length (irdsu), NULL, NULL, NULL); |
335 | - name = g_utf8_strup (utf8str, -1); | |
336 | - g_free (utf8str); | |
437 | + name = g_utf8_strup (utf8str, -1); | |
438 | + g_free (utf8str); | |
439 | + } | |
440 | + } | |
337 | 441 | } |
338 | 442 | else |
339 | 443 | { |
@@ -359,6 +463,179 @@ | ||
359 | 463 | } |
360 | 464 | |
361 | 465 | |
466 | +/* ja:PEイメージのエクスポートテーブルを列挙する | |
467 | + image,PEイメージ | |
468 | + RET,リスト,NULL:エラー */ | |
469 | +GList * | |
470 | +peimage_file_enum_export (const guint8 *image) | |
471 | +{ | |
472 | + GList *glist = NULL; | |
473 | + | |
474 | + if (image && pe_ioh_get_data_directory_size (image, | |
475 | + PEIMAGE_DIRECTORY_ENTRY_EXPORT)) | |
476 | + { | |
477 | + guint32 address, size, size_of_image; | |
478 | + const ImageExportDirectory *ied; | |
479 | + | |
480 | + size_of_image = pe_ioh_get_size_of_image (image); | |
481 | + address = pe_ioh_get_data_directory_virtual_address (image, | |
482 | + PEIMAGE_DIRECTORY_ENTRY_EXPORT); | |
483 | + size = pe_ioh_get_data_directory_size (image, | |
484 | + PEIMAGE_DIRECTORY_ENTRY_EXPORT); | |
485 | + ied = (const ImageExportDirectory *)(image + address); | |
486 | + if (address + size <= size_of_image | |
487 | + && size >= sizeof (ImageExportDirectory) | |
488 | + && ied_get_address_of_functions (ied) | |
489 | + + ied_get_number_of_functions (ied) * sizeof (guint32) | |
490 | + <= size_of_image | |
491 | + && ied_get_address_of_names (ied) | |
492 | + + ied_get_number_of_names (ied) * sizeof (guint32) | |
493 | + <= size_of_image | |
494 | + && ied_get_address_of_name_ordinals (ied) | |
495 | + + ied_get_number_of_names (ied) * sizeof (guint16) | |
496 | + <= size_of_image) | |
497 | + { | |
498 | + gint i; | |
499 | + const guint16 *ordinals; | |
500 | + const guint32 *functions, *names; | |
501 | + | |
502 | + functions = (const guint32 *)(image | |
503 | + + ied_get_address_of_functions (ied)); | |
504 | + names = (const guint32 *)(image | |
505 | + + ied_get_address_of_names (ied)); | |
506 | + ordinals = (const guint16 *)(image | |
507 | + + ied_get_address_of_name_ordinals (ied)); | |
508 | + for (i = 0; i < ied_get_number_of_names (ied); i++) | |
509 | + { | |
510 | + guint32 func; | |
511 | + | |
512 | + func = GUINT32_FROM_LE (functions[i]); | |
513 | + if (func < size_of_image) | |
514 | + { | |
515 | + gint j; | |
516 | + PeExport *peexp; | |
517 | + | |
518 | + peexp = g_malloc0 (sizeof (PeExport)); | |
519 | + if (address <= func && func < address + size) | |
520 | + peexp->forward = (const gchar *)(image + func); | |
521 | + else | |
522 | + peexp->address = func; | |
523 | + peexp->ordinal = i + ied_get_base (ied); | |
524 | + for (j = 0; j < ied_get_number_of_names (ied); j++) | |
525 | + if (i == GUINT16_FROM_LE (ordinals[j])) | |
526 | + { | |
527 | + gint k; | |
528 | + guint32 name; | |
529 | + | |
530 | + name = GUINT32_FROM_LE (names[j]); | |
531 | + for (k = name; 0 <= k && k < size_of_image; k++) | |
532 | + if (image[k] == '\0') | |
533 | + { | |
534 | + peexp->name = (const gchar *)(image + name); | |
535 | + break; | |
536 | + } | |
537 | + } | |
538 | + glist = g_list_append (glist, peexp); | |
539 | + } | |
540 | + } | |
541 | + } | |
542 | + } | |
543 | + return glist; | |
544 | +} | |
545 | + | |
546 | + | |
547 | +/* ja:PEイメージのインポートテーブルを列挙する | |
548 | + image,PEイメージ | |
549 | + RET,リスト,NULL:エラー */ | |
550 | +GList * | |
551 | +peimage_file_enum_import (const guint8 *image) | |
552 | +{ | |
553 | + GList *glist = NULL; | |
554 | + | |
555 | + if (image && pe_ioh_get_data_directory_size (image, | |
556 | + PEIMAGE_DIRECTORY_ENTRY_IMPORT)) | |
557 | + { | |
558 | + guint16 sections; | |
559 | + guint32 address, size; | |
560 | + | |
561 | + size = pe_ioh_get_size_of_image (image); | |
562 | + sections = pe_ifh_get_number_of_sections (image); | |
563 | + for (address = pe_ioh_get_data_directory_virtual_address (image, | |
564 | + PEIMAGE_DIRECTORY_ENTRY_IMPORT); | |
565 | + address + sizeof (ImageImportDescriptor) <= size; | |
566 | + address += sizeof (ImageImportDescriptor)) | |
567 | + { | |
568 | + gint i; | |
569 | + guint32 lookup; | |
570 | + const gchar *file; | |
571 | + const ImageSectionHeader *ish; | |
572 | + const ImageImportDescriptor *iid; | |
573 | + | |
574 | + iid = (const ImageImportDescriptor *)(image + address); | |
575 | + for (i = iid_get_name (iid); 0 < i && i < size; i++) | |
576 | + if (image[i] == '\0') | |
577 | + break; | |
578 | + if (i <= 0 || size <= i) | |
579 | + break; | |
580 | + file = (const gchar *)(image + iid_get_name (iid)); | |
581 | + ish = pe_image_section_header (image); | |
582 | + for (i = 0; i < sections; i++) | |
583 | + { | |
584 | + if (ish_get_virtual_address (ish) | |
585 | + <= iid_get_original_first_thunk (iid) | |
586 | + && iid_get_original_first_thunk (iid) | |
587 | + < ish_get_virtual_address (ish) | |
588 | + + ish_get_virtual_size (ish)) | |
589 | + break; | |
590 | + ish++; | |
591 | + } | |
592 | + lookup = i < sections ? iid_get_original_first_thunk (iid) | |
593 | + : iid_get_first_thunk (iid); | |
594 | + while (lookup + sizeof (guint32) <= size) | |
595 | + { | |
596 | + PeImport *peimp; | |
597 | + const ImageThunkData *ilt; | |
598 | + | |
599 | + ilt = (const ImageThunkData *)(image + lookup); | |
600 | + if (!itd_get_address_of_data (ilt)) | |
601 | + break; | |
602 | + peimp = g_malloc0 (sizeof (PeImport)); | |
603 | + peimp->file = file; | |
604 | + if (itd_get_ordinal (ilt) & PEIMAGE_ORDINAL_FLAG) | |
605 | + { | |
606 | + peimp->ordinal = itd_get_ordinal (ilt) | |
607 | + & ~PEIMAGE_ORDINAL_FLAG; | |
608 | + } | |
609 | + else if (itd_get_address_of_data (ilt) | |
610 | + + sizeof (guint16) <= size) | |
611 | + { | |
612 | + for (i = itd_get_address_of_data (ilt) + sizeof (guint16); | |
613 | + 0 <= i && i < size; i++) | |
614 | + if (image[i] == '\0') | |
615 | + { | |
616 | + const ImageImportByName *iibn; | |
617 | + | |
618 | + iibn = (const ImageImportByName *)(image | |
619 | + + itd_get_address_of_data (ilt)); | |
620 | + peimp->name = iibn_get_name (iibn); | |
621 | + break; | |
622 | + } | |
623 | + } | |
624 | + else | |
625 | + { | |
626 | + g_free (peimp); | |
627 | + peimp = NULL; | |
628 | + } | |
629 | + if (peimp) | |
630 | + glist = g_list_append (glist, peimp); | |
631 | + lookup += sizeof (guint32); | |
632 | + } | |
633 | + } | |
634 | + } | |
635 | + return glist; | |
636 | +} | |
637 | + | |
638 | + | |
362 | 639 | /****************************************************************************** |
363 | 640 | * * |
364 | 641 | * ja:モジュール関数群 * |
@@ -369,7 +646,7 @@ | ||
369 | 646 | guint8 *image; |
370 | 647 | gchar *file, *name; |
371 | 648 | gint counter; |
372 | - GList *glist; | |
649 | + GList *library; | |
373 | 650 | } PeModule; |
374 | 651 | |
375 | 652 |
@@ -424,7 +701,7 @@ | ||
424 | 701 | for (glist = g_list_first (process->module); |
425 | 702 | glist; glist = g_list_next (glist)) |
426 | 703 | if (g_ascii_strcasecmp (((PeModule *)glist->data)->name, base) == 0 |
427 | - || g_ascii_strcasecmp (((PeModule *)glist->data)->name, name) == 0) | |
704 | + || g_ascii_strcasecmp (((PeModule *)glist->data)->name, name) == 0) | |
428 | 705 | { |
429 | 706 | image = ((PeModule *)glist->data)->image; |
430 | 707 | break; |
@@ -556,33 +833,30 @@ | ||
556 | 833 | g_free (module); |
557 | 834 | return NULL; |
558 | 835 | } |
559 | - /* ja:再配置 */ | |
560 | - if (pemodule_relocate) | |
561 | - peimage_file_relocate (module->image, | |
562 | - pemodule_relocate (process, module->image, user_data)); | |
563 | 836 | |
564 | - /* ja:プロセス登録 */ | |
565 | -#ifdef USE_THREAD | |
566 | - G_LOCK (critical); | |
567 | - critical = TRUE; | |
568 | -#endif /* USE_THREAD */ | |
569 | - process->module = g_list_append (process->module, module); | |
570 | -#ifdef USE_THREAD | |
571 | - critical = FALSE; | |
572 | - G_UNLOCK (critical); | |
573 | -#endif /* USE_THREAD */ | |
574 | - | |
575 | 837 | /* ja:インポート */ |
576 | 838 | if (pe_ioh_get_data_directory_size (module->image, |
577 | 839 | PEIMAGE_DIRECTORY_ENTRY_IMPORT)) |
578 | 840 | { |
579 | - ImageImportDescriptor *iid; | |
841 | + guint16 sections; | |
842 | + guint32 address, size; | |
580 | 843 | |
581 | - for (iid = pe_image_import_descriptor (module->image); | |
582 | - iid_get_name (iid); iid++) | |
844 | + sections = pe_ifh_get_number_of_sections (module->image); | |
845 | + size = pe_ioh_get_size_of_image (module->image); | |
846 | + for (address = pe_ioh_get_data_directory_virtual_address (module->image, | |
847 | + PEIMAGE_DIRECTORY_ENTRY_IMPORT); | |
848 | + address + sizeof (ImageImportDescriptor) <= size; | |
849 | + address += sizeof (ImageImportDescriptor)) | |
583 | 850 | { |
584 | 851 | gchar *name; |
852 | + ImageImportDescriptor *iid; | |
585 | 853 | |
854 | + iid = (ImageImportDescriptor *)(module->image + address); | |
855 | + for (i = iid_get_name (iid); 0 < i && i < size; i++) | |
856 | + if (module->image[i] == '\0') | |
857 | + break; | |
858 | + if (i <= 0 || size <= i) | |
859 | + break; | |
586 | 860 | name = (gchar *)(module->image + iid_get_name (iid)); |
587 | 861 | image = peimage_module_load_library (process, |
588 | 862 | name, |
@@ -593,41 +867,64 @@ | ||
593 | 867 | user_data); |
594 | 868 | if (image) |
595 | 869 | { |
596 | - ImageThunkData *iat, *ilt; | |
870 | + guint32 lookup, thunk; | |
871 | + ImageSectionHeader *ish; | |
597 | 872 | |
598 | - iat = (ImageThunkData *)(module->image | |
599 | - + (iid_get_original_first_thunk (iid) | |
600 | - ? iid_get_original_first_thunk (iid) | |
601 | - : iid_get_first_thunk (iid))); | |
602 | - ilt = (ImageThunkData *)(module->image | |
603 | - + iid_get_first_thunk (iid)); | |
604 | - while (itd_get_address_of_data (iat)) | |
873 | + ish = pe_image_section_header (module->image); | |
874 | + for (i = 0; i < sections; i++) | |
605 | 875 | { |
606 | - gconstpointer func; | |
876 | + if (ish_get_virtual_address (ish) | |
877 | + <= iid_get_original_first_thunk (iid) | |
878 | + && iid_get_original_first_thunk (iid) | |
879 | + < ish_get_virtual_address (ish) | |
880 | + + ish_get_virtual_size (ish)) | |
881 | + break; | |
882 | + ish++; | |
883 | + } | |
884 | + lookup = i < sections ? iid_get_original_first_thunk (iid) | |
885 | + : iid_get_first_thunk (iid); | |
886 | + thunk = iid_get_first_thunk (iid); | |
887 | + while (lookup + sizeof (guint32) <= size | |
888 | + && thunk + sizeof (guint32) <= size) | |
889 | + { | |
890 | + gconstpointer func = NULL; | |
891 | + ImageThunkData *ilt, *iat; | |
607 | 892 | |
608 | - if (itd_get_ordinal (iat) & PEIMAGE_ORDINAL_FLAG) | |
893 | + ilt = (ImageThunkData *)(module->image + lookup); | |
894 | + iat = (ImageThunkData *)(module->image + thunk); | |
895 | + if (!itd_get_address_of_data (ilt) | |
896 | + || !itd_get_address_of_data (iat)) | |
897 | + break; | |
898 | + if (itd_get_ordinal (ilt) & PEIMAGE_ORDINAL_FLAG) | |
609 | 899 | { |
610 | 900 | guint16 ordinal; |
611 | 901 | |
612 | - ordinal = itd_get_ordinal (iat) & ~PEIMAGE_ORDINAL_FLAG; | |
902 | + ordinal = itd_get_ordinal (ilt) & ~PEIMAGE_ORDINAL_FLAG; | |
613 | 903 | func = peimage_file_get_proc (image, ordinal); |
614 | 904 | } |
615 | - else | |
905 | + else if (itd_get_address_of_data (ilt) | |
906 | + + sizeof (guint16) <= size) | |
616 | 907 | { |
617 | - const ImageImportByName *iibn; | |
908 | + for (i = itd_get_address_of_data (ilt) | |
909 | + + sizeof (guint16); 0 <= i && i < size; i++) | |
910 | + if (module->image[i] == '\0') | |
911 | + { | |
912 | + const ImageImportByName *iibn; | |
618 | 913 | |
619 | - iibn = (const ImageImportByName *)(module->image | |
620 | - + itd_get_address_of_data (iat)); | |
621 | - func = peimage_file_get_func (image, | |
914 | + iibn = (const ImageImportByName *)(module->image | |
915 | + + itd_get_address_of_data (ilt)); | |
916 | + func = peimage_file_get_func (image, | |
622 | 917 | iibn_get_name (iibn)); |
918 | + break; | |
919 | + } | |
623 | 920 | } |
624 | - itd_set_function (ilt, pemodule_import | |
921 | + itd_set_function (iat, pemodule_import | |
625 | 922 | ? pemodule_import (process, func, user_data) |
626 | 923 | : GPOINTER_TO_UINT (func)); |
627 | - iat++; | |
628 | - ilt++; | |
924 | + lookup += sizeof (guint32); | |
925 | + thunk += sizeof (guint32); | |
629 | 926 | } |
630 | - module->glist = g_list_append (module->glist, image); | |
927 | + module->library = g_list_append (module->library, image); | |
631 | 928 | } |
632 | 929 | else |
633 | 930 | { |
@@ -635,12 +932,37 @@ | ||
635 | 932 | } |
636 | 933 | } |
637 | 934 | } |
935 | + | |
638 | 936 | if (!result) |
639 | 937 | { |
640 | - peimage_module_free_library (process, module->image, NULL, user_data); | |
938 | + for (module->library = g_list_first (module->library); module->library; | |
939 | + module->library = g_list_delete_link | |
940 | + (module->library, module->library)) | |
941 | + peimage_module_free_library (process, module->library->data, | |
942 | + pemodule_entry, user_data); | |
943 | + g_free (module->image); | |
944 | + g_free (module->name); | |
945 | + g_free (module->file); | |
946 | + g_free (module); | |
641 | 947 | return NULL; |
642 | 948 | } |
643 | 949 | |
950 | + /* ja:再配置 */ | |
951 | + if (pemodule_relocate) | |
952 | + peimage_file_relocate (module->image, | |
953 | + pemodule_relocate (process, module->image, user_data)); | |
954 | + | |
955 | + /* ja:プロセス登録 */ | |
956 | +#ifdef USE_THREAD | |
957 | + G_LOCK (critical); | |
958 | + critical = TRUE; | |
959 | +#endif /* USE_THREAD */ | |
960 | + process->module = g_list_append (process->module, module); | |
961 | +#ifdef USE_THREAD | |
962 | + critical = FALSE; | |
963 | + G_UNLOCK (critical); | |
964 | +#endif /* USE_THREAD */ | |
965 | + | |
644 | 966 | if (pemodule_entry |
645 | 967 | && !pemodule_entry (process, module->image, TRUE, user_data)) |
646 | 968 | { |
@@ -673,7 +995,7 @@ | ||
673 | 995 | if (module->counter <= 0) |
674 | 996 | { |
675 | 997 | if (pemodule_entry) |
676 | - pemodule_entry (process, module->image, FALSE, user_data); | |
998 | + result = pemodule_entry (process, module->image, FALSE, user_data); | |
677 | 999 | #ifdef USE_THREAD |
678 | 1000 | G_LOCK (critical); |
679 | 1001 | critical = TRUE; |
@@ -683,10 +1005,11 @@ | ||
683 | 1005 | critical = FALSE; |
684 | 1006 | G_UNLOCK (critical); |
685 | 1007 | #endif /* USE_THREAD */ |
686 | - for (module->glist = g_list_first (module->glist); module->glist; | |
687 | - module->glist = g_list_delete_link (module->glist, module->glist)) | |
688 | - if (!peimage_module_free_library (process, | |
689 | - ((PeModule *)module->glist->data)->image, | |
1008 | + for (module->library = g_list_first (module->library); | |
1009 | + module->library; | |
1010 | + module->library = g_list_delete_link | |
1011 | + (module->library, module->library)) | |
1012 | + if (!peimage_module_free_library (process, module->library->data, | |
690 | 1013 | pemodule_entry, user_data)) |
691 | 1014 | result = FALSE; |
692 | 1015 | g_free (module->image); |
@@ -714,6 +1037,29 @@ | ||
714 | 1037 | } |
715 | 1038 | |
716 | 1039 | |
1040 | +/* ja:プロセスのイメージ一覧を取得する | |
1041 | + process,プロセス | |
1042 | + RET,リスト,NULL:エラー */ | |
1043 | +GList * | |
1044 | +peimage_module_get_list (PeProcess *process) | |
1045 | +{ | |
1046 | + GList *module = NULL, *glist; | |
1047 | + | |
1048 | +#ifdef USE_THREAD | |
1049 | + G_LOCK (critical); | |
1050 | + critical = TRUE; | |
1051 | +#endif /* USE_THREAD */ | |
1052 | + for (glist = g_list_first (process->module); | |
1053 | + glist; glist = g_list_next (glist)) | |
1054 | + module = g_list_append (module, ((PeModule *)glist->data)->image); | |
1055 | +#ifdef USE_THREAD | |
1056 | + critical = FALSE; | |
1057 | + G_UNLOCK (critical); | |
1058 | +#endif /* USE_THREAD */ | |
1059 | + return module; | |
1060 | +} | |
1061 | + | |
1062 | + | |
717 | 1063 | /****************************************************************************** |
718 | 1064 | * * |
719 | 1065 | * ja:ディレクトリ関数群 * |
@@ -336,8 +336,8 @@ | ||
336 | 336 | #define ioh_get_size_of_heap_commit(ioh) GUINT32_FROM_LE(*(guint32 *)((guint8 *)(ioh)+84)) |
337 | 337 | #define ioh_get_loader_flags(ioh) GUINT32_FROM_LE(*(guint32 *)((guint8 *)(ioh)+88)) |
338 | 338 | #define ioh_get_number_of_rva_and_sizes(ioh) GUINT32_FROM_LE(*(guint32 *)((guint8 *)(ioh)+92)) |
339 | -#define ioh_get_data_directory_virtual_address(ioh,entry) idd_get_virtual_address((guint8 *)(ioh)+96+(entry)*IDD_SIZE) | |
340 | -#define ioh_get_data_directory_size(ioh,entry) idd_get_size((guint8 *)(ioh)+96+(entry)*IDD_SIZE) | |
339 | +#define ioh_get_data_directory_virtual_address(ioh,entry) (ioh_get_number_of_rva_and_sizes(ioh)>entry?idd_get_virtual_address((guint8 *)(ioh)+96+(entry)*IDD_SIZE):0) | |
340 | +#define ioh_get_data_directory_size(ioh,entry) (ioh_get_number_of_rva_and_sizes(ioh)>entry?idd_get_size((guint8 *)(ioh)+96+(entry)*IDD_SIZE):0) | |
341 | 341 | #define ioh_set_magic(ioh,magic) (*(guint16 *)(ioh)=GUINT16_TO_LE(magic)) |
342 | 342 | #define ioh_set_major_linker_version(ioh,major_linker_version) (*((guint8 *)(ioh)+2)=(major_linker_version)) |
343 | 343 | #define ioh_set_minor_linker_version(ioh,minor_linker_version) (*((guint8 *)(ioh)+3)=(minor_linker_version)) |
@@ -591,10 +591,10 @@ | ||
591 | 591 | #define pe_ioh_set_loader_flags(image,loader_flags) ioh_set_loader_flags(pe_image_optional_header(image),loader_flags) |
592 | 592 | #define pe_ioh_set_number_of_rva_and_sizes(image,number_of_rva_and_sizes) ioh_set_number_of_rva_and_sizes(pe_image_optional_header(image),number_of_rva_and_sizes) |
593 | 593 | #define pe_ioh_set_data_directory_virtual_address(image,entry,virtual_address) ioh_set_data_directory_virtual_address(pe_image_optional_header(image),entry,virtual_address) |
594 | -#define pe_ioh_set_data_directory_size(image,entry,virtual_address) ioh_set_data_directory_size(pe_image_optional_header(image),entry,size) | |
594 | +#define pe_ioh_set_data_directory_size(image,entry,size) ioh_set_data_directory_size(pe_image_optional_header(image),entry,size) | |
595 | 595 | |
596 | 596 | |
597 | -#define pe_image_section_header_nth(image,n) (ImageSectionHeader *)((guint8 *)(image)+idh_get_lfanew(image)+4+IFH_SIZE+IOH_SIZE+(n)*ISH_SIZE) | |
597 | +#define pe_image_section_header_nth(image,n) (ImageSectionHeader *)((guint8 *)(image)+idh_get_lfanew(image)+4+IFH_SIZE+pe_ifh_get_size_of_optional_header(image)+(n)*ISH_SIZE) | |
598 | 598 | #define pe_image_section_header(image) pe_image_section_header_nth(image,0) |
599 | 599 | #define pe_ish_get_name(image,n) ish_get_name(pe_image_section_header_nth(image,n)) |
600 | 600 | #define pe_ish_get_physical_address(image,n) ish_get_physical_address(pe_image_section_header_nth(image,n)) |
@@ -672,13 +672,28 @@ | ||
672 | 672 | * ja:PEイメージ関数 * |
673 | 673 | * * |
674 | 674 | ******************************************************************************/ |
675 | +typedef struct _PeExport | |
676 | +{ | |
677 | + const gchar *name; | |
678 | + const gchar *forward; | |
679 | + guint16 ordinal; | |
680 | + guint32 address; | |
681 | +} PeExport; | |
682 | +typedef struct _PeImport | |
683 | +{ | |
684 | + const gchar *file; | |
685 | + const gchar *name; | |
686 | + guint16 ordinal; | |
687 | +} PeImport; | |
688 | + | |
689 | + | |
675 | 690 | /* ja:PEイメージのヘッダサイズを取得する |
676 | 691 | image,PEイメージ(ヘッダ) |
677 | 692 | RET,バイト数 */ |
678 | 693 | #define peimage_file_header_bytes(image) \ |
679 | 694 | (pe_idh_get_lfanew(image)+sizeof(guint32) \ |
680 | - +sizeof(ImageFileHeader)+sizeof(ImageOptionalHeader) \ | |
681 | - +sizeof(ImageSectionHeader)*pe_ifh_get_number_of_sections(image)) | |
695 | + +sizeof(ImageFileHeader)+pe_ifh_get_size_of_optional_header(image) \ | |
696 | + +pe_ifh_get_number_of_sections(image)*sizeof(ImageSectionHeader)) | |
682 | 697 | |
683 | 698 | |
684 | 699 | /* ja:PEイメージを検証する |
@@ -685,11 +700,38 @@ | ||
685 | 700 | image,PEイメージ(ヘッダ) |
686 | 701 | length,バイト数 |
687 | 702 | RET,TRUE:正常終了,FALSE:エラー */ |
688 | -gboolean | |
689 | -peimage_file_is_valid (const guint8 *image, | |
690 | - const gssize length); | |
703 | +#define peimage_file_is_valid(image,size) \ | |
704 | + ((image) && sizeof(ImageDosHeader)<=(size) \ | |
705 | + && pe_idh_get_magic(image)==PEIMAGE_DOS_SIGNATURE \ | |
706 | + && pe_idh_get_lfanew(image)+sizeof(guint32) \ | |
707 | + +sizeof(ImageFileHeader)+sizeof(ImageOptionalHeader)<=(size) \ | |
708 | + && pe_get_signature(image)==PEIMAGE_NT_SIGNATURE \ | |
709 | + && pe_ifh_get_machine(image)==PEIMAGE_FILE_MACHINE_I386 \ | |
710 | + && pe_ifh_get_size_of_optional_header(image)<96 \ | |
711 | + && pe_ioh_get_magic(image)==PEIMAGE_NT_OPTIONAL_HDR_MAGIC \ | |
712 | + && peimage_file_header_bytes(image)<=(size)) | |
691 | 713 | |
692 | 714 | |
715 | +/* ja:PEイメージの仮想相対アドレスをファイルオフセットに変換する | |
716 | + image,PEイメージ(ヘッダ) | |
717 | + address,仮想相対アドレス | |
718 | + RET,ファイルオフセット,-1:エラー */ | |
719 | +gint | |
720 | +peimage_file_address_to_offset (const guint8 *image, | |
721 | + const guint32 address); | |
722 | +#define peimage_file_offset_from_address peimage_file_address_to_offset | |
723 | + | |
724 | + | |
725 | +/* ja:PEイメージのファイルオフセットを仮想相対アドレスに変換する | |
726 | + image,PEイメージ(ヘッダ) | |
727 | + offset,ファイルオフセット | |
728 | + RET,仮想相対アドレス,-1:エラー */ | |
729 | +guint32 | |
730 | +peimage_file_offset_to_address (const guint8 *image, | |
731 | + const gint offset); | |
732 | +#define peimage_file_address_from_offset peimage_file_offset_to_address | |
733 | + | |
734 | + | |
693 | 735 | /* ja:PEイメージを読み込む |
694 | 736 | file,ファイル名 |
695 | 737 | RET,PEイメージ,NULL:エラー */ |
@@ -732,6 +774,20 @@ | ||
732 | 774 | const gchar *key); |
733 | 775 | |
734 | 776 | |
777 | +/* ja:PEイメージのエクスポートテーブルを列挙する | |
778 | + image,PEイメージ | |
779 | + RET,リスト,NULL:エラー */ | |
780 | +GList * | |
781 | +peimage_file_enum_export (const guint8 *image); | |
782 | + | |
783 | + | |
784 | +/* ja:PEイメージのインポートテーブルを列挙する | |
785 | + image,PEイメージ | |
786 | + RET,リスト,NULL:エラー */ | |
787 | +GList * | |
788 | +peimage_file_enum_import (const guint8 *image); | |
789 | + | |
790 | + | |
735 | 791 | /****************************************************************************** |
736 | 792 | * * |
737 | 793 | * ja:モジュール関数群 * |
@@ -797,6 +853,13 @@ | ||
797 | 853 | const guint8 *image); |
798 | 854 | |
799 | 855 | |
856 | +/* ja:プロセスのイメージ一覧を取得する | |
857 | + process,プロセス | |
858 | + RET,リスト,NULL:エラー */ | |
859 | +GList * | |
860 | +peimage_module_get_list (PeProcess *process); | |
861 | + | |
862 | + | |
800 | 863 | /****************************************************************************** |
801 | 864 | * * |
802 | 865 | * ja:ディレクトリ関数群 * |
@@ -5,7 +5,7 @@ | ||
5 | 5 | dnl version number |
6 | 6 | MAJOR_VERSION=2 |
7 | 7 | MINOR_VERSION=2 |
8 | -MICRO_VERSION=2 | |
8 | +MICRO_VERSION=3 | |
9 | 9 | EXTRA_VERSION= |
10 | 10 | VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION |
11 | 11 |
@@ -6,7 +6,7 @@ | ||
6 | 6 | msgstr "" |
7 | 7 | "Project-Id-Version: vmaid 2.2.1\n" |
8 | 8 | "Report-Msgid-Bugs-To: http://www.maid.org/\n" |
9 | -"POT-Creation-Date: 2009-11-29 11:33+0900\n" | |
9 | +"POT-Creation-Date: 2010-02-09 18:47+0900\n" | |
10 | 10 | "PO-Revision-Date: 2002-07-25 03:38+0900\n" |
11 | 11 | "Last-Translator: Kazuki IWAMOTO <iwm@maid.org>\n" |
12 | 12 | "Language-Team: Kazuki IWAMOTO <iwm@maid.org>\n" |
@@ -683,107 +683,107 @@ | ||
683 | 683 | msgid "Breton" |
684 | 684 | msgstr "ブルターニュ語" |
685 | 685 | |
686 | -#: avicore/aviextra.c:806 | |
686 | +#: avicore/aviextra.c:772 | |
687 | 687 | msgid "_Null Frame" |
688 | 688 | msgstr "ヌルフレーム(_N)" |
689 | 689 | |
690 | -#: avicore/aviextra.c:811 | |
690 | +#: avicore/aviextra.c:777 | |
691 | 691 | msgid "Uncompress" |
692 | 692 | msgstr "未圧縮" |
693 | 693 | |
694 | -#: avicore/aviextra.c:860 avicore/aviextra.c:1095 | |
694 | +#: avicore/aviextra.c:827 avicore/aviextra.c:1062 | |
695 | 695 | msgid "_Recompress" |
696 | 696 | msgstr "再圧縮(_R)" |
697 | 697 | |
698 | -#: avicore/aviextra.c:915 avicore/aviextra.c:1159 | |
698 | +#: avicore/aviextra.c:882 avicore/aviextra.c:1126 | |
699 | 699 | msgid "_Compressor" |
700 | 700 | msgstr "圧縮(_C)" |
701 | 701 | |
702 | -#: avicore/aviextra.c:936 avicore/aviextra.c:1435 | |
702 | +#: avicore/aviextra.c:903 avicore/aviextra.c:1396 | |
703 | 703 | msgid "_Quality" |
704 | 704 | msgstr "品質(_Q)" |
705 | 705 | |
706 | -#: avicore/aviextra.c:948 | |
706 | +#: avicore/aviextra.c:915 | |
707 | 707 | msgid "_Key Frame" |
708 | 708 | msgstr "キーフレーム(_K)" |
709 | 709 | |
710 | -#: avicore/aviextra.c:959 | |
710 | +#: avicore/aviextra.c:926 | |
711 | 711 | msgid "_Data Rate" |
712 | 712 | msgstr "データレート(_D)" |
713 | 713 | |
714 | -#: avicore/aviextra.c:1041 avicore/aviextra.c:1045 | |
714 | +#: avicore/aviextra.c:1007 avicore/aviextra.c:1011 | |
715 | 715 | msgid "PCM" |
716 | 716 | msgstr "PCM" |
717 | 717 | |
718 | -#: avicore/aviextra.c:1252 | |
718 | +#: avicore/aviextra.c:1218 | |
719 | 719 | msgid "_AVI" |
720 | 720 | msgstr "AVI(_A)" |
721 | 721 | |
722 | -#: avicore/aviextra.c:1258 | |
722 | +#: avicore/aviextra.c:1224 | |
723 | 723 | msgid "_GtkShot Raw" |
724 | 724 | msgstr "GtkShot Raw(_G)" |
725 | 725 | |
726 | -#: avicore/aviextra.c:1280 | |
726 | +#: avicore/aviextra.c:1245 | |
727 | 727 | msgid "_Bitmap" |
728 | 728 | msgstr "ビットマップ(_B)" |
729 | 729 | |
730 | -#: avicore/aviextra.c:1300 | |
730 | +#: avicore/aviextra.c:1265 | |
731 | 731 | msgid "_Start" |
732 | 732 | msgstr "開始(_S)" |
733 | 733 | |
734 | -#: avicore/aviextra.c:1301 | |
734 | +#: avicore/aviextra.c:1266 | |
735 | 735 | msgid "_End" |
736 | 736 | msgstr "終了(_E)" |
737 | 737 | |
738 | -#: avicore/aviextra.c:1343 src/prop.c:299 | |
738 | +#: avicore/aviextra.c:1304 src/prop.c:299 | |
739 | 739 | msgid "_Color" |
740 | 740 | msgstr "色(_C)" |
741 | 741 | |
742 | -#: avicore/aviextra.c:1350 src/prop.c:473 | |
742 | +#: avicore/aviextra.c:1311 src/prop.c:473 | |
743 | 743 | msgid "_16 bits" |
744 | 744 | msgstr "16ビット(_1)" |
745 | 745 | |
746 | -#: avicore/aviextra.c:1354 | |
746 | +#: avicore/aviextra.c:1315 | |
747 | 747 | msgid "_Full Color" |
748 | 748 | msgstr "フルカラー(_F)" |
749 | 749 | |
750 | -#: avicore/aviextra.c:1358 | |
750 | +#: avicore/aviextra.c:1319 | |
751 | 751 | msgid "_32 bits" |
752 | 752 | msgstr "32ビット(_3)" |
753 | 753 | |
754 | -#: avicore/aviextra.c:1363 | |
754 | +#: avicore/aviextra.c:1324 | |
755 | 755 | msgid "_Cursor" |
756 | 756 | msgstr "カーソル(_C)" |
757 | 757 | |
758 | -#: avicore/aviextra.c:1378 | |
758 | +#: avicore/aviextra.c:1339 | |
759 | 759 | msgid "_X Hot Spot" |
760 | 760 | msgstr "X座標ホットスポット(_X)" |
761 | 761 | |
762 | -#: avicore/aviextra.c:1380 | |
762 | +#: avicore/aviextra.c:1341 | |
763 | 763 | msgid "_Y Hot Spot" |
764 | 764 | msgstr "Y座標ホットスポット(_Y)" |
765 | 765 | |
766 | -#: avicore/aviextra.c:1457 | |
766 | +#: avicore/aviextra.c:1418 | |
767 | 767 | msgid "_Compress Level" |
768 | 768 | msgstr "圧縮レベル(_C)" |
769 | 769 | |
770 | -#: avicore/aviextra.c:1533 | |
770 | +#: avicore/aviextra.c:1493 | |
771 | 771 | msgid "_GdkPixbuf" |
772 | 772 | msgstr "GdkPixbuf(_G)" |
773 | 773 | |
774 | -#: avicore/aviextra.c:1575 | |
774 | +#: avicore/aviextra.c:1535 | |
775 | 775 | msgid "Range and Format" |
776 | 776 | msgstr "範囲と形式" |
777 | 777 | |
778 | -#: avicore/aviextra.c:1588 | |
778 | +#: avicore/aviextra.c:1548 | |
779 | 779 | msgid "_WAVE" |
780 | 780 | msgstr "WAVE(_W)" |
781 | 781 | |
782 | -#: avicore/aviextra.c:1597 | |
782 | +#: avicore/aviextra.c:1557 | |
783 | 783 | msgid "Scenario _Object" |
784 | 784 | msgstr "シナリオオブジェクト(_O)" |
785 | 785 | |
786 | -#: avicore/aviextra.c:1621 | |
786 | +#: avicore/aviextra.c:1581 | |
787 | 787 | msgid "Format" |
788 | 788 | msgstr "形式" |
789 | 789 |
@@ -907,7 +907,7 @@ | ||
907 | 907 | msgid "Status" |
908 | 908 | msgstr "状況" |
909 | 909 | |
910 | -#: src/change.c:197 src/thread.c:305 | |
910 | +#: src/change.c:197 src/thread.c:307 | |
911 | 911 | msgid "Change Frames" |
912 | 912 | msgstr "フレーム数変更" |
913 | 913 |
@@ -915,15 +915,15 @@ | ||
915 | 915 | msgid "Justify audio stream" |
916 | 916 | msgstr "オーディオにあわせる" |
917 | 917 | |
918 | -#: src/codec.c:126 src/codec.c:279 src/version.c:132 src/version.c:351 | |
918 | +#: src/codec.c:126 src/codec.c:265 src/version.c:132 src/version.c:337 | |
919 | 919 | msgid "Name" |
920 | 920 | msgstr "名前" |
921 | 921 | |
922 | -#: src/codec.c:126 src/codec.c:280 src/version.c:132 src/version.c:352 | |
922 | +#: src/codec.c:126 src/codec.c:266 src/version.c:132 src/version.c:338 | |
923 | 923 | msgid "Code" |
924 | 924 | msgstr "コード" |
925 | 925 | |
926 | -#: src/codec.c:126 src/codec.c:281 src/version.c:132 src/version.c:353 | |
926 | +#: src/codec.c:126 src/codec.c:267 src/version.c:132 src/version.c:339 | |
927 | 927 | msgid "Attribute" |
928 | 928 | msgstr "属性" |
929 | 929 |
@@ -935,23 +935,23 @@ | ||
935 | 935 | msgid "Video Compressor" |
936 | 936 | msgstr "ビデオ圧縮" |
937 | 937 | |
938 | -#: src/codec.c:176 src/codec.c:241 src/version.c:248 src/version.c:313 | |
938 | +#: src/codec.c:171 src/codec.c:229 src/version.c:243 src/version.c:301 | |
939 | 939 | msgid "Video maid Native" |
940 | 940 | msgstr "Video maid 固有" |
941 | 941 | |
942 | -#: src/codec.c:180 src/codec.c:245 src/version.c:252 src/version.c:317 | |
942 | +#: src/codec.c:175 src/codec.c:233 src/version.c:247 src/version.c:305 | |
943 | 943 | msgid "Win32 Native" |
944 | 944 | msgstr "Win32 固有" |
945 | 945 | |
946 | -#: src/codec.c:182 src/codec.c:247 src/version.c:254 src/version.c:319 | |
946 | +#: src/codec.c:177 src/codec.c:235 src/version.c:249 src/version.c:307 | |
947 | 947 | msgid "Win32 Emulation" |
948 | 948 | msgstr "Win32 エミュレーション" |
949 | 949 | |
950 | -#: src/codec.c:186 src/codec.c:251 src/version.c:258 src/version.c:323 | |
950 | +#: src/codec.c:181 src/codec.c:239 src/version.c:253 src/version.c:311 | |
951 | 951 | msgid "Unknown" |
952 | 952 | msgstr "不明" |
953 | 953 | |
954 | -#: src/codec.c:213 src/version.c:285 | |
954 | +#: src/codec.c:206 src/version.c:278 | |
955 | 955 | msgid "Audio Compressor" |
956 | 956 | msgstr "オーディオ圧縮" |
957 | 957 |
@@ -1198,11 +1198,11 @@ | ||
1198 | 1198 | msgid "Constrain _aspect ratio" |
1199 | 1199 | msgstr "縦横比を保持(_A)" |
1200 | 1200 | |
1201 | -#: src/thread.c:312 | |
1201 | +#: src/thread.c:314 | |
1202 | 1202 | msgid "Reverse" |
1203 | 1203 | msgstr "フレーム反転" |
1204 | 1204 | |
1205 | -#: src/thread.c:360 src/thread.c:367 src/thread.c:459 src/thread.c:467 | |
1205 | +#: src/thread.c:362 src/thread.c:369 src/thread.c:461 src/thread.c:469 | |
1206 | 1206 | msgid "Error" |
1207 | 1207 | msgstr "エラー" |
1208 | 1208 |
@@ -1218,6 +1218,6 @@ | ||
1218 | 1218 | msgid "_About..." |
1219 | 1219 | msgstr "バージョン情報(_A)..." |
1220 | 1220 | |
1221 | -#: src/version.c:388 | |
1221 | +#: src/version.c:374 | |
1222 | 1222 | msgid "Codecs" |
1223 | 1223 | msgstr "コーデック" |