8 int main( int argc, char **argv, char **env) {
9 int len, match, ret = 0;
10 off_t pos, extent, pdm;
12 unsigned char *device = "/dev/mem";
13 unsigned char *pdm_sig = "$PDM";
14 unsigned char buffer[256];
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);
23 unsigned char byte_count;
24 unsigned long pdm_address;
25 unsigned char checksum;
26 unsigned int cs, ip, table, offset;
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];
41 for (checksum = 0, i = 0; i < byte_count; i++)
42 checksum += buffer[i];
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);
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) {
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);
59 cs = (pdm & 0xFFFF0000) >> 16;
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);
81 else perror("Cannot read instructions at PDM function");
83 else printf("No jump instruction\n");
85 else printf("unreadable\n");
86 lseek(fd, pos, SEEK_SET);
100 else perror("Cannot open /dev/mem, need superuser privileges to access");