Original code from 2007
[vt-enable.git] / src / find-pdm.c
1 #include <stdio.h>
2 #include <fcntl.h>
3 #include <unistd.h>
4 #include <string.h>
5
6 #define VER "0.1"
7
8 int main( int argc, char **argv, char **env) {
9         int len, match, ret = 0;
10         off_t pos, extent, pdm;
11         ssize_t qty;
12         unsigned char *device = "/dev/mem";
13         unsigned char *pdm_sig = "$PDM";
14         unsigned char buffer[256];
15         
16  printf("\n"
17         "find-pdm version %s © 2007 TJ http://intuitivenipple.net\n"
18         "Licensed on the terms of GPL version 3\n\n"
19         "Finds Phoenix Dispatch Manager (for supported BIOS's only).\n\n", VER);
20         
21  if (ret == 0) {
22         int i, fd;
23         unsigned char byte_count;
24         unsigned long pdm_address;
25         unsigned char checksum;
26         unsigned int cs, ip, table, offset;
27         
28         if ((fd = open(device, O_RDONLY)) > 0) {
29                 /* get memory extent */
30                 extent = lseek(fd, 0, SEEK_END);
31                 printf("0x%0.16lX Memory size\n", extent);
32                 len = strlen(pdm_sig);
33                 for (pos = 0; pos < (unsigned)extent; pos+=0x10) { 
34                 pos = lseek(fd, pos, SEEK_SET);
35                 if ((qty = read(fd, buffer, 16)) > 0) {
36                          if (buffer[0] == pdm_sig[0]) {
37                                 if (strncmp(pdm_sig, buffer, len) == 0) {
38                                         printf("0x%0.16lX ", pos);
39                                         byte_count = buffer[5];
40                                         if (byte_count > 0) {
41                                         for (checksum = 0, i = 0; i < byte_count; i++)
42                                                 checksum += buffer[i];
43                                         if (checksum == 0) {
44                                         pdm_address = 0;
45                                         for (i=0; i<16; i++) {
46                                                 printf("%0.2X", buffer[i]);
47                                          if (i >= 7 && i <= 10) pdm_address |= ((unsigned long)buffer[i]) << ((i-7) * 8);
48                                         }
49                                          printf(" PDM @ %0.16lX sum: %u\n", pdm_address, checksum);
50                                          pdm = ((pdm_address & 0xFFFF0000) >> 12) | (pdm_address & 0xFFFF);
51                                          pdm = lseek(fd, pdm, SEEK_SET);
52                                          printf("Seek to 0x%0.8lX ", pdm);
53                                         if ((qty = read(fd, buffer, 16)) > 0) {
54                                                 printf("readable\n");
55                                                 if (buffer[0] == 0xEA ) {
56                                                 for (pdm = 0, i = 0; i < 8; i++) {
57                                                  if (i >= 1 && i <= 4) pdm |= ((unsigned long)buffer[i]) << ((i-1) * 8);
58                                                 }
59                                                 cs = (pdm & 0xFFFF0000) >> 16;
60                                                 ip = pdm & 0xFFFF;
61                                                  pdm = (cs << 4) + ip;
62                                                         printf("Jump to 0x%0.4X:%0.4X (0x%0.8lX)\n", cs, ip, pdm);
63                                                         pdm = lseek(fd, pdm, SEEK_SET);
64                                                         // look for indirect indexed call instruction
65                                                         if ((qty = read(fd, buffer, 256)) > 0) {
66                                                                 for (i = 0; i < qty-5; i++) {
67                                                                         if (buffer[i] == 0x2E && buffer[i+1] == 0xFF && buffer[i+2] == 0x95) {
68                                                                                 table = (buffer[i+3]  | (buffer[i+4] << 8)) + (cs << 4);
69                                                                                 printf("Table starts at 0x%0.4X\n", table);
70                                                                                 lseek(fd, table, SEEK_SET);
71                                                                                 if ((qty = read(fd, buffer, 256)) > 0) {
72                                                                                  for (i = 0; table < pdm; i++, table+=2) {
73                                                                                         offset = buffer[i*2] | (buffer[i*2+1] << 8);
74                                                                                         printf("%0.2X (0x%0.8X) 0x%0.4X\n", i, table, offset);
75                                                                                  }
76                                                                                 }
77                                                                                 break;
78                                                                         }
79                                                                 }
80                                                         }
81                                                         else perror("Cannot read instructions at PDM function");
82                                                 }
83                                                 else printf("No jump instruction\n");
84                                         }
85                                         else printf("unreadable\n");
86                                         lseek(fd, pos, SEEK_SET);
87                                   }
88                                          else printf("\n");
89                                  }
90                                         printf("\n");
91                                 }
92                          }
93                 }
94                 else {
95                         break;
96                 }
97                 }
98                 close(fd);
99         }
100         else perror("Cannot open /dev/mem, need superuser privileges to access");
101  }
102         return ret;
103 }