RCE Endeavors 😅

May 10, 2015

Debugging Injected DLLs

Filed under: General x86,General x86-64,NoCode,Programming — admin @ 11:58 AM

A quick post on how to debug injected DLLs through Visual Studio. This is rather straightforward, but it seems like a fair amount of people are unaware that this can be done. It might possibly because programs typically don’t have DLLs injected to them at runtime, so perhaps people think that debugging them can’t be done in a straightforward way. Fortunately, if you attach to the target process beforehand and inject a DLL, the Visual Studio debugger will detect the loaded DLL and allow for an ordinary debugging experience. The steps are rather simple:

1. Choose to attach to a process through the “Debug” menu in Visual Studio.

dbg1

2. Select the target process from the list and attach.

dbg2

3. Attach to the process and verify that breakpoints can get hit.

dbg3And that’s all there is to it. All of the useful features of the Visual Studio debugger are now available for debugging the injected DLLs.

April 24, 2015

Code Snippets: FindWindowLike

Filed under: General x86,General x86-64,Programming — admin @ 6:06 PM

Like many developers who write code in their free time, I have an overwhelming backlog of side projects. A lot of these projects don’t get finished for the usual variety of reasons: lack of time, loss of interest, another side projects comes up, and so on. As I searched through the folders of these projects, I realized that while I might not be able to complete them now or in the future, that there are certain portions of them that I can carve out and post about. These snippets will typically be short code blocks that I had written to solve a rather particular problem at the time.

The code snippet covered here will be a function I wrote called FindWindowLike. Interestingly enough, while Googling this, there appears to be an MSDN article from 1997 which lists a VB6 function that does the same thing. The one posted here is implemented much differently than that horrible mess though. The purpose of this function is to get a handle to a window while knowing only part of its title. This was useful when I was trying to get a window handle which changed on every instance of the program — for example the process id was part of the title. The code is very straightforward and uses EnumWindows to enumerate all windows on the desktop and perform a substring match.

typedef struct
{
    const TCHAR * const pPartialTitle;
    const bool bCaseSentitive;
    HWND hFoundHandle;
} WindowInformation;
 
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    //Read up to 255 characters of window title
    TCHAR strWindowTitle[255] = { 0 };
 
    auto success = GetWindowText(hWnd, strWindowTitle, sizeof(strWindowTitle));
    if (success > 0)
    {
        WindowInformation *pWindowInfo = (WindowInformation *)lParam;
        auto isFound = pWindowInfo->bCaseSentitive ?
            StrStr(strWindowTitle, pWindowInfo->pPartialTitle) :
            StrStrI(strWindowTitle, pWindowInfo->pPartialTitle);
        if (isFound)
        {
            pWindowInfo->hFoundHandle = hWnd;
            return FALSE;
        }
    }
 
    return TRUE;
}
 
const HWND FindWindowLike(const TCHAR * const pPartialTitle, const bool bCaseSensitive = true)
{
    WindowInformation windowInfo = { pPartialTitle, bCaseSensitive, nullptr };
    (void)EnumWindows(EnumWindowsProc, (LPARAM)&windowInfo);
 
    if (windowInfo.hFoundHandle == nullptr)
    {
        fprintf(stderr, "Could not find window.\n");
    }
 
    return windowInfo.hFoundHandle;
}

The sample code is hosted on GitHub here.

April 16, 2015

Everything up on Github

Filed under: NoCode — admin @ 7:58 PM

I’ve finally and painstakingly moved all of the code relating to my previous blogs posts to GitHub. The descriptions in the repositories are not very descriptive (that’s what the actual blog posts are for!), but now the code is available to look at without needing to download and unzip archives. The GitHub site is https://github.com/codereversing/. Going through this also allowed me to see how my programming style (indent, variable/function naming) has evolved. I definitely prefer the more .NET type of style

if(someVariable == 10)
{
    f();
}
else
{
    g();
}

to the more space conscious, but harder to read, K&R C style

if(some_variable == 10) {
    f();
} else {
    g();
}

All future code will be posted on GitHub now instead of zipped and linked through the blog post.

April 13, 2015

Reverse Engineering Vectored Exception Handlers: Implementation (3/3)

Filed under: General x86,General x86-64,Programming,Reverse Engineering — admin @ 8:33 AM

Here an implementation of AddVectoredExceptionHandler as it was reverse engineered.

PVOID RtlAddVectoredExceptionHandler(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler, int Unknown)
{
    PPEB pPeb = GetPEB();
 
    VECTORED_HANDLER_ENTRY *pVecNewEntry =
        (VECTORED_HANDLER_ENTRY *)HeapAlloc((HANDLE)pPeb->ProcessHeap, 0, sizeof(VECTORED_HANDLER_ENTRY));
    if(pVecNewEntry == nullptr)
    {
        return nullptr;
    }
    pVecNewEntry->dwAlwaysOne = 1;
 
    PVOID pEncodedHandler = EncodePointer(VectoredHandler);
    VECTORED_HANDLER_LIST *pVecHandlerBase = (VECTORED_HANDLER_LIST *)(VectorHandlerListBase);
 
    AcquireSRWLockExclusive(&pVecHandlerBase->srwLock);
 
    pVecNewEntry->pVectoredHandler = (PVECTORED_EXCEPTION_HANDLER)pEncodedHandler;
 
    //If the list is empty then set the CrossProcessFlags fields
    if(pVecHandlerBase->pFirstHandler == (VECTORED_HANDLER_ENTRY *)&pVecHandlerBase->pFirstHandler)
    {
        InterlockedBitTestAndSet((LONG *)&pPeb->CrossProcessFlags, 2);
    }
 
    if(FirstHandler)
    {
        //Insert new node at the head of the VEH list
        pVecNewEntry->pNext = pVecHandlerBase->pFirstHandler;
        pVecNewEntry->pPrev = (VECTORED_HANDLER_ENTRY *)&pVecHandlerBase->pFirstHandler;
        pVecHandlerBase->pFirstHandler->pPrev = pVecNewEntry;
        pVecHandlerBase->pFirstHandler = pVecNewEntry;
    }
    else
    {
        //Insert new node at the end of the VEH list
        pVecNewEntry->pNext = (VECTORED_HANDLER_ENTRY *)&pVecHandlerBase->pFirstHandler;
        pVecNewEntry->pPrev = pVecHandlerBase->pLastHandler;
        pVecHandlerBase->pLastHandler->pNext = pVecNewEntry;
        pVecHandlerBase->pLastHandler = pVecNewEntry;
    }
 
    ReleaseSRWLockExclusive(&pVecHandlerBase->srwLock);
 
    return (PVOID)pVecNewEntry;
}

You can download the full Visual Studio 2013 project here. Follow on Twitter for more updates.

April 11, 2015

Reverse Engineering Vectored Exception Handlers: Functionality (2/3)

Filed under: General x86,General x86-64,Programming,Reverse Engineering — admin @ 11:00 AM

This post will continue where the first one left off and explain the operations happening on the doubly linked list of exception handlers. To understand anything in this post, you should read the first one.

Finding the Link Relationships

Given the information from part one, there are two structures at work here: _LdrpVectorHandlerList, which is a non-exported named symbol, and _LdrpVectorHandlerEntry, which is the name given to the struct allocated in _RtlpAddVectoredHandler. Each of these structures has two pointers within them that get moved around.

771E3686 cmp dword ptr [ebp+8],0
771E368A je _RtlpAddVectoredHandler@12+13DF3h (771F7414h)
--------> Jump resolved below
----771F7414 mov eax,dword ptr [edi+4]
----771F7417 mov dword ptr [esi],edi
----771F7419 mov dword ptr [esi+4],eax
----771F741C mov dword ptr [eax],es
----771F741E mov dword ptr [edi+4],esi
----771F7421 jmp _RtlpAddVectoredHandler@12+7Bh (771E369Ch)
771E3690 mov eax,dword ptr [edi]
771E3692 mov dword ptr [esi],eax
771E3694 mov dword ptr [esi+4],edi
771E3697 mov dword ptr [eax+4],esi
771E369A mov dword ptr [edi],esi
vec4

The best way to find out what is happening is to dynamically trace adding exception handlers. For example, what goes on in the code when three exception handlers are added in series?Each one will be added to the head of the list, so that if an exception occurs then the call order will be VectoredHandler3 -> VectoredHandler2 -> VectoredHandler1 -> Unhandled exception. For the case of a handler being inserted at the head of the list, the following instructions will be executed:

771E3690 mov eax,dword ptr [edi]
771E3692 mov dword ptr [esi],eax
771E3694 mov dword ptr [esi+4],edi
771E3697 mov dword ptr [eax+4],esi
771E369A mov dword ptr [edi],esi

The easiest way to see what is going on is to make a table of the runs. Here let X, Y, Z be the different memory addresses of ESI. Let Base be the base address of _LdrpVectorHandlerList, relative to EAX and EDI. I’ve also reproduced the structures and the mappings of registers to fields below.

typedef struct _LdrpVectorHandlerEntry
{
    _LdrpVectorHandlerEntry *pLink1; +0x0 [ESI]
    _LdrpVectorHandlerEntry *pLink2; +0x4 [ESI+0x4]
    DWORD dwAlwaysOne; +0x8
    PVECTORED_EXCEPTION_HANDLER pVectoredHandler; +0xC
} VECTORED_HANDLER_ENTRY, *PVECTORED_HANDLER_ENTRY;

typedef struct _LdrpVectorHandlerList
{
    SRWLOCK srwLock; +0x0
    VECTORED_HANDLER_ENTRY *pLink1; +0x4 [EDI]
    VECTORED_HANDLER_ENTRY *pLink2; +0x8
} VECTORED_HANDLER_LIST, *PVECTORED_HANDLER_LIST; +0xC

First run

[X][X+4][*(Base+4)][Base]
0x772847280x77284728XX

Second run

[Y][Y+4][*(Base+4)][Base]
X0x77284728YY

Third run

[Z][Z+4][*(Base+4)][Base]
Y0x77284728ZZ

Looking at the results of these three adds, you can begin to see a relationship.

[X] = [ESI] Always holds the address of the previous handler

[X+4] = [ESI+0x4] Always holds the address of the base of the table

[*(Base+4)] = [EAX+0x4] Always holds the address of the new handler

[Base] = [EDI] Always holds the address of the new handler

Given that this operation is to insert at the head of the list, it is possible to draw some conclusions. Since [ESI] always contains the address of the previous topmost handler, it can be assumed to be a pointer to the next handler in the chain. [ESI+0x4] can be assumed to be a pointer to the previous handler in the chain, which in the case of inserting a head node, is set as the base of the exception list. Now the struct definition can be completed.

typedef struct _LdrpVectorHandlerEntry { _LdrpVectorHandlerEntry *pNext; _LdrpVectorHandlerEntry *pPrev; DWORD dwAlwaysOne; PVECTORED_EXCEPTION_HANDLER pVectoredHandler; } VECTORED_HANDLER_ENTRY, *PVECTORED_HANDLER_ENTRY;

[EAX+0x4] is a bit more difficult to discern. EAX holds the value of the address of the second field in _LdrpVectorHandlerList. This is dereferenced and the second item in the dereferenced struct is set to the address of the new handler. What is happening here is that the pPrev field of the current topmost handler prior to inserting a new one is set to the address of the new handler, thus keeping the list chain intact. This may not seem obvious from looking at the assembly but is what is occurring when actually stepping through the instructions with a debugger. Lastly, EDI, which is the first member of _LdrpVectorHandlerList is set to hold the address of the new handler.

Now for the other case: inserting at the back of the vectored exception list. In that scenario, the following instructions will be executed:

771F7414 mov eax,dword ptr [edi+4]
771F7417 mov dword ptr [esi],edi
771F7419 mov dword ptr [esi+4],eax
771F741C mov dword ptr [eax],esi
771F741E mov dword ptr [edi+4],esi
771F7421 jmp _RtlpAddVectoredHandler@12+7Bh (771E369Ch)

This is a slight variation on the first case. The best way to see what is going on is to step through the assembly code again. Here X, Y, and Z will map to [ESI] like last time. Here Base will be [EDI+0x4], the third member of _LdrpVectorHandlerList — unlike [EDI] in the previous segment, which was the second member. [Base+0x4] will be [EDI + 0x4].

First run

[X][X+4][Base][*(Base+4)]
0x772847280x77284728XX

Second run

[Y][Y+4][Base][*(Base+4)]
0x77284728XYY

Third run

[Z][Z+4][Base][*(Base+4)]
0x77284728YZZ

Again,

[X] = [ESI]  Always holds the address of the base of the table

[X+4] = [ESI+0x4] Holds the address of the previous handler

[Base] = [EAX] Holds the address to the new handler

[*(Base +4)] = [EDI+0x4] Holds the address of the new handler

Here, the mappings that were established for [X] and [X+4] as pNext and pPrev still make sense. For a node inserted at the back of the exception list, pNext will point to the base of the table (end), and pPrev will point to the address of the previous handler. Here [Base] is the third member of _LdrpVectorHandlerList. Given what is known from the previous run and this one, it is possible to draw a conclusion that the two pointers in _LdrpVectorHandlerList are pointers to the first and last exception handlers. The definition of _LdrpVectorHandlerList can now be completed.

typedef struct _LdrpVectorHandlerList { SRWLOCK srwLock; VECTORED_HANDLER_ENTRY *pFirstHandler; VECTORED_HANDLER_ENTRY *pLastHandler; } VECTORED_HANDLER_LIST, *PVECTORED_HANDLER_LIST;

That wraps up the implementation details of vectored exception handlers. The full C implementation will be provided in the next post. Follow on Twitter for more updates.

Follow me

« Newer PostsOlder Posts »

Powered by WordPress