#include <stdio.h>#include <windows.h>DWORD GetHash(const char* fun_name){ DWORD digest = 0; while (*fun_name) { digest = ((digest << 25) | (digest >> 7)); //循环右移 7 位 digest += *fun_name; //累加 fun_name++; } return digest;}void main(){ DWORD hash; hash = GetHash("GetProcAddress"); printf("result of hash is 0x%.8x\n", hash);}
提取shellcode
源码
cpp
#pragma code_seg("shellcode")
#include <windows.h>
#pragma comment(linker,"/entry:main")
void main()
{
//the pointer of kernel32.dll base address
DWORD dwKernel32Addr = 0;
_asm {
push eax
mov eax, dword ptr fs:[0x30]
mov eax, [eax + 0x0C]
mov eax,[eax + 0x1C]
mov eax, [eax]
mov eax, [eax + 0x08]
mov dwKernel32Addr, eax
pop eax
}
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)dwKernel32Addr;
PIMAGE_NT_HEADERS32 pNtHeader = (PIMAGE_NT_HEADERS32)(dwKernel32Addr + pDosHeader->e_lfanew);
PIMAGE_DATA_DIRECTORY pDataDirectory = pNtHeader->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT;
PIMAGE_EXPORT_DIRECTORY pExportFuncTable = (PIMAGE_EXPORT_DIRECTORY)(dwKernel32Addr + pDataDirectory->VirtualAddress);
PDWORD pAddrOfFunc = (PDWORD)(pExportFuncTable->AddressOfFunctions + dwKernel32Addr);
PDWORD pAddrOfFuncNames = (PDWORD)(pExportFuncTable->AddressOfNames + dwKernel32Addr);
PWORD pAddrOfOrdinals = (PWORD)(pExportFuncTable->AddressOfNameOrdinals + dwKernel32Addr);
DWORD dwFuncGetProcAddress = 0;
for (size_t i = 0; i < pExportFuncTable->NumberOfNames; i++)
{
PCHAR lpFuncName = (PCHAR)(pAddrOfFuncNames[i] + dwKernel32Addr);
DWORD digest = 0;
while (*lpFuncName)
{
digest = ((digest << 25) | (digest >> 7));
digest += *lpFuncName;
lpFuncName++;
}
if (digest == 0xbbafdf85)//0xbbafdf85是经过自定义hash算法得到GetProcAddress函数的摘要
{
dwFuncGetProcAddress = pAddrOfFunc[pAddrOfOrdinals[i]] + dwKernel32Addr;
break;
}
}
/*
如果是弹窗弹窗,这里我们需要 : LoadLibraryExA、MessageBoxA、ExitProcess、user32.dll
*/
/*
定义函数指针GetProcAddress
*/
typedef FARPROC (WINAPI *funcGetProcAddress)(
HMODULE hModule,
LPCSTR lpProcName
);
funcGetProcAddress pfuncGetProcAddress = (funcGetProcAddress)dwFuncGetProcAddress;
/*
LoadLibraryExA 函数指针获取
*/
typedef HMODULE (WINAPI *funcLoadLibraryExA)(
LPCSTR lpLibFileName,
HANDLE hFile,
DWORD dwFlags
);
//如果采用字符串模式,其字符串会被放入数据段,使用的每次加载地址都不一样,
char szLoadLibraryExA[] = { 'L','o','a','d','L','i','b','r','a','r','y','E','x','A','\0' };
char szUser32[] = { 'u','s','e','r','3','2','.','d','l','l','\0' };
char szMessageBoxA[] = { 'M','e','s','s','a','g','e','B','o','x','A','\0' };
char szExitProcess[] = { 'E','x','i','t','P','r','o','c','e','s','s','\0' };
funcLoadLibraryExA pfuncLoadLibraryExA = (funcLoadLibraryExA)(pfuncGetProcAddress((HMODULE)dwKernel32Addr,szLoadLibraryExA));
/*
ExitProcess函数指针
*/
typedef VOID
(WINAPI *funcExitProcess)(
_In_ UINT uExitCode
);
funcExitProcess pfuncExitProcess = (funcExitProcess)(pfuncGetProcAddress((HMODULE)dwKernel32Addr, szExitProcess));
/*
* 加载user32.dll 和messagebox
*/
typedef int (WINAPI *funcMessageBoxA)(
_In_opt_ HWND hWnd,
_In_opt_ LPCSTR lpText,
_In_opt_ LPCSTR lpCaption,
_In_ UINT uType);
funcMessageBoxA pfuncMessageBoxA = (funcMessageBoxA)(pfuncGetProcAddress((HMODULE)(pfuncLoadLibraryExA(szUser32, NULL, NULL)), szMessageBoxA));
char szContext[] = {'t','h','i','s',' ','i','s',' ','a',' ','t','e','s','t','\0' };
char szTitle[] = { 't','e','s','t','\0' };
pfuncMessageBoxA(NULL, szContext, szTitle, MB_OK);
pfuncExitProcess(0);
}