WindowsPE文件格式入門05.PE加載器LoadPE

https://bpsend.net/thread-316-1-1.html

LoadPE - pe 加載器 殼的前身

如果想訪問一個程序運行起來的內存,一種方法就是跨進程讀寫內存,但是跨進程讀寫內存需要來回調用api,不如直接訪問地址來得方便,那么如果我們需要直接訪問地址,該怎么做呢?.需要把dll注進程,注進去的代碼跟他在同一塊進程里面,這樣我們就可以直接訪問這個進程的地址,但是不想注入,也不想跨進程讀寫地址,就直接讀進程地址,有什么方法呢?如果把導入表里面加一個dll,這樣很容易檢查出來,模塊里一遍歷,就可容易看到了,?其實我們可以反其道行之,換種思路,不是往他進程里面塞東西,而是把他加載到我們進程里面.,這個時候再去訪問進程內存其實就是訪問我們自己的內存.
1.系統加載exe的流程
  • 準備一個新的內存;
  • 按照順序把節表內容映射進內存;
  • 填寫導入表。
2.LoadPE的目的
  • 可以在自己進程更改目標PE的內存。
3.LoadPE的重點
  • 1.在自己代碼前留出足夠空間--目標進程的SizeofImage;
  • 2.更改自己程序的ImageBase加載到目標ImageBase處:/base:0x。

img

這樣,目標進程的PE頭就占據了我們自己進程的 PE頭,他的數據節就覆蓋了我們自己的數據節,即目標進程的數據就會覆蓋我們自己進程的數據,因此我們需要 把我們的代碼往后移,給 目標進程 留出足夠的空間

4.LoadPE的實現思路
  • 設置我們進程的 ImageBase 和 目標進程 ImageBase 保持一致
  • 我們需要把我們的代碼往后移,騰出來的內存可以放目標程序
  • 讀目標進程的數據,按照節表拷貝數據幫他處理導入表
  • 執行目標進程代碼。
5.LoadPE的匯編實現
  1. 用winhex查看目標進程的 ImageBase 和 SizeofImage
  2. 新建工程,并且在工程選項設置 自己工程 的 ImageBase 與目標進程的一致
  3. 后移自己的代碼,可以在開頭定義 SizeofImage 大小的全局變量 或者通過指令 org 偏移調整指令

注意,很多 C 庫函數 并不會 保存 ecx , edx 環境,自己使用前記得先保存

進程的模塊基址和 數據大小可以通過 winhex看

img

.586
.model?flat,stdcall
option?casemap:noneinclude?windows.incinclude?user32.incinclude?kernel32.incinclude?msvcrt.incincludelib?user32.libincludelib?kernel32.libincludelib?msvcrt.libIMAGE_SIZE?equ?20000h?????;往后移的大小,即目標進程的SizeofImage.datag_szFile?db?"winmine.exe",?0????;要讀取的進程.codeorg?IMAGE_SIZE?LoadPe?procLOCAL?@dwImageBase:DWORD???????;自己進程的模塊基址LOCAL?@hFile:HANDLE????????????;文件句柄LOCAL?@hFileMap:HANDLE?????????;映射句柄LOCAL?@pPEBuf:LPVOID???????????;映射文件的緩沖地址LOCAL?@pDosHdr:ptr?IMAGE_DOS_HEADER??????;目標進程的dos頭LOCAL?@pNTHdr:ptr?IMAGE_NT_HEADERS???????;目標進程的NT頭LOCAL?@pSecHdr:ptr?IMAGE_SECTION_HEADER??;目標進程的節表LOCAL?@dwNumOfSecs:DWORD?????????????????;目標進程的節表數量LOCAL?@pImpHdr:ptr?IMAGE_IMPORT_DESCRIPTOR???;目標進程的導入表LOCAL?@dwSizeOfHeaders:DWORD?????????????????;目標進程的選項頭大小LOCAL?@dwOldProc:DWORD???????????????????????;舊的內存屬性LOCAL?@hdrZeroImp:IMAGE_IMPORT_DESCRIPTOR????;導入表結束標志,所有項全0LOCAL?@hDll:HMODULE??????????????????????????;加載dll的句柄LOCAL?@dwOep:DWORD???????????????????????????;進程的入口地址;判斷導入表結束的標志清0invoke?RtlZeroMemory,?addr?@hdrZeroImp,?size?IMAGE_IMPORT_DESCRIPTOR;自己的模塊基址invoke?GetModuleHandle,?NULLmov?@dwImageBase,?eax;解析PE文件,獲取表;打開文件invoke?CreateFile,?offset?g_szFile,?GENERIC_READ,?FILE_SHARE_READ,NULL,?OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,?NULL;check?....mov?@hFile,?eax???;保存文件句柄invoke?CreateFileMapping,?@hFile,?NULL,?PAGE_READONLY,?0,?0,?NULL???;創建文件映射;checkmov?@hFileMap,?eax????;創建文件映射句柄invoke?MapViewOfFile,?@hFileMap,?FILE_MAP_READ,?0,?0,?0??????;將整個文件映射進內存;check?mov?@pPEBuf,?eax??????;保存映射文件內存的地址;解析目標進程;目標進程的?dos?頭mov?eax,?@pPEBuf????mov?@pDosHdr,?eax;目標進程的?nt頭mov?esi,?@pDosHdrassume?esi:ptr?IMAGE_DOS_HEADERmov?eax,?@pPEBufadd?eax,?[esi].e_lfanew???;獲取nt頭的偏移地址mov?@pNTHdr,?eaxmov?esi,?@pNTHdrassume?esi:ptr?IMAGE_NT_HEADERS;選項頭信息mov?eax,?[esi].OptionalHeader.SizeOfHeaders????;獲取選項頭大小mov?@dwSizeOfHeaders,?eax;進程的入口地址??=??進程的內存偏移地址?+?模塊基址mov?eax,?[esi].OptionalHeader.AddressOfEntryPointadd?eax,?@dwImageBasemov?@dwOep,?eax;節表??地址:?選項頭地址+大小movzx?eax,?[esi].FileHeader.NumberOfSectionsmov?@dwNumOfSecs,eaxlea?ebx,?[esi].OptionalHeader;獲取選項頭大小:用于定位節表位置=選項頭地址+選項頭大小movzx?eax,?[esi].FileHeader.SizeOfOptionalHeader???;把?word?轉為?dwordadd?eax,?ebxmov?@pSecHdr,?eax???;保存節表地址;修改內存屬性invoke?VirtualProtect,?@dwImageBase,?IMAGE_SIZE,?PAGE_EXECUTE_READWRITE,?addr?@dwOldProc;拷貝PE頭??從映射內存拷貝到?自己進程的最開始處?invoke?crt_memcpy,?@dwImageBase,?@pPEBuf,?@dwSizeOfHeaders;按照節表,拷貝節區數據mov?esi,?@pSecHdrassume?esi:ptr?IMAGE_SECTION_HEADERxor?ecx,?ecx.while?ecx?<?@dwNumOfSecs???;遍歷節表;目標mov?edi,?@dwImageBaseadd?edi,?[esi].VirtualAddress??;獲取節的內存地址?+?模塊地址?就是內存中的絕對地址;源mov?ebx,?@pPEBufadd?ebx,?[esi].PointerToRawData??;獲取指定進程的節數據的偏移地址??映射的首地址?+?文件偏移地址;大小[esi].SizeOfRawData;拷貝??注意,很多?C?庫函數?并不會?保存?ecx?,edx?環境,自己使用前記得先保存push?ecxpush?edxinvoke?crt_memcpy,?edi,?ebx,?[esi].SizeOfRawData???;將目標進程的節數據拷貝進自己的進程pop?edxpop?ecxinc?ecx??????;計數++add?esi,?size?IMAGE_SECTION_HEADER??;指針移動.endw;獲取導入表??如果在前面獲取導入表信息,那么就需要對內存地址和文件地址做轉化比較麻煩;但是把數據拷貝到我們進程之后只需要訪問內存進程就可以了mov?esi,?@pNTHdrassume?esi:ptr?IMAGE_NT_HEADERS;獲取導入表地址?,數組的第二個元素的第一個成員?mov?eax,?[esi].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT*8].VirtualAddressadd?eax,?@dwImageBase???;獲取導入表在進程的絕對地址??內存偏移?+?模塊基址mov?@pImpHdr,?eax???????;保存導入表的地址;處理導入表mov?esi,?@pImpHdrassume?esi:ptr?IMAGE_IMPORT_DESCRIPTOR.while?TRUE?????;遍歷導入表;判斷結束,全0項結束invoke?crt_memcmp,?esi,?addr?@hdrZeroImp.if?eax?==?0.break.endif;判斷字段,為空則結束.if?[esi].Name1?==?NULL?||?[esi].FirstThunk?==?NULL.break.endif?;加載dllmov?eax,?[esi].Name1add?eax,?@dwImageBasepush?ecxpush?edxinvoke?LoadLibrary,?eax???;根據dll名加載?dll?pop?edxpop?ecx;check??????????????如果此時為空加說明無法找到dllmov?@hDll,?eax??????;保存dll的模句柄;獲取導入地址表,IATmov?ebx,?[esi].FirstThunkadd?ebx,?@dwImageBase;獲取導入名稱表,INTmov?edi,?ebx.if?[esi].OriginalFirstThunk?!=?NULLmov?edi,?[esi].OriginalFirstThunkadd?edi,?@dwImageBase??????????.endif;遍歷導入名稱表.while?dword?ptr?[edi]?!=?0.if?dword?ptr?[edi]?&?80000000h???;判斷最高位是否為1;序號導入,獲取序號mov?edx,?dword?ptr?[edi]and?edx,?0ffffh???????????????;獲取低?word?.else;名稱導入mov?edx,?dword?ptr?[edi]add?edx,?@dwImageBaseadd?edx,?2??????????????????;名稱前面有2個無用字節.endif;獲取dll導入函數進程加載后地址push?ecxpush?edxinvoke?GetProcAddress,?@hDll,?edxpop?edxpop?ecx;check;把地址存入?INT?表mov?dword?ptr?[ebx],?eaxadd?ebx,?4add?edi,?4.endwadd?esi,?size?IMAGE_IMPORT_DESCRIPTOR.endw;清理invoke?UnmapViewOfFile,@pPEBufinvoke?CloseHandle,@hFileMapinvoke?CloseHandle,@hFile;?執行加載的pe的代碼jmp?@dwOepretLoadPe?endpstart:invoke?LoadPeinvoke?ExitProcess,0end?start

需要合并節

.text,ERW

img

C++版:

#include?<windows.h>
#include?<concrt.h>
#include?<iostream>
using?namespace?std;#define?IMAGE_SIZE?0x5000//留空的全局變量
char?szBuff[IMAGE_SIZE]?=?{?1?};#if?1
char?g_szExeName[]?=?"PE.exe";??//需要加載的PE路徑LPVOID?lpMapAddr?=?NULL;HANDLE?LoadPe()
{DWORD??dwOldProc?=?0;PIMAGE_IMPORT_DESCRIPTOR?pImpHdr?=?NULL;IMAGE_IMPORT_DESCRIPTOR??zeroImp?=?{?0?};HANDLE?hDll?=?NULL;PIMAGE_THUNK_DATA?pTmpThunk?=?NULL;DWORD??dwPFNAddr?=?0;DWORD??dwIAT?=?0;//?獲取模塊句柄HANDLE?hInst?=?GetModuleHandle(NULL);//?讀取文件HANDLE?hFile?=?CreateFile(g_szExeName,?GENERIC_READ,?FILE_SHARE_READ,?NULL,?OPEN_EXISTING,?FILE_ATTRIBUTE_NORMAL,?NULL);if?(hFile?==?INVALID_HANDLE_VALUE){return?0;}//?創建文件映射對象HANDLE?hFileMap?=?CreateFileMapping(hFile,?NULL,?PAGE_READONLY,?0,?0,?NULL);if?(hFileMap?==?NULL){CloseHandle(hFile);return?0;}void*?lpMapAddr?=?MapViewOfFile(hFileMap,?FILE_MAP_READ,?0,?0,?0);if?(lpMapAddr?==?NULL){CloseHandle(hFileMap);CloseHandle(hFile);return?0;}//?拷貝PE頭PIMAGE_DOS_HEADER?pDosHeader?=?(PIMAGE_DOS_HEADER)lpMapAddr;PIMAGE_NT_HEADERS?pNtHeader?=?(PIMAGE_NT_HEADERS)((DWORD)lpMapAddr?+?pDosHeader->e_lfanew);DWORD?dwSizeOfHeaders?=?pNtHeader->OptionalHeader.SizeOfHeaders;DWORD?dwNumOfSection?=?pNtHeader->FileHeader.NumberOfSections;//獲取節表首地址??(選項頭地址+?大小)PIMAGE_SECTION_HEADER?pSecHdr?=?(PIMAGE_SECTION_HEADER)((DWORD)pNtHeader->FileHeader.SizeOfOptionalHeader?+?(DWORD)(&pNtHeader->OptionalHeader));DWORD?dwOep?=?(DWORD)hInst?+?pNtHeader->OptionalHeader.AddressOfEntryPoint;//?更改內存屬性VirtualProtect(hInst,?IMAGE_SIZE,?PAGE_EXECUTE_READWRITE,?&dwOldProc);//拷貝PE頭memcpy(hInst,?lpMapAddr,?dwSizeOfHeaders);//?拷貝拷貝節區數據DWORD?i?=?0;while?(dwNumOfSection?>?i){//拷貝數據DWORD?pDst?=?(DWORD)hInst?+?(DWORD)pSecHdr->VirtualAddress;DWORD?pSrc?=?(DWORD)lpMapAddr?+?(DWORD)pSecHdr->PointerToRawData;//DWORD?pSrc?=?(DWORD)pSecHdr;memcpy((void*)pDst,?(void*)pSrc,?pSecHdr->SizeOfRawData);int?nSecHdrSzie?=?sizeof(IMAGE_SECTION_HEADER);pSecHdr?=?(PIMAGE_SECTION_HEADER)((DWORD)pSecHdr?+?(DWORD)nSecHdrSzie);i++;}//獲取導入表地址pImpHdr?=?(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pNtHeader->OptionalHeader.DataDirectory[1].VirtualAddress?+?(DWORD)hInst);//?處理導入表while?(TRUE){//?遇到全0項,遍歷結束?int?nRet?=?memcmp(pImpHdr,?&zeroImp,?sizeof(IMAGE_IMPORT_DESCRIPTOR));if?(nRet?==?0){break;}//判斷字段,?為空則結束if?(pImpHdr->Name?==?NULL?||?pImpHdr->FirstThunk?==?NULL){break;}DWORD?pNameAddre?=?(DWORD)pImpHdr->Name?+?(DWORD)hInst;//?加載dllHMODULE?hDll?=?LoadLibrary((LPCSTR)pNameAddre);if?(hDll?==?NULL){break;}DWORD?pFunAddr?=?0;DWORD?pIAT?=?(DWORD)pImpHdr->FirstThunk?+?(DWORD)hInst;DWORD?pINT?=?(DWORD)pImpHdr->OriginalFirstThunk;if?(pINT?!=?0){pFunAddr?=?pINT?+?(DWORD)hInst;}else{pFunAddr?=?pIAT;}//?遍歷導入名稱表while?(true){DWORD?pAddr?=?*(DWORD*)pFunAddr;if?(pAddr?==?0){break;}DWORD??pFun?=?0;if?(pAddr?&?0x80000000){//序號導入,?獲取序號pFun?=?pAddr?&?0xffff;}else{pFun?=?pAddr?+?2?+?(DWORD)hInst;}DWORD??dwPFNAddr?=?(DWORD)GetProcAddress(hDll,?(LPCSTR)LOWORD(pFun));*(DWORD*)pIAT?=?dwPFNAddr;pIAT?+=?4;pFunAddr+=4;}pImpHdr?=?(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImpHdr?+?(DWORD)sizeof(IMAGE_IMPORT_DESCRIPTOR));}//?關閉句柄UnmapViewOfFile(lpMapAddr);CloseHandle(hFileMap);CloseHandle(hFile);//?返回地址return?&dwOep;
}#endif?//?0int?main()
{#if?1//?加載PE文件,返回原OEPvoid*?pOep?=?LoadPe();if?(pOep?!=?NULL){__asm?jmp?pOep}#endif?//?0return?0;
}
#include?<iostream>
#include?<Windows.h>
#include?<stdio.h>using?namespace?std;#define?FILESIZE??0x00020000?????????//目標進程的SizeofImage
#define?IMAGEBASE?0x01000000char?szExeDataBuff[FILESIZE]?=?{1};
char?g_szExeName[]?=?"winmine.exe";???//要加載的進程路徑DWORD?g_oep?=?0;void?LoadPe()
{//?創建文件映射//打開文件HANDLE?hFile?=?CreateFile(g_szExeName,?GENERIC_READ,?FILE_SHARE_READ,?NULL,?OPEN_EXISTING,?FILE_ATTRIBUTE_NORMAL,?NULL);if?(hFile?==?INVALID_HANDLE_VALUE){return?;}//?創建文件映射對象HANDLE?hFileMap?=?CreateFileMapping(hFile,?NULL,?PAGE_READONLY,?0,?0,?NULL);if?(hFileMap?==?NULL){CloseHandle(hFile);return;}//將文件映射進內存LPVOID?pView?=?MapViewOfFile(hFileMap,?FILE_MAP_READ,?0,?0,?0);if?(pView?==?NULL){CloseHandle(hFileMap);CloseHandle(hFile);return;}//?修改代碼節屬性DWORD?nOldProtect?=?0;VirtualProtect((LPVOID)IMAGEBASE,?FILESIZE,?PAGE_EXECUTE_READWRITE,?&nOldProtect);//?處理PEPIMAGE_DOS_HEADER?pDos?=?(PIMAGE_DOS_HEADER)pView;//?獲取pe頭大小PIMAGE_NT_HEADERS32?pNt?=?(PIMAGE_NT_HEADERS32)((DWORD)pView?+?pDos->e_lfanew);memcpy((void*)IMAGEBASE,?(void*)pDos,?pNt->OptionalHeader.SizeOfHeaders);//?OEPg_oep?=?pNt->OptionalHeader.AddressOfEntryPoint?+?IMAGEBASE;//?解析節PIMAGE_SECTION_HEADER?pSec?=?(PIMAGE_SECTION_HEADER)((DWORD)?&?(pNt->OptionalHeader.Magic)?+?pNt->FileHeader.SizeOfOptionalHeader);//?節數量unsigned?int?nNumberOfSections?=?pNt->FileHeader.NumberOfSections;while?(nNumberOfSections?!=?0){void*?pVirtualAddress?=?(void*)(pSec->VirtualAddress?+?IMAGEBASE);void*?pFileAddress?=?(void*)(pSec->PointerToRawData?+?(DWORD)pDos);memcpy(pVirtualAddress,?pFileAddress,?pSec->SizeOfRawData);nNumberOfSections--;pSec++;}if?(pNt->OptionalHeader.NumberOfRvaAndSizes?>?2){//?處理導入表PIMAGE_IMPORT_DESCRIPTOR?pIm?=?(PIMAGE_IMPORT_DESCRIPTOR)(pNt->OptionalHeader.DataDirectory[1].VirtualAddress?+?IMAGEBASE);while?(pIm->Name?&&?pIm->FirstThunk){HMODULE?hModule?=?LoadLibraryA((char*)(pIm->Name?+?IMAGEBASE));if?(hModule?==?NULL){pIm++;continue;}DWORD?dwThunkData?=?pIm->OriginalFirstThunk???pIm->OriginalFirstThunk?:?pIm->FirstThunk;if?(dwThunkData?==?0){return?;}PIMAGE_THUNK_DATA?pThunkData?=?(PIMAGE_THUNK_DATA)(dwThunkData?+?IMAGEBASE);DWORD*?pPfn?=?(DWORD*)(pIm->FirstThunk?+?IMAGEBASE);while?(pThunkData->u1.AddressOfData){FARPROC?farProc?=?0;LPCSTR?lpParam2?=?0;//?最高位判斷if?(pThunkData->u1.AddressOfData?&?0x80000000){//?序號lpParam2?=?LPCSTR(LOWORD(pThunkData->u1.AddressOfData));}else{//?函數名lpParam2?=?LPCSTR(pThunkData->u1.AddressOfData?+?IMAGEBASE?+?2);}farProc?=?GetProcAddress(hModule,?lpParam2);//?填充IAT*pPfn?=?(DWORD)farProc;pThunkData++;pPfn++;}pIm++;}}//取消映射UnmapViewOfFile(pView);//關閉文件映射對象CloseHandle(hFileMap);//關閉文件CloseHandle(hFile);
}int?main()
{LoadPe();if?(g_oep?!=?0){__asm{jmp?g_oep;}}return?0;
}

思路: 主要難點是代碼后移,留出空間

方法1: 內聯 匯編 開始 nop

方法2: 把代碼放到dll中

方法3: 合并節,全局變量是放在未初始化的節內合并后就會在第一個節

合并節代碼:

#include?<Windows.h>
#pragma?bss_seg?(".mySec")
char?g_aryImageSize[0x200000];#pragma?bss_seg()
#pragma?comment(linker,"/MERGE:.mySec=.textbss")const?char*?g_szExe?=?"mspaint.exe";int?main()
{HANDLE?hFile?=?NULL;HANDLE?hFileMap?=?NULL;LPVOID?pFileBuf?=?NULL;IMAGE_DOS_HEADER*?pDosHdr?=?NULL;IMAGE_NT_HEADERS*?pNtHdr?=?NULL;IMAGE_FILE_HEADER*?pFileHdr?=?NULL;IMAGE_OPTIONAL_HEADER*?pOptHdr?=?NULL;IMAGE_SECTION_HEADER*?pSecHdr?=?NULL;IMAGE_IMPORT_DESCRIPTOR*?pImpDes?=?NULL;DWORD?dwSizeOfOptHdr?=?0;DWORD?dwNumOfSecs?=?0;HANDLE?hMod?=?NULL;DWORD??dwSizeOfHeader?=?0;DWORD?dwOldProc?=?0;DWORD?dwEntry?=?0;HMODULE?hDll?=?NULL;LPDWORD?pINT?=?NULL;LPDWORD?pIAT?=?NULL;DWORD?dwAddrOfFunc?=?0;IMAGE_IMPORT_DESCRIPTOR?zeroImp;memset(&zeroImp,?0,?sizeof(IMAGE_IMPORT_DESCRIPTOR));//1、創建文件hMod?=?GetModuleHandle(NULL);hFile?=?CreateFile(g_szExe,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if?(hFile?==?INVALID_HANDLE_VALUE){OutputDebugString("Could?not?open?file.");return?-1;}//2、創建文件映射hFileMap?=?CreateFileMapping(hFile,?NULL,?PAGE_READONLY,?0,?0,?NULL);if?(hFileMap?==?NULL){OutputDebugString("Could?not?create?file-mapping?object.");return?-1;}//3、映射文件內容到內存pFileBuf?=?MapViewOfFile(hFileMap,?FILE_MAP_READ,?0,?0,?0);if?(pFileBuf?==?NULL){OutputDebugString("Could?not?map?view?of?file.");return?-1;}//4、解析DOS頭pDosHdr?=?(IMAGE_DOS_HEADER*)pFileBuf;//5、解析NT頭pNtHdr?=?(IMAGE_NT_HEADERS*)(pDosHdr->e_lfanew?+?(char*)pFileBuf);//6、解析文件頭pFileHdr?=?&(pNtHdr->FileHeader);//7、解析選項頭pOptHdr?=?&(pNtHdr->OptionalHeader);//8、獲取節表個數和選項頭大小dwSizeOfOptHdr?=?pFileHdr->SizeOfOptionalHeader;dwNumOfSecs?=?pFileHdr->NumberOfSections;//9、解析節表pSecHdr?=?(IMAGE_SECTION_HEADER*)((char*)pOptHdr?+?dwSizeOfOptHdr);//10、獲取PE頭大小和入口點(RVA)dwSizeOfHeader?=?pOptHdr->SizeOfHeaders;dwEntry?=?pOptHdr->AddressOfEntryPoint?+?(DWORD)hMod;//11、獲取導入表入口pImpDes?=?(IMAGE_IMPORT_DESCRIPTOR*)pOptHdr->DataDirectory[1].VirtualAddress;pImpDes?=?(IMAGE_IMPORT_DESCRIPTOR*)((DWORD)pImpDes?+?(DWORD)hMod);//12、拷貝PE頭VirtualProtect(hMod,?dwSizeOfHeader,?PAGE_EXECUTE_READWRITE,?&dwOldProc);memcpy(hMod,?pDosHdr,?dwSizeOfHeader);//13、拷貝節數據IMAGE_SECTION_HEADER*?pSecTmpHdr?=?pSecHdr;for?(size_t?i?=?0;?i?<?dwNumOfSecs;?i++){LPVOID?pSecDataFileOffset?=?(char*)pFileBuf?+?pSecTmpHdr->PointerToRawData;LPVOID?pSecDataMemory?=?(LPVOID)((DWORD)hMod?+?pSecTmpHdr->VirtualAddress);VirtualProtect(pSecDataMemory,?pSecTmpHdr->Misc.VirtualSize,?PAGE_EXECUTE_READWRITE,?&dwOldProc);memcpy(pSecDataMemory,?pSecDataFileOffset,?pSecTmpHdr->SizeOfRawData);pSecTmpHdr?=?(IMAGE_SECTION_HEADER*)((char*)pSecTmpHdr?+?sizeof(IMAGE_SECTION_HEADER));}//14、拷貝導入表信息while?(true){if?(pImpDes->Characteristics?==?0?&&pImpDes->FirstThunk?==?0?&&pImpDes->Name?==?0){break;}if?(pImpDes->Name?==?NULL){break;}LPSTR?pDllName?=?(LPSTR)((DWORD)hMod?+?pImpDes->Name);hDll?=?LoadLibrary(pDllName);if?(pImpDes->FirstThunk?==?NULL){break;}//獲取導入名稱表pINT?=?(LPDWORD)((DWORD)hMod?+?pImpDes->OriginalFirstThunk);if?(pINT?==?NULL){pINT?=?(LPDWORD)((DWORD)hMod?+?pImpDes->FirstThunk);}//獲取導入地址表pIAT?=?(LPDWORD)((DWORD)hMod?+?pImpDes->FirstThunk);//while?(true){DWORD?dwINT?=?*pINT;if?(dwINT?==?0){break;}//判斷是符號導入還是名稱導入LPSTR?pApiName?=?NULL;if?(dwINT?&?0x80000000){pApiName?=?(LPSTR)dwINT;pApiName?=?LPSTR((DWORD)pApiName?&?0x0000ffff);}else{pApiName?=?LPSTR(dwINT?+?(DWORD)hMod?+?sizeof(WORD));}*pIAT?=?(DWORD)GetProcAddress(hDll,?pApiName);pINT++;pIAT++;}pImpDes++;}__asm?jmp?dwEntry;return?0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76831.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76831.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76831.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

QGIS中第三方POI坐標偏移的快速校正-百度POI

1.百度POI&#xff1a; name,lng,lat,address 龍記黃燜雞米飯(共享區店),121.908315,30.886636,南匯新城鎮滬城環路699弄117號(A1區110室) 好福記黃燜雞(御橋路店),121.571409,31.162292,滬南路2419弄26號1層B間 御品黃燜雞米飯(安亭店),121.160322,31.305977,安亭鎮新源路792號…

SQL的調優方案

一、前言 SQL調優是提升數據庫性能的關鍵手段。需結合索引優化、SQL語句優化、執行計劃分析及數據庫架構設計等多方面綜合處理。 二、索引優化 創建合適索引 高頻查詢字段&#xff1a;對WHERE、JOIN、ORDER BY涉及的字段創建索引&#xff0c;尤其是區分度高的字段&#xff08…

【項目管理】第一部分 信息技術 1/2

相關文檔&#xff0c;希望互相學習&#xff0c;共同進步 風123456789&#xff5e;-CSDN博客 概要 知識點&#xff1a; 現代化基礎設施、數字經濟、工業互聯網、車聯網、智能制造、智慧城市、數字政府、5G、常用數據庫類型、數據倉庫、信息安全、網絡安全態勢感知、物聯網、大數…

【玩泰山派】1、mac上使用串口連接泰山派

文章目錄 前言picocom工具連接泰山派安裝picocom工具安裝ch340的驅動串口工具接線使用picocom連接泰山派 參考 前言 windows上面有xshell這個好用的工具可以使用串口連接板子&#xff0c;在mac上好像沒找到太好的工具&#xff0c;只能使用命令行工具去搞了。 之前查找說mac上…

【C++奇遇記】C++中的進階知識(繼承(一))

&#x1f3ac; 博客主頁&#xff1a;博主鏈接 &#x1f3a5; 本文由 M malloc 原創&#xff0c;首發于 CSDN&#x1f649; &#x1f384; 學習專欄推薦&#xff1a;LeetCode刷題集 數據庫專欄 初階數據結構 &#x1f3c5; 歡迎點贊 &#x1f44d; 收藏 ?留言 &#x1f4dd; 如…

【Scratch編程系列】Scratch編程軟件界面

Scratch是一款由麻省理工學院(MIT&#xff09; 設計開發的少兒編程工具。其特點是&#xff1a;使用者可以不認識英文單詞&#xff0c;也可以不使用鍵盤&#xff0c;就可以進行編程。構成程序的命令和參數通過積木形狀的模塊來實現。用鼠標拖動指令模塊到腳本區就可以了。 這個軟…

開篇 - 配置Unlua+VsCode的智能提示、調試以及學習方法

智能提示 為要綁定Lua的藍圖創建模板文件&#xff0c;這會在Content/Script下生成lua文件 然后點擊生成智能代碼提示&#xff0c;這會在Plugins/Unlua/Intermediate/生成Intenllisense文件夾 打開VSCode,點擊文件->將工作區另存為。生成一個空工作區&#xff0c;放置在工程…

QEMU-KVM加SPICE,云電腦誕生了

沒錯&#xff01;?QEMU-KVM SPICE? 的組合&#xff0c;本質上就是一套?輕量級云電腦&#xff08;云桌面&#xff09;?的解決方案。通過虛擬化技術將計算資源池化&#xff0c;再通過SPICE協議提供流暢的遠程桌面體驗&#xff0c;用戶用任意設備&#xff08;筆記本/平板/瘦客…

hashtable遍歷的方法有哪些

在 Java 中&#xff0c;遍歷 Hashtable&#xff08;或其現代替代品 HashMap&#xff09;有多種方式&#xff0c;以下是 6 種常用方法的詳細說明和代碼示例&#xff1a; 1. 使用 keySet() 增強 for 循環 Hashtable<String, Integer> table new Hashtable<>(); // …

如何完整遷移 Git 倉庫 ?

Git 已經成為軟件開發中版本控制和協作的事實上的標準。有時&#xff0c;開發人員可能需要將整個 Git 存儲庫 (包括其歷史記錄、分支和標記) 移動到新的位置或托管服務。在這個全面的指南中&#xff0c;我們將討論在不丟失任何關鍵數據或歷史記錄的情況下無縫地重新定位完整 Gi…

BPSK調制器的作用和基本原理

BPSK&#xff08;Binary Phase Shift Keying&#xff0c;二進制相移鍵控&#xff09;調制器是數字通信系統中的關鍵組件&#xff0c;其核心作用是將二進制數字信號轉換為模擬載波信號&#xff0c;通過相位變化傳遞信息。其具體作用的詳細說明如下&#xff1a; 一、BPSK調制器的…

LeetCode-98. 驗證二叉搜索樹

一、題目 給定一個二叉樹&#xff0c;判斷其是否是一個有效的二叉搜索樹。假設一個二叉搜索樹具有如下特征&#xff1a; 若它的左子樹不空&#xff0c;則左子樹上所有結點的值均小于它的根結點的值&#xff1b; 若它的右子樹不空&#xff0c;則右子樹上所有結點的值均大于它的…

Python菜鳥教程(小程序)

目錄 一.簡易計算器 二.學生成績分級 三.密碼設置 四.作業選擇 點贊收藏,評論支持 一.簡易計算器 print(-------使用的運算符-------\n) print(1.加號) print(2.減號) print(3.乘號) print(4.除號) Aint(input(請輸入第一個數: )) Bint(input(請輸入第二個數: )) Fi…

Golang的Goroutine(協程)與runtime

目錄 Runtime 包概述 Runtime 包常用函數 1. GOMAXPROCS 2. Caller 和 Callers 3. BlockProfile 和 Stack 理解Golang的Goroutine Goroutine的基本概念 特點&#xff1a; Goroutine的創建與啟動 示例代碼 解釋 Goroutine的調度 Gosched的作用 示例代碼 輸出 解…

Dubbo(30)如何配置Dubbo的服務分片?

配置Dubbo的服務分片&#xff08;也稱為服務分組&#xff09;可以幫助你將不同的服務實例分組&#xff0c;以實現隔離和管理。通過服務分片&#xff0c;可以在同一個注冊中心中注冊多個相同接口的服務&#xff0c;但它們屬于不同的分組&#xff0c;消費者可以根據需要選擇特定分…

文檔的預解析

1. 預解析的核心目標 瀏覽器在正式解析&#xff08;Parsing&#xff09;HTML 前&#xff0c;會啟動一個輕量級的 預解析器&#xff08;Pre-Parser&#xff09;&#xff0c;快速掃描文檔內容&#xff0c;實現&#xff1a; 提前發現并加載關鍵資源&#xff08;如 CSS、JavaScrip…

通過構造函數和幾何條件,研究了不同函數的最近點存在性、性質及單調性

解&#xff1a; &#xff08;1&#xff09;對于函數 f ( x ) 1 x f(x) \frac{1}{x} f(x)x1? 和點 M ( 1 , 0 ) M(1, 0) M(1,0)&#xff0c;構造函數 s ( x ) ( x ? 1 ) 2 ( 1 x ) 2 s(x) (x - 1)^2 \left(\frac{1}{x}\right)^2 s(x)(x?1)2(x1?)2。求導得到 s ′ …

C語言之編譯和debug工具

gcc gcc是GUN項目為C和C提供的編譯器 入門案例 gcc編譯器最簡單的使用案例&#xff1a;gcc hello.c -o hello&#xff0c;hello.c是源文件&#xff0c;-o參數指定了結果文件的名稱 gcc命令的選項&#xff1a; -v&#xff1a;打印編譯細節-E&#xff1a;僅僅進行預處理&…

Altshuller矛盾矩陣查詢:基于python和streamlit

基于python和streamlit實現的Altshuller矛盾矩陣查詢 import streamlit as st import json# 加載數據 st.cache_resource def load_data():with open(parameter.json, encodingutf-8) as f:parameters json.load(f)with open(way.json, encodingutf-8) as f:contradictions …

Maven的下載配置及在Idea中的配置

編寫項目管理中存在的問題 在大型Java項目開發中&#xff0c;依賴管理是一個極其復雜的挑戰。傳統方式下&#xff0c;開發者需要手動下載并引入數十甚至上百個JAR包到項目中&#xff0c;這一過程不僅繁瑣低效&#xff0c;還存在諸多痛點&#xff1a; 依賴傳遞性問題&#xff1a…