├── .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
--------------------------------------------------------------------------------