C++ MFC应用程序中的代码注入

C++ MFC应用程序中的代码注入,c++,winapi,mfc,C++,Winapi,Mfc,我有一个Win32应用程序,可以获得MFC应用程序的句柄。我的目标是强制MFC程序不显示断言错误消息框 基本上,我已经制作了一个原型,允许我的Win32应用程序强制MFC应用程序显示一个消息框,只是为了检查这个想法是否可行。现在我需要强制MFC应用程序不显示这样的断言错误消息框 这可能吗?令我非常遗憾的是,我错过了这段代码。但是你仍然可以用手来做 下载并安装 用它打开你的exe文件 在节资源管理器中选择导入目录 在导入的dll列表中选择USER32.dll 选择MessageBoxA或Messa

我有一个Win32应用程序,可以获得MFC应用程序的句柄。我的目标是强制MFC程序不显示断言错误消息框

基本上,我已经制作了一个原型,允许我的Win32应用程序强制MFC应用程序显示一个消息框,只是为了检查这个想法是否可行。现在我需要强制MFC应用程序不显示这样的断言错误消息框


这可能吗?

令我非常遗憾的是,我错过了这段代码。但是你仍然可以用手来做

  • 下载并安装
  • 用它打开你的exe文件
  • 在节资源管理器中选择导入目录
  • 在导入的dll列表中选择USER32.dll
  • 选择MessageBoxA或MessageBoxW。编辑OFT列。写一些“无害”的函数。我以GetWindowRect为例
  • 如果您仍然需要一个应用程序来执行此操作,我有一个功能非常相似的代码。它只是将dll嵌入到导入表中。您可以编辑它以获得想要的结果,也可以使用它将MessageBoxW调用重定向到您的处理程序

    #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