API-Resolving

API Resolving
Although it has a functional use, it can be abused quite simply, causing disruption in the analysis process.
This technique, which can be handle very quickly if known, will cause you to show an incomplete report to your potential readers if unknown or overlooked :))
If so, why does Microsoft allow this?
In fact, it is aimed to help us do dynamic programming. In some functions, you may come across the phrase may be altered or unavailable in future versions. Since these functions cannot be reached with a direct call, we need to call them by taking their address. Of course, by using this approach for current functions, the can aim to not see which APIs are used during static analysis. So, when the technique is easy, all kinds of additions are made in order to diversify it even more. If you like the technique, I suggest you also research API HASHING.
C++
void message() {
while (1)
std::cout << "message\n";
}
int main()
{
string str = "rCTPETeYCTPU"; // CreateThread xor 1
string Func;
char key = '1';
for (int i = 0; i < str.length(); i++)
Func += str[i] ^ key; // Func = CreateThread
typedef DWORD(WINAPI* MyFuncPtr)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD); // CreateThread Fonksiyonunun parametreleri aynı olan bir fonksiyon tanımlıyoruz
MyFuncPtr RUN = (MyFuncPtr)GetProcAddress(LoadLibrary(L"Kernel32.dll"), Func.c_str()); // GetProcAddress ile Func değişkenindeki API'nin adresini alıyoruz
RUN(NULL, 0, (LPTHREAD_START_ROUTINE)message, NULL, 0, NULL); // Artık CreateThread gibi çalıştırabiliriz
while (1)
std::cout << "MAIN\n"; // programı çalıştırarak konsolda "MAIN" ve "message" yazılarını gözlemleyebilirsiniz.
}

It doesn’t seem to use any CreateThread API.
Practice

While compiling the code in the image, encryption was not applied, it is clearly seen which function was called.

Although the technique is known, in order to understand the function to be called here, it must be either decrypted or dynamically arrived at.
Let's go one step further. The GetProcAddress we use gives us a address dynamically, as DWORD type. What if we try to take it as static?
There is a small risk, of course, but let's grasp the theory first.

The eax value 75D50000 after the LoadLibrary call. This is the starting address of Kernel32.dll, but we need CreateThread in it and when we call GetProcAddress for reach the CreateThread address we can see it in eax “75D6CBC0”.

The difference is “1CBC0”, that is, if we add this difference to the variable we assigned the LoadLibrary value to, we will actually reach the CreateThread address.
The problem is that after a minor update the CreateThread address in the file may change. Therefore, the value we assign static will show a completely different address, so it will be inoperable. In this case you will need to check the version and run it. How hard you try now is up to you :))
~Fall in love with the process, and the results will come.

