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 ((INT_PTR)UserContext == -1)
59 	{
60 		printf("%s ", pSymInfo->Name);
61 	}
62 	else
63 	{
64 		if (!bX64)
65 		{
66 			printf("%s@%Iu ", pSymInfo->Name, (UINT_PTR)UserContext);
67 		}
68 		else
69 		{
70 			printf("%s <+ %Iu> ", pSymInfo->Name, (UINT_PTR)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_PTR)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_PTR)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 }
236