An example of using an undocumented Windows function

Most programs from Sysinternals use undocumented features. I had enough of this fact to become interested in this topic. It is interesting how cool guys use undescribed functions in their equally cool programs.

We assume that we are lazy programmers to the necessary extent, we know C, in tune with WinAPI and with the architecture of the modern Windows OS, and we have Ida Pro, hehe. We want to beautifully, quickly and efficiently complete the task without reinventing the wheel (and so as not to strain our arms and head too much).

Let's look for an experimental function. A lot of goodies can be found in ntdll.dll. I myself am writing from under Win7 64, but I took a 32-bit version of a wonderful library. Just in case:% SystemDisk% \ Windows \ System32 \ ntdll.dll.

To make it simple, open ntdll in Ida and see what functions are exported. If there is no Ida, then you can take any program that works with PE-files (for example, PETools). We are interested in the functions with the Rtl (Run Time Library) prefix. That is, during the execution of our code, we can ask this system function about the service.

After a little search for a simple function, one was found - RtlComputeCrc32.



By double-clicking on the function name we get its disassembled code. You can learn the function with any other disassembler like HDasm or W32Dasm. In order not to waste space, I will cite the pseudocode RtlComputeCrc32, kindly provided by the Ida decompiler (press F5 in the function body if Hex-Rays Decompiler is available in the Edit-> Plugins plugins).



We get a lot of information right away! You have to think what we are actually looking for. We need:
1) the name of the function to get its address in ntdll;
2) the prototype of the function to create the correct pointer to it;
3) an approximate principle of operation in order to pass the correct arguments to it and correctly process the result;

Items 1-2 we already have from the pseudocode. Our task now is to understand the function and based on it to write a program that calculates CRC32 from something.

It’s easy to understand from the pseudo-code that the function iterates over the bytes of the array a2 , whose size is a3 , and a1Is the initialization value of the algorithm. Having done the calculations with bytes, it gets the index from the RtlCrc32Table table (double-clicking will show the monstrous table). Google CRC32 and implementation examples and we understand that everything is right.

The thing is small - take advantage of prey. I made an empty console application in Visual Studio, but of course you can do it in any other environment.

GetModuleHandle () returns the ntdll handle, GetProcAddress () is the address of the function. We use a pointer to a function of type UndocFoo to call RtlComputeCRC32 ().

#include 
#include 
typedef INT (WINAPI *UndocFoo)(INT accumCRC32, const BYTE* buffer, UINT buflen);
int main()
{
	HMODULE hDLL = GetModuleHandle(TEXT("ntdll.dll"));
	if (hDLL == NULL)
	{
		puts("[-] Failed to find ntdll.dll\n");
		return EXIT_FAILURE;
	}
	puts("[+] Got ntdll.dll handle\n");
	UndocFoo ComputeCrc32 = (UndocFoo)GetProcAddress(hDLL, "RtlComputeCrc32");
	if (ComputeCrc32 == NULL)
	{
		puts("[-] Failed to find RtlComputeCrc32\n");
		return EXIT_FAILURE;
	}
	puts("[+] Found RtlComputeCrc32 address\n");
	puts("[*] Calling RtlComputeCrc32...\n");
	BYTE buffer[] = {0x01, 'a', 7};
	INT iCRC32 = ComputeCrc32(INT(0), (BYTE*)buffer, 3);
	printf("[+] Computed CRC32 --> 0x%x\n\n", iCRC32);
	puts("Press any key to quit\n");
	getchar();
	return EXIT_SUCCESS;
}




Success. You can check using any online calculator.
Our bytes 016107 gave CRC32 = 0x1c017c60.



The online calculator gave the same thing:



So, without wasting time implementing our own function or using someone else’s big code, we made such a wonderful program. It was easy and fun.

Also popular now: