Personally, if you were going to go that route. I'd still try to drop the 'last' parameter from being passed in. It is just extra baggage for someone to maintain in order to call your method.

One solution I can see would be to override a StringReader. The index would still be maintained internal to that object, but at least they don't have access to modifying it or incorrectly passing it back in. The parameter just strikes me as exterior to finding items in a string.

Just a heads up, you might want to review the code:
-GetBetween - You have an extra + 1 on the second argument for computing endIndex.
-GetBetweenExcludeTokens - You didn't subtract the start.Length on the return.