syscalldump: use debghelp function to get the address inside the file image. Hopefull...
[reactos.git] / rosapps / devutils / syscalldump / syscalldump.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <ctype.h>
4 #define _WINVER 0x501
5 #include <windows.h>
6 #include <shlwapi.h>
7 #include <dbghelp.h>
8
9 HANDLE hCurrentProcess;
10
11 #define MAX_SYMBOL_NAME 1024
12
13 BOOL InitDbgHelp(HANDLE hProcess)
14 {
15 if (!SymInitialize(hProcess, 0, FALSE))
16 return FALSE;
17
18 SymSetOptions(SymGetOptions() | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS);
19 SymSetOptions(SymGetOptions() & (~SYMOPT_DEFERRED_LOADS));
20 SymSetSearchPath(hProcess, "srv**symbols*http://msdl.microsoft.com/download/symbols");
21 return TRUE;
22 }
23
24 DWORD64
25 GetOffsetFromName(HANDLE hProcess, PSYMBOL_INFO pSym, PBYTE pModule, PCSTR Name, PBOOL pbX64)
26 {
27 PIMAGE_NT_HEADERS NtHeaders;
28 PVOID p;
29
30 pSym->SizeOfStruct = sizeof(SYMBOL_INFO);
31 pSym->MaxNameLen = MAX_SYMBOL_NAME-1;
32
33 if (!SymFromName(hProcess, Name, pSym))
34 {
35 printf("SymGetSymFromName64() failed: %ld\n", GetLastError());
36 return 0;
37 }
38 printf("looking up adress for %s: 0x%llx\n", Name, pSym->Address);
39
40 NtHeaders = ImageNtHeader(pModule);
41 *pbX64 = (NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386);
42
43 p = ImageRvaToVa(NtHeaders, pModule, pSym->Address - pSym->ModBase, NULL);
44
45 return (DWORD64)((ULONG_PTR)p - (ULONG_PTR)pModule);
46 }
47
48 BOOL CALLBACK EnumSymbolsProc(
49 PSYMBOL_INFO pSymInfo,
50 ULONG SymbolSize,
51 PVOID UserContext)
52 {
53 if ((UINT)UserContext == -1)
54 {
55 printf("%s ", pSymInfo->Name);
56 }
57 else
58 {
59 printf("%s@%d ", pSymInfo->Name, (UINT)UserContext);
60 }
61 return TRUE;
62 }
63
64 int main(int argc, char* argv[])
65 {
66 HANDLE hProcess;
67 CHAR szModuleFileName[MAX_PATH+1];
68 DWORD64 dwModuleBase;
69 HANDLE hFile = 0, hMap = 0;
70 PBYTE pModule = NULL;
71 UINT i;
72 BOOL bX64;
73 DWORD64 dwW32pServiceTable, dwW32pServiceLimit, dwW32pArgumentTable;
74 DWORD64 dwSimpleCall;
75 PVOID *pfnSimpleCall;
76 DWORD dwServiceLimit;
77 BYTE *pdwArgs;
78
79 struct
80 {
81 SYMBOL_INFO Symbol;
82 CHAR Name[MAX_SYMBOL_NAME];
83 } Sym;
84
85 printf("Win32k Syscall dumper\n");
86 printf("Copyright (c) Timo Kreuzer 2007\n");
87
88 hProcess = GetCurrentProcess();
89
90 // try current dir
91 GetCurrentDirectory(MAX_PATH, szModuleFileName);
92 strcat(szModuleFileName, "\\win32k.sys");
93 hFile = CreateFile(szModuleFileName, FILE_READ_DATA, FILE_SHARE_READ, NULL,
94 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
95 if (hFile != INVALID_HANDLE_VALUE)
96 {
97 goto cont;
98 }
99
100 // try system dir
101 GetSystemDirectory(szModuleFileName, MAX_PATH);
102 strcat(szModuleFileName, "\\win32k.sys");
103 hFile = CreateFile(szModuleFileName, FILE_READ_DATA, FILE_SHARE_READ, NULL,
104 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
105 if (hFile == INVALID_HANDLE_VALUE)
106 {
107 printf("CreateFile() failed: %ld!\n", GetLastError());
108 goto cleanup;
109 }
110
111 cont:
112 printf("Trying to get syscalls from: %s\n", szModuleFileName);
113
114 if (!InitDbgHelp(hProcess))
115 {
116 printf("SymInitialize() failed\n");
117 goto cleanup;
118 }
119
120 printf("Loading symbols for %s, please wait...\n", szModuleFileName);
121 dwModuleBase = SymLoadModule64(hProcess, 0, szModuleFileName, 0, 0, 0);
122 if (dwModuleBase == 0)
123 {
124 printf("SymLoadModule64() failed: %ld\n", GetLastError());
125 goto cleanup;
126 }
127
128 hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
129 if (!hMap)
130 {
131 printf("CreateFileMapping() failed: %ld\n", GetLastError());
132 goto cleanup;
133 }
134
135 pModule = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
136 if(!pModule)
137 {
138 printf("MapViewOfFile() failed: %ld\n", GetLastError());
139 goto cleanup;
140 }
141
142 dwW32pServiceTable = GetOffsetFromName(hProcess, &Sym.Symbol, pModule, "W32pServiceTable", &bX64);
143 dwW32pServiceLimit = GetOffsetFromName(hProcess, &Sym.Symbol, pModule, "W32pServiceLimit", &bX64);
144 dwW32pArgumentTable = GetOffsetFromName(hProcess, &Sym.Symbol, pModule, "W32pArgumentTable", &bX64);
145 printf("dwW32pServiceTable = %llx\n", dwW32pServiceTable);
146 printf("dwW32pServiceLimit = %llx\n", dwW32pServiceLimit);
147 printf("dwW32pArgumentTable = %llx\n", dwW32pArgumentTable);
148
149 if (!dwW32pServiceTable || !dwW32pServiceLimit || !dwW32pArgumentTable)
150 {
151 printf("Couldn't find adress!\n");
152 goto cleanup;
153 }
154
155 dwServiceLimit = *((DWORD*)(pModule + dwW32pServiceLimit));
156 pdwArgs = (BYTE*)(pModule + dwW32pArgumentTable);
157
158 if (!bX64)
159 {
160 DWORD *pdwEntries32 = (DWORD*)(pModule + dwW32pServiceTable);
161
162 for (i = 0; i < dwServiceLimit; i++)
163 {
164 printf("0x%x:", i+0x1000);
165 SymEnumSymbolsForAddr(hProcess, (DWORD64)pdwEntries32[i], EnumSymbolsProc, (PVOID)(DWORD)pdwArgs[i]);
166 printf("\n");
167 }
168 }
169 else
170 {
171 DWORD64 *pdwEntries64 = (DWORD64*)(pModule + dwW32pServiceTable);
172
173 for (i = 0; i < dwServiceLimit; i++)
174 {
175 printf("0x%x:", i+0x1000);
176 SymEnumSymbolsForAddr(hProcess, (DWORD64)pdwEntries64[i], EnumSymbolsProc, (PVOID)(i+0x1000));
177 printf("\n");
178 }
179 }
180
181 /* Dump apfnSimpleCall */
182 printf("\nDumping apfnSimpleCall:\n");
183 dwSimpleCall = GetOffsetFromName(hProcess, &Sym.Symbol, pModule, "apfnSimpleCall", &bX64);
184 pfnSimpleCall = (PVOID*)(pModule + dwSimpleCall);
185 i = 0;
186 while (pfnSimpleCall[i] != NULL)
187 {
188 printf("0x%x:", i);
189 SymEnumSymbolsForAddr(hProcess, (DWORD64)(ULONG_PTR)pfnSimpleCall[i], EnumSymbolsProc, (PVOID)-1);
190 printf("\n");
191 i++;
192 }
193
194
195 cleanup:
196 if (pModule)
197 {
198 UnmapViewOfFile(pModule);
199 }
200 if (hMap)
201 {
202 CloseHandle(hMap);
203 }
204 if (hFile)
205 {
206 CloseHandle(hFile);
207 }
208
209 return 0;
210 }