├── .gitattributes ├── .gitignore ├── LICENSE.md ├── README.md ├── Symex.sln ├── Symex ├── Symex.vcxproj ├── Symex.vcxproj.filters ├── icons │ └── logo.ico ├── main.cpp └── resource.rc └── bin └── Symex.exe /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Arthur Gerkis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Symex 2 | 3 | ## About and usage 4 | 5 | This is a tool to resolve symbols of running application. You provide 6 | application PID, module name and offset (or address) to resolve. 7 | 8 | ``` 9 | Symex\Release>Symex.exe --pid 11008 -m chrome_child.dll -o 1122334 -v 10 | Symex - symbol resolver, v 0.3 11 | Using default programSymbolPath = C:\Symbols 12 | dwBaseAddr = 261095424 13 | DBGHELP: C:\Symbols\chrome_child.dll.pdb\2BD21F87ADDF496AB15BE30C003CEBD01\chrome_child.dll.pdb - mismatched pdb 14 | DBGHELP: C:\Symbols\chrome_child.dll.pdb\41B9BDD32ABE4E59844480CE83A0A21F1\chrome_child.dll.pdb - mismatched pdb 15 | DBGHELP: chrome_child - private symbols & lines 16 | C:\Symbols\chrome_child.dll.pdb\4E70D83A8AB644FE908B17EC5187BB3C1\chrome_child.dll.pdb 17 | blink::ScrollingCoordinator::scrollableAreaScrollbarLayerDidChange+0x262 18 | ``` 19 | 20 | If you provide no -v (vebose output), then you will receive only 21 | resolved symbol (last line in paste). 22 | 23 | By default Symex considers that symbols are in C:\\Symbols. You can 24 | overide this with -s (or --symbol-path). 25 | 26 | ## Disclaimer 27 | 28 | Some parts of code are taken somewhere from internet. 29 | -------------------------------------------------------------------------------- /Symex.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Symex", "Symex\Symex.vcxproj", "{570B40A0-451A-4E24-AB8E-DEE91217980B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {570B40A0-451A-4E24-AB8E-DEE91217980B}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {570B40A0-451A-4E24-AB8E-DEE91217980B}.Debug|Win32.Build.0 = Debug|Win32 16 | {570B40A0-451A-4E24-AB8E-DEE91217980B}.Release|Win32.ActiveCfg = Release|Win32 17 | {570B40A0-451A-4E24-AB8E-DEE91217980B}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Symex/Symex.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {570B40A0-451A-4E24-AB8E-DEE91217980B} 15 | Symex 16 | 17 | 18 | 19 | Application 20 | true 21 | v120 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | AllRules.ruleset 43 | true 44 | 45 | 46 | 47 | Level3 48 | Disabled 49 | true 50 | 51 | 52 | true 53 | 54 | 55 | 56 | 57 | Level3 58 | MaxSpeed 59 | true 60 | true 61 | true 62 | MultiThreaded 63 | true 64 | 65 | 66 | true 67 | true 68 | true 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /Symex/Symex.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Resource Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /Symex/icons/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ax330d/Symex/e99ce7998936c846f677d61abc145bf1804b5373/Symex/icons/logo.ico -------------------------------------------------------------------------------- /Symex/main.cpp: -------------------------------------------------------------------------------- 1 | // Symbol resolver 2 | // 3 | // v 0.1 - 29/01/2015 4 | // v 0.2 - 26/02/2016 5 | // v 0.3 - 16/04/2016 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "Psapi.h" 16 | // Link with the dbghelp import library 17 | #pragma comment(lib, "dbghelp.lib") 18 | 19 | #ifdef UNICODE 20 | #define DBGHELP_TRANSLATE_TCHAR 21 | #endif 22 | #include 23 | 24 | 25 | struct CSymbolInfoPackage : public SYMBOL_INFO_PACKAGE 26 | { 27 | CSymbolInfoPackage() 28 | { 29 | si.SizeOfStruct = sizeof(SYMBOL_INFO); 30 | si.MaxNameLen = sizeof(name); 31 | } 32 | }; 33 | 34 | 35 | BOOL 36 | CALLBACK 37 | SymRegisterCallbackProc64( 38 | __in HANDLE hProcess, 39 | __in ULONG ActionCode, 40 | __in_opt ULONG64 CallbackData, 41 | __in_opt ULONG64 UserContext 42 | ) 43 | { 44 | UNREFERENCED_PARAMETER(hProcess); 45 | UNREFERENCED_PARAMETER(UserContext); 46 | 47 | PIMAGEHLP_CBA_EVENT evt; 48 | 49 | // If SYMOPT_DEBUG is set, then the symbol handler will pass 50 | // verbose information on its attempt to load symbols. 51 | // This information be delivered as text strings. 52 | 53 | switch (ActionCode) 54 | { 55 | case CBA_EVENT: 56 | evt = (PIMAGEHLP_CBA_EVENT)CallbackData; 57 | _tprintf(_T("%s"), (PTSTR)evt->desc); 58 | break; 59 | 60 | // CBA_DEBUG_INFO is the old ActionCode for symbol spew. 61 | // It still works, but we use CBA_EVENT in this example. 62 | #if 0 63 | case CBA_DEBUG_INFO: 64 | _tprintf(_T("%s"), (PTSTR)CallbackData); 65 | break; 66 | #endif 67 | 68 | default: 69 | // Return false to any ActionCode we don't handle 70 | // or we could generate some undesirable behavior. 71 | return FALSE; 72 | } 73 | 74 | return TRUE; 75 | } 76 | 77 | 78 | //You don't have to use this function if you don't want to.. 79 | int strcompare(const char* One, const char* Two, bool CaseSensitive) 80 | { 81 | #if defined _WIN32 || defined _WIN64 82 | return CaseSensitive ? strcmp(One, Two) : _stricmp(One, Two); 83 | #else 84 | return CaseSensitive ? strcmp(One, Two) : strcasecmp(One, Two); 85 | #endif 86 | } 87 | 88 | 89 | //You read module information like this.. 90 | MODULEENTRY32 GetModuleInfo(int ProcessID, char* ModuleName) 91 | { 92 | void* hSnap = nullptr; 93 | MODULEENTRY32 Mod32 = { 0 }; 94 | 95 | if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)) == 96 | INVALID_HANDLE_VALUE) 97 | return Mod32; 98 | 99 | Mod32.dwSize = sizeof(MODULEENTRY32); 100 | while (Module32Next(hSnap, &Mod32)) 101 | { 102 | if (!strcompare(ModuleName, Mod32.szModule, false)) 103 | { 104 | CloseHandle(hSnap); 105 | return Mod32; 106 | } 107 | } 108 | 109 | CloseHandle(hSnap); 110 | return{ 0 }; 111 | } 112 | 113 | 114 | VOID usage() 115 | { 116 | printf( 117 | "Symex is a tool to resolve symbols by address or offset.\n" 118 | "Made by Arthur Gerkis.\n\n" 119 | "Options:\n" 120 | " -p | --pid process PID (required)\n" 121 | " -m | --module module name (required)\n" 122 | " -o | --offset offset (required, either this or --address)\n" 123 | " -a | --address address to resolve (required, either this or --offset)\n" 124 | " -s | --symbol-path path to your symbols (defaults to C:\\Symbols)\n" 125 | " -v | --v verbosity (defaults to FALSE)\n\n" 126 | "Example: symex.exe -p 1234 -m mshtml.dll -o 0x1234\n" 127 | "Example: symex.exe -p 1234 -m mshtml.dll -a 0x41414141\n\n" 128 | ); 129 | } 130 | 131 | 132 | VOID cleanup(HANDLE hProcess) 133 | { 134 | if (SymCleanup(hProcess)) 135 | { 136 | CloseHandle(hProcess); 137 | } 138 | else 139 | { 140 | printf("[?/?] SymCleanup returned error : %ul\n", GetLastError()); 141 | } 142 | } 143 | 144 | 145 | int main(int argc, char* argv[]) 146 | { 147 | int pid = -1; 148 | int offset = -1; 149 | int address = -1; 150 | char moduleName[MAX_MODULE_NAME32] = { 0 }; 151 | char symbolPath[MAX_PATH] = { 0 }; 152 | 153 | HANDLE hProcess; 154 | BOOL verbose = FALSE; 155 | 156 | struct { 157 | SYMBOL_INFO info; 158 | char buf[MAX_SYM_NAME]; 159 | } info = { 0 }; 160 | 161 | for (int i = 0; i < argc; i += 1) 162 | { 163 | if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--pid") == 0) 164 | { 165 | sscanf_s(argv[i + 1], "%i", &pid); 166 | } else 167 | if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--module") == 0) 168 | { 169 | sscanf_s(argv[i + 1], "%s", moduleName, 170 | (unsigned)_countof(moduleName)); 171 | } else 172 | if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--symbol-path") == 0) 173 | { 174 | sscanf_s(argv[i + 1], "%s", symbolPath, 175 | (unsigned)_countof(symbolPath)); 176 | } else 177 | if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--offset") == 0) 178 | { 179 | sscanf_s(argv[i + 1], "%i", &offset); 180 | } else 181 | if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--address") == 0) 182 | { 183 | sscanf_s(argv[i + 1], "%i", &address); 184 | } 185 | else 186 | if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) 187 | { 188 | verbose = TRUE; 189 | } 190 | } 191 | 192 | if (verbose) { 193 | printf("Symex - symbol resolver, v 0.3\n"); 194 | } 195 | 196 | if (pid == -1 || (offset == -1 && address == -1) || !strlen(moduleName)) { 197 | usage(); 198 | return FALSE; 199 | } 200 | 201 | // 202 | // Set Symbol options 203 | // 204 | if (verbose) { 205 | SymSetOptions(SYMOPT_DEBUG | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); 206 | } 207 | else { 208 | SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); 209 | } 210 | 211 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid); 212 | 213 | 214 | // 215 | // Initialise symbol handler 216 | // 217 | 218 | char programSymbolPath[MAX_PATH] = { 0 }; 219 | if (strlen(symbolPath)) 220 | { 221 | strcpy_s(programSymbolPath, sizeof(programSymbolPath), symbolPath); 222 | if (verbose) { 223 | printf("Using provided programSymbolPath = %s\n", 224 | programSymbolPath); 225 | } 226 | 227 | } 228 | else { 229 | strcpy_s(programSymbolPath, sizeof(programSymbolPath), "C:\\Symbols"); 230 | if (verbose) { 231 | printf("Using default programSymbolPath = %s\n", 232 | programSymbolPath); 233 | } 234 | 235 | } 236 | 237 | if (!SymInitialize(hProcess, programSymbolPath, TRUE)) 238 | { 239 | printf("[1/5] SymInitialize returned error : 0x%x\n", 240 | GetLastError()); 241 | cleanup(hProcess); 242 | return FALSE; 243 | } 244 | 245 | 246 | // 247 | // Register callbacks 248 | // 249 | 250 | if (!SymRegisterCallback64(hProcess, SymRegisterCallbackProc64, NULL)) 251 | { 252 | printf("[2/5] SymRegisterCallback64 returned error : 0x%x\n", 253 | GetLastError()); 254 | cleanup(hProcess); 255 | return FALSE; 256 | } 257 | 258 | 259 | // 260 | // Loading symbol module 261 | // 262 | 263 | DWORD64 dwBaseAddr = (DWORD64)GetModuleInfo(pid, moduleName).modBaseAddr; 264 | if (verbose) { 265 | printf("dwBaseAddr = %I64u\n", 266 | dwBaseAddr); 267 | } 268 | 269 | if (!SymLoadModuleEx(hProcess, // target process 270 | NULL, // handle to image - not used 271 | (PCSTR)moduleName, // name of image file 272 | NULL, // name of module - not required 273 | dwBaseAddr, // base address - not required 274 | 0, // size of image - not required 275 | NULL, // MODLOAD_DATA used for special cases 276 | 0)) // flags - not required 277 | { 278 | printf("[3/5] SymLoadModuleEx returned error : 0x%x\n", 279 | GetLastError()); 280 | cleanup(hProcess); 281 | return FALSE; 282 | } 283 | 284 | 285 | // 286 | // Retrieve symbol information by address 287 | // 288 | 289 | DWORD64 dwAddress; 290 | if (address != -1) { 291 | dwAddress = address; 292 | } 293 | else if (offset != -1) { 294 | dwAddress = dwBaseAddr + offset; 295 | } 296 | else { 297 | usage(); 298 | cleanup(hProcess); 299 | return FALSE; 300 | } 301 | 302 | info.info.SizeOfStruct = sizeof(info.info); 303 | info.info.ModBase = dwBaseAddr; 304 | info.info.MaxNameLen = MAX_SYM_NAME; 305 | DWORD64 displacement = 0; 306 | if (!SymFromAddr(hProcess, dwAddress, &displacement, &info.info)) 307 | { 308 | printf("[4/5] SymFromAddr returned error : 0x%x\n", 309 | GetLastError()); 310 | cleanup(hProcess); 311 | return FALSE; 312 | } 313 | else 314 | { 315 | printf("%s+0x%I64u\n", info.info.Name, displacement); 316 | } 317 | 318 | // 319 | // Unloading module 320 | // 321 | 322 | if (SymUnloadModule64(hProcess, (DWORD64)dwBaseAddr)) 323 | { 324 | cleanup(hProcess); 325 | return TRUE; 326 | } 327 | else 328 | { 329 | printf("[5/5] SymUnloadModule64 returned error : 0x%x\n", 330 | GetLastError()); 331 | cleanup(hProcess); 332 | return FALSE; 333 | } 334 | 335 | return TRUE; 336 | } -------------------------------------------------------------------------------- /Symex/resource.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON "icons\logo.ico" 2 | 3 | #include 4 | 5 | VS_VERSION_INFO VERSIONINFO 6 | FILEVERSION 1,0,3 7 | PRODUCTVERSION 1,0,3 8 | BEGIN 9 | BLOCK "StringFileInfo" 10 | BEGIN 11 | BLOCK "040904E4" 12 | BEGIN 13 | VALUE "CompanyName", "Arthur Gerkis" 14 | VALUE "FileDescription", "Resolves symbols\0" 15 | VALUE "FileVersion", "1, 0, 3\0" 16 | VALUE "InternalName", "Symex\0" 17 | VALUE "LegalCopyright", "Copyright (C) 2016\0" 18 | VALUE "LegalTrademarks", "\0" 19 | VALUE "OriginalFilename", "symex.exe\0" 20 | VALUE "ProductName", "Symex\0" 21 | VALUE "ProductVersion", "1, 0, 3\0" 22 | END 23 | END 24 | 25 | BLOCK "VarFileInfo" 26 | BEGIN 27 | VALUE "Translation", 0x409, 1252 28 | END 29 | END 30 | -------------------------------------------------------------------------------- /bin/Symex.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ax330d/Symex/e99ce7998936c846f677d61abc145bf1804b5373/bin/Symex.exe --------------------------------------------------------------------------------