This post is an introduction how shellcode works at the assembly level. I found a simple sample of shellcode on the Internet, which all it did was display a message box displaying “Hello World!” to screen, it also prints out the string length of the shellcode,
For this demonstration this is the code I used:
# include <stdio.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <windows.h>
int main(void)
{
char *shellcode = "\x33\xc9\x64\x8b\x49\x30\x8b\x49\x0c\x8b"
"\x49\x1c\x8b\x59\x08\x8b\x41\x20\x8b\x09"
"\x80\x78\x0c\x33\x75\xf2\x8b\xeb\x03\x6d"
"\x3c\x8b\x6d\x78\x03\xeb\x8b\x45\x20\x03"
"\xc3\x33\xd2\x8b\x34\x90\x03\xf3\x42\x81"
"\x3e\x47\x65\x74\x50\x75\xf2\x81\x7e\x04"
"\x72\x6f\x63\x41\x75\xe9\x8b\x75\x24\x03"
"\xf3\x66\x8b\x14\x56\x8b\x75\x1c\x03\xf3"
"\x8b\x74\x96\xfc\x03\xf3\x33\xff\x57\x68"
"\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68"
"\x4c\x6f\x61\x64\x54\x53\xff\xd6\x33\xc9"
"\x57\x66\xb9\x33\x32\x51\x68\x75\x73\x65"
"\x72\x54\xff\xd0\x57\x68\x6f\x78\x41\x01"
"\xfe\x4c\x24\x03\x68\x61\x67\x65\x42\x68"
"\x4d\x65\x73\x73\x54\x50\xff\xd6\x57\x68"
"\x72\x6c\x64\x21\x68\x6f\x20\x57\x6f\x68"
"\x48\x65\x6c\x6c\x8b\xcc\x57\x57\x51\x57"
"\xff\xd0\x57\x68\x65\x73\x73\x01\xfe\x4c"
"\x24\x03\x68\x50\x72\x6f\x63\x68\x45\x78"
"\x69\x74\x54\x53\xff\xd6\x57\xff\xd0";
DWORD variable;
BOOL ret = VirtualProtect (shellcode, strlen(shellcode),
PAGE_EXECUTE_READWRITE, &variable);
if (!ret) {
printf ("VirtualProtect\n");
return EXIT_FAILURE;
}
printf("strlen(shellcode)=%d\n", strlen(shellcode));//print out length of shellcode
((void (*)(void))shellcode)();//Execute Shellcode
return EXIT_SUCCESS;
}
IDA Pro
When we load the program into IDA PRO and open the main function, we see an unknown pointer to a location in memory. When we look at this more closely we see it’s an unreadable hex string, we can convert this into data to see the assembly code more clearly.
I have converted this variable pointer into a function and called it shellcode function. We can see from the below assembly this shellcode function is moved into a variable pointer which I call shellcode.
The next stage is go get the length of the shellcode. Using the strlen function the length of the code, which is gotten and placed into eax. This is passed as an argument to the printf function where it will output to screen “strlen(shellcode)=199”
The shellcode pointer is passed into EAX. EAX is than called, where the shellcode_function will execute the shellcode, displaying the hello world messagebox.
The Shellcode Function
We will now look more closely at the shellcode_function. The code for this function if you were to write the code in c language would be simple as:
MessageBox(0,”Hello World!”,0,0);
Shellcode does not have access the API Library’s which are needed to get this shellcode to function correctly. The shellcode has to dynamically locate the API functions in order to work it does this using GetProcAddress and LoadLibraryA.
GetProcAddress searches for a library’s exports for the given name, symbol or ordinal number. LoadLibraryA loads a specific library and returns a handle. If shellcode had access to these two functions it can load any library on the system and find exported symbols giving it full access to the API.
We can step through this process in IDA PRO, by using the debugger, allowing us to understand what is happening.
Find GetProcAddress
The first function it has to find is GetProcAddress, which it does by using a do while loop
The shellcode needs to get a handle for LoadLibraryA using GetProcAddress. Then next stage is to get a handle to user32.dll using LoadLibraryA.
The final stage after getting a handle to user32.dll is to get a handle for MessageBoxA and call for it to be executed.
I have recreated the shellcode below, making it more understandable why it needs Handle to the user32.dll and the MessageBox function. If you look below you will see the API GetProcAddress gets a handle to MessageBoxA and placed into a pointer to a function. This function is called, executing the MessageBoxA function, which will display the Messagebox.








