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

Sunday, May 30, 2010

Utilities

1. You can use the undname.exe to convert a decorated name to its undecorated form.

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

Assembly Language Programming

Why does the compiler generate a MOV EDI, EDI instruction at the beginning of functions?

Assembly language1

Assembly language2

THE 80x86 INSTRUCTION SET

Thursday, May 27, 2010

Dump Generation

Starting with Windows Server 2008 and Windows Vista with Service Pack 1 (SP1), Windows Error Reporting (WER) can be configured so that full user-mode dumps are collected and stored locally after a user-mode application crashes.
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

C++0x New Standard and TR1

C++0x Core Language Features In VC10: The Table
Presentation Materials: Overview of the New C++ (C++0x)

Tuesday, May 25, 2010

extern "C" function assumed not to throw execption

Hi,

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

How to Collect Information for Handle Leak Issues in Process Space for Post-mortem Analysis Click here!!!

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 & BOM

Friday, April 2, 2010

Singleton Class using shared_ptr

Hi All,

Today I have come across one class called shared_ptr which has one good constructor which can accept function pointer. This function will be called by destructor of shared_ptr. Hence this function can be used for releasing SINGLETON CLASS REFERENCE.

Lets see the code:-

Singleton.h

#ifndef __SINGLETON__
#define __SINGLETON__

namespace myapp
{
class SingletonPattern
{
public:
static SingletonPattern* GetInstance();
void Release();
private:
SingletonPattern();
SingletonPattern(const SingletonPattern&);
~SingletonPattern();
SingletonPattern& operator =(const SingletonPattern&);
private:
static SingletonPattern* m_pSinglePattern;
static int m_Count;
};

void Release(SingletonPattern* obj);
};

#endif //__SINGLETON__

Singleton.cpp


#include "stdafx.h"

#include "Singleton.h"

using namespace myapp;

SingletonPattern* SingletonPattern::m_pSinglePattern = NULL;
int SingletonPattern::m_Count=0;

SingletonPattern::SingletonPattern()
{
}

SingletonPattern::SingletonPattern(const SingletonPattern &)
{
}

SingletonPattern::~SingletonPattern()
{
}

SingletonPattern& SingletonPattern::operator =(const SingletonPattern& rhs)
{
if (this != &rhs) {
// Deallocate, allocate new space, copy values...
}
return *this;
}

SingletonPattern* SingletonPattern::GetInstance()
{
if(NULL == m_pSinglePattern)
{
m_pSinglePattern = new SingletonPattern;
}

m_Count++;

return m_pSinglePattern;
}

void SingletonPattern::Release()
{
if(m_Count > 0) --m_Count;
if(NULL != m_pSinglePattern && 0 == m_Count)
{
delete m_pSinglePattern;
m_pSinglePattern = NULL;
}
}

void myapp::Release(SingletonPattern* obj)
{
if(NULL != obj) obj->Release();
}

SingletonTest.cpp

Main Function

#include "stdafx.h"

#include "vld.h"

#include "Singleton.h"

using namespace myapp;

using namespace std::tr1;

int _tmain(int argc, _TCHAR* argv[])
{
shared_ptr objshared(SingletonPattern::GetInstance(), Release);

shared_ptr objshared1(SingletonPattern::GetInstance(), Release);

return 0;
}

Singleton class reference will be release automatically when destructor of shared_ptr class is called.

Hence when main function is about to finish, shared_ptr destructor will be called and finally release function will be called.

We neednot have call Release explicitly for singleton class.

We cannot use auto_ptr because there is no such constructor which accepts function pointer.

Monday, March 29, 2010

Exception Handing

What is the output of the following program?

CRITICAL_SECTION g_cs;

int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
OutputDebugStringA("Inside Filter Function");
if (code == EXCEPTION_ACCESS_VIOLATION)
{
return EXCEPTION_EXECUTE_HANDLER;
}
else
{
return EXCEPTION_CONTINUE_SEARCH;
}
}


int _tmain(int argc, _TCHAR* argv[])
{
__try
{
__try
{
__try
{
EnterCriticalSection(&g_cs);
}
__finally
{
OutputDebugStringA("inner\n");
}
}
__finally
{
OutputDebugStringA("outer\n");
}
}
__except(EXCEPTION_EXECUTE_HANDLER/*filter(GetExceptionCode(), GetExceptionInformation())*/)
{
OutputDebugStringA("Got the exception\n");
}

return 0;
}

Answer:

Inside Filter function
Inner
Outer
Got the exception

Summary:

Whenever exception happens it searches for very first __except irrespective of any number of __finally block in between(like above) and then it executes very first finally block and soon...

Why exception has occurred in above code?
Ans: We have not called InitializeCriticalSection().

Where are variables stored?

Local Variables - Stack
Register variables - Register
Global & static variables - data segment.
dynamically created memory - Heap
C program instructions get stored - code segment
extern variables - data segment.

Tuesday, March 23, 2010

Argument of KiUserExceptionDispatcher() function

For hardware generated exceptions (such as access violations), one can look for ntdll!KiUserExceptionDispatcher on the stack, which takes a PCONTEXT and PEXCEPTION_RECORD as argument.

Stack Trace:

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+0xc5

0: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=????????

0:000> dt -r1 0x21eb04 CONTEXT
ntdll!CONTEXT
+0x000 ContextFlags : 0x1003f
+0x004 Dr0 : 0
+0x008 Dr1 : 0
+0x00c Dr2 : 0
+0x010 Dr3 : 0
+0x014 Dr6 : 0
+0x018 Dr7 : 0
+0x01c FloatSave : _FLOATING_SAVE_AREA
   +0x000 ControlWord : 0xffff027f
   +0x004 StatusWord : 0xffff0000
   +0x008 TagWord : 0xffffffff
   +0x00c ErrorOffset : 0
   +0x010 ErrorSelector : 0
   +0x014 DataOffset : 0
   +0x018 DataSelector : 0xffff0000
   +0x01c RegisterArea : [80] ""
   +0x06c Cr0NpxState : 0
+0x08c SegGs : 0
+0x090 SegFs : 0x3b
+0x094 SegEs : 0x23
+0x098 SegDs : 0x23
+0x09c Edi : 0x737b19a4
+0x0a0 Esi : 0x737b19a0
+0x0a4 Ebx : 0xfffffffc
+0x0a8 Edx : 4
+0x0ac Ecx : 0
+0x0b0 Eax : 0
+0x0b4 Ebp : 0x21ee20
+0x0b8 Eip : 0x77d8e13d
+0x0bc SegCs : 0x1b
+0x0c0 EFlags : 0x10213
+0x0c4 Esp : 0x21edd0
+0x0c8 SegSs : 0x23
+0x0cc ExtendedRegisters : [512] "???"

0:000> dt -r1 0x21eae8 EXCEPTION_RECORD
ntdll!EXCEPTION_RECORD
+0x000 ExceptionCode : 0xc0000005
+0x004 ExceptionFlags : 0
+0x008 ExceptionRecord : (null)
+0x00c ExceptionAddress : 0x77d8e13d
+0x010 NumberParameters : 2
+0x014 ExceptionInformation : [15] 1

0:000> !error 0xc0000005
Error code: (NTSTATUS) 0xc0000005 (3221225477) - The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s".


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

How to enable Windows Installer logging

How to enable Windows Installer logging Clickhere!!!

Windows Template Library

Windows Template Library 8.0 Click here!!!

ETW

Event Tracing for Windows

  1. Core OS Events in Windows 7 Click here!!!
  2. Core Instrumentation Events in Windows 7 Click here!!!

IRP

Working With An Incomplete Or Invalid IRP Click here!!!

Windows 7

  1. Introducing The Taskbar APIs Click here!!!
  2. Introducing Libraries Click here!!!

Solving 11 Likely Problems In Your Multithreaded Code

Solving 11 Likely Problems In Your Multithreaded Code Click here!!!

Test Your Security IQ

Test Your Security IQ Click here!!!

Debugging Information

  1. Create Dump File Click Here!!!
  2. Debugging Windows Services Click here!!!
  3. Debugging Winlogon.exe Click here!!!
  4. Debugging CSRSS Click here!!!
  5. 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.

  1. Protecting Your Code with Visual C++ Defenses Click here!!!
  2. FAQ about HeapSetInformation Click here!!!
  3. HeapSetInformation in VC++ 2010 Click here!!!