I am new to reversing. My apologies if question sounds to beginer-ish :) I have created simple code in Visual Studio C++ 2010 on XP SP3:
int main()
{
return 0;
}
Whenever I open it in Olly it shows the following state of the stack with execution paused:
0012FFC4 7C817077 RETURN to kernel32.7C817077
0012FFC8 7C910228 ntdll.7C910228
0012FFCC FFFFFFFF
0012FFD0 7FFD5000
0012FFD4 80544CFD
0012FFD8 0012FFC8
0012FFDC 82537DA8
0012FFE0 FFFFFFFF End of SEH chain
0012FFE4 7C839AD8 SE handler
0012FFE8 7C817080 kernel32.7C817080
0012FFEC 00000000
0012FFF0 00000000
0012FFF4 00000000
0012FFF8 004012A0 Reversin.<ModuleEntryPoint>
0012FFFC 00000000
I can see end of SEH chain and SE handler the rest of it just doesn't make sense to me. I have found the following stack layout for the functions with exception handler installed:
Function_Local_Variables
Exception_Registration_Record
Exception_Handler
Callers_EBP
Return_Address_in_Caller
Function_Arguments
It does not seem to apply in my case. I need help trying to understand what's been stored in stack please.
Thank you.
If you're trying to learn the stack convention by looking at hex in Olly, you should consider which stack convention your code is following. By default, most C++ code follows the __cdecl convention. Check out this link: http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl
Related
Is there a way to predict/calculate where in a module's memory a function will be located?
*Sigh* The first thing you'll tell me is: you have to have symbols for stuff to work well. I know. (Oh! Do I know!) It isn't an option for me, so I'm looking to make the most of what I have. I'm not trying to get the values of local variables or anything (which would require intimate knowledge of compiler optimizations, etc.). I just would like to know what DLL function we were in.
I have a memory dump from a crashed process. The process loads numerous DLL's, each of which have some exported functions. One thread in the process has some items on the call stack "within" this DLL. The Visual Studio debugger reports them as (the names are changed to protect the innocent):
msvcr120.dll!abort() Line 90
msvcr120.dll!_XcptFilter(unsigned long xcptnum, _EXCEPTION_POINTERS * pxcptinfoptrs) Line 366
MyProcess.exe!016c9a9a()
[Frames below may be incorrect and/or missing, no symbols loaded for Mach4GUI.exe]
[External Code]
MyProcess.exe!016ca390()
[External Code]
ExtLib01.dll!6eb1f75c()
ExtLib01.dll!6eb95991()
ExtLib01.dll!6e658979()
ExtLib01.dll!6e653bab()
ExtLib01.dll!6e66d5dd()
[External Code]
The DLL wasn't built for debugging, and I don't have a .PDB or other source of symbols.
Visual Studio reports this about the DLL module:
Name Path Address
---- ---- -------
ExtLib01.dll C:\MyProj\ExtLib01.dll 6E5E0000-6FE8800
The DLL, of course, has some exported functions (reported by dumpbin /exports ExtLib01.dll), like:
ordinal hint RVA name
1 0 0009CE30 LibFunc1#16
2 1 0009CDF0 LibFunc2#4
3 2 0009CE60 LibFunc3#4
...
482 1E1 0010FB40 LibFunc482
483 1E2 0010FBD0 LibFunc483
484 1E3 0010FAC0 LibFunc484
Not knowing any better, it seems like there might be enough information here to figure out what functions are in the call stack (if the return address is "within" one of the DLL functions).
Some simple arithmetic on the first item in the call stack, 0x6eb1f75c-0x6E5E0000, yields an offset into the ExtLib01.dll "module" in memory: +0x0053f75c, but this doesn't correspond at all to the relative virtual addresses listed in the DLL exports.
So, Visual Studio tells me nothing but the module name and an address (within that module) in the call stack. One might assume that this is because more information isn't available. My experience with Microsoft products suggests that they just might not have implemented such a feature—though in the case of their flagship development tool, surely they would try hard to make it useful.
More confusingly, WinDbg tells me different things about about the call stack for the same thread.
# ChildEBP RetAddr
00 0022cdb8 7740171a ntdll!NtWaitForMultipleObjects+0x15
01 0022ce54 76c519fc KERNELBASE!WaitForMultipleObjectsEx+0x100
02 0022ce9c 76c541d8 kernel32!WaitForMultipleObjectsExImplementation+0xe0
03 0022ceb8 76c780bc kernel32!WaitForMultipleObjects+0x18
04 0022cf24 76c77f7b kernel32!WerpReportFaultInternal+0x186
05 0022cf38 76c77870 kernel32!WerpReportFault+0x70
06 0022cf48 76c777ef kernel32!BasepReportFault+0x20
07 0022cfd4 74fb4820 kernel32!UnhandledExceptionFilter+0x1af
08 0022cfe0 74fb4611 msvcr120!__crtUnhandledException+0x14 [f:\dd\vctools\crt\crtw32\misc\winapisupp.c # 259]
09 0022d318 74fb7676 msvcr120!_call_reportfault+0xfe [f:\dd\vctools\crt\crtw32\misc\invarg.c # 201]
0a 0022d328 74fb4e38 msvcr120!abort+0x38 [f:\dd\vctools\crt\crtw32\misc\abort.c # 90]
0b 0022d340 016c9a9a msvcr120!_XcptFilter+0x14b [f:\dd\vctools\crt\crtw32\misc\winxfltr.c # 366]
WARNING: Stack unwind information not available. Following frames may be wrong.
0c 0022f8c8 76c5336a MyProcess!SomeSymbol+0xa0d71a
0d 0022f8d4 77b39902 kernel32!BaseThreadInitThunk+0xe
0e 0022f914 77b398d5 ntdll!__RtlUserThreadStart+0x70
0f 0022f92c 00000000 ntdll!_RtlUserThreadStart+0x1b
I can perhaps understand some of the items at the top of the list (everything above UnhandledExceptionFilter, where Windows Error Reporting is doing its thing, capturing the memory dump, etc.), but why the discrepancy between the two call stacks? I see that both report "Following frames may be wrong." Is this information completely unreliable? What can be known or discerned from the information available?
What can be discerned about the items in the call stack from the information available?
Is it possible to know where a function from a loaded DLL is located in memory of a running process?
I'm willing to use WinDbg if it'll help. I'm willing to use PowerShell within Visual Studio's NuGet console. I'm not unwilling to do some work, but I have no real idea if it's even possible to know something these DLL functions.
Note: I realize the answer may very well be, "Nope. It's impossible." I'm looking for a good answer with an explanation (or references to some sort of authoritative source with an explanation) as to how the DLL's are loaded and its functions called and why a memory dump doesn't contain enough information to figure out where any given function "starts" in memory.
I develop a win32 application using i686-w64-mingw32-gcc 4.7.2 crosscompiler under Ubuntu 12.10.
When I run my application compiled in the release mode and it crashes, I may receive an output like bellow.
I am wondering how to interpret it? Is there some useful information that I could get from that? For example would it be possible to get lines in my source code from the Stack dump?
wine: Unhandled page fault on read access to 0x00006c11 at address 0x401cb1 (thread 0009), starting debugger...
Application tried to create a window, but no driver could be loaded.
Make sure that your X server is running and that $DISPLAY is set correctly.
Unhandled exception: page fault on read access to 0x00006c11 in 32-bit code (0x00401cb1).
Register dump:
CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
EIP:00401cb1 ESP:007af750 EBP:007af9c8 EFLAGS:00010206( R- -- I - -P- )
EAX:00406a20 EBX:00000004 ECX:00006c11 EDX:00006c11
ESI:00000068 EDI:00110440
Stack dump:
0x007af750: 007af7df 00000030 00000043 00000004
0x007af760: 00142fc0 3ff54e5b 00406a20 3ff57208
0x007af770: 0207251c 3ff4cb7d 02072574 3ff51f7f
0x007af780: ea9e6eeb 3ff49b90 e09fe868 3ff4c562
0x007af790: 00006c11 00000045 0209c5b4 007afa0c
0x007af7a0: 00000004 019b0000 007af7f8 00110000
000c: sel=0067 base=00000000 limit=00000000 16-bit --x
Backtrace:
=>0 0x00401cb1 in analyser (+0x1cb1) (0x007af9c8)
1 0x00536147 in analyser (+0x136146) (0x007afd98)
2 0x004013fa __tmainCRTStartup+0x279() [/home/ruben/mingw-w64/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:313] in analyser (0x007afe70)
3 0x7b859ddc call_process_entry+0xb() in kernel32 (0x007afe88)
4 0x7b85b04f in kernel32 (+0x4b04e) (0x007afec8)
5 0x7bc71d90 call_thread_func_wrapper+0xb() in ntdll (0x007afed8)
6 0x7bc7486d call_thread_func+0x7c() in ntdll (0x007affa8)
7 0x7bc71d6e RtlRaiseException+0x21() in ntdll (0x007affc8)
8 0x7bc49f4e call_dll_entry_point+0x61d() in ntdll (0x007affe8)
0x00401cb1: movl 0x0(%edx),%eax
Modules:
Module Address Debug info Name (89 modules)
PE 240000- 273000 Deferred ssleay32
PE 280000- 37e000 Deferred libeay32
...
I am wondering how to interpret it?
It appears pretty clear already: your code, more precisely: instruction at address 0x401cb1, attempted to dereference memory at address 0x00006c11. That memory access was not valid, and triggered a page fault.
Is there some useful information that I could get from that?
Yes, as above.
For example would it be possible to get lines in my source code from the Stack dump?
Sure: when you build your application in release mode, add the -g flag. Then
addr2line -fe analyser 0x401cb1
should tell you which file/line the address 0x401cb1 corresponds to.
We're using Fogbugz for tracking issues and I am in the middle of writing a C++ wrapper around the XML API for Fogbugz.
The best practice seems to be to use the "scout" field so that similar/same crashes are just counted but not reported again. To do that we need a unique string for a particular cause of a crash.
In Win32 - after getting a dmp file or other crash handler what is a good way to make a unique string for a crash? (we're going to create a dmp file and send it to the fogbugz server)
In previous postings/articles/etc Joel has made various suggestions but much of those counted on a language like C# that use reflection and have a lot of information that is either harder to get or not possible to get.
Have any other people gotten things like stack traces or other things to make scout entries in fogbugz?
EDIT
To clarify - we don;t want a unique id for every incident - there are likely crashes that have the same code path. We want to capture that. I was thinking that we would get the last few stack calls that are in our code (not ones from win32 DLLs) - but not sure how to go about doing this.
Reporting every crash as unique is not right. Reporting all crashes under the same case is not right. Different users repeating a scenario that causes a crash should map to the same incident.
EDIT
What I think we want is a general "signature" of a crash - based on what is on the stack. Similar stacks should have the same signature. For example - take the top 5 methods that are in our app and then the first call (if any) we make into an MS DLL. This would probably be sufficient for a signature and would likely correlate the crashes that are "the same".
So how does one get the list of methods on the stack? And how can you tell if they are from your own app or in another DLL?
EDIT - NOTE
We want to create a "bucket id"/signature while in the exception handler so that we can create the minidump and send it to fogbugz as a scout description. Alternatively we can load up the dump on t he next start of the app and send it then with a signature we generate.
Here in my project I use the Address Memory of the Crash as a "Unique" ID.
IMO the best thing you can use will be bucket id from dump analysis. Use properly configured Debugging Tools for Windows (windbg), one can do !analyze -v and classify your dumps into different buckets based on bucket id. Bucket id guaranteed that if two dumps are the same, their bucket id will be the same. That solves part of the puzzle.
Many times two dumps rooted from same problem will create different bucket id's (maybe version difference, say your 1.0 and 1.1 both crash at same point). You can use faulting module and stack signature to correlate bugs from the same point of fault.
There will be certain things that causes very random dumps (e.g. heap corruption, the faulting module is typically the victim). Therefore dump analysis should be considered best-effort. When you can't, you can't.
I used something like this to generate exceptions in my last app (MSVC), so every error would get logged with the sourcefile and line it occured on:
class Error {
//...
public: Error(string file, string line, string error) ;
};
#define ERROR(err) Error(__FILE__, __LINE__, err)
It's probably a little bit late, but I will add my solution here, too, in case it can help other people.
You can do this using fools from "Debugging Tools for Windows", for example windbg.exe or better kd.exe.
Running the command "kd.exe -z "path_to_dump.dmp" -c "kd;q" >> dumpstack.txt, you might get the following result:
Microsoft (R) Windows Debugger Version 10.0.15063.400 X86
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [d:\work\bugs\14122\myexe.exe.2624.dmp]
User Mini Dump File with Full Memory: Only application data is available
************* Symbol Path validation summary **************
Response Time (ms) Location
Deferred srv*C:\Symbols*http://msdl.microsoft.com/download/symbols
Symbol search path is: srv*C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows 10 Version 15063 MP (4 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS
15063.0.x86fre.rs2_release.170317-1834
Machine Name:
Debug session time: Fri Oct 13 00:09:01.000 2017 (UTC + 1:00)
System Uptime: 0 days 0:18:33.797
Process Uptime: 0 days 0:03:40.000
................................................................
.....................................................
Loading unloaded module list
..............................
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(a40.2580): Security check failure or stack buffer overrun - code c0000409 (first/second chance not available)
eax=00000001 ebx=00000000 ecx=00000007 edx=77cc4350 esi=00000000 edi=00000000
eip=62ae7666 esp=0b75e17c ebp=0b75e1a8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
msvcr120!abort+0x28:
62ae7666 cd29 int 29h
0:068> kd: Reading initial command 'kb;q'
ChildEBP RetAddr Args to Child
0b75e178 62addc5f 935dda1f 00000000 00000000 msvcr120!abort+0x28
0b75e1a8 0b75e7d4 62a9b436 0b75e1dc 62a52aa5 msvcr120!terminate+0x33
WARNING: Frame IP not in any known module. Following frames may be wrong.
0b75e1ac 62a9b436 0b75e1dc 62a52aa5 00000000 0xb75e7d4
0b75e1b4 62a52aa5 00000000 62a59740 0b75e7d4 msvcr120!__FrameUnwindToState+0x89
0b75e1c8 62a52b33 00000000 00000000 00000000 msvcr120!_EH4_CallFilterFunc+0x12
0b75e1f4 62a5a0f3 62b1f7b8 62a4f7c6 0b75e324 msvcr120!_except_handler4_common+0x8e
0b75e214 77cd6152 0b75e324 0b75e7c4 0b75e344 msvcr120!_except_handler4+0x1e
0b75e238 77cd6124 0b75e324 0b75e7c4 0b75e344 ntdll!ExecuteHandler2+0x26
0b75e30c 77cc4266 0b75e324 0b75e344 0b75e324 ntdll!ExecuteHandler+0x24
0b75e30c 74cf28f2 0b75e324 0b75e344 0b75e324 ntdll!KiUserExceptionDispatcher+0x26
0b75e684 62a59339 e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x62
0b75e6c4 6001821c 0b75e6e4 6004e1bc 946a8f2a msvcr120!_CxxThrowException+0x5b
0b75e6f8 60018042 0b75e720 946a8efa ffffffff mymodule!FunctionC+0x7c
0b75e730 60016544 946a8ece ffffffff 092889d8 mymodule!FunctionB+0x32
0b75e754 600166b8 00842338 6000588d 00000001 myothermodule!FunctionB+0x44
From this stack, you can create a unique bucket if you take for example only your methods from the stack and concatenate them in a string: "mymodule!FunctionC+0x7c;mymodule!FunctionB+0x32;myothermodule!FunctionB+0x44". In order for this to work, you need to have access to you personal symbols server, either using the environment variable _NT_SYMBOL_PATH or with the -y command line switch.
You can alternatively create a string from the return addresses only (second column): "62addc5f,0b75e7d4,62a9b436,62a52aa5,62a52b33,62a5a0f3,77cd6152,77cd6124,77cc4266,74cf28f2,62a59339,6001821c,60018042,60016544,600166b8"
Just use an MD5 string generated from the dump file and you will likely to get a unique string for every crash.
I would start with collecting the data on how often every function in your code has been "flashed" in a crash report stack trace. Every report would have to be added to some kind of database, and every function would have to be indexed so that you could later query, which functions seem to crash more often than others. (And of course, functions like main() will be in every report, but that's understandable).
Or, you think that only crash reports seem to be the problem, you could just remove all those entries from crash stack traces, and then hash the rest (your functions). That way you could see if any particular call chain of your own functions causes a crash repeatedly, no matter what external functions have been called in between.
Then of course, some of the more complicated problems will not be captured this way anyway, as the stack trace will be completely different. To help that, you could record other data from your application along with the stack trace in every report, like sizes of buffers, counters, states of different parts of the application and so on... And then do some statistics on that.
I´m new to C++ programing. I am compiling a Windows Application which compiles ok with just a few warnings, but when I launch it, it doesn´t even seem to start and returns an Access Violation 3 seconds into the run. When I try to debug it doesn´t even seem to get into the code, so I don´t know where to start looking for the problem.
Here is the info I have been able to retrieve from the debugger:
Building to ensure sources are up-to-date
Build succeeded
Selecting target:
Debug
Adding source dir: C:\Documents and Settings\Christian Ekiza\Mis documentos\My Dropbox\Private Files\coding\juego_pruebas_01\juego_pruebas_01\
Adding source dir: C:\Documents and Settings\Christian Ekiza\Mis documentos\My Dropbox\Private Files\coding\juego_pruebas_01\juego_pruebas_01\
Adding file: bin\Debug\juego_pruebas_01.exe
Starting debugger:
done
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints
Debugger name and version: GNU gdb 6.8
Child process PID: 3328
Program received signal SIGSEGV, Segmentation fault.
In ?? () ()
and this is from the Call Stack
#0 00000000 0x000154e4 in ??() (??:??)
#1 00409198 __cmshared_create_or_grab() (../../../../gcc-4.4.1/libgcc/../gcc/config/i386/cygming-shared-data.c:140)
#2 00000000 0x0040131b in __gcc_register_frame() (??:??)
#3 00000000 0x0040a09b in register_frame_ctor() (??:??)
#4 00000000 0x00408f42 in __do_global_ctors() (??:??)
#5 00000000 0x00401095 in __mingw_CRTStartup() (??:??)
#6 00000000 0x00401148 in mainCRTStartup() (??:??)
And the CPU Registers end with a
'gs' register with a hex value '0x0'
I don't really know where to start looking for the problem. Anyone can help me out or point me in the right direction?
Note: I am using Code::Blocks
As you say it is a Windows application. Then, any issues with startup, I have found ADPlus very useful.
EDIT 2:
You may also check User Mode Process Dumper if ADPlus does not apply
See, if you have some global instance(s) of class with constructor - if error is raised in constructor and class is declared globally (bad thing to do btw) - you'll get sigsegv even before main().
If you have such classes - try to refactor your code to have them inside main (or other function) - it will be easier to debug.
Try the following free MS tools - both are great for debugging this kind of problem.
Application Verifier http://www.microsoft.com/downloads/en/details.aspx?familyid=c4a25ab9-649d-4a1b-b4a7-c9d8b095df18&displaylang=en
Gflags from Debugging Tools for Windows http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b&displaylang=en
Sounds to me like one of your DLL dependencies can't be loaded or instantiated correctly.
Did you you compile with debug mode (-g) enabled?
Also seriously consider actually fixing the warnings. Most of the time they are actual problems in the code that should be resolved.
You should also try to see if this happens with a nearly empty main (comment out most/all of your code in main).
How do I restore the stack trace function name instead of <UNKNOWN>?
Event Type: Error
Event Source: abcd
Event Category: None
Event ID: 16
Date: 1/3/2010
Time: 10:24:10 PM
User: N/A
Computer: CMS01
Description:
Server.exe caused a in module at 2CA001B:77E4BEF7
Build 6.0.0.334
WorkingSetSize: 1291071488 bytes
EAX=02CAF420 EBX=00402C88 ECX=00000000 EDX=7C82860C ESI=02CAF4A8
EDI=02CAFB68 EBP=02CAF470 ESP=02CAF41C EIP=77E4BEF7 FLG=00000206
CS=2CA001B DS=2CA0023 SS=7C820023 ES=2CA0023 FS=7C82003B GS=2CA0000
2CA001B:77E4BEF7 (0xE06D7363 0x00000001 0x00000003 0x02CAF49C)
2CA001B:006DFAC7 (0x02CAF4B8 0x00807F50 0x00760D50 0x007D951C)
2CA001B:006DFC87 (0x00003561 0x7F6A0F38 0x008E7290 0x00021A6F)
2CA001B:0067E4C3 (0x00003561 0x00000000 0x02CAFBB8 0x02CAFB74)
2CA001B:00674CB2 (0x00003561 0x006EBAC7 0x02CAFB68 0x02CAFA64)
2CA001B:00402CA4 (0x00003560 0x00000000 0x00000000 0x02CAFBB8)
2CA001B:00402B29 (0x00003560 0x00000001 0x02CAFBB8 0x00000000)
2CA001B:00683096 (0x00003560 0x563DDDB6 0x00000000 0x02CAFC18)
2CA001B:00688E32 (0x02CAFC58 0x7C7BE590 0x00000000 0x00000000)
2CA001B:00689F0C (0x02CAFC58 0x7C7BE590 0x00000000 0x00650930)
2CA001B:0042E8EA (0x7F677648 0x7F677648 0x00CAFD6C 0x02CAFD6C)
2CA001B:004100CA (0x563DDB3E 0x00000000 0x00000000 0x008E7290)
2CA001B:0063AC39 (0x7F677648 0x02CAFD94 0x02CAFD88 0x77B5B540)
2CA001B:0064CB51 (0x7F660288 0x563DD9FE 0x00000000 0x00000000)
2CA001B:0063A648 (0x00000000 0x02CAFFEC 0x77E6482F 0x008E7290)
2CA001B:0063A74D (0x008E7290 0x00000000 0x00000000 0x008E7290)
2CA001B:77E6482F (0x0063A740 0x008E7290 0x00000000 0x00000000)
Get the exact same build of the program, objdump it, and have a look at what function is at the address. If symbol names have been stripped from the executable, this might be a little bit difficult.
If the program code is in any way dynamic, you may have to run it into a debugger to find the addresses of functions.
If the program is deliberately obfuscated and nasty, and it randomises its function addresses in some way at runtime (evasive things like viruses, or copy-protection code sometimes do this) then all bets are off.
In general:
The easiest way to find out what caused the crash is to follow the steps necessary to reproduce it in an instance of the application running in a debugger. All other approaches are much more difficult. This is why developers will often not spend time trying to tackle bugs which there are no known methods to reproduce.
You need to have the debug info file (.pdb) next to the exe when the crash occurs.
Then hopefully, your crash dumping code can load it and use the information in it.
Try to run the same built from your IDE, pause it and jump to the adresses in assembly. Then you can switch to source code and see the functions there.
At least that's how it works in Delphi. And I know of this possibility in Visual Studio as well.
If you don't have the built in your IDE, you have to use a Debugger like OllyDbg. Run the exe that caused the errors and pause the application in OllyDbg. Go to the adresses from the stack trace.
Open a similar application project in your IDE, run it and pause it. Search for the same binary pattern you see in OllyDbg and then switch to source code.
The last possibility I know is analysing the map file if you built it during your built.
I use StackWalker - just compile it into the source of your program, and if it crashes you can generate a stack trace at that time, including function names.
The most common cause is that you in fact don't have a module at the specified address. This can happen e.g. when you dereference an uninitialized function pointer, or call a virtual function using an invalid this pointer.
This is probably not the case here: "77E4BEF7" is with very high probability a Windows DLL, and 006DFAC7 an address in one of your modules. You don't need PDB files for this: Windows should always know the module name (.EXE or .DLL) - in fact, it needs first that module name to even find the proper PDB file.
Now, the remaining question is why you don't have the module information. This I can't tell from the information above. You need information about the actual system. For instance, does if have DEP? Is DEP enabled for your process?