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