代码有点乱 但是我不想整理
1 // AddBoxDlg.cpp : 实现文件 2 // 3 4 #include "stdafx.h" 5 #include "AddBox.h" 6 #include "AddBoxDlg.h" 7 #include "afxdialogex.h" 8 #include "PEInfo.h" 9 #include <ImageHlp.h> 10 #ifdef _DEBUG 11 #define new DEBUG_NEW 12 #endif 13 #define MAX_SECDATA_SIZE 2048 14 #pragma comment (lib,"Dbghelp.lib") 15 16 17 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 18 19 char szTargetPath[MAX_PATH] = "D:\Target.exe"; //目标文件的路径 20 char szPatchPath[MAX_PATH] = "D:\helloworld_1.exe"; //补丁文件的路径 21 char szModifyPEPath[MAX_PATH] = "D:\haha.exe"; //修改后生成新文件的路径 22 23 class CAboutDlg : public CDialogEx 24 { 25 public: 26 CAboutDlg(); 27 28 // 对话框数据 29 #ifdef AFX_DESIGN_TIME 30 enum { IDD = IDD_ABOUTBOX }; 31 #endif 32 33 protected: 34 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 35 36 // 实现 37 protected: 38 DECLARE_MESSAGE_MAP() 39 }; 40 41 CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) 42 { 43 } 44 45 void CAboutDlg::DoDataExchange(CDataExchange* pDX) 46 { 47 CDialogEx::DoDataExchange(pDX); 48 } 49 50 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) 51 END_MESSAGE_MAP() 52 53 54 // CAddBoxDlg 对话框 55 56 57 58 CAddBoxDlg::CAddBoxDlg(CWnd* pParent /*=NULL*/) 59 : CDialogEx(IDD_ADDBOX_DIALOG, pParent) 60 , m_strPEFilePath(_T("")) 61 , m_strBoxTitle(_T("")) 62 , m_strBoxContent(_T("")) 63 { 64 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 65 } 66 67 void CAddBoxDlg::DoDataExchange(CDataExchange* pDX) 68 { 69 CDialogEx::DoDataExchange(pDX); 70 DDX_Text(pDX, IDC_EDIT1, m_strPEFilePath); 71 DDX_Text(pDX, IDC_EDIT2, m_strBoxTitle); 72 DDX_Text(pDX, IDC_EDIT3, m_strBoxContent); 73 } 74 75 BEGIN_MESSAGE_MAP(CAddBoxDlg, CDialogEx) 76 ON_WM_SYSCOMMAND() 77 ON_WM_PAINT() 78 ON_WM_QUERYDRAGICON() 79 ON_BN_CLICKED(IDC_BUTTON_SCAN, &CAddBoxDlg::OnBnClickedButtonScan) 80 ON_BN_CLICKED(IDOK, &CAddBoxDlg::OnBnClickedOk) 81 END_MESSAGE_MAP() 82 83 84 // CAddBoxDlg 消息处理程序 85 86 BOOL CAddBoxDlg::OnInitDialog() 87 { 88 CDialogEx::OnInitDialog(); 89 90 // 将“关于...”菜单项添加到系统菜单中。 91 92 // IDM_ABOUTBOX 必须在系统命令范围内。 93 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 94 ASSERT(IDM_ABOUTBOX < 0xF000); 95 96 CMenu* pSysMenu = GetSystemMenu(FALSE); 97 if (pSysMenu != NULL) 98 { 99 BOOL bNameValid; 100 CString strAboutMenu; 101 bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); 102 ASSERT(bNameValid); 103 if (!strAboutMenu.IsEmpty()) 104 { 105 pSysMenu->AppendMenu(MF_SEPARATOR); 106 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 107 } 108 } 109 110 // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 111 // 执行此操作 112 SetIcon(m_hIcon, TRUE); // 设置大图标 113 SetIcon(m_hIcon, FALSE); // 设置小图标 114 115 // TODO: 在此添加额外的初始化代码 116 117 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE 118 } 119 120 void CAddBoxDlg::OnSysCommand(UINT nID, LPARAM lParam) 121 { 122 if ((nID & 0xFFF0) == IDM_ABOUTBOX) 123 { 124 CAboutDlg dlgAbout; 125 dlgAbout.DoModal(); 126 } 127 else 128 { 129 CDialogEx::OnSysCommand(nID, lParam); 130 } 131 } 132 133 // 如果向对话框添加最小化按钮,则需要下面的代码 134 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, 135 // 这将由框架自动完成。 136 137 void CAddBoxDlg::OnPaint() 138 { 139 if (IsIconic()) 140 { 141 CPaintDC dc(this); // 用于绘制的设备上下文 142 143 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); 144 145 // 使图标在工作区矩形中居中 146 int cxIcon = GetSystemMetrics(SM_CXICON); 147 int cyIcon = GetSystemMetrics(SM_CYICON); 148 CRect rect; 149 GetClientRect(&rect); 150 int x = (rect.Width() - cxIcon + 1) / 2; 151 int y = (rect.Height() - cyIcon + 1) / 2; 152 153 // 绘制图标 154 dc.DrawIcon(x, y, m_hIcon); 155 } 156 else 157 { 158 CDialogEx::OnPaint(); 159 } 160 } 161 162 //当用户拖动最小化窗口时系统调用此函数取得光标 163 //显示。 164 HCURSOR CAddBoxDlg::OnQueryDragIcon() 165 { 166 return static_cast<HCURSOR>(m_hIcon); 167 } 168 169 170 171 void CAddBoxDlg::OnBnClickedButtonScan() 172 { 173 // TODO: 在此添加控件通知处理程序代码 174 static const TCHAR* szFileFilter = TEXT("PE File(*.exe)|*.exe||"); 175 CFileDialog filedlg(TRUE, 0, 0, 4 | 2, szFileFilter); 176 if (IDOK == filedlg.DoModal()) 177 { 178 m_strPEFilePath = filedlg.GetPathName(); 179 this->UpdateData(FALSE); 180 } 181 } 182 183 184 void CAddBoxDlg::OnBnClickedOk() 185 { 186 // TODO: 在此添加控件通知处理程序代码 187 UpdateData(TRUE); 188 //验证用户输入的合法性 189 //if (m_strPEFilePath.IsEmpty()) 190 //{ 191 // MessageBox(TEXT("请选择目标PE文件路径")); 192 // return; 193 //} 194 195 //if (m_strBoxTitle.IsEmpty()) 196 //{ 197 // MessageBox(TEXT("请输入目标PE弹出对话框标题")); 198 // return; 199 //} 200 201 //if (m_strBoxContent.IsEmpty()) 202 //{ 203 // MessageBox(TEXT("请输入目标PE弹出对话框内容")); 204 // return; 205 //} 206 207 ////加载并链接到用户所选择PE文件的映像 208 //FILEMAPITEM OldFileMap = { 0 }, NewFileMap = { 0 }; 209 //if (!PEInfo.CreateFileMap(m_strPEFilePath.GetBuffer(0), &OldFileMap)) 210 //{ 211 // MessageBox(TEXT("创建目标PE文件映像失败!")); 212 // return; 213 //} 214 215 ////将OldFileMap基本信息保存到PEInfo中 216 //PEInfo.GetBaseInfo(&OldFileMap); 217 218 ////初始化新区块头 219 //PEInfo.InitNewSectionHeader(); 220 221 //TCHAR szNewFilePathName[MAX_PATH] = { 0 }; 222 //BYTE pSectionData[MAX_SECDATA_SIZE] = { 0 }; 223 224 ////生成新区块数据并修正新区块头 225 //DWORD dwSecDataSize = GenSecData(pSectionData, OldFileMap.ImageBase); 226 //if (dwSecDataSize > PEInfo.NewSectionHeader.SizeOfRawData) 227 //{ 228 // PEInfo.NewSectionHeader.SizeOfRawData = dwSecDataSize; 229 // PEInfo.AdjustSectionSize(); 230 //} 231 232 ////得到要建立的PE_Box.exe路径 233 //CString strTempPath = m_strPEFilePath; 234 //strTempPath.SetAt(strTempPath.GetLength() - 4, 0); 235 //wsprintf(szNewFilePathName, TEXT("%s%s"), strTempPath, TEXT("_box.exe")); 236 237 ////创建一个新的映像 238 //DWORD dwNewFileSize = PEInfo.NewSectionHeader.PointerToRawData + PEInfo.NewSectionHeader.SizeOfRawData; 239 //if (!PEInfo.CreateNewFileMap(szNewFilePathName, dwNewFileSize, &NewFileMap)) 240 //{ 241 // MessageBox(TEXT("创建新的映像文件失败!")); 242 // DeleteFile(szNewFilePathName); 243 // return; 244 //} 245 246 ////拷贝原PE数据 247 //memcpy(NewFileMap.ImageBase, OldFileMap.ImageBase, this->PEInfo.NewSectionHeader.PointerToRawData); 248 ////将及新区块头拷贝到新文件映像 249 //PEInfo.AddNewSectionHeader(&OldFileMap, &NewFileMap, dwNewFileSize); 250 ////将新区块内容拷贝到新文件映像 251 //LPVOID pvNewSec = (LPVOID)((DWORD)(NewFileMap.ImageBase) + PEInfo.NewSectionHeader.PointerToRawData); 252 //memcpy(pvNewSec, pSectionData, this->PEInfo.NewSectionHeader.SizeOfRawData); 253 254 //PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)NewFileMap.ImageBase; 255 //PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)NewFileMap.ImageBase + pDosHeader->e_lfanew); 256 //PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)(&pNtHeader->OptionalHeader); 257 258 ////修改输入表大小和位置 259 //pOptionalHeader->DataDirectory[1].Size += 0x14; 260 //pOptionalHeader->DataDirectory[1].VirtualAddress = PEInfo.NewSectionHeader.VirtualAddress; 261 262 ////清除绑定输入表 263 //pOptionalHeader->DataDirectory[11].Size = 0; 264 //pOptionalHeader->DataDirectory[11].VirtualAddress = 0; 265 266 ////修改程序入口 267 //pOptionalHeader->AddressOfEntryPoint = PEInfo.NewSectionHeader.VirtualAddress + this->dwNewEntryOff; 268 269 ////刷新映像缓冲 并卸载两个文件映像 270 //FlushViewOfFile(NewFileMap.ImageBase, dwNewFileSize); 271 //PEInfo.DeleteMap(&OldFileMap); 272 //PEInfo.DeleteMap(&NewFileMap); 273 274 //MessageBox(TEXT("添加PE _Box成功! 请到目标PE文件所在路径查看")); 275 276 277 PVOID lpPatchMemory = NULL; 278 PVOID lpTargetMemory = NULL; 279 ULONG ulPatchSize = 0; 280 ULONG ulTargetSize = 0; 281 282 lpTargetMemory = GetFileBaseAddressAndSize(szTargetPath, &ulTargetSize); 283 lpPatchMemory = GetFileBaseAddressAndSize(szPatchPath, &ulPatchSize); //patch 补丁 284 285 InsertPatchFileToTargetFile(lpTargetMemory, lpPatchMemory, ulTargetSize); 286 287 CDialogEx::OnOK(); 288 } 289 290 291 BOOL CAddBoxDlg::InsertPatchFileToTargetFile(PVOID lpTargetMemory, PVOID lpPatchMemory, ULONG ulTargetSize) 292 { 293 DWORD dwFileAlignPatchCodeSize = 0; 294 DWORD dwRealPatchCodeSize = 0; 295 ULONG ulPathCodeSectionRVA = 0; 296 ULONG ULNewFileOEP = 0; 297 ULONG ulOldOEP = 0; 298 ULONG ulFileAlignment = 0; 299 300 301 dwRealPatchCodeSize = GetFileInfo(lpPatchMemory, RealSectionSize); //获得Patch文件未对齐时的大小 302 ulPathCodeSectionRVA = GetFileInfo(lpPatchMemory, SectionRVA); //获得Patch文件所要加载节的RVA 303 ulOldOEP = GetFileInfo(lpTargetMemory, AddressOfEntryPoint); 304 ulFileAlignment = GetFileInfo(lpTargetMemory, FileAlignment); 305 ULNewFileOEP = GetNewFileOEP(lpTargetMemory); 306 dwFileAlignPatchCodeSize = Align(dwRealPatchCodeSize, ulFileAlignment); //align 对齐 返回需要申请的个数 307 308 PVOID NewFileBaseAddress = malloc(ulTargetSize + dwFileAlignPatchCodeSize); 309 memset(NewFileBaseAddress, 0, ulTargetSize + dwFileAlignPatchCodeSize); 310 311 memcpy(NewFileBaseAddress, lpTargetMemory, ulTargetSize); 312 memcpy((PVOID)((ULONG_PTR)NewFileBaseAddress + ulTargetSize), (PVOID)((ULONG_PTR)lpPatchMemory + ulPathCodeSectionRVA), dwRealPatchCodeSize); 313 314 315 ModifyPatchCodeJumpAddress(NewFileBaseAddress, ulTargetSize + dwRealPatchCodeSize, ULNewFileOEP, ulOldOEP, dwRealPatchCodeSize); //修改PatchCode结尾E9跳转地址 316 317 ModifyParameter(NewFileBaseAddress, ulTargetSize, dwFileAlignPatchCodeSize, dwRealPatchCodeSize, ULNewFileOEP); //修改最后一节和PE头的参数 318 319 320 HANDLE hNewFile = CreateFileA(szModifyPEPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL); 321 if (hNewFile == INVALID_HANDLE_VALUE) 322 { 323 printf("CreateFileA Failed! "); 324 return FALSE; 325 } 326 DWORD dwRet = 0; 327 if (WriteFile(hNewFile, NewFileBaseAddress, ulTargetSize + dwFileAlignPatchCodeSize, &dwRet, NULL) == 0) 328 { 329 printf("WriteFile Failed! "); 330 return FALSE; 331 } 332 else 333 { 334 printf("Succeed! "); 335 } 336 337 return TRUE; 338 339 340 } 341 VOID CAddBoxDlg::ModifyParameter(PVOID FileBaseAddress, ULONG ulTargetSize, ULONG ulFlieAlignPatchCodeSize, ULONG ulRealPatchCodeSize, ULONG ulNewOEP) 342 { 343 PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)FileBaseAddress; 344 PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead + DosHead->e_lfanew); 345 PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead + sizeof(IMAGE_NT_HEADERS)); 346 347 ULONG MemoryAlignment = NTHead->OptionalHeader.SectionAlignment; 348 ULONG ulNumberOfSection = NTHead->FileHeader.NumberOfSections; 349 350 SectionHead[ulNumberOfSection - 1].Characteristics = 0x60000020; 351 SectionHead[ulNumberOfSection - 1].Misc.VirtualSize = SectionHead[ulNumberOfSection - 1].SizeOfRawData + ulRealPatchCodeSize; 352 SectionHead[ulNumberOfSection - 1].SizeOfRawData += ulFlieAlignPatchCodeSize; 353 354 355 NTHead->OptionalHeader.SizeOfImage = Align(SectionHead[ulNumberOfSection - 1].VirtualAddress + SectionHead[ulNumberOfSection - 1].SizeOfRawData, MemoryAlignment); 356 NTHead->OptionalHeader.AddressOfEntryPoint = ulNewOEP; 357 } 358 359 VOID CAddBoxDlg::ModifyPatchCodeJumpAddress(PVOID lpNewFileBaseAddress, ULONG NewFileSize, ULONG ULNewFileOEP, ULONG ulOldOEP, ULONG ulRealPatchCodeSize) 360 { 361 UCHAR JmpCode[] = "x00x00x00x00"; 362 *(int*)JmpCode = (ulOldOEP + 1) - (ULNewFileOEP + ulRealPatchCodeSize); //+1越过E9 363 memcpy((PVOID)((UCHAR*)lpNewFileBaseAddress + NewFileSize - 5), JmpCode, strlen((char*)JmpCode)); //看内存 E9后有5个非0字节,所以不是-4 364 365 } 366 367 ULONG CAddBoxDlg::Align(ULONG FileSize, ULONG ulAlignment) 368 { 369 if (FileSize%ulAlignment != 0) 370 { 371 int Temp = FileSize / ulAlignment; 372 return ulAlignment*(Temp + 1); 373 } 374 else 375 { 376 return FileSize; 377 } 378 } 379 380 ULONG CAddBoxDlg::GetNewFileOEP(PVOID lpTargetMemory) 381 { 382 PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)lpTargetMemory; 383 PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead + DosHead->e_lfanew); 384 PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead + sizeof(IMAGE_NT_HEADERS)); 385 386 ULONG ulNumberOfSection = NTHead->FileHeader.NumberOfSections; 387 ULONG ulNewFileOEP = SectionHead[ulNumberOfSection - 1].VirtualAddress + 388 SectionHead[ulNumberOfSection - 1].SizeOfRawData; 389 return ulNewFileOEP; 390 } 391 DWORD CAddBoxDlg::GetFileInfo(PVOID FileBaseAddress, PATCH_FILE_INFO Type) 392 { 393 PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)FileBaseAddress; 394 PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead + DosHead->e_lfanew); 395 PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead + sizeof(IMAGE_NT_HEADERS)); 396 397 DWORD dwEntryPoint = NTHead->OptionalHeader.AddressOfEntryPoint; 398 DWORD dwRet = 0; 399 if (Type == AddressOfEntryPoint) 400 { 401 dwRet = dwEntryPoint; 402 } 403 if (Type == FileAlignment) 404 { 405 dwRet = NTHead->OptionalHeader.FileAlignment; 406 } 407 408 for (int i = 0;i<NTHead->FileHeader.NumberOfSections;i++) 409 { 410 if (dwEntryPoint >= SectionHead[i].VirtualAddress && dwEntryPoint<SectionHead[i].VirtualAddress + SectionHead[i].SizeOfRawData) 411 { 412 413 if (Type == RealSectionSize) 414 { 415 dwRet = SectionHead[i].Misc.VirtualSize; 416 } 417 if (Type == SectionRVA) 418 { 419 dwRet = SectionHead[i].PointerToRawData; 420 } 421 422 } 423 424 } 425 426 if (dwRet == NULL) 427 { 428 printf("GetFileInfo Failed! "); 429 } 430 431 return dwRet; 432 433 } 434 PVOID CAddBoxDlg:: GetFileBaseAddressAndSize(char* szFilePath, PULONG ulFileSize) 435 { 436 HANDLE hFile = CreateFileA(szFilePath, 437 GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_WRITE, NULL, 438 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 439 int a = GetLastError(); 440 if (hFile == INVALID_HANDLE_VALUE) 441 { 442 printf("CreateFile Failed! "); 443 return NULL; 444 } 445 *ulFileSize = GetFileSize(hFile, NULL); 446 447 if (!(*ulFileSize)) 448 { 449 printf("GetFileSize Failed! "); 450 CloseHandle(hFile); 451 return NULL; 452 } 453 HANDLE hMapFile = CreateFileMapping( 454 hFile, 455 NULL, 456 PAGE_READWRITE, 457 0, 458 0, 459 NULL); 460 461 if (hMapFile == INVALID_HANDLE_VALUE) 462 { 463 printf("CreateFileMapping Failed! "); 464 CloseHandle(hFile); 465 return NULL; 466 } 467 468 PVOID FileBaseAddress = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, NULL, NULL, NULL); 469 if (FileBaseAddress == NULL) 470 { 471 CloseHandle(hFile); 472 CloseHandle(hMapFile); 473 printf("MapViewOfFile Failed! "); 474 return NULL; 475 } 476 477 return FileBaseAddress; 478 } 479 480 481 DWORD CAddBoxDlg::GenSecData(PBYTE pData, LPVOID ImageBase) 482 { 483 //相关首部 484 PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)ImageBase; 485 PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)ImageBase + pDosHeader->e_lfanew); 486 PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader; 487 488 //得到输入表数据 489 PIMAGE_DATA_DIRECTORY pImportData = (PIMAGE_DATA_DIRECTORY)(&(pOptionalHeader->DataDirectory[1])); 490 PIMAGE_IMPORT_DESCRIPTOR pIID = (PIMAGE_IMPORT_DESCRIPTOR)ImageRvaToVa(pNtHeader, 491 ImageBase, pImportData->VirtualAddress, NULL); 492 493 //统计IID数量 用于后面添加新的IID 494 this->dwIIDNum = 0; 495 while (pIID[this->dwIIDNum].FirstThunk) 496 { 497 this->dwIIDNum++; 498 } 499 500 501 const char szDllName[] = "USER32.dll"; 502 const char szFunName[] = "MessageBoxA"; 503 504 //计算各项数据的摆放偏移 505 this->dwDllNameOff = pImportData->Size + 0x14; 506 this->dwFunNameOff = this->dwDllNameOff + sizeof(szDllName) + 0x3; 507 this->dwIATOff = this->dwFunNameOff + sizeof(szFunName) + 0x4; 508 this->dwBoxTitleOff = this->dwIATOff + 12; 509 char pTitle[128] = { 0 }; 510 char pContent[512] = { 0 }; 511 GetDlgItemTextA(this->GetSafeHwnd(), IDC_EDIT2, pTitle, 128); 512 GetDlgItemTextA(this->GetSafeHwnd(), IDC_EDIT3, pContent, 512); 513 this->dwBoxContentOff = this->dwBoxTitleOff + strlen(pTitle) + 1; 514 this->dwNewEntryOff = this->dwBoxContentOff + strlen(pContent) + 1; 515 516 //写入数据 517 //拷贝输入表数据 518 memcpy(pData, (LPVOID)pIID, pImportData->Size); 519 520 //写入新输入表条目数据 521 //这里新IID的起始地址用dwIIDNum*0x14计算 而不用DataDirectory[1].size(可能有对齐问题,前者偏移140 后者160) 522 PIMAGE_IMPORT_DESCRIPTOR pNewIID = PIMAGE_IMPORT_DESCRIPTOR(pData + this->dwIIDNum * 0x14); 523 pNewIID->FirstThunk = this->dwIATOff + this->PEInfo.NewSectionHeader.PointerToRawData; 524 pNewIID->OriginalFirstThunk = pNewIID->FirstThunk; 525 pNewIID->ForwarderChain = 0xFFFFFFFF; 526 pNewIID->TimeDateStamp = 0xFFFFFFFF; 527 pNewIID->Name = this->PEInfo.NewSectionHeader.PointerToRawData + this->dwDllNameOff; 528 //将IAT指向函数名 529 *((DWORD*)(pData + this->dwIATOff)) 530 = this->PEInfo.NewSectionHeader.VirtualAddress + this->dwFunNameOff; 531 //写入字符串数据 532 memcpy(pData + this->dwDllNameOff, szDllName, sizeof(szDllName)); //DllName 533 memcpy(pData + this->dwFunNameOff + 2, szFunName, sizeof(szFunName)); //FunName(前面留两个字节作序号) 534 memcpy(pData + this->dwBoxTitleOff, pTitle, strlen(pTitle) + 1); //BoxTitle 535 memcpy(pData + this->dwBoxContentOff, pContent, strlen(pContent) + 1); //BoxContent 536 537 538 539 //代码数据(程序入口) 540 /********************************** 541 / pushad 542 / push 0 543 / push 0x11111111 //指向消息框标题 需修正 544 / push 0x11111111 //指向消息框内容 需修正 545 / push 0 546 / call dword ptr MessageBoxA 547 / popad 548 / jmp 0x11111111 //指向原始入口 需修正 549 */ 550 //写入入口代码 551 BYTE pbCode[] = { 0x60, 0x6A, 0x00, 0x68, 0x11, 0x11, 0x11, 0x11, 552 0x68, 0x11, 0x11, 0x11, 0x11, 0x6A, 0x00, 0xFF, 0x15, 0xBC, 0xF2, 0x42, 553 0x00, 0x61, 0xE9, 0x11, 0x11, 0x11, 0x11 }; 554 555 memcpy(pData + this->dwNewEntryOff, pbCode, sizeof(pbCode)); 556 557 //计算JMP跳转值 558 DWORD dwOldEntryRVA = pOptionalHeader->AddressOfEntryPoint; 559 DWORD dwNewEntryRVA = this->PEInfo.NewSectionHeader.VirtualAddress + this->dwNewEntryOff + 22; 560 DWORD dwJmpDist = dwOldEntryRVA - dwNewEntryRVA - 5; 561 562 //修正代码块中三个0x11111111待修改操作数 563 //修正BoxTitle VA 564 *((DWORD*)(pData + this->dwNewEntryOff + 4)) = pOptionalHeader->ImageBase + 565 this->PEInfo.NewSectionHeader.VirtualAddress + this->dwBoxTitleOff; 566 //修正BoxContent VA 567 *((DWORD*)(pData + this->dwNewEntryOff + 9)) = pOptionalHeader->ImageBase + 568 this->PEInfo.NewSectionHeader.VirtualAddress + this->dwBoxContentOff; 569 //修正IAT VA(call ****) 570 *((DWORD*)(pData + this->dwNewEntryOff + 17)) = pOptionalHeader->ImageBase + 571 this->PEInfo.NewSectionHeader.VirtualAddress + this->dwIATOff; 572 //修正jmp操作数 573 *((DWORD*)(pData + this->dwNewEntryOff + 23)) = dwJmpDist; 574 575 return this->dwNewEntryOff + sizeof(pbCode) + 0x10; 576 }