284/* 285 * Import format 286 */ 287 288struct image_import_by_name { 289 uint16_t iibn_hint; 290 uint8_t iibn_name[1]; 291}; 292 293#define IMAGE_ORDINAL_FLAG 0x80000000 294#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) 295 296struct image_import_descriptor { 297 uint32_t iid_import_name_table_addr; 298 uint32_t iid_timestamp; 299 uint32_t iid_forwardchain; 300 uint32_t iid_nameaddr; 301 uint32_t iid_import_address_table_addr; 302}; 303 304typedef struct image_import_descriptor image_import_descriptor; 305 306struct image_base_reloc { 307 uint32_t ibr_vaddr; 308 uint32_t ibr_blocksize; 309 uint16_t ibr_rel[1]; 310}; 311 312typedef struct image_base_reloc image_base_reloc; 313 314#define IMR_RELTYPE(x) ((x >> 12) & 0xF) 315#define IMR_RELOFFSET(x) (x & 0xFFF) 316 317/* generic relocation types */ 318#define IMAGE_REL_BASED_ABSOLUTE 0 319#define IMAGE_REL_BASED_HIGH 1 320#define IMAGE_REL_BASED_LOW 2 321#define IMAGE_REL_BASED_HIGHLOW 3 322#define IMAGE_REL_BASED_HIGHADJ 4 323#define IMAGE_REL_BASED_MIPS_JMPADDR 5 324#define IMAGE_REL_BASED_SECTION 6 325#define IMAGE_REL_BASED_REL 7 326#define IMAGE_REL_BASED_MIPS_JMPADDR16 9 327#define IMAGE_REL_BASED_IA64_IMM64 9 /* yes, 9 too */ 328#define IMAGE_REL_BASED_DIR64 10 329#define IMAGE_REL_BASED_HIGH3ADJ 11 330 331struct image_resource_directory_entry { 332 uint32_t irde_name; 333 uint32_t irde_dataoff; 334}; 335 336typedef struct image_resource_directory_entry image_resource_directory_entry; 337 338#define RESOURCE_NAME_STR 0x80000000 339#define RESOURCE_DIR_FLAG 0x80000000 340 341struct image_resource_directory { 342 uint32_t ird_characteristics; 343 uint32_t ird_timestamp; 344 uint16_t ird_majorver; 345 uint16_t ird_minorver; 346 uint16_t ird_named_entries; 347 uint16_t ird_id_entries; 348#ifdef notdef 349 image_resource_directory_entry ird_entries[1]; 350#endif 351}; 352 353typedef struct image_resource_directory image_resource_directory; 354 355struct image_resource_directory_string { 356 uint16_t irds_len; 357 char irds_name[1]; 358}; 359 360typedef struct image_resource_directory_string image_resource_directory_string; 361 362struct image_resource_directory_string_u { 363 uint16_t irds_len; 364 char irds_name[1]; 365}; 366 367typedef struct image_resource_directory_string_u 368 image_resource_directory_string_u; 369 370struct image_resource_data_entry { 371 uint32_t irde_offset; 372 uint32_t irde_size; 373 uint32_t irde_codepage; 374 uint32_t irde_rsvd; 375}; 376 377typedef struct image_resource_data_entry image_resource_data_entry; 378 379struct message_resource_data { 380 uint32_t mrd_numblocks; 381#ifdef notdef 382 message_resource_block mrd_blocks[1]; 383#endif 384}; 385 386typedef struct message_resource_data message_resource_data; 387 388struct message_resource_block { 389 uint32_t mrb_lowid; 390 uint32_t mrb_highid; 391 uint32_t mrb_entryoff; 392}; 393 394typedef struct message_resource_block message_resource_block; 395 396struct message_resource_entry { 397 uint16_t mre_len; 398 uint16_t mre_flags; 399 char mre_text[]; 400}; 401 402typedef struct message_resource_entry message_resource_entry; 403 404#define MESSAGE_RESOURCE_UNICODE 0x0001 405 406struct image_patch_table { 407 char *ipt_name; 408 void (*ipt_func)(void); 409 void (*ipt_wrap)(void); 410 int ipt_argcnt; 411 int ipt_ftype; 412}; 413 414typedef struct image_patch_table image_patch_table; 415 416/* 417 * AMD64 support. Microsoft uses a different calling convention 418 * than everyone else on the amd64 platform. Sadly, gcc has no 419 * built-in support for it (yet). 420 * 421 * The three major differences we're concerned with are: 422 * 423 * - The first 4 register-sized arguments are passed in the 424 * %rcx, %rdx, %r8 and %r9 registers, and the rest are pushed 425 * onto the stack. (The ELF ABI uses 6 registers, not 4). 426 * 427 * - The caller must reserve space on the stack for the 4 428 * register arguments in case the callee has to spill them. 429 * 430 * - The stack myst be 16-byte aligned by the time the callee 431 * executes. A call instruction implicitly pushes an 8 byte 432 * return address onto the stack. We have to make sure that 433 * the amount of space we consume, plus the return address, 434 * is a multiple of 16 bytes in size. This means that in 435 * some cases, we may need to chew up an extra 8 bytes on 436 * the stack that will be unused. 437 * 438 * On the bright side, Microsoft seems to be using just the one 439 * calling convention for all functions on amd64, unlike x86 where 440 * they use a mix of _stdcall, _fastcall and _cdecl. 441 */ 442 443#ifdef __amd64__ 444 445extern uint64_t x86_64_call1(void *, uint64_t); 446extern uint64_t x86_64_call2(void *, uint64_t, uint64_t); 447extern uint64_t x86_64_call3(void *, uint64_t, uint64_t, uint64_t); 448extern uint64_t x86_64_call4(void *, uint64_t, uint64_t, uint64_t, uint64_t); 449extern uint64_t x86_64_call5(void *, uint64_t, uint64_t, uint64_t, uint64_t, 450 uint64_t); 451extern uint64_t x86_64_call6(void *, uint64_t, uint64_t, uint64_t, uint64_t, 452 uint64_t, uint64_t); 453 454 455#define MSCALL1(fn, a) \ 456 x86_64_call1((fn), (uint64_t)(a)) 457#define MSCALL2(fn, a, b) \ 458 x86_64_call2((fn), (uint64_t)(a), (uint64_t)(b)) 459#define MSCALL3(fn, a, b, c) \ 460 x86_64_call3((fn), (uint64_t)(a), (uint64_t)(b), \ 461 (uint64_t)(c)) 462#define MSCALL4(fn, a, b, c, d) \ 463 x86_64_call4((fn), (uint64_t)(a), (uint64_t)(b), \ 464 (uint64_t)(c), (uint64_t)(d)) 465#define MSCALL5(fn, a, b, c, d, e) \ 466 x86_64_call5((fn), (uint64_t)(a), (uint64_t)(b), \ 467 (uint64_t)(c), (uint64_t)(d), (uint64_t)(e)) 468#define MSCALL6(fn, a, b, c, d, e, f) \ 469 x86_64_call6((fn), (uint64_t)(a), (uint64_t)(b), \ 470 (uint64_t)(c), (uint64_t)(d), (uint64_t)(e), (uint64_t)(f)) 471 472#endif /* __amd64__ */ 473 474#ifdef __i386__ 475 476extern uint32_t x86_stdcall_call(void *, int, ...); 477 478#define MSCALL1(fn, a) x86_stdcall_call(fn, 1, (a)) 479#define MSCALL2(fn, a, b) x86_stdcall_call(fn, 2, (a), (b)) 480#define MSCALL3(fn, a, b, c) x86_stdcall_call(fn, 3, (a), (b), (c)) 481#define MSCALL4(fn, a, b, c, d) x86_stdcall_call(fn, 4, (a), (b), (c), (d)) 482#define MSCALL5(fn, a, b, c, d, e) \ 483 x86_stdcall_call(fn, 5, (a), (b), (c), (d), (e)) 484#define MSCALL6(fn, a, b, c, d, e, f) \ 485 x86_stdcall_call(fn, 6, (a), (b), (c), (d), (e), (f)) 486 487#endif /* __i386__ */ 488 489 490#define FUNC void(*)(void) 491 492#ifdef __i386__ 493#define IMPORT_SFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_STDCALL } 494#define IMPORT_SFUNC_MAP(x, y, z) \ 495 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_STDCALL } 496#define IMPORT_FFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_FASTCALL } 497#define IMPORT_FFUNC_MAP(x, y, z) \ 498 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_FASTCALL } 499#define IMPORT_RFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_REGPARM } 500#define IMPORT_RFUNC_MAP(x, y, z) \ 501 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_REGPARM } 502#define IMPORT_CFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_CDECL } 503#define IMPORT_CFUNC_MAP(x, y, z) \ 504 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_CDECL } 505#endif /* __i386__ */ 506 507#ifdef __amd64__ 508#define IMPORT_SFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 } 509#define IMPORT_SFUNC_MAP(x, y, z) \ 510 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 } 511#define IMPORT_FFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 } 512#define IMPORT_FFUNC_MAP(x, y, z) \ 513 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 } 514#define IMPORT_RFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 } 515#define IMPORT_RFUNC_MAP(x, y, z) \ 516 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 } 517#define IMPORT_CFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 } 518#define IMPORT_CFUNC_MAP(x, y, z) \ 519 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 } 520#endif /* __amd64__ */ 521 522__BEGIN_DECLS 523extern int pe_get_dos_header(vm_offset_t, image_dos_header *); 524extern int pe_is_nt_image(vm_offset_t); 525extern int pe_get_optional_header(vm_offset_t, image_optional_header *); 526extern int pe_get_file_header(vm_offset_t, image_file_header *); 527extern int pe_get_section_header(vm_offset_t, image_section_header *); 528extern int pe_numsections(vm_offset_t); 529extern vm_offset_t pe_imagebase(vm_offset_t); 530extern vm_offset_t pe_directory_offset(vm_offset_t, uint32_t); 531extern vm_offset_t pe_translate_addr (vm_offset_t, vm_offset_t); 532extern int pe_get_section(vm_offset_t, image_section_header *, const char *); 533extern int pe_relocate(vm_offset_t); 534extern int pe_get_import_descriptor(vm_offset_t, image_import_descriptor *, char *); 535extern int pe_patch_imports(vm_offset_t, char *, image_patch_table *); 536extern int pe_get_messagetable(vm_offset_t, message_resource_data **); 537extern int pe_get_message(vm_offset_t, uint32_t, char **, int *, uint16_t *); 538__END_DECLS 539 540#endif /* _PE_VAR_H_ */
| 293/* 294 * Import format 295 */ 296 297struct image_import_by_name { 298 uint16_t iibn_hint; 299 uint8_t iibn_name[1]; 300}; 301 302#define IMAGE_ORDINAL_FLAG 0x80000000 303#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) 304 305struct image_import_descriptor { 306 uint32_t iid_import_name_table_addr; 307 uint32_t iid_timestamp; 308 uint32_t iid_forwardchain; 309 uint32_t iid_nameaddr; 310 uint32_t iid_import_address_table_addr; 311}; 312 313typedef struct image_import_descriptor image_import_descriptor; 314 315struct image_base_reloc { 316 uint32_t ibr_vaddr; 317 uint32_t ibr_blocksize; 318 uint16_t ibr_rel[1]; 319}; 320 321typedef struct image_base_reloc image_base_reloc; 322 323#define IMR_RELTYPE(x) ((x >> 12) & 0xF) 324#define IMR_RELOFFSET(x) (x & 0xFFF) 325 326/* generic relocation types */ 327#define IMAGE_REL_BASED_ABSOLUTE 0 328#define IMAGE_REL_BASED_HIGH 1 329#define IMAGE_REL_BASED_LOW 2 330#define IMAGE_REL_BASED_HIGHLOW 3 331#define IMAGE_REL_BASED_HIGHADJ 4 332#define IMAGE_REL_BASED_MIPS_JMPADDR 5 333#define IMAGE_REL_BASED_SECTION 6 334#define IMAGE_REL_BASED_REL 7 335#define IMAGE_REL_BASED_MIPS_JMPADDR16 9 336#define IMAGE_REL_BASED_IA64_IMM64 9 /* yes, 9 too */ 337#define IMAGE_REL_BASED_DIR64 10 338#define IMAGE_REL_BASED_HIGH3ADJ 11 339 340struct image_resource_directory_entry { 341 uint32_t irde_name; 342 uint32_t irde_dataoff; 343}; 344 345typedef struct image_resource_directory_entry image_resource_directory_entry; 346 347#define RESOURCE_NAME_STR 0x80000000 348#define RESOURCE_DIR_FLAG 0x80000000 349 350struct image_resource_directory { 351 uint32_t ird_characteristics; 352 uint32_t ird_timestamp; 353 uint16_t ird_majorver; 354 uint16_t ird_minorver; 355 uint16_t ird_named_entries; 356 uint16_t ird_id_entries; 357#ifdef notdef 358 image_resource_directory_entry ird_entries[1]; 359#endif 360}; 361 362typedef struct image_resource_directory image_resource_directory; 363 364struct image_resource_directory_string { 365 uint16_t irds_len; 366 char irds_name[1]; 367}; 368 369typedef struct image_resource_directory_string image_resource_directory_string; 370 371struct image_resource_directory_string_u { 372 uint16_t irds_len; 373 char irds_name[1]; 374}; 375 376typedef struct image_resource_directory_string_u 377 image_resource_directory_string_u; 378 379struct image_resource_data_entry { 380 uint32_t irde_offset; 381 uint32_t irde_size; 382 uint32_t irde_codepage; 383 uint32_t irde_rsvd; 384}; 385 386typedef struct image_resource_data_entry image_resource_data_entry; 387 388struct message_resource_data { 389 uint32_t mrd_numblocks; 390#ifdef notdef 391 message_resource_block mrd_blocks[1]; 392#endif 393}; 394 395typedef struct message_resource_data message_resource_data; 396 397struct message_resource_block { 398 uint32_t mrb_lowid; 399 uint32_t mrb_highid; 400 uint32_t mrb_entryoff; 401}; 402 403typedef struct message_resource_block message_resource_block; 404 405struct message_resource_entry { 406 uint16_t mre_len; 407 uint16_t mre_flags; 408 char mre_text[]; 409}; 410 411typedef struct message_resource_entry message_resource_entry; 412 413#define MESSAGE_RESOURCE_UNICODE 0x0001 414 415struct image_patch_table { 416 char *ipt_name; 417 void (*ipt_func)(void); 418 void (*ipt_wrap)(void); 419 int ipt_argcnt; 420 int ipt_ftype; 421}; 422 423typedef struct image_patch_table image_patch_table; 424 425/* 426 * AMD64 support. Microsoft uses a different calling convention 427 * than everyone else on the amd64 platform. Sadly, gcc has no 428 * built-in support for it (yet). 429 * 430 * The three major differences we're concerned with are: 431 * 432 * - The first 4 register-sized arguments are passed in the 433 * %rcx, %rdx, %r8 and %r9 registers, and the rest are pushed 434 * onto the stack. (The ELF ABI uses 6 registers, not 4). 435 * 436 * - The caller must reserve space on the stack for the 4 437 * register arguments in case the callee has to spill them. 438 * 439 * - The stack myst be 16-byte aligned by the time the callee 440 * executes. A call instruction implicitly pushes an 8 byte 441 * return address onto the stack. We have to make sure that 442 * the amount of space we consume, plus the return address, 443 * is a multiple of 16 bytes in size. This means that in 444 * some cases, we may need to chew up an extra 8 bytes on 445 * the stack that will be unused. 446 * 447 * On the bright side, Microsoft seems to be using just the one 448 * calling convention for all functions on amd64, unlike x86 where 449 * they use a mix of _stdcall, _fastcall and _cdecl. 450 */ 451 452#ifdef __amd64__ 453 454extern uint64_t x86_64_call1(void *, uint64_t); 455extern uint64_t x86_64_call2(void *, uint64_t, uint64_t); 456extern uint64_t x86_64_call3(void *, uint64_t, uint64_t, uint64_t); 457extern uint64_t x86_64_call4(void *, uint64_t, uint64_t, uint64_t, uint64_t); 458extern uint64_t x86_64_call5(void *, uint64_t, uint64_t, uint64_t, uint64_t, 459 uint64_t); 460extern uint64_t x86_64_call6(void *, uint64_t, uint64_t, uint64_t, uint64_t, 461 uint64_t, uint64_t); 462 463 464#define MSCALL1(fn, a) \ 465 x86_64_call1((fn), (uint64_t)(a)) 466#define MSCALL2(fn, a, b) \ 467 x86_64_call2((fn), (uint64_t)(a), (uint64_t)(b)) 468#define MSCALL3(fn, a, b, c) \ 469 x86_64_call3((fn), (uint64_t)(a), (uint64_t)(b), \ 470 (uint64_t)(c)) 471#define MSCALL4(fn, a, b, c, d) \ 472 x86_64_call4((fn), (uint64_t)(a), (uint64_t)(b), \ 473 (uint64_t)(c), (uint64_t)(d)) 474#define MSCALL5(fn, a, b, c, d, e) \ 475 x86_64_call5((fn), (uint64_t)(a), (uint64_t)(b), \ 476 (uint64_t)(c), (uint64_t)(d), (uint64_t)(e)) 477#define MSCALL6(fn, a, b, c, d, e, f) \ 478 x86_64_call6((fn), (uint64_t)(a), (uint64_t)(b), \ 479 (uint64_t)(c), (uint64_t)(d), (uint64_t)(e), (uint64_t)(f)) 480 481#endif /* __amd64__ */ 482 483#ifdef __i386__ 484 485extern uint32_t x86_stdcall_call(void *, int, ...); 486 487#define MSCALL1(fn, a) x86_stdcall_call(fn, 1, (a)) 488#define MSCALL2(fn, a, b) x86_stdcall_call(fn, 2, (a), (b)) 489#define MSCALL3(fn, a, b, c) x86_stdcall_call(fn, 3, (a), (b), (c)) 490#define MSCALL4(fn, a, b, c, d) x86_stdcall_call(fn, 4, (a), (b), (c), (d)) 491#define MSCALL5(fn, a, b, c, d, e) \ 492 x86_stdcall_call(fn, 5, (a), (b), (c), (d), (e)) 493#define MSCALL6(fn, a, b, c, d, e, f) \ 494 x86_stdcall_call(fn, 6, (a), (b), (c), (d), (e), (f)) 495 496#endif /* __i386__ */ 497 498 499#define FUNC void(*)(void) 500 501#ifdef __i386__ 502#define IMPORT_SFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_STDCALL } 503#define IMPORT_SFUNC_MAP(x, y, z) \ 504 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_STDCALL } 505#define IMPORT_FFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_FASTCALL } 506#define IMPORT_FFUNC_MAP(x, y, z) \ 507 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_FASTCALL } 508#define IMPORT_RFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_REGPARM } 509#define IMPORT_RFUNC_MAP(x, y, z) \ 510 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_REGPARM } 511#define IMPORT_CFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_CDECL } 512#define IMPORT_CFUNC_MAP(x, y, z) \ 513 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_CDECL } 514#endif /* __i386__ */ 515 516#ifdef __amd64__ 517#define IMPORT_SFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 } 518#define IMPORT_SFUNC_MAP(x, y, z) \ 519 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 } 520#define IMPORT_FFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 } 521#define IMPORT_FFUNC_MAP(x, y, z) \ 522 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 } 523#define IMPORT_RFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 } 524#define IMPORT_RFUNC_MAP(x, y, z) \ 525 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 } 526#define IMPORT_CFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 } 527#define IMPORT_CFUNC_MAP(x, y, z) \ 528 { #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 } 529#endif /* __amd64__ */ 530 531__BEGIN_DECLS 532extern int pe_get_dos_header(vm_offset_t, image_dos_header *); 533extern int pe_is_nt_image(vm_offset_t); 534extern int pe_get_optional_header(vm_offset_t, image_optional_header *); 535extern int pe_get_file_header(vm_offset_t, image_file_header *); 536extern int pe_get_section_header(vm_offset_t, image_section_header *); 537extern int pe_numsections(vm_offset_t); 538extern vm_offset_t pe_imagebase(vm_offset_t); 539extern vm_offset_t pe_directory_offset(vm_offset_t, uint32_t); 540extern vm_offset_t pe_translate_addr (vm_offset_t, vm_offset_t); 541extern int pe_get_section(vm_offset_t, image_section_header *, const char *); 542extern int pe_relocate(vm_offset_t); 543extern int pe_get_import_descriptor(vm_offset_t, image_import_descriptor *, char *); 544extern int pe_patch_imports(vm_offset_t, char *, image_patch_table *); 545extern int pe_get_messagetable(vm_offset_t, message_resource_data **); 546extern int pe_get_message(vm_offset_t, uint32_t, char **, int *, uint16_t *); 547__END_DECLS 548 549#endif /* _PE_VAR_H_ */
|