I would like to share a very simple way of hiding your API call from static analyses. Actually, there are many ways to hide it but let start from the easiest and common way.
As we know that the behaviour of malware could also be determined by what API call’s it does either to User32 or Kernel32. For malware creator it is important to hide them in order to make the detection harder.
We know that in the PE header there is a section called Import table where it contains all API call made to loadable module like user32, kernel32 or any other dll. The list will look like below table

Lets look simple code below and check what the import table looks like
#include <windows.h>
#include <iostream>
int main()
{
std::cout << "Rio Test\n";
int msgboxID = MessageBox(
NULL,
(LPCWSTR)L"Resource not available\nDo you want to try again?",
(LPCWSTR)L"Account Details",
MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2
);
}

Because of the code statically use MessageBox wich invokes MessageBoxW API call to user32 then the compiler will add MessageBoxW to the import table. See highligted below

Based on above table, The malware analyst or sandboxing system will be able to determine that your application will call MessageBox somewhere in the code so that it is easier to identify it during static analysis.
In order to hide it from the import table, You can call the MessageBox dynamically so that API MessageBoxW will not be listed out in the import table. The code will look like this
#include <windows.h>
#include <iostream>
typedef int (*Msg)(HWND, LPCTSTR, LPCTSTR, UINT);
int main()
{
HINSTANCE hDLL = LoadLibrary("User32.dll");
if (hDLL == NULL) {
std::cout << "Failed to load the library.\n";
}
else {
std::cout << "Library loaded.\n";
std::cout << "Rio Test\n";
Msg MsgBox = (Msg)GetProcAddress(hDLL, "MessageBoxA");
MsgBox(
NULL,
"Resource not available\nDo you want to try again?",
"Account Details",
MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2
);
}
FreeLibrary(hDLL);
return 0;
}

With the above code we basically load the user32.dll dynamically during the runtime by calling LoadLibrary(“User32.dll”);. In order get the address of MessageBoxW address from the user32.dll, We need to call GetProcAddress(hDLL, “MessageBoxA”) where it will return the pointer to the MessageBoxA
If we look at the import table, We cannot find that MessageBoxA or MessageBoxW is in the table and even we cannot find user32.dll is in the list

So with the help of dynamic loading, we are able to hide some artefacs of API call from the import table which help the malware analyst or sandbox to determine the behaviour of the application.
But as the analyst we should not only rely on the one place to determine the behaviour of the malware. With the above code samples, Basically the malware analyst could also check the strings collected from the code. Here our API call could be seen by the malware analyst.

Malware analyst will be able to spot API call if they eye ball to this list
I will explain in the next post on how to evade this detection so that it is harder to spot from the prying eyes.