コード例 #1
0
ファイル: VadRoutines.c プロジェクト: 9176324/Blackbone
/// <summary>
/// Find VAD that describes target address
/// </summary>
/// <param name="pProcess">Target process object</param>
/// <param name="address">Address to find</param>
/// <param name="pResult">Found VAD. NULL if not found</param>
/// <returns>Status code</returns>
NTSTATUS BBFindVAD( IN PEPROCESS pProcess, IN ULONG_PTR address, OUT PMMVAD_SHORT* pResult )
{
    NTSTATUS status = STATUS_SUCCESS;
    ULONG_PTR vpnStart = address >> PAGE_SHIFT;

    ASSERT( pProcess != NULL && pResult != NULL );
    if (pProcess == NULL || pResult == NULL)
        return STATUS_INVALID_PARAMETER;

    if (dynData.VadRoot == 0)
    {
        DPRINT( "BlackBone: %s: Invalid VadRoot offset\n", __FUNCTION__ );
        status = STATUS_INVALID_ADDRESS;
    }


    PMM_AVL_TABLE pTable = (PMM_AVL_TABLE)((PUCHAR)pProcess + dynData.VadRoot);
    PMM_AVL_NODE pNode = GET_VAD_ROOT( pTable );

    // Search VAD
    if (MiFindNodeOrParent( pTable, vpnStart, &pNode ) == TableFoundNode)
    {
        *pResult = (PMMVAD_SHORT)pNode;
    }
    else
    {
        DPRINT( "BlackBone: %s: VAD entry for address 0x%p not found\n", __FUNCTION__, address );
        status = STATUS_NOT_FOUND;
    }

    return status;
}
コード例 #2
0
ファイル: PrivateRoutines.c プロジェクト: d366/DarkMMap
VOID
MiInsertNode (
    IN PMMADDRESS_NODE NodeToInsert,
    IN PMM_AVL_TABLE Table
    )

/*++

Routine Description:

    This function inserts a new element in a table.

Arguments:

    NodeToInsert - The initialized address node to insert.

    Table - Pointer to the table in which to insert the new node.

Return Value:

    None.

Environment:

    Kernel mode.  The PFN lock is held for some of the tables.

--*/

{
    //
    // Holds a pointer to the node in the table or what would be the
    // parent of the node.
    //

    PMMADDRESS_NODE NodeOrParent;
    TABLE_SEARCH_RESULT SearchResult;

    SearchResult = MiFindNodeOrParent (Table,
                                       (ULONG_PTR)((PMMVAD_SHORT)NodeToInsert)->StartingVpn,
                                       &NodeOrParent);


    //
    // The node wasn't in the (possibly empty) tree.
    //
    // We just check that the table isn't getting too big.
    //

    NodeToInsert->LeftChild = NULL;
    NodeToInsert->RightChild = NULL;

    Table->NumberGenericTableElements += 1;

    //
    // Insert the new node in the tree.
    //

    if (SearchResult == TableEmptyTree) {

        Table->BalancedRoot.RightChild = NodeToInsert;
        NodeToInsert->u1.Parent = &Table->BalancedRoot;
        Table->DepthOfTree = 1;

    }
    else {

        PMMADDRESS_NODE R = NodeToInsert;
        PMMADDRESS_NODE S = NodeOrParent;

        if (SearchResult == TableInsertAsLeft) {
            NodeOrParent->LeftChild = NodeToInsert;
        }
        else {
            NodeOrParent->RightChild = NodeToInsert;
        }

        NodeToInsert->u1.Parent = NodeOrParent;

        //
        // The above completes the standard binary tree insertion, which
        // happens to correspond to steps A1-A5 of Knuth's "balanced tree
        // search and insertion" algorithm.  Now comes the time to adjust
        // balance factors and possibly do a single or double rotation as
        // in steps A6-A10.
        //
        // Set the Balance factor in the root to a convenient value
        // to simplify loop control.
        //

        COUNT_BALANCE_MAX ((SCHAR)-1);
        Table->BalancedRoot.u1.Balance = (ULONG_PTR) -1;

        //
        // Now loop to adjust balance factors and see if any balance operations
        // must be performed, using NodeOrParent to ascend the tree.
        //

        for(;;) {

            SCHAR a;

            //
            // Calculate the next adjustment.
            //

            a = 1;
            if (MiIsLeftChild (R)) {
                a = -1;
            }

            //
            // If this node was balanced, show that it is no longer and
            // keep looping.  This is essentially A6 of Knuth's algorithm,
            // where he updates all of the intermediate nodes on the
            // insertion path which previously had balance factors of 0.
            // We are looping up the tree via Parent pointers rather than
            // down the tree as in Knuth.
            //

            if (S->u1.Balance == 0) {

                COUNT_BALANCE_MAX ((SCHAR)a);
                S->u1.Balance = a;
                R = S;
                S = SANITIZE_PARENT_NODE (S->u1.Parent);
            }
            else if ((SCHAR) S->u1.Balance != a) {


                //
                // If this node has the opposite balance, then the tree got
                // more balanced (or we hit the root) and we are done.
                //
                // Step A7.ii
                //

                S->u1.Balance = 0;

                //
                // If S is actually the root, then this means the depth
                // of the tree just increased by 1!  (This is essentially
                // A7.i, but we just initialized the root balance to force
                // it through here.)
                //

                if (Table->BalancedRoot.u1.Balance == 0) {
                    Table->DepthOfTree += 1;
                }

                break;
            }
            else {

                //
                // The tree became unbalanced (path length differs
                // by 2 below us) and we need to do one of the balancing
                // operations, and then we are done.  The RebalanceNode routine
                // does steps A7.iii, A8 and A9.
                //

                MiRebalanceNode (S);
                break;
            }
        }
    }

    //
    // Sanity check tree size and depth.
    //


    return;
}