Friday, October 22, 2010
DllMain and RPC Call
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
if(ptr) may generate "test eax eax" . Test instruction tests against zero
Reference:
X86 Disassembly/Optimization Examples
Thursday, June 3, 2010
LoadLibrary
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
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
First and second chance exception handling
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
Monday, May 31, 2010
Good Links
What’s New in Visual Basic 2010
Debugging Applications with IntelliTrace
WinCE: KITL Transport
Using the Emulator in Smart Device Projects
Exploring New C++ and MFC Features in Visual Studio 2010
Debugging Functions
C Run-Time (CRT) Library
Shell Functions
File Management Functions
Sunday, May 30, 2010
Utilities
2. SubInACL is a command-line tool that enables administrators to obtain security information about files, registry keys, and services, and transfer this information from user to user, from local or global group to group, and from domain to domain.
Gook Link:- Clickhere
3.guidgen To generate new GUIDs
4.ErrorLookup To decode last error code.
5.HRPlus To convert the HResult into string
6. DUMPBIN
a. Using DUMPBIN to View Decorated Names
Friday, May 28, 2010
Thursday, May 27, 2010
Dump Generation
Collecting user-mode dumps
WER Settings Click Here!!!
How to Use the Userdump.exe Tool to Create a Dump File
How to use ADPlus to troubleshoot "hangs" and "crashes"
ProcDump is a command-line utility whose primary purpose is monitoring an application for CPU spikes and generating crash dumps during a spike that an administrator or developer can use to determine the cause of the spike. ProcDump also includes hung window monitoring (using the same definition of a window hang that Windows and Task Manager use) and unhandled exception monitoring. It also can serve as a general process dump utility that you can embed in other scripts.
ProcDump v1.72
Dr. Watson
You can use windbg and .dump command with appropriate switch
How to use Dumpchk.exe to check a Memory Dump file
Configuring Automatic Debugging
Specifying the Debugger for Unhandled User Mode Exceptions
How to: Launch the Debugger Automatically
Finding crash information using the MAP file
Forcing a System Crash from the Keyboard
Wednesday, May 26, 2010
x64 Programming
Everything You Need To Know To Start Programming 64-Bit Windows Systems
Writing 64-bit programs
win64 Structured Exception Handling
X64 Debugging With Pseudo Variables And Format Specifiers
Challenges of Debugging Optimized x64 Code
x64 Manual Stack Reconstruction and Stack Walking
How do I use sample dumpfiles from dia2dump.exe like .map files?
Tuesday, May 25, 2010
extern "C" function assumed not to throw execption
Today I have noticed that function declared with extern "C", are not assumed to throw.
If this function does throw execption, results are unexpected.
It could corrupt whole data section, anything can happen
More Reference:- Clickhere!!!
Clickhere!!!
Saturday, April 10, 2010
Handle Leak, Memory Leak
Memory Leak Detection Using Windbg Click here!!!
Visual Leak Detector - Enhanced Memory Leak Detection for Visual C++ Click hete!!!
Thursday, April 8, 2010
Conversion between Unicode UTF-16 and UTF-8
There are several possible representations of Unicode text, e.g. UTF-8, UTF-16, UTF-32, etc.
UTF-16 is the default Unicode encoding form used by Windows.
UTF-8 is a common encoding form used to exchange text data on the Internet.
One of the advantages of UTF-8 is that there is no endian problem (i.e. big-endian vs. little-end), because UTF-8 is interpreted just as a sequence of bytes (instead, it is important to specify the correct endiannes of UTF-16 and UTF-32 code units).
//----------------------------------------------------------------------------
// FUNCTION: ConvertUTF8ToUTF16
// DESC: Converts Unicode UTF-8 text to Unicode UTF-16 (Windows default).
//----------------------------------------------------------------------------
wstring ConvertUTF8ToUTF16( IN const string& szTextUTF8)
{
//
// Special case empty input string
//
if(0 == szTextUTF8.length())
{
return L"";
}
//
// Get size of destination UTF-16 buffer, in WCHAR's
//
int cchUTF16 = ::MultiByteToWideChar(
CP_UTF8, // convert from UTF-8
MB_ERR_INVALID_CHARS, // error on invalid chars
szTextUTF8.c_str(), // source UTF-8 string
szTextUTF8.length() + 1,// total length of source UTF-8 string,
// in CHAR's (= bytes), including end-of-string \0
NULL, // unused - no conversion done in this step
0 // request size of destination buffer, in WCHAR's
);
assert( cchUTF16 != 0 );
if ( cchUTF16 == 0 )
{
stringstream ssError;
ssError << "Error in " <<>
OutputDebugStringA(ssError.str().c_str());
return L"";
}
//
// Allocate destination buffer to store UTF-16 string
//
WCHAR * pszUTF16 = new WCHAR[cchUTF16];
//
// Do the conversion from UTF-8 to UTF-16
//
int result = ::MultiByteToWideChar(
CP_UTF8, // convert from UTF-8
MB_ERR_INVALID_CHARS, // error on invalid chars
szTextUTF8.c_str(), // source UTF-8 string
szTextUTF8.length() + 1, // total length of source UTF-8 string,
// in CHAR's (= bytes), including end-of-string \0
pszUTF16, // destination buffer
cchUTF16 // size of destination buffer, in WCHAR's
);
assert( result != 0 );
if ( result == 0 )
{
stringstream ssError;
ssError << "Error in " <<>
OutputDebugStringA(ssError.str().c_str());
}
wstring str(pszUTF16);
delete [] pszUTF16;
// Return resulting UTF16 string
return str;
}
//----------------------------------------------------------------------------
// FUNCTION: ConvertUTF16ToUTF8
// DESC: Converts Unicode UTF-16 (Windows default) text to Unicode UTF-8.
//----------------------------------------------------------------------------
string ConvertUTF16ToUTF8( IN const wstring& szTextUTF16 )
{
//
// Special case of NULL or empty input string
//
if ( 0 == szTextUTF16.length() )
{
// Return empty string
return "";
}
//
// WC_ERR_INVALID_CHARS flag is set to fail if invalid input character
// is encountered.
// This flag is supported on Windows Vista and later.
// Don't use it on Windows XP and previous.
//
#if (WINVER >= 0x0600)
DWORD dwConversionFlags = WC_ERR_INVALID_CHARS;
#else
DWORD dwConversionFlags = 0;
#endif
//
// Get size of destination UTF-8 buffer, in CHAR's (= bytes)
//
int cchUTF8 = ::WideCharToMultiByte(
CP_UTF8, // convert to UTF-8
0, // specify conversion behavior
szTextUTF16.c_str(), // source UTF-16 string
szTextUTF16.length() + 1, // total source string length, in WCHAR's,
// including end-of-string \0
NULL, // unused - no conversion required in this step
0, // request buffer size
NULL, NULL // unused
);
assert( cchUTF8 != 0 );
if ( cchUTF8 == 0 )
{
stringstream ssError;
ssError << "Error in " <<>
OutputDebugStringA(ssError.str().c_str());
return "";
}
//
// Allocate destination buffer for UTF-8 string
//
CHAR * pszUTF8 = new CHAR[cchUTF8];
//
// Do the conversion from UTF-16 to UTF-8
//
int result = ::WideCharToMultiByte(
CP_UTF8, // convert to UTF-8
0, // specify conversion behavior
szTextUTF16.c_str(), // source UTF-16 string
szTextUTF16.length() + 1, // total source string length, in WCHAR's,
// including end-of-string \0
pszUTF8, // destination buffer
cchUTF8, // destination buffer size, in bytes
NULL, NULL // unused
);
assert( result != 0 );
if ( result == 0 )
{
stringstream ssError;
ssError << "Error in " <<>
OutputDebugStringA(ssError.str().c_str());
}
string str(pszUTF8);
delete [] pszUTF8;
// Return resulting UTF-8 string
return str;
}
References: UTF-8, UTF-16, UTF-32 & BOMFriday, April 2, 2010
Singleton Class using shared_ptr
Monday, March 29, 2010
Exception Handing
Where are variables stored?
Tuesday, March 23, 2010
Argument of KiUserExceptionDispatcher() function
0021e9fc 77db5f79 fffffffe 0021f878 0021eb04 ntdll!_except_handler4+0x8e
0021ea20 77db5f4b 0021eae8 0021f878 0021eb04 ntdll!ExecuteHandler2+0x26
0021ead0 77db5dd7 0121eae8 0021eb04 0021eae8 ntdll!ExecuteHandler+0x24
0021ead0 77d8e13d 0121eae8 0021eb04 0021eae8 ntdll!KiUserExceptionDispatcher+0xf
0021ee20 77d8e04d 00000000 00000000 00000001 ntdll!RtlpWaitOnCriticalSection+0xc50:000> .exr 0x21eae8
ExceptionAddress: 77d8e13d (ntdll!RtlpWaitOnCriticalSection+0x000000c5)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000001
Parameter[1]: 00000014
Attempt to write to address 00000014
0:000> .cxr 0x21eb04
eax=00000000 ebx=fffffffc ecx=00000000 edx=00000004 esi=737b19a0 edi=737b19a4
eip=77d8e13d esp=0021edd0 ebp=0021ee20 iopl=0 nv up ei pl nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010213
ntdll!RtlpWaitOnCriticalSection+0xc5:
77d8e13d 83401401 add dword ptr [eax+14h],1 ds:0023:00000014=????????You can see the exception code is 0xc0000005 which is Access Violation
So whenever you find the KiUserExceptionDispatcher() function in call stack you can check for CONTEXT structure and EXCEPTION_RECORD structure, to find the exception code.
References:
Debugger tricks: Find all probable CONTEXT records in a crash dump
Wednesday, March 17, 2010
ETW
- Core OS Events in Windows 7 Click here!!!
- Core Instrumentation Events in Windows 7 Click here!!!
Solving 11 Likely Problems In Your Multithreaded Code
Debugging Information
- Create Dump File Click Here!!!
- Debugging Windows Services Click here!!!
- Debugging Winlogon.exe Click here!!!
- Debugging CSRSS Click here!!!
- Analyze Crashes to find Security Vulnerabilities in your App Click here!!!
Good Links
You will never get the code perfect but you can add defenses.
- Protecting Your Code with Visual C++ Defenses Click here!!!
- FAQ about HeapSetInformation Click here!!!
- HeapSetInformation in VC++ 2010 Click here!!!