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

April 8, 2015

Reverse Engineering Vectored Exception Handlers: Structures (1/3)

Filed under: General x86,General x86-64,Programming,Reverse Engineering — admin @ 5:02 PM

This series of posts will cover the details of reverse engineering the AddVectoredExceptionHandler function, a Windows API function responsible for registering a special type of exception handler at runtime. The series will be split in to three parts: first identifying key structures that are used, second understanding the implementation, and lastly re-implementing the reverse engineered assembly to working C code. This reverse engineered implementation will behave identically with the original function, and presumably under the same compiler options, would produce a very close assembly listing. The reverse engineering was done on Windows 7, so there will be slight differences in assembly listings if you are following along on a different version. The re-implementation code (part 3) was tested on Windows 7 and 8.1 on x86 and x64, so the high-level details should not change.

Starting out

The goal is to see how AddVectoredExceptionHandler works. This means tracing it through from an example program over in to kernel32.dll, where the implementation resides. Naturally, the best way to go about doing this is with a debugger. The Visual Studio debugger will be the debugger of choice for this series since we’ll be debugging our own code.

vec1

Stepping in to the disassembly shows that AddVectoredExceptionHandler calls _RtlAddVectoredExceptionHandler, which in turn is a wrapper for _RtlpAddVectoredHandler. The assembly listing for _RtlAddVectoredExceptionHandler is shown below:

_RtlAddVectoredExceptionHandler@8:
771F742B  mov         edi,edi  
771F742D  push        ebp  
771F742E  mov         ebp,esp  
771F7430  push        0  
771F7432  push        dword ptr [ebp+0Ch]  
771F7435  push        dword ptr [ebp+8]  
771F7438  call        _RtlpAddVectoredHandler@12 (771E3621h)  
771F743D  pop         ebp  
771F743E  ret         8

This  code simply pushes an extra constant parameter and invokes _RtlpAddVectoredHandler(FirstHandler, VectoredHandler, 0). The actual details reside in _RtlpAddVectoredHandler, reproduced in its entirety, below:

_RtlpAddVectoredHandler@12:
771E3621  mov         edi,edi  
771E3623  push        ebp  
771E3624  mov         ebp,esp  
771E3626  mov         eax,dword ptr fs:[00000018h]  
771E362C  mov         eax,dword ptr [eax+30h]  
771E362F  push        esi  
771E3630  push        10h  
771E3632  push        0  
771E3634  push        dword ptr [eax+18h]  
771E3637  call        _RtlAllocateHeap@12 (771AE026h)  
771E363C  mov         esi,eax  
771E363E  test        esi,esi  
771E3640  je          _RtlpAddVectoredHandler@12+83h (771E36A4h)  
771E3642  push        ebx  
771E3643  push        edi  
771E3644  push        dword ptr [ebp+0Ch]  
771E3647  mov         dword ptr [esi+8],1  
771E364E  call        _RtlEncodePointer@4 (771C0FCBh)  
771E3653  mov         ebx,dword ptr [ebp+10h]  
771E3656  imul        ebx,ebx,0Ch  
771E3659  add         ebx,77284724h  
771E365F  push        ebx  
771E3660  mov         dword ptr [esi+0Ch],eax  
771E3663  lea         edi,[ebx+4]  
771E3666  call        _RtlAcquireSRWLockExclusive@4 (771B29F1h)  
771E366B  cmp         dword ptr [edi],edi  
771E366D  jne         _RtlpAddVectoredHandler@12+65h (771E3686h)  
771E366F  mov         ecx,dword ptr fs:[18h]  
771E3676  mov         eax,dword ptr [ebp+10h]  
771E3679  mov         ecx,dword ptr [ecx+30h]  
771E367C  add         eax,2  
771E367F  add         ecx,28h  
771E3682  lock bts    dword ptr [ecx],eax  
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],esi  
    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  
771E369C  push        ebx  
771E369D  call        _RtlReleaseSRWLockExclusive@4 (771B29ABh)  
771E36A2  pop         edi  
771E36A3  pop         ebx  
771E36A4  mov         eax,esi  
771E36A6  pop         esi  
771E36A7  pop         ebp  
771E36A8  ret         0Ch  

Decoding the Assembly

Don’t mind the gratuitous highlighting above; it is there to highlight individual pieces of the function and make it more manageable to understand. The function begins by performing a call to RtlAllocateHeap, highlighted in orange. The three parameters provided are [EAX+18], 0, and 16 (0x10). EAX is initially loaded with the address of the TIB structure (light pink). From this structure, the PEB structure is then retrieved. The member at [PEB+0x18], which is documented as ProcessHeap is then given to RtlAllocateHeap. Everything here seems to make sense so far.

Next, in green, comes a call to RtlEncodePointer, which is the implementation of EncodePointer. The address of the vectored handler, at [EBP+0xC] is given as the argument here. This function, as its name implies, is responsible for encoding the provided pointer. It does this by performing an XOR with a cookie value generated at runtime.

From earlier, it should be noticed that the requested allocation size provided to RtlAllocateHeap was 16 bytes (0x10). The next few instructions give some information about how this returned memory is accessed. The instructions in black move two values into this memory region, one at 0x8 and one at 0xC. Given this information, it is safe to assume that what is being allocated is a 16 byte struct. The third field at +0x8 is always set to 1 in this function, and the fourth at +0xC is set to hold the encoded handler address. It’s possible to write out a basic definition for this struct at this point:

struct MysteryStruct
{
    DWORD dwUnknown1; +0x0
    DWORD dwUnknown2; +0x4
    DWORD dwAlwaysOne; +0x8
    PVECTORED_EXCEPTION_HANDLER pVectoredHandler; +0xC
};

This definition will be revisited and completed later.

The next block of code, in teal, performs some arithmetic operations. It loads [EBP+0x10], which was shown to be always 0 (from _RtlAddVectoredExceptionHandler) into EBX. This value is multipled by 12 (0xC), which still yields a zero. Then the value 0x77284724 is added to it. Checking what resides at this address in a debugger shows something interesting:

_LdrpVectorHandlerList:
77284724 01 00                add         dword ptr [eax],eax  
77284726 00 00                add         byte ptr [eax],al  
77284728 28 47 28             sub         byte ptr [edi+28h],al  
7728472B 77 28                ja          _RtlpProcessHeapsListBuffer+15h (77284755h)  
7728472D 47                   inc         edi  
7728472E 28 77 00             sub         byte ptr [edi],dh  
...

It turns out that 0x77284724 is the address of the symbol _LdrpVectorHandlerList. The non-sense assembly instructions there are simply mnemonic representations of _LdrpVectorHandlerList‘s  data members. The base of this structure is used as an argument for _RtlAcquireSRWLockExclusive, which is the implementation of AcquireSRWLockExclusive. This function takes a PSRWLOCK argument. Given this, it is immediately possible to deduce that the first member of _LdrpVectorHandlerList is an SRWLOCK structure. More about this structure will be revealed later.

The code in bright pink begins by loading the second field in the _LdrpVectorHandlerList structure in to EDI. This value is then dereferenced and compared to its own address — basically a check if a pointer is pointing to itself. If that is the case then the rest of the pink block will be executed. The code once again retrieves the PEB structure similar to light pink. Expect this time, [PEB+0x28] will be the value that ends up being used. Additionally, it loads [EBP+0x10] (always 0) into EAX, and adds 2 to it. There it an atomic bit test and set instruction that is carried out between [PEB+0x28] and 2. [PEB+0x28] has been documented as “CrossProcessFlags” and is a bit of a mystery in the context of this function.

Lastly, the block in red is where the actual interesting code happens. It begins by checking to see if the first parameter to the function, the flag saying whether the handler is to be the first or last in the chain, is zero. In either case, there are a lot of pointers moving around from looking at the instructions. One would guess that from implementing an exception handler list that there would be pointers to next/previous nodes. Lets begin investigating the case where an exception handler will be added to front of the chain (FirstHandler parameter does not equal 0). Starting at 0x771E3690, [EDI] is moved into EAX. From earlier, [EDI] holds the second member of the _LdrpVectorHandlerList structure. This is then moved in to [ESI], which is the first member of the structure allocated with RtlAllocateHeap (MysteryStruct above). Then EDI (not dereferenced) is moved in to [ESI+0x4].

This completes finding references to the allocated structure. RtlAllocateHeap had a request for 16 bytes, and 16 bytes have now been used/written to. ESI is then moved in to [EAX+4] and [EDI], which relate to two pointers in _LdrpVectorHandlerList. The part where the handler is added to the back over the list won’t be covered in this post, since it’s basically the same thing except for which pointers get rearranged.

Finalizing Structure Definitions

Going through the code revealed two main structures at work here. There is the 16 byte structure that was allocated in the beginning and the _LdrpVectorHandlerList structure. The MysteryStruct from earlier can be better defined now. I’ve renamed it as _LdrpVectorHandlerEntry to be consistent with the known _LdrpVectorHandlerList symbol.

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

Also, from studying the pointer swapping operations between the new entry and the list, it is possible to define _LdrpVectorHandlerList a bit more clearly as well:

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

The types in these structures have been defined. The next part of this series will cover how the links behave. Follow on Twitter for more updates.

« Newer PostsOlder Posts »

Powered by WordPress