I had written some windows PE shellcode since last year. However, when i try to fit the shellcode into my main windows code it will crash sometimes (the shellcode runs smoothly but it exits with error). Picture below shows the issue that i mentioned above.
After the investigation by using the debugger, i found out there is an esp repositioning issue when the program starts to exit. This cause the program returns to a unknown memory space.
Exit with error (Cause Analysis)
First, the program is push all the registers (eax, ebx, ecx, edx, esi, edi, ebp) into the stack, actually
push ebp itself is enough. You can see the register’s value at the bottom right of the picture from 0x79fb30 til 0x79fb18. Just keep an eye on these value.
After the program ready to return to the main code. It will adjust (by
add esp, 64) the esp value to ensure the
eip later will points to the return to the correct address.
eip = esp
(You may refer to the Wiki link below for more details)
After series of pop instruction and reaches the
esp is now pointed to some unknown address/inaccessible memory address which will crashed later.
In order to fix it, we need to subtract the correct value to the
esp , so
eip later will points to the correct memory address.
Exit With no Crash (Analysis)
The difference here is just the substraction value for the
esp . This time, the code will return to the main code and exit gracefully (Shown in 3rd picture below).
From here you will see the
ret instruction later will reutrn to the main code (cppplayground_v1._main), with
add esp, 44. The program then exit with no error :D
Another easier way to exit the program without crash is using
exitProcess() from Windows API. It’s kind of force exit somehow.
Exit Program with ExitProcess() Windows API
Call the ExitProcess() by pushing the string into the stack and then get the function call address. You can find more details in the references link below.
Another way to push value into stack in assembly
constant value . It means that the program will jump to the function and call it. As you know, the constant appears before the function will push in the stack and access by the function e.g.
push ebp; call <func_name>.
By utilising this method, you can make a trick on it to push a constant into a stack.
push edx ; LPPROCESS_INFORMATION lpProcessInformation
push edx ; LPSTARTUPINFO lpStartupInfo
push ebx ; LPCTSTR lpCurrentDirectory
push ebx ; LPVOID lpEnvironment
push ebx ; DWORD dwCreationFlags
push ebx ; BOOL bInheritHandles
push ebx ; LPSECURITY_ATTRIBUTES lpThreadAttributes
push ebx ; LPSECURITY_ATTRIBUTES lpProcessAttributes
lol: ; LPTSTR lpCommandLine after call will push args into stacks
push ebx ; LPCTSTR lpApplicationName
add esp, 0xEC
command db "cmd /c notepad",0 ; cmd args of CreateProcessA
As for how to write basic a windows PE shellcode, you may refer to the link below for details. Cheers!
All the shellcode in this story is written using NASM. As how to compile it into windows PE file, I’m using the command below.
(Install NASM for
nasm and GNU for
nasm -f win32 <file.asm> -o <file.o> && ld <file.o> -o <file.exe>
How to detect a windows shellcode in a PE file
Basically, I will find these instruction in the assembly code to determine whether it is a windows based shellcode or not. Original source here.
mov ebx, fs:0x30 ; Get pointer to PEB
mov ebx, [ebx + 0x0C] ; Get pointer to PEB_LDR_DATA
mov ebx, [ebx + 0x14] ; Get pointer to first entry in InMemoryOrderModuleList
mov ebx, [ebx] ; Get pointer to second (ntdll.dll) entry in InMemoryOrderModuleList
mov ebx, [ebx] ; Get pointer to third (kernel32.dll) entry in InMemoryOrderModuleList
mov ebx, [ebx + 0x10] ; Get kernel32.dll base address
Hope it helps as there are some windows malware uses this kind of shellcode too.
Basics of Windows shellcode writing
This tutorial is for x86 32bit shellcode. Windows shellcode is a lot harder to write than the shellcode for Linux and…
Introduction to Windows shellcode development - Part 3
If you missed the first two parts of this article, you can find in Part I what is a shellcode, how it works and which…