Exemplo n.º 1
0
 /// <summary>
 /// Restores the context by loading the values from the given context.
 /// </summary>
 /// <param name="context">The register context to restore the state from</param>
 private static void RestoreContext(RegisterContext context)
 {
     Native.RestoreContext(context.Ebp, context.Esp, context.Eip);
     //Native.RestoreContext(context.edi, context.esi, context.ebp, context.esp, context.ebx, context.edx, context.ecx, context.eax);
 }
Exemplo n.º 2
0
 /// <summary>
 /// Call the appropriate handler or rethrow the exception
 /// </summary>
 /// <param name="registerContext">The register status right before the throw</param>
 /// <param name="exception">The thrown exception</param>
 /// <param name="eip">EIP to return to when handled</param>
 private static void HandlerInvocationPass(RegisterContext registerContext, uint exception, uint eip)
 {
 }
Exemplo n.º 3
0
 /// <summary>
 /// Calls the given filter to handle the exception
 /// </summary>1
 /// <param name="registerContext">The register status right before the throw</param>
 /// <param name="exceptionInformation">The exception handler information</param>
 private static void CallFilter(RegisterContext registerContext, object exceptionInformation)
 {
     //Native.CallFilter();
 }
Exemplo n.º 4
0
        /// <summary>
        /// Tries to handle the exception by searching the method header for a suitable exception handler/filter.
        /// </summary>
        /// <param name="registerContext">The register status right before the throw</param>
        /// <param name="exception">The thrown exception</param>
        /// <param name="eip">EIP to return to when handled</param>
        private static unsafe void HandleException(RegisterContext registerContext, uint exception, uint eip)
        {
            // Get the method lookup entry
            uint methodLookupEntry = GetMethodLookupEntry(registerContext.Eip);

            if (methodLookupEntry == 0)
            {
                // We're not in a compiled method - where are we?

                // Go panic!
            }

            // Find the method description
            uint methodDescription = GetMethodDescription(methodLookupEntry);

            // Get the protected block table
            uint exceptionHandlerTable = GetExceptionHandlerTable(methodDescription);

            if (exceptionHandlerTable == 0)
            {
                // Method does not have any protected blocks

                // At-the-moment: All methods have this table, even if the method doesn't have any exceptions.

                // Go panic!

                // TODO
                // 1. Unwind stack
                //   A. If at top of stack then notify kernel to terminate this thread
                // 2. Update EIP of calling method
                // 3. Re-execute this method to look for a protected block
            }

            // Get the protected block
            uint protectedBlock = GetProtectedBlock(exceptionHandlerTable, eip, 0);

            if (protectedBlock == 0)
            {
                // No protected block

                // TODO
                // 1. Unwind stack
                //   A. If at top of stack then notify kernel to terminate this thread
                // 2. Update EIP of calling method
                // 3. Re-execute this method to look for a protected block
            }

            uint* entry = (uint*)protectedBlock;
            uint exceptionType = entry[0];
            uint handlerOffset = entry[3];

            uint methodStart = GetMethodStartAddress(methodLookupEntry);

            uint handler = methodStart + handlerOffset;

            // TODO:

            if (exceptionType == 0) // exception handler type
            {
                // TODO
                // Set next EIP to exception handler
                // Place exception object in EDX
                // Restore Context (e.g. execute return)

            }
            else if (exceptionType == 2) // finally handler type
            {
                // TODO
                // Set next EIP to exception handler
                // Call finally handler (with return address on stack to resume search for next protected block or exception)
            }
            else
            {
                // Go panic!
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Saves the context and handles the exceptions.
        /// </summary>
        /// <param name="edi">The edi.</param>
        /// <param name="esi">The esi.</param>
        /// <param name="ebp">The ebp.</param>
        /// <param name="esp">The esp.</param>
        /// <param name="ebx">The ebx.</param>
        /// <param name="edx">The edx.</param>
        /// <param name="ecx">The ecx.</param>
        /// <param name="eax">The eax.</param>
        public static unsafe void ThrowException(uint edi, uint esi, uint ebp, uint esp, uint ebx, uint edx, uint ecx, uint eax, uint exception)
        {
            // EIP is on the stack

            // Two ways to get this:
            // 1. As an offset from the ESP stored on the stack; offset is -36 (just after the 9 x 32-bit values that the pushad operand pushed)
            uint eip = (uint)((uint*)(esp - (9 * 4)));

            // 2. As an offset from GetEBP(); offset is +4 (the EIP stored by the CALL operand)
            uint eip2 = (uint)((uint*)(Native.GetEBP() + 4));

            // Create context
            RegisterContext registerContext = new RegisterContext(eax, ebx, ecx, edx, esi, edi, ebp, eip, esp);

            // Try to handle the exception
            HandleException(registerContext, exception, eip);

            // Return after exception has been handled
            RestoreContext(registerContext);
        }