| 1 | /* -*- Mode: C; c-basic-offset:4 ; -*- */ |
|---|
| 2 | /* |
|---|
| 3 | * (C) 2001 by Argonne National Laboratory. |
|---|
| 4 | * See COPYRIGHT in top-level directory. |
|---|
| 5 | */ |
|---|
| 6 | #include <stdio.h> |
|---|
| 7 | #include <windows.h> |
|---|
| 8 | |
|---|
| 9 | unsigned int read16(HANDLE fd, int offset) |
|---|
| 10 | { |
|---|
| 11 | DWORD num_read; |
|---|
| 12 | unsigned char b[2]; |
|---|
| 13 | |
|---|
| 14 | SetFilePointer(fd, offset, NULL, FILE_BEGIN); |
|---|
| 15 | if (!ReadFile(fd, b, 2, &num_read, NULL)) |
|---|
| 16 | { |
|---|
| 17 | ExitProcess(-1); |
|---|
| 18 | } |
|---|
| 19 | return b[0] + (b[1] << 8); |
|---|
| 20 | } |
|---|
| 21 | |
|---|
| 22 | unsigned int read32(HANDLE fd, int offset) |
|---|
| 23 | { |
|---|
| 24 | DWORD num_read; |
|---|
| 25 | unsigned char b[4]; |
|---|
| 26 | |
|---|
| 27 | SetFilePointer(fd, offset, NULL, FILE_BEGIN); |
|---|
| 28 | if (!ReadFile(fd, b, 4, &num_read, NULL)) |
|---|
| 29 | { |
|---|
| 30 | ExitProcess(-1); |
|---|
| 31 | } |
|---|
| 32 | return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24); |
|---|
| 33 | } |
|---|
| 34 | |
|---|
| 35 | unsigned int to32(void *p) |
|---|
| 36 | { |
|---|
| 37 | unsigned char *b = p; |
|---|
| 38 | return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24); |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | int main(int argc, char *argv[]) |
|---|
| 42 | { |
|---|
| 43 | DWORD num_read; |
|---|
| 44 | HANDLE fd; |
|---|
| 45 | unsigned long pe_header_offset, opthdr_ofs, num_entries, i; |
|---|
| 46 | unsigned long export_rva, export_size, nsections, secptr, expptr; |
|---|
| 47 | unsigned long name_rvas, nexp; |
|---|
| 48 | unsigned char *expdata, *erva; |
|---|
| 49 | unsigned long name_rva; |
|---|
| 50 | unsigned long secptr1; |
|---|
| 51 | unsigned long vaddr; |
|---|
| 52 | unsigned long vsize; |
|---|
| 53 | unsigned long fptr; |
|---|
| 54 | char sname[8]; |
|---|
| 55 | |
|---|
| 56 | if (argc < 2) |
|---|
| 57 | { |
|---|
| 58 | printf("usage: %s <filename>.dll\n", argv[0]); |
|---|
| 59 | return 0; |
|---|
| 60 | } |
|---|
| 61 | |
|---|
| 62 | fd = CreateFile(argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS, NULL); |
|---|
| 63 | if (fd == INVALID_HANDLE_VALUE) |
|---|
| 64 | { |
|---|
| 65 | return 1; |
|---|
| 66 | } |
|---|
| 67 | |
|---|
| 68 | pe_header_offset = read32(fd, 0x3c); |
|---|
| 69 | opthdr_ofs = pe_header_offset + 4 + 20; |
|---|
| 70 | num_entries = read32(fd, opthdr_ofs + 92); |
|---|
| 71 | |
|---|
| 72 | if (num_entries < 1) |
|---|
| 73 | { |
|---|
| 74 | /* no exports */ |
|---|
| 75 | CloseHandle(fd); |
|---|
| 76 | return 1; |
|---|
| 77 | } |
|---|
| 78 | |
|---|
| 79 | export_rva = read32(fd, opthdr_ofs + 96); |
|---|
| 80 | export_size = read32(fd, opthdr_ofs + 100); |
|---|
| 81 | nsections = read16(fd, pe_header_offset + 4 + 2); |
|---|
| 82 | secptr = (pe_header_offset + 4 + 20 + read16(fd, pe_header_offset + 4 + 16)); |
|---|
| 83 | |
|---|
| 84 | expptr = 0; |
|---|
| 85 | for (i = 0; i < nsections; i++) |
|---|
| 86 | { |
|---|
| 87 | secptr1 = secptr + 40 * i; |
|---|
| 88 | vaddr = read32(fd, secptr1 + 12); |
|---|
| 89 | vsize = read32(fd, secptr1 + 16); |
|---|
| 90 | fptr = read32(fd, secptr1 + 20); |
|---|
| 91 | SetFilePointer(fd, secptr1, NULL, FILE_BEGIN); |
|---|
| 92 | if (!ReadFile(fd, sname, 8, &num_read, NULL)) |
|---|
| 93 | { |
|---|
| 94 | ExitProcess(-1); |
|---|
| 95 | } |
|---|
| 96 | if (vaddr <= export_rva && vaddr+vsize > export_rva) |
|---|
| 97 | { |
|---|
| 98 | expptr = fptr + (export_rva - vaddr); |
|---|
| 99 | if (export_rva + export_size > vaddr + vsize) |
|---|
| 100 | { |
|---|
| 101 | export_size = vsize - (export_rva - vaddr); |
|---|
| 102 | } |
|---|
| 103 | break; |
|---|
| 104 | } |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | expdata = (unsigned char*)malloc(export_size); |
|---|
| 108 | SetFilePointer(fd, expptr, NULL, FILE_BEGIN); |
|---|
| 109 | if (!ReadFile(fd, expdata, export_size, &num_read, NULL)) |
|---|
| 110 | { |
|---|
| 111 | ExitProcess(-1); |
|---|
| 112 | } |
|---|
| 113 | erva = expdata - export_rva; |
|---|
| 114 | |
|---|
| 115 | nexp = to32(expdata + 24); |
|---|
| 116 | name_rvas = to32(expdata + 32); |
|---|
| 117 | |
|---|
| 118 | printf ("EXPORTS\n"); |
|---|
| 119 | for (i = 0; i<nexp; i++) |
|---|
| 120 | { |
|---|
| 121 | name_rva = to32(erva + name_rvas + i * 4); |
|---|
| 122 | printf ("\t%s @ %ld ;\n", erva + name_rva, 1 + i); |
|---|
| 123 | } |
|---|
| 124 | |
|---|
| 125 | CloseHandle(fd); |
|---|
| 126 | return 0; |
|---|
| 127 | } |
|---|