学校的oj系统禁止包含windows.h,而又想用一些API,
在参考了看雪Cryin 的帖子【原创】Win 7下定位kernel32.dll基址及shellcode编写
(http://bbs.pediy.com/showthread.php?t=122260)后,加上自己对PE结构的认识,写出了这几行代码,本着共享精神,特来献丑
不解释,直接上代码
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> //pe常量 #define DOS_HEADER_SIZE 64 #define PE_HEADER_SIZE 248 #define SECTION_SIZE 40 #define SECTION_NAME_SIZE 8 #define IED_SIZE 40 #define SECOND_DATA_DIR_LIST_OFFSET 0x78 //用到的类型定义 typedef unsigned long DWORD; typedef unsigned int UINT; typedef char * LPSTR; typedef const char * LPCSTR,*LPCTSTR; typedef void * HMODULE; typedef void * HINSTANCE; typedef void * HWND; #define WINAPI __stdcall //函数类型 typedef int T_GetKernelBase(); typedef void * WINAPI T_GetProcAddress ( HMODULE hModule, LPCSTR lpProcName ); typedef DWORD WINAPI T_GetCurrentDirectoryA( DWORD nBufferLength, LPSTR lpBuffer ); typedef void * WINAPI T_GetModuleHandleA( LPCSTR lpModuleName ); typedef HINSTANCE WINAPI T_LoadLibrary( LPCSTR lpLibFileName); //ShellCode函数 char szGetKernelBase[] = { '\x56', '\x33', '\xC0', '\x64', '\x8B', '\x40', '\x30', '\x85', '\xC0', '\x78', '\x0F', '\x8B', '\x40', '\x0C', '\x8B', '\x70', '\x1C', '\xAD', '\x8B', '\x40', '\x08', '\xEB', '\x0C', '\x90', '\x90', '\x90', '\x8B', '\x40', '\x34', '\x8D', '\x40', '\x7C', '\x8B', '\x40', '\x3C', '\x5E', '\xC3', '\x90' }; int GetAPIGetProcAddressOffset(int hKernel32) { char *pMem = (char *)hKernel32; int *piOffset = NULL; int iETFileOffset = 0; pMem += DOS_HEADER_SIZE - 4; //取得pe头偏移 piOffset = (int *)pMem; pMem = (char *)hKernel32 + *piOffset; pMem += SECOND_DATA_DIR_LIST_OFFSET; //取得输出表偏移 piOffset = (int *)pMem; //pMem 指向输出表 pMem = (char *)hKernel32 + *piOffset; int *piAddressOfName = NULL; int *piPointerOfName = NULL; int *piAddressOfFunctions = NULL; int *piPointerOfFunctions = NULL; char *pszAddressOfName = NULL; piAddressOfFunctions = (int *)(pMem + 28); piAddressOfName = (int *)(pMem + 32); piPointerOfName = (int *)(hKernel32 + *piAddressOfName); piPointerOfFunctions = (int *)(hKernel32 + *piAddressOfFunctions); pszAddressOfName = (char *)(hKernel32 + *piPointerOfName); while (strcmp(pszAddressOfName,"GetProcAddress") != 0) { piPointerOfName++; //= (int *) (hKernel32 + *piAddressOfName); piPointerOfFunctions++; pszAddressOfName = (char *)(hKernel32 + *piPointerOfName); } return (*piPointerOfFunctions); } int main() { int hKernel32Base = NULL; void *pTmp = szGetKernelBase; T_GetKernelBase *pGetKernelBase = (T_GetKernelBase *)pTmp; hKernel32Base = pGetKernelBase(); int ProcAddressAPIOffset = 0; ProcAddressAPIOffset = GetAPIGetProcAddressOffset(hKernel32Base); T_GetProcAddress *pGetProcAddress = (T_GetProcAddress *) (hKernel32Base + ProcAddressAPIOffset); T_LoadLibrary *pLoadLibraryA = (T_LoadLibrary *) pGetProcAddress((void *)hKernel32Base,"LoadLibraryA"); //虽然没必要,但是作为演示,还是来一次 HMODULE hDll = (HMODULE)pLoadLibraryA("kernel32.dll"); T_GetCurrentDirectoryA *pGetCurrentDirectoryA =(T_GetCurrentDirectoryA *) pGetProcAddress(hDll,"GetCurrentDirectoryA"); char buf[1024]; pGetCurrentDirectoryA(1024,buf); printf("当前目录是:\n%s\n",buf); return 0; }