Just started to step my kernel mode usb driver and it is in assembler. How do I configure WinDbg to c-level debugging? This is how i looks now =/
MyDriver!MyDriver_EvtDeviceAdd+0xb:
af20801b 833d647020af03 cmp dword ptr [MyDriver!DebugLevel (af207064)],3
0: kd> p
MyDriver!MyDriver_EvtDeviceAdd+0x2e:
af20803e ff15006020af call dword ptr [MyDriver!_imp__KeGetCurrentIrql (af206000)]
0: kd> p
MyDriver!MyDriver_EvtDeviceAdd+0x58:
af208068 8d95a8feffff lea edx,[ebp-158h]
0: kd> p
MyDriver!MyDriver_EvtDeviceAdd+0x64:
af208074 c785bcfeffff508420af mov dword ptr [ebp-144h],offset MyDriver!MyDriver_EvtDevicePrepareHardware (af208450)
WinDbg cannot find pdb files. Fill properly all WinDbg paths:
Symbol search path - must include driver .pdb files and local path for MS debugging symbols.
Source search path - must include directory with driver source files.
Image file path - must contain driver .sys file.
Look at WinDbg log: it reports all errors trying to load debug information. If you see something like "Cannot load debug information for your_driver.sys", something is wrong.
Your symbols look fine based on the output above. If you're not getting your source window popping up, you're typically in one of two cases:
1) You've moved your source code from where you originally built it. By default, the PDBs have the fully qualified path to the orignal source code location. If you move it, WinDBG won't be able to find it. You can see where WinDBG is looking by doing:
u MyDriver!MyDriver_EvtDeviceAdd
That should give you the full path of the source module containing that function embedded in the PDB. You can override this path by setting your Source Search Path to point to the new location.
2) You've managed to hide the source window somehow. Seems silly, but happens to my students all the time :) Check under the "Window" menu item in WinDBG to see if the window is open somewhere.
To clarify an earlier point, you do not need to set your Image File Path in this case. The only time that is required is if you're debugging a mini-dump.
-scott
You need to ensure you are generating "Codeview"/debug symbols for your driver, and the file generated is accessible to Windbg.
Related
I wanted to debug printf function, so when I step inside the printf function (gdb debugger) it showed me this:
__printf (format=0x80484d0 " my name is Adam") at printf.c:28
28 printf.c: No such file or directory.
What is the meaning of this?
And when I again started step then there are a lot more statements like this.
Please help me to understand this.
I think it's pretty clear. There is a place where the gdb expects the source code to be, so download glibc's source code and put it there. I think the error message contains the full path.
If it's a linux distro it's fairly simple in fact because usually source packages are shipped too. Otherwise you need to find the source code yourself, note that it MUST be exactly the same that was used to compile the c library components, not just the same version because distributors often make changes to the sources.
Well, for the debugger to show you the code that was compiled into the binaries you're using, you need the original code somewhere.
You don't seem to have that, so your debugger can't find it.
Notice that you usually do not want to debug the source code of your std library functions, but only the way they are being called. For that, the usual "debug symbol" packages of your operating systems are optimal.
As others have answered, GDB was unable to find the source file.
For the C runtime libraries, Linux distributions may provide a debuginfo RPM that you can install, which may allow GDB to view the files. For example:
$ yum search glibc-debuginfo
...
glibc-debuginfo.x86_64 : Debug information for package glibc
glibc-debuginfo-common.x86_64 : Debug information for package glibc
...
The glibc package and the glibc-debuginfo are a matched pair. There is no explicit dependency, but glibc-debuginfo package won't work unless it is matched with the same version of glibc.
If you have the sources unpacked somewhere, but not where GDB is expecting them to be, you can attempt to use either the directory or the set substitute-path command to let GDB know where the sources are.
The directory command tells GDB to prepend a prefix ahead of any source file path it is attempting to find. For example, if the source tree is actually located under the /tmp, you could use:
(gdb) directory /tmp
The set substitute-path command is used to tell GDB to replace a matching prefix in a source file path with a different path prefix. For example, if the compiled source file was in /build/path/source.c, but in debugging the source file is actually in /usr/home/alice/release-1.1/source.c, then you could use:
(gdb) set substitute-path /build/path /usr/home/alice/release-1.1
The command assumes that you are only specifying a complete path names, so it won't perform the substitution on /build/pathological/source.c.
I tried loading the DLL file "bcryptprimitives.dll" (which in my case, originally sits under "C:\Windows\syswow64\bcryptprimitives.dll") from another location, with this snippet of code:
LoadLibraryW(L"<altered path>\\bcryptprimitives.dll");
However, right after executing this line of code I get the following error:
C:\Program Files (x86)\Notepad++\bcryptprimitives.dll is either not designed to run on Windows or it contains an error. Try installing the program again using the original installation media or contact your system administrator or the software vendor for support. Error status 0xc0000428.
I searched the 0xc0000428 NTSTATUS in the following dictionary: https://msdn.microsoft.com/en-us/library/cc704588.aspx
and apparently this status means STATUS_INVALID_IMAGE_HASH.
The error at first makes sense, because I changed the "LoaderFlags" field in the image PE header from 0x00000000 to 0x00000001 (which doesn't need to affect anything because this field is deprecated), but even though I changed the field, I fixed the PE checksum.
As you can see:
However, LoadLibrary still refuses to load the DLL.
Diving deep into ntdll reveals that the error is returned from kernel:
It makes me think that the DLL is somehow signed and the kernel checks whether the DLL was altered.
So to my point, how can I load this DLL from another location anyway and remove the sign check?
If a DLL is signed, then by changing a single byte in the file will invalidate the signature. It appears you are doing exactly that by modifying PE header.
This blog post might be of interest to for deeper insight how this technology works:
Code Integrity is a feature that improves the security of the operating system by validating the integrity of a driver or system file each time it is loaded into memory. Code Integrity detects whether an unsigned driver or system file is being loaded into the kernel, or whether a system file has been modified by malicious software that is being run by a user account with administrative permissions. On x64-based versions of the operating system, kernel-mode drivers must be digitally signed.
Found a quick solution:
DWORD dwIndex = 0;
hFile = CreateFileW(L"C:\\Program Files (x86)\\Notepad++\\bcryptprimitives.dll", FILE_READ_DATA | FILE_WRITE_DATA, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
while (ImageRemoveCertificate(hFile, dwIndex))
{
++dwIndex;
}
LoadLibraryW(L"C:\\Program Files (x86)\\Notepad++\\bcryptprimitives.dll");
It is working like a charm :)
This is how the API works:
Calculate the offset of the end of the last section.
Remove all the data following that section.
Remove the security data directory.
Shrink the image.
Calculate an updated checksum of the PE.
I am trying to debug my application which use one static builded library.
I want to set break points in my library so i tried to set it using below command :
break TS.cpp:600(FIle name:line no)
but it says
No source file named TS.cpp.
Make breakpoint pending on future shared library load?(y or [n])
so I presses y here (I came to know after browsing internet) but after pressing y gdb is not stopping at my break point and it completed executing program.
Why GDB is not stopped at my break point??
Any input is highly appreciated.
No source file named TS.cpp
This means one of two things:
either the file TS.cpp was not compiled with -g (or equivalently TS.o has been stripped), or
the file TS.o was not linked into the application.
Since you are seeing prints from that source, it's a safe bet that #1 is the actual root cause.
info sources command shows only my application.c and not the files of my library
That is another confirmation that #1 is the root cause.
The problem in your case is with source mapping. It normally happens when application is compiled at some other machine and you are debugging it on some other machine where source location is different.
You can specify source path using directory command of gdb. e.g. if your sources are in /home/taimoor/testApp/src, you can do following:
(gdb) directory /home/taimoor/testApp/src
I'm trying to figure out how to detect whether a binary has been compressed with UPX. I am using a simple CRC to detect whether my app was in any way changed and if the CRC failed on the size due to a packer I would like to detect that as OK.
Right now I am starting with UPX.
So, is there any marker on the binary? are there any specific JMP or other instructions that I should search?
This will mainly be tested in Windows, but in the future I might add it to Linux as well.
Any help (and code) is appreciated.
ADDED:
I found that in the 10 binaries I checked the
AddressOfEntryPoint
Import Directory RVA
Resouce Directory RVA
either point to UPX or have an offset that is set by UPX. Any information on this?
Thanks
Download upx source code from UPX Homepage and open src/p_w32pe.cpp file; the function you are looking for is;
int PackW32Pe::canUnpack()
This function checks if the file is compressed with win32 upx.
You might try checking the section names of the executable. UPX changes them to UPX0, UPX1, UPX2, I believe.
I'm modifying an open-source GUI (written in c) to add a new menu item to the tray app. The new menu entry executes a file (update.exe) in the program root in c:\program files directory. Im using shellexec() and it works fine on x86, but since the path is different on x64 - c:\program files (x86), it fails to load. I'd like to use something to the effect of an environment variable like %programfiles%. What is an elegant solution to this?
Alternatively, I do have the ability to change where the update.exe file is stored. Putting it in 'program files' just seemed the most logical. For the problem above, should it go outside of program files? If so where?
You can use GetModuleFileName() to retrieve the full path to the executable. Then you'll just have to cut the filename from the end, and you'll have the complete directory path.
Something like this should to the trick:
TCHAR szPath[MAX_PATH];
LPTSTR szFileName;
GetModuleFileName(g_hInstance, szPath, sizeof(szPath)/sizeof(TCHAR));
szFileName = _tcsrchr(szPath, TEXT("\\"));
*szFileName = TEXT('\0');
// szPath now contains the path
(Warning! Untested!)