Ignore:
Timestamp:
Feb 25, 2010, 6:43:10 PM (15 years ago)
Author:
vladest
Message:

KERNEL32:

  • Added some security related functions
  • removed extra logging
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/heap.cpp

    r21337 r21361  
    925925//******************************************************************************
    926926//******************************************************************************
     927
     928/*************************************************************************
     929 * RtlUniform *
     930 * Generates an uniform random number
     931 *
     932 * PARAMS
     933 *  seed [O] The seed of the Random function
     934 *
     935 * RETURNS
     936 *  It returns a random number uniformly distributed over [0..MAXLONG-1].
     937 *
     938 * NOTES
     939 *  Generates an uniform random number using D.H. Lehmer's 1948 algorithm.
     940 *  In our case the algorithm is:
     941 *
     942 *|  result = (*seed * 0x7fffffed + 0x7fffffc3) % MAXLONG;
     943 *|
     944 *|  *seed = result;
     945 *
     946 * DIFFERENCES
     947 *  The native documentation states that the random number is
     948 *  uniformly distributed over [0..MAXLONG]. In reality the native
     949 *  function and our function return a random number uniformly
     950 *  distributed over [0..MAXLONG-1].
     951 */
     952ULONG WINAPI RtlUniform (PULONG seed)
     953{
     954    ULONG result;
     955
     956   /*
     957    * Instead of the algorithm stated above, we use the algorithm
     958    * below, which is totally equivalent (see the tests), but does
     959    * not use a division and therefore is faster.
     960    */
     961    result = *seed * 0xffffffed + 0x7fffffc3;
     962    if (result == 0xffffffff || result == 0x7ffffffe) {
     963        result = (result + 2) & MAXLONG;
     964    } else if (result == 0x7fffffff) {
     965        result = 0;
     966    } else if ((result & 0x80000000) == 0) {
     967        result = result + (~result & 1);
     968    } else {
     969        result = (result + (result & 1)) & MAXLONG;
     970    } /* if */
     971    *seed = result;
     972    return result;
     973}
     974
     975static DWORD_PTR get_pointer_obfuscator( void )
     976{
     977    static DWORD_PTR pointer_obfuscator;
     978
     979    if (!pointer_obfuscator)
     980    {
     981        ULONG seed = GetTickCount();
     982        ULONG_PTR rand;
     983
     984        /* generate a random value for the obfuscator */
     985        rand = RtlUniform( &seed );
     986
     987        /* handle 64bit pointers */
     988        rand ^= (ULONG_PTR)RtlUniform( &seed ) << ((sizeof (DWORD_PTR) - sizeof (ULONG))*8);
     989
     990        /* set the high bits so dereferencing obfuscated pointers will (usually) crash */
     991        rand |= (ULONG_PTR)0xc0000000 << ((sizeof (DWORD_PTR) - sizeof (ULONG))*8);
     992
     993        InterlockedCompareExchange( (PLONG) &pointer_obfuscator, (LONG) rand, NULL );
     994    }
     995
     996    return pointer_obfuscator;
     997}
     998
     999/*************************************************************************
     1000 * EncodePointer
     1001 */
     1002PVOID WINAPI EncodePointer( PVOID ptr )
     1003{
     1004    DWORD_PTR ptrval = (DWORD_PTR) ptr;
     1005    return (PVOID)((ULONG)ptrval ^ (ULONG)get_pointer_obfuscator());
     1006}
     1007
     1008PVOID WINAPI DecodePointer( PVOID ptr )
     1009{
     1010    DWORD_PTR ptrval = (DWORD_PTR) ptr;
     1011    return (PVOID)((ULONG)ptrval ^ (ULONG)get_pointer_obfuscator());
     1012}
     1013
Note: See TracChangeset for help on using the changeset viewer.