最近在做一个基于VC++的ARX项目,要求CAD禁止保存wmf格式的文件,在网上找了一下解决方法,用重写函数的地址替换原来的WriteFile函数的地址,可是CAD进行保存时并没有进入到自己写的函数里面,求高手帮帮解决一下。CADVisual C++wmf

解决方案 »

  1.   

    这是找到的代码BOOL MyWriteFile(  HANDLE hFile,
     LPCVOID lpBuffer,
     DWORD nNumberOfBytesToWrite,
     LPDWORD lpNumberOfBytesWritten,
     LPOVERLAPPED lpOverlapped)
    {
        //printf("MyWriteFile\n");
        return true;
    }BOOL MyWriteFileEx(HANDLE hFile,
    LPCVOID lpBuffer,
    DWORD nNumberOfBytesToWrite,
    LPOVERLAPPED lpOverlapped,
    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
    {
    return true;
    }void RedirectAPI(int *addr, int *myaddr)
    {
        PIMAGE_DOS_HEADER  pDosHeader;
        PIMAGE_NT_HEADERS  pNTHeaders;
        PIMAGE_OPTIONAL_HEADER   pOptHeader;
        PIMAGE_IMPORT_DESCRIPTOR  pImportDescriptor;
        PIMAGE_THUNK_DATA         pThunkData;
        PIMAGE_IMPORT_BY_NAME     pImportByName;
        HMODULE hMod;

        hMod = GetModuleHandle(NULL);

        pDosHeader = (PIMAGE_DOS_HEADER)hMod;
        pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)hMod + pDosHeader->e_lfanew);
        pOptHeader = (PIMAGE_OPTIONAL_HEADER)&(pNTHeaders->OptionalHeader);

        pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hMod + pOptHeader->DataDirectory[1].VirtualAddress);

        while(pImportDescriptor->FirstThunk)
        {
    char * dllname = (char *)((BYTE *)hMod + pImportDescriptor->Name);
    //printf("函数模块:%s\n",dllname);

    pThunkData = (PIMAGE_THUNK_DATA)((BYTE *)hMod + pImportDescriptor->OriginalFirstThunk);

    int no = 1;
    while(pThunkData->u1.Function)
    {
    char * funname = (char *)((BYTE *)hMod + (DWORD)pThunkData->u1.AddressOfData + 2);
    //printf("%s\n", funname);
    PDWORD lpAddr = (DWORD *)((BYTE *)hMod + (DWORD)pImportDescriptor->FirstThunk) +(no-1);

    //printf("%4d:  ",no);
    //printf("%30s",funname);
    //printf("%8x\n",lpAddr);
    //printf("%8x\n",*lpAddr);
    //修改内存的部分
    if((*lpAddr) == (int)addr)
    {
    //修改内存页的属性
    DWORD dwOLD;
    MEMORY_BASIC_INFORMATION  mbi;
    VirtualQuery(lpAddr,&mbi,sizeof(mbi));
    VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,&dwOLD);
    //写内存
    BOOL b = WriteProcessMemory(GetCurrentProcess(),
    lpAddr, &myaddr, sizeof(DWORD), NULL);
    //恢复内存页的属性
    VirtualProtect(lpAddr,sizeof(DWORD),dwOLD,0);
    }
    //---------
    no++;
    pThunkData++;
    }

    pImportDescriptor++;
        }


        return;
    }
    主函数中的调用 RedirectAPI((int *)WriteFile, (int *)MyWriteFile);
    RedirectAPI((int *)WriteFileEx, (int *)MyWriteFileEx);
      

  2.   

    1、调试下CAD程序确认在保存文件时是否调用了WriteFile
    2、确认下你是否hook代码是否有问题,你自己可以写个MyCAD,然后用户的hook程序去禁止MyCAD保存