C++ MFC应用程序中的代码注入
我有一个Win32应用程序,可以获得MFC应用程序的句柄。我的目标是强制MFC程序不显示断言错误消息框 基本上,我已经制作了一个原型,允许我的Win32应用程序强制MFC应用程序显示一个消息框,只是为了检查这个想法是否可行。现在我需要强制MFC应用程序不显示这样的断言错误消息框C++ MFC应用程序中的代码注入,c++,winapi,mfc,C++,Winapi,Mfc,我有一个Win32应用程序,可以获得MFC应用程序的句柄。我的目标是强制MFC程序不显示断言错误消息框 基本上,我已经制作了一个原型,允许我的Win32应用程序强制MFC应用程序显示一个消息框,只是为了检查这个想法是否可行。现在我需要强制MFC应用程序不显示这样的断言错误消息框 这可能吗?令我非常遗憾的是,我错过了这段代码。但是你仍然可以用手来做 下载并安装 用它打开你的exe文件 在节资源管理器中选择导入目录 在导入的dll列表中选择USER32.dll 选择MessageBoxA或Messa
这可能吗?令我非常遗憾的是,我错过了这段代码。但是你仍然可以用手来做
#include <windows.h>
#include <tchar.h>
#include "stdafx.h"
#include <stdio.h>
DWORD MapFile(HANDLE &FileMapping, LPVOID &FileBegin, const _TCHAR *exeName) {
HANDLE File = CreateFile(exeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (File == INVALID_HANDLE_VALUE) {
return GetLastError();
}
FileMapping = CreateFileMapping(File, NULL, PAGE_READWRITE, 0, 0, NULL);
CloseHandle(File);
if (!FileMapping) {
return GetLastError();
}
FileBegin = MapViewOfFile(FileMapping, FILE_MAP_WRITE, 0, 0, 0);
if (!FileBegin) {
CloseHandle(FileMapping);
return GetLastError();
}
return 0;
}
DWORD RewriteImportTable(const HANDLE FileMapping, const LPVOID FileBegin, const _TCHAR *dllName, const _TCHAR *funcName, DWORD &finalResult) {
IMAGE_DOS_HEADER* dos_header;
IMAGE_FILE_HEADER* file_header;
IMAGE_OPTIONAL_HEADER* optional_header;
IMAGE_SECTION_HEADER* section_header;
// Counting PE-header offset
dos_header = (IMAGE_DOS_HEADER*) FileBegin;
DWORD PEOffset = dos_header->e_lfanew;
file_header = (IMAGE_FILE_HEADER*) ((DWORD)FileBegin + PEOffset); // file_header must reference "PE\0"
// Checking if we work with PE
_TCHAR* PEString = "PE\0";
if (_tcscmp(PEString, (const _TCHAR*) file_header) != 0) {
printf("This file is not Portable Executable!\n");
return 666;
}
file_header = (IMAGE_FILE_HEADER *)((DWORD)file_header + sizeof(DWORD)); // Ignoring PE
optional_header = (IMAGE_OPTIONAL_HEADER *)((DWORD)file_header + sizeof(IMAGE_FILE_HEADER));
// Finding import section
DWORD ImportRVA = optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
int sectNum = -1;
// Finding import table
section_header = (IMAGE_SECTION_HEADER*) ((DWORD) optional_header + sizeof(IMAGE_OPTIONAL_HEADER));
for (int i = 0; i < (file_header->NumberOfSections); i++) {
if (ImportRVA < (section_header->VirtualAddress)) {
section_header--;
sectNum = i-1;
break;
}
section_header++;
}
if (sectNum == -1) {
printf("This program uses no external libraries! (strange)\n");
return 666;
}
// Getting address of section folowing import section
section_header++;
DWORD SectionNextToImportBegin = (DWORD)FileBegin + section_header->PointerToRawData;
section_header--;
// Getting the address of the import table
LPVOID ImportSectionBegin = (LPVOID) ((DWORD)FileBegin + section_header->PointerToRawData);
// Counting the import table offset in the import section
LPVOID ImportTable = (LPVOID)((DWORD)ImportSectionBegin + (ImportRVA - section_header->VirtualAddress));
IMAGE_IMPORT_DESCRIPTOR *DLLInfo = (IMAGE_IMPORT_DESCRIPTOR*) ImportTable;
LPVOID DLLName;
DWORD DLLCounter = 0;
while (DLLInfo->Name != NULL) {
DLLCounter++;
DLLName = (LPVOID) ((DWORD)ImportSectionBegin + ((DWORD)DLLInfo->Name - section_header->VirtualAddress));
DLLInfo++;
}
printf("Number of imported libraries: %d\n", DLLCounter);
// Counting the size of the future import table
DWORD newImportTableSize = sizeof(IMAGE_IMPORT_DESCRIPTOR) * (DLLCounter + 2);
// Finding the end of the import section
LPVOID pos = (LPVOID) (SectionNextToImportBegin - 1);
DWORD maxFree = 0;
DWORD prevPtr;
LPVOID freePtr = NULL;
// Searching for the free place
while (pos >= ImportSectionBegin) {
if (*(BYTE*)pos == 0) {
prevPtr = (DWORD) pos;
while (*(BYTE*)pos == 0) {
pos = (LPVOID) ((DWORD)pos - 1);
}
if (((DWORD)prevPtr - (DWORD)pos) > maxFree) {
maxFree = ((DWORD)prevPtr - (DWORD)pos);
freePtr = (LPVOID) ((DWORD)pos + 1);
}
}
pos = (LPVOID) ((DWORD)pos - 1);
}
// Modifying pointer: it can refer the tailing zero of some stucture
freePtr = (LPVOID) ((LPDWORD)freePtr + 1);
maxFree -= 4;
// Checking if we have enough space in the import section
if (maxFree < newImportTableSize) {
printf("Not enough free space in Import Section\n");
return 666;
}
printf("Injecting new library...\n");
// Copying old import table on the new place
memcpy(freePtr, ImportTable, sizeof(IMAGE_IMPORT_DESCRIPTOR) * DLLCounter);
// Saving everithing we need on the old place
typedef struct {
DWORD ZeroDword;
DWORD IAT;
DWORD IATEnd;
} MeanStruct;
MeanStruct patch;
patch.ZeroDword = NULL; // this is \0 for dll name
patch.IAT = ImportRVA + _tcslen(dllName) + sizeof(MeanStruct); // RVA to where list of functions begins
patch.IATEnd = NULL;
WORD Hint = 0;
IMAGE_IMPORT_BY_NAME myName;
myName.Hint = 0x00;
myName.Name[0] = 0x00;
LPDWORD zeroPtr = (LPDWORD) ImportTable;
memcpy(zeroPtr, dllName, _tcslen(dllName));
zeroPtr = (LPDWORD) ((DWORD)zeroPtr + strlen(dllName));
memcpy(zeroPtr, &patch, sizeof(patch));
zeroPtr = (LPDWORD) ((DWORD)zeroPtr + sizeof(patch));
finalResult = (DWORD)zeroPtr - (DWORD)ImportSectionBegin + section_header->VirtualAddress;
memcpy(zeroPtr, &Hint, sizeof(WORD));
zeroPtr = (LPDWORD) ((DWORD)zeroPtr + sizeof(WORD));
memcpy(zeroPtr, funcName, strlen(funcName) + 1); // we have no need to write \0 into the end - this is already free space
zeroPtr = (LPDWORD) ((DWORD)zeroPtr + strlen(funcName) + 1);
memcpy(zeroPtr, &myName, sizeof(IMAGE_IMPORT_BY_NAME));
// filling info about dll
IMAGE_IMPORT_DESCRIPTOR myDLL;
// counting RVA for IMAGE_IMPORT_BY_NAME:
DWORD IIBN_Table = ImportRVA + strlen(dllName) + sizeof(DWORD);
// function name pointer
myDLL.Characteristics = IIBN_Table;
myDLL.TimeDateStamp = NULL;
myDLL.ForwarderChain = NULL;
// dll name pointer
myDLL.Name = ImportRVA;
myDLL.FirstThunk = IIBN_Table;
// writting dll info into the new import table
LPVOID oldFreePtr = freePtr;
freePtr = (LPVOID) ((DWORD)freePtr + sizeof(IMAGE_IMPORT_DESCRIPTOR) * DLLCounter);
memcpy(freePtr, &myDLL, sizeof(IMAGE_IMPORT_DESCRIPTOR));
// creating list tail
myDLL.Characteristics = NULL;
myDLL.TimeDateStamp = NULL;
myDLL.ForwarderChain = NULL;
myDLL.Name = NULL;
myDLL.FirstThunk = NULL;
// writing list tail
freePtr = (LPVOID) ((DWORD)freePtr + sizeof(IMAGE_IMPORT_DESCRIPTOR));
memcpy(freePtr, &myDLL, sizeof(IMAGE_IMPORT_DESCRIPTOR));
// setting new import table rva
DWORD newImportTableRVA = (DWORD)oldFreePtr - (DWORD)ImportSectionBegin + section_header->VirtualAddress;
// changing DataDirectory
optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = newImportTableRVA;
optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (DLLCounter + 1) * sizeof(IMAGE_IMPORT_DESCRIPTOR);
// clearing non-actual values
optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0;
optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0;
return 0;
}
int _tmain(int argc, _TCHAR *argv[]) {
if (argc != 4) {
printf("Invalid arguments number!!!\n");
return 0;
}
HANDLE FileMapping;
LPVOID FileBegin;
DWORD FileMappingResult = MapFile(FileMapping, FileBegin, argv[1]);
if (0 != FileMappingResult) {
printf("Error of file mapping (%d)\n", FileMappingResult);
if (NULL != FileMapping) CloseHandle(FileMapping);
return FileMappingResult;
}
DWORD functionAddr;
DWORD RewriteImportTableResult = RewriteImportTable(FileMapping, FileBegin, argv[2], argv[3], functionAddr);
if (0 != RewriteImportTableResult) {
UnmapViewOfFile(FileBegin);
CloseHandle(FileMapping);
return 666;
}
printf("Library successfully injected!\n");
printf("Address of injected function: %X", functionAddr);
UnmapViewOfFile(FileBegin);
CloseHandle(FileMapping);
return 0;
}
#包括
#包括
#包括“stdafx.h”
#包括
DWORD映射文件(句柄和文件映射、LPVOID和文件开始、常量*exeName){
HANDLE File=CreateFile(exeName,GENERIC_READ | GENERIC_WRITE,File_SHARE_WRITE,NULL,
打开\现有,文件\属性\正常,空);
if(File==无效的\u句柄\u值){
返回GetLastError();
}
FileMapping=CreateFileMapping(文件,NULL,页\读写,0,0,NULL);
关闭句柄(文件);
if(!FileMapping){
返回GetLastError();
}
FileBegin=MapViewOfFile(FileMapping,FILE\u-MAP\u-WRITE,0,0);
如果(!FileBegin){
CloseHandle(文件映射);
返回GetLastError();
}
返回0;
}
DWORD RewriteImportable(常量句柄文件映射、常量LPVOID文件开始、常量TCHAR*dllName、常量TCHAR*funcName、DWORD和finalResult){
图像_DOS_头*DOS_头;
图像\文件\头*文件\头;
图像\可选\头*可选\头;
图像\节\头*节\头;
//计数PE头偏移量
dos\U头=(图像\U dos\U头*)文件开始;
DWORD PEOffset=dos_头->e_lfanew;
文件头=(图像文件头*)((DWORD)文件开始+PEOffset);//文件头必须引用“PE\0”
//检查我们是否与PE合作
_TCHAR*PEString=“PE\0”;
如果(_tcscmp(PEString,(const _TCHAR*)文件头)!=0){
printf(“此文件不是可移植的可执行文件!\n”);
返回666;
}
file_header=(IMAGE_file_header*)((DWORD)file_header+sizeof(DWORD));//忽略PE
可选_头=(图像_可选_头*)((DWORD)文件_头+大小(图像_文件_头));
//查找导入部分
DWORD ImportRVA=可选的\u头->数据目录[IMAGE\u DIRECTORY\u ENTRY\u IMPORT].VirtualAddress;
int sectNum=-1;
//查找导入表
节头=(图像节头*)((DWORD)可选节头+sizeof(图像节头*);
对于(inti=0;i<(文件头->NumberOfSections);i++){
if(导入<(节头->虚拟地址)){
第_节标题--;
sectNum=i-1;
打破
}
节头++;
}
如果(sectNum==-1){
printf(“此程序不使用外部库!(奇怪)\n”);
返回666;
}
//正在获取导入节后面的节的地址
节头++;
DWORD SECTIONNEXTOTOMPORTTBEGIN=(DWORD)文件开始+节头->指针或WDATA;
第_节标题--;
//获取导入表的地址
LPVOID导入操作开始=(LPVOID)((DWORD)文件开始+节头->指针或数据);
//计算导入部分中的导入表偏移量
LPVOID ImportTable=(LPVOID)((DWORD)ImportSectionBegin+(ImportRVA-section_header->VirtualAddress));
图像导入描述符*DLLInfo=(图像导入描述符*)可导入;
LPVOID-DLLName;
DWORD DLL计数器=0;
while(DLLInfo->Name!=NULL){
DLLCounter++;
DLLName=(LPVOID)((DWORD)ImportSectionBegin+((DWORD)DLLInfo->Name-section_header->VirtualAddress));
DLLInfo++;
}
printf(“导入库的数量:%d\n”,DLLCounter);
//计算未来导入表的大小
DWORD NewImportableSize=sizeof(图像\导入\描述符)*(DLLCounter+2);
//查找导入节的结尾
LPVOID pos=(LPVOID)(第二节导入开始-1);
DWORD-maxFree=0;
德沃德·普雷夫特;
LPVOID freePtr=NULL;
//寻找自由的地方
while(pos>=导入操作开始){
如果(*(字节*)位置==0){
prevPtr=(DWORD)位置;
而(*(字节*)pos==0){
位置=(LPVOID)((DWORD)位置-1);
}
如果(((DWORD)prevPtr-(DWORD)pos)>maxFree){
maxFree=((DWORD)前置PTR-(DWORD)位置);
freePtr=(LPVOID)((德沃德)位置+1);
}
}
位置=(LPVOID)((DWORD)位置-1);
}
//修改指针:它可以引用某些结构的尾随零
freePtr=(LPVOID)((LPDWORD)freePtr+1);
maxFree-=4;
//检查导入部分是否有足够的空间
if(maxFree