PE文件入门(一)
作者:互联网
Shellcode直接注入代码块
使用代码,在文件中将shellcode注入进程序的text节中,也就是代码块中
条件:代码块有足够的空间存下shellcode
思路:获取shellcode的注入位置,然后再通过计算把硬编码应该跳转的地址计算出来 其公式为:要跳转的地址=当前指令的下一条指令地址+5+X——>就可以推出X=要跳转的地址-(当前指令的下一条指令地址+5)
在通过指针将其值修改
在最后修改OEP,并使shellcode最后跳回原来的程序入口
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<Windows.h> #define SHELLCODELENGTH 0x12 BYTE shellCode[] = { 0x6a,00,0x6a,00,0x6a,00,0x6a,00, 0xe8,00,00,00,00, 0xe9,00,00,00,00 }; PVOID FileToFileBuffer(LPSTR lpszFile) { FILE* file=NULL; PVOID FileBuffer=NULL; size_t FileOfSize=0; file = fopen(lpszFile, "rb+"); if (!file) { printf("文件打开错误"); return NULL; } fseek(file, NULL,SEEK_END); FileOfSize=ftell(file); fseek(file, NULL, SEEK_SET); FileBuffer = malloc(FileOfSize); if (!FileBuffer) { printf("内存分配错误"); fclose(file); return NULL; } if (!fread(FileBuffer, FileOfSize, 1, file)) { printf("文件读取错误"); fclose(file); return NULL; } fclose(file); return FileBuffer; } PVOID FileBufferToMemBuffer(LPVOID FileBuffer) { PVOID MemBuffer = NULL; PIMAGE_DOS_HEADER pFileDosHeader = NULL; PIMAGE_NT_HEADERS pFileNTHeader = NULL; PIMAGE_FILE_HEADER pFilePEHeader = NULL; PIMAGE_OPTIONAL_HEADER pFileOptionHeader = NULL; PIMAGE_SECTION_HEADER pFileSectionHeader = NULL; pFileDosHeader = (PIMAGE_DOS_HEADER)FileBuffer; pFilePEHeader = (PIMAGE_FILE_HEADER)(pFileDosHeader->e_lfanew + (DWORD)pFileDosHeader + 4); pFileOptionHeader = (PIMAGE_OPTIONAL_HEADER)(pFileDosHeader->e_lfanew + (DWORD)pFileDosHeader + 4 + IMAGE_SIZEOF_FILE_HEADER); pFileSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pFileOptionHeader+ pFilePEHeader->SizeOfOptionalHeader); size_t size = pFileOptionHeader->SizeOfImage; MemBuffer = malloc(size); memset(MemBuffer, 0, size); memcpy(MemBuffer, pFileDosHeader, pFileOptionHeader->SizeOfHeaders); for (int i = 0; i < pFilePEHeader->NumberOfSections; i++) { memcpy((PVOID)((DWORD)MemBuffer + pFileSectionHeader->VirtualAddress), (PVOID)((DWORD)FileBuffer + pFileSectionHeader->PointerToRawData), pFileSectionHeader->Misc.VirtualSize); pFileSectionHeader++; } return MemBuffer; } PVOID MemBufferToFile(LPVOID MemBuffer) { FILE* file=NULL; PVOID FileBuffer = NULL; PIMAGE_DOS_HEADER pFileDosHeader = NULL; PIMAGE_NT_HEADERS pFileNTHeader = NULL; PIMAGE_FILE_HEADER pFilePEHeader = NULL; PIMAGE_OPTIONAL_HEADER pFileOptionHeader = NULL; PIMAGE_SECTION_HEADER pFileSectionHeader = NULL; file = fopen("cpyj.exe", "wb+"); pFileDosHeader = (PIMAGE_DOS_HEADER)MemBuffer; pFilePEHeader = (PIMAGE_FILE_HEADER)(pFileDosHeader->e_lfanew + (DWORD)pFileDosHeader + 4); pFileOptionHeader = (PIMAGE_OPTIONAL_HEADER)(pFileDosHeader->e_lfanew + (DWORD)pFileDosHeader + 4 + IMAGE_SIZEOF_FILE_HEADER); pFileSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pFileOptionHeader + pFilePEHeader->SizeOfOptionalHeader); size_t size = pFileOptionHeader->SizeOfHeaders; for (int i = 0; i < pFilePEHeader->NumberOfSections; i++) { size += pFileSectionHeader->SizeOfRawData; pFileSectionHeader++; } pFileSectionHeader= (PIMAGE_SECTION_HEADER)((DWORD)pFileOptionHeader + pFilePEHeader->SizeOfOptionalHeader); FileBuffer = malloc(size); memset(FileBuffer, 0, size); memcpy(FileBuffer, MemBuffer, pFileOptionHeader->SizeOfHeaders); for (int i = 0; i < pFilePEHeader->NumberOfSections; i++) { memcpy((PVOID)((DWORD)FileBuffer+pFileSectionHeader->PointerToRawData), (PVOID)((DWORD)MemBuffer + pFileSectionHeader->VirtualAddress), pFileSectionHeader->SizeOfRawData); pFileSectionHeader++; } fwrite(FileBuffer, size, 1, file); return FileBuffer; } PVOID TestAddCodeInCodeSec(LPVOID ImageBuffer) { HMODULE AddressOfDll = GetModuleHandle((LPCWSTR)"user32.dll");//这里本机代码我没有求出来,所以messagebox传出来的值为NULL,所以什么都没变 FARPROC AddressOfMessage = GetProcAddress(AddressOfDll, (LPCSTR)"MessageBox"); PIMAGE_DOS_HEADER pFileDosHeader = NULL; PIMAGE_NT_HEADERS pFileNTHeader = NULL; PIMAGE_FILE_HEADER pFilePEHeader = NULL; PIMAGE_OPTIONAL_HEADER pFileOptionHeader = NULL; PIMAGE_SECTION_HEADER pFileSectionHeader = NULL; pFileDosHeader = (PIMAGE_DOS_HEADER)ImageBuffer; pFilePEHeader = (PIMAGE_FILE_HEADER)(pFileDosHeader->e_lfanew + (DWORD)pFileDosHeader + 4); pFileOptionHeader = (PIMAGE_OPTIONAL_HEADER)(pFileDosHeader->e_lfanew + (DWORD)pFileDosHeader + 4 + IMAGE_SIZEOF_FILE_HEADER); pFileSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pFileOptionHeader + pFilePEHeader->SizeOfOptionalHeader); if (((pFileSectionHeader->SizeOfRawData) - (pFileSectionHeader->Misc.VirtualSize)) < SHELLCODELENGTH) { printf("代码区空间不够"); return NULL; } PVOID codeBegin = (PBYTE)((pFileOptionHeader->SizeOfHeaders) + (DWORD)ImageBuffer + pFileSectionHeader->Misc.VirtualSize); memcpy(codeBegin, shellCode, SHELLCODELENGTH); //修正E8 DWORD callAddr = ((DWORD)AddressOfMessage - (pFileOptionHeader->ImageBase + (DWORD)codeBegin + 0xD) + (DWORD)ImageBuffer); *(PDWORD)((DWORD)codeBegin + 9) = callAddr; //修正E9 DWORD jmpAddr = (pFileOptionHeader->AddressOfEntryPoint+pFileOptionHeader->ImageBase-(pFileOptionHeader->ImageBase + SHELLCODELENGTH) + (DWORD)ImageBuffer); *(PDWORD)((DWORD)codeBegin + 0xE) = jmpAddr; //修改OEP pFileOptionHeader->AddressOfEntryPoint = (DWORD)codeBegin - (DWORD)ImageBuffer; MemBufferToFile(ImageBuffer); } VOID TestAddSection() { } int main() { LPSTR lpszFile = (LPSTR)"pe.exe"; PVOID FileBuffer = FileToFileBuffer(lpszFile); PVOID MemBuffer=FileBufferToMemBuffer(FileBuffer); TestAddCodeInCodeSec(MemBuffer); }
上面条件不成立的话,可以通过扩展节来进行注入和跳转,请看下面
通过扩展节来向程序注入shellcode
标签:文件,入门,pFileSectionHeader,DWORD,HEADER,PE,PIMAGE,NULL,pFileOptionHeader 来源: https://www.cnblogs.com/pppyyyzzz/p/13262139.html