Saturday, December 7, 2013

Debugging Map using Windbg

Here is the script which we can use for displaying the MAP:

.if ($sicmp("${$arg1}", "-n") == 0) {
    .if (@@(@$t0->_Isnil) == 0) {
        .if (@$t2 == 1) {
            .printf /D "%p\n", @$t0, @$t0
            .printf "key = "
            ?? @$t0->_Myval.first
            .printf "value = "
            ?? @$t0->_Myval.second
        } .else {
            r? $t9 = @$t0->_Myval
            command
        }
    }

    $$ Recurse into _Left, _Right unless they point to the root of the tree
    .if (@@(@$t0->_Left) != @@(@$t1)) {
        .push /r /q
        r? $t0 = @$t0->_Left
        $$>a< ${$arg0} -n
        .pop /r /q
    }
    .if (@@(@$t0->_Right) != @@(@$t1)) {
        .push /r /q
        r? $t0 = @$t0->_Right
        $$>a< ${$arg0} -n
        .pop /r /q
    }
} .else {
    r? $t0 = ${$arg1}

    .if (${/d:$arg2}) {
        .if ($sicmp("${$arg2}", "-c") == 0) {
            r $t2 = 0
            aS ${/v:command} "${$arg3}"
        }
    } .else {
        r $t2 = 1
        aS ${/v:command} " "
    }

    .printf "size = %d\n", @@(@$t0._Mysize)
   
    r? $t0 = @$t0._Myhead->_Parent
    r? $t1 = @$t0->_Parent

    $$>a< ${$arg0} -n

    ad command
}

traverse_map.script
A WinDbg script that traverses std::map objects.

Usage:

$$>a< traverse_map.script [-c "cmd"]

where cmd can reference @$t9, e.g. "?? @$t9.second" (this is the pair held by the map) and can also reference @$t0, which is the actual tree node pointer.

Examples:

$$>a< traverse_map.script my_map -c ".block { .echo ----; ?? @$t9.first; ?? @$t9.second; }"
$$>a< traverse_map.script m -c ".block { .if (@@(@$t9.first) == 8) { .echo ----; ?? @$t9.second } }"
$$>a< traverse_map.script my_map

Sample Program:-

class MapTest
{
public:
void PopulateMap();
private:
map m_Map1;
map m_Map2;
};

void MapTest::PopulateMap()
{
m_Map1[0] = 99;
m_Map1[1] = 100;

m_Map2[0] = wstring(L"Hello");
m_Map2[1] = wstring(L"World");

//stop the debugger here
__asm int 3
}

int _tmain(int argc, _TCHAR* argv[])
{

map  mm;
mm[1] = 1;
mm[2] = 2;

//stop the debugger
__asm int 3
MapTest mt;
mt.PopulateMap();
}


TestApp!wmain+0x8a:
0125203a 8d4d94          lea     ecx,[ebp-6Ch]
0:000> $$>a<C:\Users\ankurm\Desktop\traverse_map1.script mm
size = 2
002e8a48
key = int 0n1
value = int 0n1
002e8aa0
key = int 0n2
value = int 0n2
0:000> g
(2f68.2260): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=7efde000 ecx=8c2cadb9 edx=65a7d238 esi=001af620 edi=001af784
eip=01251f26 esp=001af620 ebp=001af790 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
TestApp!MapTest::PopulateMap+0x186:
01251f26 cc              int     3
0:000> dv
           this = 0x001af8ec
0:000> $$>a<C:\Users\ankurm\Desktop\traverse_map1.script this->m_Map1
size = 2
002e8bc0
key = int 0n0
value = int 0n99
002e8c18
key = int 0n1
value = int 0n100
0:000> $$>a<C:\Users\ankurm\Desktop\traverse_map1.script this->m_Map2
size = 2
002e8c70
key = int 0n0
value = class std::basic_string,std::allocator >
   +0x000 _Myfirstiter     : (null) 
   +0x004 _Alval           : std::allocator
   =01240000 npos             : 0x905a4d
   +0x008 _Bx              : std::basic_string,std::allocator >::_Bxty
   +0x018 _Mysize          : 5
   +0x01c _Myres           : 7
002e8ce0
key = int 0n1
value = class std::basic_string,std::allocator >
   +0x000 _Myfirstiter     : (null) 
   +0x004 _Alval           : std::allocator
   =01240000 npos             : 0x905a4d
   +0x008 _Bx              : std::basic_string,std::allocator >::_Bxty
   +0x018 _Mysize          : 5
   +0x01c _Myres           : 7


References:-
http://blogs.microsoft.co.il/sasha/2013/07/25/displaying-and-searching-stdmap-contents-in-windbg/
https://github.com/goldshtn/windbg-extensions

Monday, September 24, 2012

Description of the default C and C++ libraries that a program will link

Description of the default C and C++ libraries that a program will link with when built by using Visual C++

http://support.microsoft.com/kb/154753

Manually Verifing the stack

#define SAVE_EBP   static unsigned int dwValue1 = 0, dwValue2 = 0; __asm mov eax, [ebp] __asm mov dwValue1, eax
#define COPY_EBP  __asm mov eax, [ebp] __asm mov dwValue2, eax 
#define CHECK_EBP if(dwValue1 != dwValue2) { int i = 0; i = 1/i; }

e.g.

void function()
{
SAVE_EBP
.
.
.
.

COPY_EBP
CHECK_EBP
}

Inspecting CString, wstring, and static char buffer

    char *pString = new char[20];
    ::strcpy_s(pString, 20*sizeof(char), "Test string");
    CString *pStr = new CString("Hello World");
    std::wstring stdString = L"STD String";
    CDialogEx::OnOK(); <= Break point

0:000> dv /V /i /t

prv local  001af284 @ebp-0x3c class ATL::CStringT > > * pStr = 0x0097b830
prv local  001af290 @ebp-0x30 char * pString = 0x0097b7e0 "Test string"
prv local  001af25c @ebp-0x64 class std::basic_string,std::allocator > stdString = class std::basic_string,std::allocator >
0:000> dt -a11 0x0097b7e0 char
[0] @ 0097b7e0
---------------------------------------------
84 'T'

[1] @ 0097b7e1
---------------------------------------------
101 'e'
[2] @ 0097b7e2
---------------------------------------------
115 's'
[3] @ 0097b7e3
---------------------------------------------
116 't'
[4] @ 0097b7e4
---------------------------------------------
32 ' '
[5] @ 0097b7e5
---------------------------------------------
115 's'
[6] @ 0097b7e6
---------------------------------------------
116 't'
[7] @ 0097b7e7
---------------------------------------------
114 'r'
[8] @ 0097b7e8
---------------------------------------------
105 'i'
[9] @ 0097b7e9
---------------------------------------------
110 'n'
[10] @ 0097b7ea
---------------------------------------------
103 'g'
0:000> da 0x0097b7e0
0097b7e0  "Test string"
0:000> !stl -n (std::basic_string,std::allocator >) 001af25c
[du 0x97b920]
0097b920  "STD String"
0:000> dpu 001af25c L2
001af25c  0097b8d8 ".."
001af260  0097b920 "STD String"
0:000> !stl stdString
[du 0x97b920]
0097b920  "STD String"
0:000> !SDbgExt.stlwstring 001af25c
wstring size=10 reserved=15 buf=0097b920 "STD String"
0:000> dt 0x0097b830 CString
mfc_test_del!CString
   +0x000 m_pszData        : 0x0097b880  "Hello World"

Inspecting CObList using Windbg

void Cmfc_test_delDlg::OnBnClickedOk()
{
    CObList *pList = new CObList();
    pList->AddTail(new CAge(10));
    pList->AddTail(new CAge(20));
    pList->AddTail(new CAge(30));
    pList->AddTail(new CAge(40));
    pList->AddTail(new CAge(50));
    pList->AddTail(new CAge(60));
    // TODO: Add your control notification handler code here
    CDialogEx::OnOK();
}
0:000> *Beakpoint is at CDialogEx::OnOK() in Cmfc_test_delDlg::OnBnClickedOk()
0:000> bl
 0 e 00335010 [c:\vs\mfc_test_del\mfc_test_del\mfc_test_deldlg.cpp @ 158]    0001 (0001)  0:**** mfc_test_del!Cmfc_test_delDlg::OnBnClickedOk
0:000> *Lets look at local variable
0:000> dv /V /i /t
prv local  00a8ef58 @ebp-0x14 class Cmfc_test_delDlg * this = 0x00a8f864
prv local  00a8ef4c @ebp-0x20 class CObList * pList = 0x01e58cc8
0:000> *Display  the type for CObList
0:000> dt 0x01e58cc8 CObList
mfc_test_del!CObList
   +0x000 __VFN_table : 0x007f7f6c
   =007f7fb4 CObject::classCObject : CRuntimeClass
   =008b0c28 CObList::classCObList : CRuntimeClass
   +0x004 m_pNodeHead      : 0x01e5b5dc CObList::CNode  <= Pointer to linked list from Start
   +0x008 m_pNodeTail      : 0x01e5b618 CObList::CNode   <= Pointer to listed list from  End
   +0x00c m_nCount         : 0n6                                                <= Number of elements in the linked list
   +0x010 m_pNodeFree      : 0x01e5b624 CObList::CNode
   +0x014 m_pBlocks        : 0x01e5b5d8 CPlex
   +0x018 m_nBlockSize     : 0n10                                           <= memory reserved for 10 elements
0:000> *Find the head of the list
0:000> ?poi(0x01e58cc8+0x004 )
Evaluate expression: 31831516 = 01e5b5dc
0:000> *Display the list
0:000> dt CObList::CNode -l 0x01e5b5dc pNext
mfc_test_del!CObList::CNode
pNext at 0x1e5b5dc
---------------------------------------------
   +0x000 pNext            : 0x01e5b5e8 CObList::CNode
   +0x004 pPrev            : (null)
   +0x008 data             : 0x01e58d20 CObject
pNext at 0x1e5b5e8
---------------------------------------------
   +0x000 pNext            : 0x01e5b5f4 CObList::CNode
   +0x004 pPrev            : 0x01e5b5dc CObList::CNode
   +0x008 data             : 0x01e5b690 CObject
pNext at 0x1e5b5f4
---------------------------------------------
   +0x000 pNext            : 0x01e5b600 CObList::CNode
   +0x004 pPrev            : 0x01e5b5e8 CObList::CNode
   +0x008 data             : 0x01e5b6d8 CObject
pNext at 0x1e5b600
---------------------------------------------
   +0x000 pNext            : 0x01e5b60c CObList::CNode
   +0x004 pPrev            : 0x01e5b5f4 CObList::CNode
   +0x008 data             : 0x01e5b720 CObject
pNext at 0x1e5b60c
---------------------------------------------
   +0x000 pNext            : 0x01e5b618 CObList::CNode
   +0x004 pPrev            : 0x01e5b600 CObList::CNode
   +0x008 data             : 0x01e5b768 CObject
pNext at 0x1e5b618
---------------------------------------------
   +0x000 pNext            : (null)
   +0x004 pPrev            : 0x01e5b60c CObList::CNode
   +0x008 data             : 0x01e5b7b0 CObject
0:000> *Display the list from back
0:000> dt CObList::CNode -l 0x1e5b618 pPrev
mfc_test_del!CObList::CNode
pPrev at 0x1e5b618
---------------------------------------------
   +0x000 pNext            : (null)
   +0x004 pPrev            : 0x01e5b60c CObList::CNode
   +0x008 data             : 0x01e5b7b0 CObject
pPrev at 0x1e5b60c
---------------------------------------------
   +0x000 pNext            : 0x01e5b618 CObList::CNode
   +0x004 pPrev            : 0x01e5b600 CObList::CNode
   +0x008 data             : 0x01e5b768 CObject
pPrev at 0x1e5b600
---------------------------------------------
   +0x000 pNext            : 0x01e5b60c CObList::CNode
   +0x004 pPrev            : 0x01e5b5f4 CObList::CNode
   +0x008 data             : 0x01e5b720 CObject
pPrev at 0x1e5b5f4
---------------------------------------------
   +0x000 pNext            : 0x01e5b600 CObList::CNode
   +0x004 pPrev            : 0x01e5b5e8 CObList::CNode
   +0x008 data             : 0x01e5b6d8 CObject
pPrev at 0x1e5b5e8
---------------------------------------------
   +0x000 pNext            : 0x01e5b5f4 CObList::CNode
   +0x004 pPrev            : 0x01e5b5dc CObList::CNode
   +0x008 data             : 0x01e5b690 CObject
pPrev at 0x1e5b5dc
---------------------------------------------
   +0x000 pNext            : 0x01e5b5e8 CObList::CNode
   +0x004 pPrev            : (null)
   +0x008 data             : 0x01e58d20 CObject
0:000> *Check the data field
0:000> dt 0x01e58d20 CAge
mfc_test_del!CAge
   +0x000 __VFN_table : 0x007f0c58
   =007f7fb4 CObject::classCObject : CRuntimeClass
   +0x004 m_years          : 0n10
0:000> *Same thing can be done using !list too.
0:000> !list -t CObList::CNode.pNext -x "dt" -a "CObList::CNode" -e 01e5b5dc

dt 0x1e5b5dc CObList::CNode
mfc_test_del!CObList::CNode
   +0x000 pNext            : 0x01e5b5e8 CObList::CNode
   +0x004 pPrev            : (null)
   +0x008 data             : 0x01e58d20 CObject
dt 0x1e5b5e8 CObList::CNode
mfc_test_del!CObList::CNode
   +0x000 pNext            : 0x01e5b5f4 CObList::CNode
   +0x004 pPrev            : 0x01e5b5dc CObList::CNode
   +0x008 data             : 0x01e5b690 CObject
dt 0x1e5b5f4 CObList::CNode
mfc_test_del!CObList::CNode
   +0x000 pNext            : 0x01e5b600 CObList::CNode
   +0x004 pPrev            : 0x01e5b5e8 CObList::CNode
   +0x008 data             : 0x01e5b6d8 CObject
dt 0x1e5b600 CObList::CNode
mfc_test_del!CObList::CNode
   +0x000 pNext            : 0x01e5b60c CObList::CNode
   +0x004 pPrev            : 0x01e5b5f4 CObList::CNode
   +0x008 data             : 0x01e5b720 CObject
dt 0x1e5b60c CObList::CNode
mfc_test_del!CObList::CNode
   +0x000 pNext            : 0x01e5b618 CObList::CNode
   +0x004 pPrev            : 0x01e5b600 CObList::CNode
   +0x008 data             : 0x01e5b768 CObject
dt 0x1e5b618 CObList::CNode
mfc_test_del!CObList::CNode
   +0x000 pNext            : (null)
   +0x004 pPrev            : 0x01e5b60c CObList::CNode
   +0x008 data             : 0x01e5b7b0 CObject
0:000> !list -t CObList::CNode.pNext -x "dt" -a "CObList::CNode data" -e 01e5b5dc
dt 0x1e5b5dc CObList::CNode data
mfc_test_del!CObList::CNode
   +0x008 data : 0x01e58d20 CObject
dt 0x1e5b5e8 CObList::CNode data
mfc_test_del!CObList::CNode
   +0x008 data : 0x01e5b690 CObject
dt 0x1e5b5f4 CObList::CNode data
mfc_test_del!CObList::CNode
   +0x008 data : 0x01e5b6d8 CObject
dt 0x1e5b600 CObList::CNode data
mfc_test_del!CObList::CNode
   +0x008 data : 0x01e5b720 CObject
dt 0x1e5b60c CObList::CNode data
mfc_test_del!CObList::CNode
   +0x008 data : 0x01e5b768 CObject
dt 0x1e5b618 CObList::CNode data
mfc_test_del!CObList::CNode
   +0x008 data : 0x01e5b7b0 CObject
 

Tuesday, September 11, 2012

Windows: Transition from User to Kernel


1. Find the notepad process object
kd> !process 0 0 notepad.exe
PROCESS 859c29b8  SessionId: 1  Cid: 0914    Peb: 7ffd4000  ParentCid: 0600
    DirBase: 3ec4c420  ObjectTable: 921e3470  HandleCount:  57.
    Image: notepad.exe

2.Switch to notepad process context
kd> .process /i 859c29b8 
You need to continue execution (press 'g' ) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.
kd> g
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
826b9394 cc              int     3

3. Disassemble the NtCreateFile
kd> uf ntdll!ntCreateFile
ntdll!NtCreateFile:
77234a10 b842000000      mov     eax,42h
77234a15 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
77234a1a ff12            call    dword ptr [edx]
77234a1c c22c00          ret     2Ch

4. Find the content at 7ffe0300
kd> dd 7ffe0300 L1
7ffe0300  772364f0

5. Disassemble the code at 7ffe0300
kd> uf 772364f0
ntdll!KiFastSystemCall:
772364f0 8bd4            mov     edx,esp
772364f2 0f34            sysenter
772364f4 c3              ret

6. Find the address of KiServiceTable
kd> x nt!KiServiceTable
826bd6f0 nt!KiServiceTable =

7. Now display the function in System Service Table
kd> dps 0x826bd6f0+0x4*0x42 L1
826bd7f8  82898e82 nt!NtCreateFile

Monday, September 3, 2012

Capturing Dump Using Windbg

Copy this script and save as .reg file. Dump files will be saved in c:\dump folder.

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug]
"Auto"="1"
"UserDebuggerHotKey"=dword:00000000
"Debugger"="\"c:\\Program Files\\Debugging Tools for Windows (x86)\\windbg.exe\" -p %ld -e %ld -g -Q -c \".dump /mfhtpu /u c:\\dump.dmp;q\""

Wednesday, June 13, 2012

!htrace: The difference between the two snapshot is too large

Click on Debug > Break (or just CTRL+Break)
image
Type “!htrace –diff” without the quotation marks and then press Enter.
image
Note: By default, Windows Vista, Windows Server 2008, Windows 7 and Windows Server 2008 R2 keep a history of 4000 handles open and close operations.
With !htrace you can enable to keep a much higher history by doing the following:
image
Type “!htrace –enable 0x20000” without the quotation marks and then press Enter.
In this example, we are increasing the handle history to 128000 (decimal, 0x20000 hexadecimal).
image

Link:- http://blogs.technet.com/b/yongrhee/archive/2011/12/19/how-to-troubleshoot-a-handle-leak.aspx

Tuesday, June 12, 2012

MSIL tutorials


The following is some useful links to MSIL tutorials.

Monday, June 4, 2012

Windows 7 No Longer Supports Full Memory Dumps??

A new registry value has been added that will override this behavior and always cause the crash dump file to be generated. By setting the \HKLM\System\CCS\Control\CrashControl\AlwaysKeepMemoryDump DWORD value to 1 you will guarantee that you will always have a crash dump file after crashing the system.

For details fo though this:- http://www.osronline.com/article.cfm?article=545

Thursday, May 24, 2012

Debugging Focus Bugs

  1. Jeffrey Richter wrote an article in 1997 which contains a tool for finding the focus among other things: http://www.microsoft.com/msj/0397/Win32/Win320397.aspx
  2. We can use SPY++ and analyze messages
  3. We can do Remote Debugging and Multi-Monitor.
  4. The Inspect tool, part of the Windows SDK download, can be useful here. It's designed to test out the two Accessibility-related APIs - MSAA and UI Automation - and one of the things that both those APIs to is allow accessibility and test tools to track the focus.
    The simplest way to use it for tracking focus is to put it into MSAA mode, check the options to follow only focus changes (ie. turn off following the mouse pointer), then turn on the yellow highlight rectangle. Now as focus changes, you can see the rectangle move. As a bonus, if focus goes to something that's hidden or offscreen, you won't see a rectangle, but the name and Win32 class of the control will be displayed in the window.
    Note that Inspect shows a superset of focus events: you get not just HWND focus changes, but also notifications when focus moves within certain controls - such as between items in a list box. Automated test and accessibility need these, but for your purposes you should be ok to just ignore these; it's extra information, but shouldn't get in the way too much.
  5. Win32 Activation and Focus :- http://blogs.msdn.com/b/jfoscoding/archive/2006/08/02/686141.aspx

Friday, October 22, 2010

DllMain and RPC Call

This post is calling RPC function from DllMain()

ntdll!ZwWaitForSingleObject+0x15 (FPO: [3,0,0])
ntdll!RtlpWaitOnCriticalSection+0x1a3 (FPO: [Non-Fpo])
ntdll!RtlEnterCriticalSection+0xa8 (FPO: [Non-Fpo])
RPCRT4!PerformRpcInitialization+0x22 (FPO: [Non-Fpo])
RPCRT4!RpcStringBindingComposeW+0x14 (FPO: [Non-Fpo])
somedll!InternalDllMain+0x41 (FPO: [Non-Fpo]) (CONV: stdcall) [f:\sp\vctools\vc7libs\ship\atlmfc\src\mfc\dllmodul.cpp @ 119]
somedll!__DllMainCRTStartup+0x6c (FPO: [Non-Fpo]) (CONV: cdecl) [f:\sp\vctools\crt_bld\self_x86\crt\src\dllcrt0.c @ 365]
somedll!_DllMainCRTStartup+0x1d (FPO: [3,0,0]) (CONV: stdcall) [f:\sp\vctools\crt_bld\self_x86\crt\src\dllcrt0.c @ 328]
ntdll!LdrpCallInitRoutine+0x14
ntdll!LdrpRunInitializeRoutines+0x367 (FPO: [Non-Fpo])
ntdll!LdrpLoadDll+0x44b (FPO: [Non-Fpo])
ntdll!LdrLoadDll+0x198 (FPO: [Non-Fpo])
kernel32!LoadLibraryExW+0x1b2 (FPO: [Non-Fpo])
kernel32!LoadLibraryW+0x11 (FPO: [Non-Fpo])
someexe!somefunction

Assembly for PerformRpcInitialization(This is not full assembly but only which is required for this post)

RPCRT4!PerformRpcInitialization:
7da3933f 8bff mov edi,edi
7da39341 55 push ebp
7da39342 8bec mov ebp,esp
7da39344 83ec28 sub esp,28h
7da39347 56 push esi
7da39348 33f6 xor esi,esi
7da3934a 3935dc00ad7d cmp dword ptr [RPCRT4!RpcHasBeenInitialized (7dad00dc)],esi
7da39350 0f842eec0000 je RPCRT4!PerformRpcInitialization+0x17 (7da47f84)

RPCRT4!PerformRpcInitialization+0x236:
7da39356 33c0 xor eax,eax

RPCRT4!PerformRpcInitialization+0x238:
7da39358 5e pop esi
7da39359 c9 leave
7da3935a c3 ret

RPCRT4!PerformRpcInitialization+0x17:
7da47f84 687800ad7d push offset RPCRT4!GlobalMutex (7dad0078)
7da47f89 ff15b402a37d call dword ptr [RPCRT4!_imp__RtlEnterCriticalSection (7da302b4)]
7da47f8f 3935dc00ad7d cmp dword ptr [RPCRT4!RpcHasBeenInitialized (7dad00dc)],esi7da47f95 0f85ba010000 jne RPCRT4!PerformRpcInitialization+0x227 (7da48155)

RPCRT4!PerformRpcInitialization+0x2e:
7da47f9b 6888c1a37d push offset RPCRT4!`string' (7da3c188)
7da47fa0 ff155c01a37d call dword ptr [RPCRT4!_imp__LoadLibraryW (7da3015c)]7da47fa6 85c0 a test eax,eax

If you see lines marked in bold, it could lead into another loadlibrary call, hence deadlock could happen.

If rpc is not initialized then it will endup into loadlibrary(). Hence it will try to acquire loaderlock which is already hold by our process hence deadlock!!!

Friday, June 4, 2010

Assembly Language Programming: Code Conversion

int *ptr = new int;
if(ptr) may generate "test eax eax" . Test instruction tests against zero

Reference:
X86 Disassembly/Optimization Examples

Thursday, June 3, 2010

LoadLibrary

When we do loadLibary for some dll then while loading the library, loadlibray calls the loader lock function which locks the loader.

ntdll!ZwWaitForSingleObject+0x15 (FPO: [3,0,0])
ntdll!RtlpWaitOnCriticalSection+0x1a3 (FPO: [2,7,4])
ntdll!RtlEnterCriticalSection+0xa8 (FPO: [1,1,0])
ntdll!LdrLockLoaderLock+0xe4 (FPO: [SEH])
ntdll!LdrLoadDll+0xc9 (FPO: [SEH])
kernel32!LoadLibraryExW+0x1b2 (FPO: [SEH])
kernel32!LoadLibraryW+0x11 (FPO: [1,0,0])

This helps in proper initialization of library.

ULONG64 on 32 bit machine

unsigned __int64 var64 = 100;

How to access lower and higher order DWORD in var64?

We can use below mentioned structure.

typedef union _ULARGE_INTEGER {
struct {
DWORD LowPart;
DWORD HighPart;
};
struct {
DWORD LowPart;
DWORD HighPart;
} u;
ULONGLONG QuadPart;
} ULARGE_INTEGER;

ULARGE_INTEGER largeVar = 0;

largeVar.QuadPart = var64;

Now you can access.
DWORD LowPart = largeVar.LowPart;
DWORD HighPart = largeVar.HighPart;

These structure can be found at WinNT.h

How LONG64 is stored on stack?

First higher order DWORD is pushed and then lower order DWORD.

code snippet:

unsigned __int64 var = 10;
ULARGE_INTEGER value;
value.QuadPart = var;
value.LowPart = 60;
value.HighPart = 70;


unsigned __int64 var = 10;
00031036 mov dword ptr [var],0Ah
0003103D mov dword ptr [ebp-0Ch],0
ULARGE_INTEGER value;
value.QuadPart = var;
00031044 mov eax,dword ptr [var]
00031047 mov dword ptr [value],eax
0003104A mov ecx,dword ptr [ebp-0Ch]
0003104D mov dword ptr [ebp-4],ecx
value.LowPart = 60;
00031050 mov dword ptr [value],3Ch
value.HighPart = 70;
00031057 mov dword ptr [ebp-4],46h


stack view

0x0019FCEC 0000000a //lower local param1
0x0019FCF0 00000000 //higher local param1
0x0019FCF4 0000003c //lower local param2
0x0019FCF8 00000046 // higher local param2
0x0019FCFC 0019fd40 // ebp

Tuesday, June 1, 2010

Good Links

A Crash Course on the Depths of Win32™ Structured Exception Handling

Exception Handling

First and second chance exception handling

Distinction between the first and second chance exception: the debugger gets the first chance to see the exception (hence the name). If the debugger allows the program execution to continue and does not handle the exception, the program will see the exception as usual. If the program does not handle the exception, the debugger gets a second chance to see the exception. In this latter case, the program normally would crash if the debugger were not present.

If you do not want to see the first chance exception in the debugger, you should disable first chance exception handling for the specific exception code. Otherwise, when the first chance exception occurs, you may need to instruct the debugger to pass on the exception to the program to be handled as usual.

Does a first chance exception mean there is a problem in my code?
First chance exception messages most often do not mean there is a problem in the code. For applications / components which handle exceptions gracefully, first chance exception messages let the developer know that an exceptional situation was encountered and was handled.


References:
First and second chance exception handling