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