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