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