ROR13
[Hashing Home][Home]
ROR13 (rotate right 13) is not a cryptographic hash, but it can be used to take strings of any length, and convert them into an integer value. It is used within executable code to generate an address to an API function within a DLL. The developer, thought, must make sure there is no collisions with other functions in other modules. With ROR13 we take each 8-bit character and then convert to a unicode value (with 16 bits). The result is a 32-bit integer value, and which is used as the address for the API function call. ROR13 (Function).
|
Outline
ROR13 (rotate right 13) is not a cryptographic hash, but it can be used to take strings of any length, and convert them into an integer value. It is used within executable code to generate an address to an API function within a DLL. The developer, thought, must make sure there is no collisions with other functions in other modules. With ROR13 we take each 8-bit character and then convert to a unicode value (with 16 bits). The result is a 32-bit integer value, and which is used as the address for the API function call. With ROR13 we take each 8-bit character and then convert to a unicode value (with 16 bits). We then rotate the bits right by thirteen places:
dword >> 13 | dword << (32 - 13)) & 0xFFFFFFFF
For "Load" we get value is 0xE124D840:
Module: test Function: Load ROR13 Hash: 0x927810A Module ROR13 hash: 0x2802A8CA Function ROR13 hash: 0xE124D840
If the try the example from here:
For a module of "wininet.dll" and a function of "InternetOpenA", we get:
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
The notation we often use for this is "wininet.dll!InternetOpenA". If we try the program, we get:
Module: wininet.dll Function: InternetOpenA ROR13 Hash: 0xa779563a Module ROR13 hash: 0x862e96f8 Function ROR13 hash: 0x214abf42
An example from here is:
;find address of loadLibraryA from kernel32.dll which was found above. mov rdx, 0xec0e4e8e ;lpProcName (loadLibraryA hash from ror13) mov rcx, r12 ;hModule call GetProcessAddress
Coding
The following is the code. In this case, we convert the name of the module into uppercase for the ROR13 operation:
# Some code extracted from https://github.com/iagox86/nbtool/blob/master/samples/shellcode-win32/hash.py import sys def ror(dword, bits): return (dword >> bits | dword << (32 - bits)) & 0xFFFFFFFF def unicode( string, uppercase=True ): result = ""; if uppercase: string = string.upper() for c in string: result += c + "\x00" return result def hash( module, function, bits=13): module_hash = 0 function_hash = 0 for c in unicode( module + "\x00" ): module_hash = ror( module_hash, bits ) module_hash += ord( c ) for c in str( function + "\x00" ): function_hash = ror( function_hash, bits ) function_hash += ord( c ) h = module_hash + function_hash & 0xFFFFFFFF return h module="wininet.dll" function="InternetOpenA" if (len(sys.argv)>1): module=str(sys.argv[1]) if (len(sys.argv)>2): function=str(sys.argv[2]) print("== ROR13 hash ===\n") print("Module:\t\t\t",module) print("Function:\t\t",function) print('Module ROR13 hash:\t0x%X' % hash(module,"")) print('Function ROR13 hash:\t0x%X' % hash("",function)) print('ROR13 Hash:\t\t0x%X' % hash(module,function))
Some well know hashes include the ones from the ws2_32.dll library, and related to the networking functions of bind, listen, accept, closesocket, connect, recv and send [here]:
( 0x6737DBC2, "ws2_32.dll!bind" ), ( 0xFF38E9B7, "ws2_32.dll!listen" ), ( 0xE13BEC74, "ws2_32.dll!accept" ), ( 0x614D6E75, "ws2_32.dll!closesocket" ), ( 0x6174A599, "ws2_32.dll!connect" ), ( 0x5FC8D902, "ws2_32.dll!recv" ), ( 0x5F38EBC2, "ws2_32.dll!send" ),
We can test the bind function with:
== ROR13 hash ===Module: ws2_32.dll Function: bind Module ROR13 hash: 0x9211A042 Function ROR13 hash: 0xD5263B80 ROR13 Hash: 0x6737DBC2
We thus need to make sure we do not have collisions in the API calls that we make for other function calls within modules.