I am trying to redo steps of a Linux 'hacking' tutorial in Windows.
In one step the program is debugged using GDB.
The command ptype is used in order to the class definitions of the class Player which is located in a DLL called GameLogic.dll.
I try to mimic this exact step and use ptype on GDB I installed for Windows using MINGW. However, I cannot see any definitions since no symbol file is loaded:
(gdb) ptype Player
No symbol table is loaded. Use the "file" command.
A symbol file GameLogic.pdb is located inside the DLL directoy. It is provided intentionally to investigate the program's structure further.
Yet, using the file command I cannot load it into the program:
(gdb) file "E:/xx/PwnAdventure3/Binaries/Win32
/GameLogic.pdb"
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
"E:/xx/PwnAdventure3/Binaries/Win32
/GameLogic.pdb": not in executable format: File format not recognized
This error could be due to the different executable format used by Windows.
However, there are other methods which I found online while researching this issue:
add-symbol-file filename address
set debug-file-directory <directory>
I cannot figure out how I should use these in this particular case. Since in the examples they provide a .o file as filename. Even though I could provide the .pdb file I also need an address (I suppose it's the address at which the DLL is loaded?).
Defining a different directory via set debug-file-directory <directory> which contains the .pdb file does not work.
I also tried different debuggers like OllDBG, WINDBG, Visual Studio and IDA Pro. In Visual Studio I can see that the symbols where loaded but I cannot find any method to further dig into the disassembled file. Only in OllyDBG I can see that the methods which belong to the Player class, e.g., Player::SetJumpState(bool) are correctly depicted.
I also must admit that I don't have much experience with these tools.
Which steps are necessary in order to load the symbols for the DLL file in GDB additionally so that the ptype command works?
Is there another (better) method using one of the mentioned programs to recreate the Player class along with it's local variables?
Regards
Unfortunately GDB does not support reading symbols from PDB files currently, even on Windows. WinDBG/Visual studio should work though.
Related
When debugging a c++ solution in Visual Studio 2010, It says "No symbols have been loaded for this document." And when I check in debug / modules / <dll I cant debug>.dll / symbol load information It is looking for a pdb with the wrong name.
So, where can I set the name of the symbol it is looking for? I looked all through the command line options, and I can't find such a name anywhere.
I've tried to do a rebuild, a clean + build, but neither helped.
There are two places in which .pdb information is collected
1) C++/Output Files/Program Database Filename
2) Linker/Debugging/Generate Program Database file
By default, 2 is set but 1 is normally set to v100.pdb (for VS2010). If both these files are set to point to the same file, then you should get the symbolic information.
Try searching all PDBs (and .idb) and manually delete them.
The reason some include path is set to that library's directory that contains your PDBs, its .pdb file seems to be used by the VS debugger.
The solution is to delete these .pdb files or to rebuild all libraries.
My C++ project folder structure is as shown below.
I am trying to debug the program using gdb in my linux machine. My main function is in g2o.cpp which is inside g2o_cli folder. I am able to put breakpoints in the files in this folder by
break g2o.cpp:<line_number>
But I am not able to put breakpoints in the files in other folders, for example, a file optimizer.cpp in the 'core' folder. I tried giving the absolute path from my home directory
break ~/HOME/g2o/core/optimizer.cpp:<line_number>
but it is giving an error
No source file named ~/HOME/g2o/core/optimizer.cpp
I also tried ../../core/optimizer.cpp instead of the absolute path. Still it did not work.
I saw a similar question here. But none of the possible reasons mentioned in the answer is applicable in my case. The file optimizer.cpp is not a shared library and the entire project was compiled using cmake.
How does gdb take folder paths? How can I give the relative folder path?
A dirty hack you can use on x86 is to use int3. Just use the statement asm volatile ("int 3"); in the code where you want the breakpoint.
I have a C++ project in Ubuntu 12.04. To run the project the make file requires the following files:
1-All the .cpp files
2-All the .h files
3-Three shared libraries.
The project is fully functionall and performs according to the specifications. All the required .cpp files and .h files are available. The problem is that there is no main() function in any of the source files and the program entry point resides in one of the three shared libraries. My job is to find out the program execution pipeline and without having any main file I am not able to do that. I can't run the project in any IDE (i.e: eclipse) because there is no main function available.
Question: Can you please tell me how to find the program entry point?
P.S: I will be glad to provide any kind of information or material you may need to solve my problem.
Edit: The CMakeLists.txt file available here.
Edit 2: The build.sh file available here.
To find enty point look into each shared object with:
nm $library | egrep "T main$"
Library with main() will output something like
090d8ab0 T main
Very usefull way to visualize execution tree is to run:
valgrind --tool=callgrind ./my_executable -arg -arg ....
(you can abort execution early with Ctrl+C)
This will output callgrind.<pid> file. To visualize it run kcachegrind callgrind.<pid>.
You will need valgrind:
sudo apt-get install valgrind
and kcachegrind
sudo apt-get install kcachegrind
Build it with the debug option -g and step into the program with a debugger like gdb (or cgdb or ddd). You'll need any appropriate debug libraries libraries though.
Short of that, play with the code a bit. Try putting printf or cout statements that print internal variables in any functions that look important, and see what the program status is and how frequently they get called. If main is hidden in a library, there's probably another function somewhere that behaves like main for the purposes of the API provided by whatever library has the real main.
What's the API documentation for your libraries? (is this a school project?). It sounds odd to have a hidden main and not say anything about it.
In case you use a build system (CMake, SCons, ...) it is highly possible that the build system is also generating some files, and one of them might be containing the main() method. We use this methodology when we generate the main function in order to instantiate classes for libraries that were specifically selected in CMake-gui.
And again, it is possible that the build system deletes the generated files due to some obscure policy the original developers thought of but didn't tell you. So search through your build system files, see what is actually happening there.
Edit
So, after seeing you CMakeLists.txt:
check ${DIR_EXT}/covis/src/ci.cpp where DIR_EXT is SET( DIR_EXT "../ext/" CACHE PATH "Folder holding external libraries" )
See what's in there and let us know :)
Edit2
After seeing build.sh (execute steps in order):
1.
change
`cmake -D COMPILE_BINARY=ON ..`
to
`cmake -D COMPILE_BINARY=ON -DCMAKE_BUILD_TYPE=Debug ..`
and add the same -DCMAKE_BUILD_TYPE=Debug to the other cmake command too.
This will build your library and executable in debug mode.
2.
Now, in one of the c++ source files you have access to and you are sure will be called (the earlier the function will be calle the better), add:
asm("int $0x03");
This will create a breakpoint in your application.
(If you do not want to use this, see below).
3.
Build your application.
4.
Run it via a debugger in terminal:
gdb ./myapplication <ENTER>
(this will give you a gdb prompt)
(if you did not add the asm breakpoint from above, type in the gdb prompt: break filename.cpp:linenumber or break methodname to add a gdb breakpoint).
run <ENTER>
Now your application should stop in your function when it is executed.
You are still in the gdb prompt, so type:
bt <ENTER>
This will print out the backtrace of your application. Somewhere you should see a main function, together with filename and linenumber.
However, that setnames.sh looks interesting, see if it does not do anything funny :)
I work on program with multiple C++ files. I have run the executable through gdb for debugging segmentation fault. Later, gdb backtrace provided the list of functions before segmentation fault. Later, I tried to set a break point in a file on a particular line-number. (The path specified is absolute path)
(gdb) break /aia/r015/home/sathish/zfs_amr/src/zfslbminterfaced2q9.cpp:100
However, gdb gives the following message:
No source file named /aia/r015/home/sathish/zfs_amr/src/zfslbminterfaced2q9.cpp.
However, this particular does exist in the location. What really the message means?
What really the message means?
The message means that GDB does not know about any source file named /aia/r015/home/sathish/zfs_amr/src/zfslbminterfaced2q9.cpp.
There are multiple reasons this could be the case:
The debug info for this file is missing, either because that file is compiled without -g, or because the debug info was (possibly inadvertantly) stripped later on,
There are some symbolic links in the above path, and GDB knows that file by fully-resolved pathname instead,
The file is actually not linked into the executable at all,
The file part of a shared library, and symbols for that shared library haven't been loaded yet,
Etc.
As Pat suggested, setting breakpoint on zfslbminterfaced2q9.cpp:100 is more likely to work.
If that doesn't work, info sources will tell you which files GDB does know about.
Update:
info sources gives blank
This means that the application doesn't have any debug info at all.
Usually this happens for one of two reasons:
You neglected to specify -g on the link line (some platforms require -g both at compile and link time),
You have a "stray" -s somewhere on your link line (which strips the final executable).
I'm including python.h in my Visual C++ DLL file project which causes an implicit linking with python25.dll. However, I want to load a specific python25.dll (several can be present on the computer), so I created a very simple manifest file named test.manifest:
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<file name="python25.dll" />
</assembly>
And I'm merging it with the automatically embedded manifest file generated by Visual Studio thanks to:
Configuration Properties -> Manifest Tool -> Input and Output -> Additional Manifest Files
-->$(ProjectDir)\src\test.manifest
python25.dll is now loaded twice: the one requested by the manifest, and the one that Windows should find through its search order.
Screendump of Process Explorer http://dl.dropbox.com/u/3545118/python25_dll.png
Why is that happening and how can I just load the DLL file pointed by the manifest?
After exhaustive battle with WinSxS and DLL redirection, here's my advice for you:
Some background
Various things can cause a DLL file to be loaded under Windows:
Explicit linking (LoadLibrary) -- the loader uses the current activation context of the running EXE file. This is intuitive.
Implicit linking ("load time linkage", the "auto" ones) -- the loader uses the default activation context of the depending DLL file. If A.exe depends on B.dll depends on C.dll (all implicit linkage), the loader will use B.dll's activation context when loading C.dll. IIRC, it means if B's DllMain loads C.dll, it can be using B.dll's activation context -- most of the time it means the system-wide default activation context. So you get your Python DLL from %SystemRoot%.
COM (CoCreateInstance) -- this is the nasty one. Extremely subtle. It turns out the loader can look up the full path of a DLL file from the registry using COM (under HKCR\CLSID). LoadLibrary will not do any searching if the user gives it a full path, so the activation context can't affect the DLL file resolution. Those can be redirected with the comClass element and friends, see [reference][msdn_assembly_ref].
Even though you have the correct manifest, sometimes someone can still change the activation context at run time using the Activation Context API. If this is the case, there is usually not much you can do about it (see the ultimate solution below); this is just here for completeness. If you want to find out who is messing with the activation context, WinDbg bp kernel32!ActivateActCtx.
Now on to finding the culprit
The easiest way to find out what causes a DLL file to load is to use Process Monitor. You can watch for "Path containing python25.dll" or "Detail containing python25.dll" (for COM lookups). Double clicking an entry will actually show you a stack trace (you need to set the symbol search paths first, and also set Microsoft's PDB server). This should be enough for most of your needs.
Sometimes the stack trace obtained from above could be spawned from a new thread. For this purpose you need WinDbg. That can be another topic, but suffice to say you can sxe ld python25 and look at what other threads are doing (!findstack MyExeModuleName or ~*k) that causes a DLL file to load.
Real world solution
Instead of fiddling with this WinSxS thing, try hooking LoadLibraryW using Mhook or EasyHook. You can just totally replace that call with your custom logic. You can finish this before lunch and find the meaning of life again.
[msdn_assembly_ref]: Assembly Manifests
I made some progress for the understanding of the issue.
First let me clarify the scenario:
I'm building a DLL file that both embeds and extends Python, using the Python C API and Boost.Python.
Thus, I'm providing a python25.dll in the same folder as my DLL file, as well as a boost_python-vc90-mt-1_39.dll.
Then I have an EXE file which is a demo to show how to link to my DLL file: this EXE file doesn't have to be in the same folder as my DLL file, as long as the DLL file can be found in the PATH (I'm assuming that the end user may or may not put it in the same folder).
Then, when running the EXE file, the current directory is not the one containing python25.dll, and that's why the search order is used and some other python25.dll can be found before mine.
Now I figured out that the manifest technique was the good approach: I managed to redirect the loading to "my" python25.dll.
The problem is that this is the Boost DLL file boost_python-vc90-mt-1_39.dll that's responsible for the "double" loading!
If I don't load this one, then python25.dll is correctly redirected. Now I somehow have to figure out how to tell the Boost DLL file not to load another python25.dll...
Dependency Walker is usually the best tool for resolving this kind of problem. I'm not too sure how well it handles manifests though...
Where in this entangled mess is the actual process executable file?
Two possibilities come to mind:
You are writing a Python extension DLL file. So the Python process is loading your DLL file, and it would already have its own python25.dll dependency.
The EXE file loading your DLL file is being built with header files and libraries provided by the DLL file project. So it is inheriting the #pragma comment(lib,"python25.lib") from your header file and as a result is loading the DLL file itself.
My problem with the second scenario is, I'd expect the EXE file, and your DLL file, to be in the same folder in the case that the EXE file is implicitly loading your DLL file. In which case the EXE file, your DLL file and the python25.dll are all already in the same folder. Why then would the system32 version ever be loaded? The search order for implicitly loaded DLL files is always in the application EXE file's folder.
So the actual interesting question implicit in your query is: How is the system32 python26.dll being loaded at all?
Recently, I hit a very similar problem:
My application embedding Python loads the python32.dll from a known location, that is a side-by-side assembly (WinSxS) with Python.manifest
Attempt to import tkinter inside the embedded Python interpreter caused second loading of the very same python32.dll, but under a different non-default address.
The initialisation function of tkinter module (specifically, _tkinter.pyd) was failing because to invalid Python interpreter thread state (_PyThreadState_Current == NULL). Obviously, Py_Initialize() was never called for the second Python interpreter loaded from the duplicate python32.dll.
Why was the python32.dll loaded twice? As I explained in my post on python-capi, this was caused by the fact the application was loading python32.dll from WinSxS, but _tkinter.pyd did not recognise the assembly, so python32.dll was loaded using the regular DLL search path.
The Python.manifest + python32.dll assembly was recognised by the DLL loading machinery as a different module (under different activation context), than the python32.dll requested by _tkinter.pyd.
Removing the reference to Python.manifest from the application embedding Python and allowing the DLL search path to look for the DLLs solved the problem.