我们在用创建EXCEL文件时,往往出于对效率的考虑,需要在内存中操作。比如:直接打开在内存中的excel文件。
先说说思路,首先如何在内存中构建excel文件,有两种方法,一种参考xls文件的格式,编写xls文件创建的所有机制代码,这种很麻烦,建议舍去(我想大家都不想自己写一个EXCEL应用程序吧。)。第二种,安装Ramdisk软件,创建虚拟内存硬盘,把excel文件保存在内存中,这种需要安装第三方的虚拟Ramdisk软件,另外的开销,在这里也不推荐。第三种,是这里要重点说的,利用excel xml文件进行,这种文件的好处很多,比如,利于修改,就像编辑HTML文件一样简单。在我们的应用中可以利用CString类似这样的类,来灵活的生成xml格式的excel文件内容。
其次,我们如何在内存中创建我们的xml格式的excel文件,这要利用windows系统的流文件,先创建一个在硬盘上的流文件空壳,然后我们进行读写,这时我们发现,读写的内容,并没有写入硬盘上的空壳文件,那说明它一定在内存中。
再次,那我们如何把这个流文件用Excel打开呢,我们注意到流文件的文件名与普通文件的文件名是不一样的,EXCEL也没有提供这样的接口,设想如果真能打开,我们可以随意的将XML格式转换成XLS格式。换句话说,我们可以用利于修改的CString,直接生成,EXCEL中的文件对象,工作簿对象等等吧,我们可以把EXCEL提供的函数等直接拿来用。
方法就是,修改EXCEL应用程序空间中加载的CreateFile,或者OpenFile的函数。把传进来的文件名,按我们设置好的规则,偷偷换成流文件的文件名,这样,我们就绕过了EXCEL程序的open函数的文件名限制的门槛,直接将我们在内存中的XML格式的EXCEL文件打开。这样做的根据是,EXCEL想打开文件,那么必须一定肯定要调用,系统底层的CreateFile API。
效果就是在内存中直接将 XML直接转换成EXCEL文件对象。毕竟EXCEL的API很好,不直接拿来用,岂不是太对不起微软了。
由于xml文件有些功能是没有的,需要用excel 工作簿,工作表等对象进行操作。
以下是代码,我就不解释了。
API 注入技术等的文件的来源,大家可以网上查,毕竟有了思路,剩下的只是苦力活。
InjectExcel.c文件如下:
#include"InjectExcel.h"
static void HookCreateFile(LPVOID lParam)
{
RemoteParam* pRP = (RemoteParam*)lParam;
DWORD NextIpAddr = 0;
DWORD dwParamaAddr = 0;
HANDLE RetFpHdl = INVALID_HANDLE_VALUE;
LPCTSTR lpFileName;
DWORD dwDesiredAccess;
DWORD dwShareMode;
LPSECURITY_ATTRIBUTES lpSecurityAttributes;
DWORD dwCreationDisposition;
DWORD dwFlagsAndAttributes;
HANDLE hTemplateFile;
unsigned char szNewCode[10];
int PramaAddr;
int funaddr;
wchar_t *tmpPtr,*tmpPtrCount;
wchar_t *tmpPtrOldParam;
wchar_t *tmpPtrOldStreamParam;
PFN_CREATEFILE pfnCreatefile;
PFN_GETCURRENTPROCESS pfnGetCurrentProcess;
PFN_WRITEPROCESSMEMORY pfnWriteProcessMemory;
int flag=1;
int i;
int j;
int iFileNameCount=0;
int iPathLastSlashPos=0;
wchar_t wcFileNameEnd='\0';
wchar_t wcFilePathSlash='\\';
wchar_t iNewFileName[300];
__asm
{
MOV EAX, [EBP+8]
MOV [dwParamaAddr], EAX
MOV EAX, [EBP+12]
MOV [NextIpAddr], EAX
MOV EAX, [EBP+16]
MOV [lpFileName], EAX
MOV EAX,[EBP+20]
MOV [dwDesiredAccess], EAX
MOV EAX, [EBP+24]
MOV [dwShareMode], EAX
MOV EAX, [EBP+28]
MOV [lpSecurityAttributes], EAX
MOV EAX, [EBP+32]
MOV [dwCreationDisposition], EAX
MOV EAX, [EBP+36]
MOV [dwFlagsAndAttributes], EAX
MOV EAX, [EBP+40]
MOV [hTemplateFile], EAX
}
PramaAddr = (int)dwParamaAddr;
pfnCreatefile = (PFN_CREATEFILE)pRP->dwCreateFile;
pfnGetCurrentProcess = (PFN_GETCURRENTPROCESS)pRP->dwGetCurrentProcess;
pfnWriteProcessMemory = (PFN_WRITEPROCESSMEMORY)pRP->dwWriteProcessMemory;
szNewCode[4] = PramaAddr >> 24;
szNewCode[3] = (PramaAddr << 8) >> 24;
szNewCode[2] = (PramaAddr << 16) >> 24;
szNewCode[1] = (PramaAddr << 24) >> 24;
szNewCode[0] = 0x68;
funaddr = (int)pRP->FunAddr - (int)pfnCreatefile - 10;
szNewCode[9] = funaddr >> 24;
szNewCode[8] = (funaddr << 8) >> 24;
szNewCode[7] = (funaddr << 16) >> 24;
szNewCode[6] = (funaddr << 24) >> 24;
szNewCode[5] = 0xE8;
tmpPtr=(wchar_t *)lpFileName;
tmpPtrCount=tmpPtr;//C:\kk\jl.txt_ iFileNameCount=13,iPathLastSlashPos=8
while(*tmpPtrCount!=wcFileNameEnd){tmpPtrCount++;iFileNameCount++;}
//tmpPtrCount=tmpPtr+iFileNameCount-1;
while(*tmpPtrCount!=wcFilePathSlash&&iPathLastSlashPos<iFileNameCount){tmpPtrCount--;iPathLastSlashPos++;}
tmpPtr=(wchar_t *)tmpPtrCount+1;
tmpPtrOldParam=pRP->szFileName;
tmpPtrOldStreamParam=pRP->szStreamName;
for(i=0;i<15;i++)
{
if(tmpPtr[i]!=tmpPtrOldParam[i])
{
flag=0;
break;
}
}
if(flag==0)
{
tmpPtrOldParam=pRP->szSecFileName;
tmpPtrOldStreamParam=pRP->szSecStreamName;
for(i=0;i<15;i++)
{
if(tmpPtr[i]!=tmpPtrOldParam[i])
{
flag=0;
break;
}
}
if(i==15)
{
flag=2;
}
}
pfnWriteProcessMemory (pfnGetCurrentProcess(),
(LPVOID)pfnCreatefile,
(LPCVOID)pRP->szOldCode,
10,
NULL);
if(flag==1)
{
tmpPtrCount=(wchar_t *)lpFileName;
j=0;//C:\kk\jl.txt_ iFileNameCount=13,iPathLastSlashPos=8
while(j<iFileNameCount-iPathLastSlashPos+1)
{
iNewFileName[j++]=*tmpPtrCount;
tmpPtrCount++;
}
iNewFileName[j++]=wcFilePathSlash;//C:\kk\//
tmpPtrCount=pRP->szStreamName;
while(*tmpPtrCount!=wcFileNameEnd)
{
iNewFileName[j++]=*tmpPtrCount;
tmpPtrCount++;
}
iNewFileName[j]=wcFileNameEnd;
RetFpHdl = pfnCreatefile (iNewFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
}
else if(flag==2)
{
tmpPtrCount=(wchar_t *)lpFileName;
j=0;//C:\kk\jl.txt_ iFileNameCount=13,iPathLastSlashPos=8
while(j<iFileNameCount-iPathLastSlashPos+1)
{
iNewFileName[j++]=*tmpPtrCount;
tmpPtrCount++;
}
iNewFileName[j++]=wcFilePathSlash;//C:\kk\//
tmpPtrCount=pRP->szSecStreamName;
while(*tmpPtrCount!=wcFileNameEnd)
{
iNewFileName[j++]=*tmpPtrCount;
tmpPtrCount++;
}
iNewFileName[j]=wcFileNameEnd;
RetFpHdl = pfnCreatefile (iNewFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
}
else
{
RetFpHdl = pfnCreatefile (lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
}
pfnWriteProcessMemory(pfnGetCurrentProcess(),
(LPVOID)pfnCreatefile,
(LPCVOID)szNewCode,
10,
NULL);
__asm
{
POP EDI
POP ESI
POP EBX
MOV EDX, [NextIpAddr]
MOV EAX, [RetFpHdl]
MOV ESP, EBP
POP EBP
ADD ESP, 28H
PUSH EDX
RET
}
}
BOOL AdjustProcessPrivileges(LPCTSTR szPrivilegesName)
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return FALSE;
}
if(!LookupPrivilegeValue(NULL, szPrivilegesName, &tkp.Privileges[0].Luid))
{
CloseHandle(hToken);
return FALSE;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
{
CloseHandle(hToken);
return FALSE;
}
CloseHandle(hToken);
return TRUE;
}
void printProcessNameByPid( DWORD ProcessId)
{
HANDLE pHd;
HMODULE pHmod;
TCHAR ProcessName[MAX_PATH] = L"unknown";
DWORD cbNeeded;
pHd = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessId );
if(pHd == NULL) return;
if(!EnumProcessModules( pHd, &pHmod, sizeof(pHmod), &cbNeeded)) return;
if(!GetModuleFileNameEx( pHd, pHmod, ProcessName, MAX_PATH)) return;
//printf( "%dt%s\n", ProcessId, ProcessName);
CloseHandle( pHd );
return;
}
DWORD dwFunAddr;
DWORD dwPramaAddr;
//HANDLE hTargetProcess;
DWORD dwPid;
RemoteParam RParam;
HMODULE hKernel32;
unsigned char newcode[10];
DWORD dwNewProt, dwOldProt;
unsigned char szFileNameTmp[15];
unsigned char szStreamNameTmp[28];
unsigned char szSecFileNameTmp[15];
unsigned char szSecStreamNameTmp[28];
HANDLE hStream;
HANDLE hSecStream;
BOOL SetHookCreateFileFunc(DWORD dwPidPara ,
wchar_t chFileName[15],wchar_t chStreamName[28],
wchar_t chSecFileName[15],wchar_t chSecStreamName[28],HANDLE* CurrentProcHandle
,unsigned char oldcode[10])
{
SIZE_T numWritten;
//wchar_t wchTmp='D';
//wchar_t wchTmp2='E';
//HANDLE hTargetProcess;
HMODULE hUser32;
int praadd ;
int threadadd;
HANDLE hTargetProcess;
SIZE_T numRead;
DWORD offsetaddr;
//hStream = CreateFile( chStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
//if( hStream == INVALID_HANDLE_VALUE )
//{
// chStreamName[0]=wchTmp;
// chFileName[0]=wchTmp;
// hStream = CreateFile( chStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
// if( hStream == INVALID_HANDLE_VALUE )
// {
// //wchar_t wchTmp2='E';
// chStreamName[0]=wchTmp2;
// chFileName[0]=wchTmp2;
// hStream = CreateFile( chStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
// //d(_T("生成过渡性临时文件失败!"));
// if( hStream == INVALID_HANDLE_VALUE )
// {
// return FALSE;
// }
// }
//}
//CloseHandle( hStream );
//hStream = INVALID_HANDLE_VALUE;
//hSecStream = CreateFile( chSecStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
//if( hSecStream == INVALID_HANDLE_VALUE )
//{
// chSecStreamName[0]=wchTmp;
// chSecFileName[0]=wchTmp;
// hSecStream = CreateFile( chSecStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
// if( hSecStream == INVALID_HANDLE_VALUE )
// {
// //wchar_t wchTmp2='E';
// chSecStreamName[0]=wchTmp2;
// chSecFileName[0]=wchTmp2;
// hSecStream = CreateFile( chSecStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
// //d(_T("生成过渡性临时文件失败!"));
// if( hSecStream == INVALID_HANDLE_VALUE )
// {
// return FALSE;
// }
// }
//}
//CloseHandle( hSecStream );
//hSecStream = INVALID_HANDLE_VALUE;
dwPid=dwPidPara;
if(!AdjustProcessPrivileges(SE_DEBUG_NAME))
{
// printf("AdjustProcessPrivileges Error!\n");
return FALSE;
}
hTargetProcess= OpenProcess(
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE,
dwPidPara
);
if(hTargetProcess == NULL)
{
// printf("OpenProcess Error!\n");
return FALSE;
}
*CurrentProcHandle=hTargetProcess;
dwFunAddr = (DWORD)VirtualAllocEx(hTargetProcess, NULL, 8192,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if((LPVOID)dwFunAddr == NULL)
{
CloseHandle(hTargetProcess);
return FALSE;
}
dwPramaAddr = (DWORD)VirtualAllocEx(hTargetProcess, NULL, sizeof(RemoteParam),
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if((LPVOID)dwPramaAddr == NULL)
{
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
CloseHandle(hTargetProcess);
return FALSE;
}
// printf("\n线程内存地址:%.8x\n 参数内存地址:%.8x\n", dwFunAddr, dwPramaAddr);
ZeroMemory(&RParam, sizeof(RParam));
hKernel32 = LoadLibrary(L"kernel32.dll");
hUser32 = LoadLibrary(L"user32.dll");
RParam.dwCreateFile = (DWORD)GetProcAddress(hKernel32, MYCREATEFILE);
RParam.CurrentProcHandl=(DWORD)hTargetProcess;
RParam.dwGetCurrentProcess=(DWORD)GetProcAddress(hKernel32, "GetCurrentProcess");
RParam.dwWriteProcessMemory = (DWORD)GetProcAddress(hKernel32, "WriteProcessMemory");
RParam.vdwMessageBox = (DWORD)GetProcAddress(hUser32, MYMESSAGEBOX);
praadd = (int)dwPramaAddr;
threadadd = (int)dwFunAddr;
newcode[4] = praadd >> 24;
newcode[3] = (praadd << 8) >> 24;
newcode[2] = (praadd << 16) >> 24;
newcode[1] = (praadd << 24) >> 24;
newcode[0] = 0x68;
offsetaddr = threadadd - (int)RParam.dwCreateFile - 10 ;
newcode[9] = offsetaddr >> 24;
newcode[8] = (offsetaddr << 8) >> 24;
newcode[7] = (offsetaddr<< 16) >> 24;
newcode[6] = (offsetaddr << 24) >> 24;
newcode[5] = 0xE8;
if(!ReadProcessMemory(GetCurrentProcess(),
(LPCVOID)RParam.dwCreateFile,
oldcode,
10,
&numRead))
{
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwPramaAddr, // 区域地址
0, // 区域大小sizeof(RemoteParam)
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwPramaAddr=(DWORD)NULL;
CloseHandle(hTargetProcess);
//FreeLibrary(hKernel32);
return FALSE;
}
RParam.CurrentProcHandl=(DWORD)hTargetProcess;
memcpy((char*)RParam.szOldCode, (char*)oldcode,10);
wcscat_s((wchar_t*)RParam.szFileName,15, (wchar_t*)chFileName);
wcscat_s((wchar_t*)RParam.szStreamName,28, (wchar_t*)chStreamName);
wcscat_s((wchar_t*)RParam.szSecFileName,15, (wchar_t*)chSecFileName);
wcscat_s((wchar_t*)RParam.szSecStreamName,28, (wchar_t*)chSecStreamName);
RParam.FunAddr = dwFunAddr;
//// printf( chStreamName[0]=wchTmp;
// chFileName[0]=wchTmp;
// "RParam.dwCreate文件:%.8x\n"
// "RParam.dwMessageBox:%.8x\n"
// "RParam.dwGetCurrentProcess:%.8x\n"
// "RParam.dwWriteProcessMemory:%.8x\n"
// "RParam.FunAddr:%.8x\n",
// RParam.dwCreateFile,
//RParam.vdwMessageBox,
// RParam.dwGetCurrentProcess,
// RParam.dwWriteProcessMemory,
// RParam.FunAddr);
// printf("RParam.szOldCode:");
// for( int i = 0; i < 10; i++)
// printf("0x%.2x ", RParam.szOldCode);
// printf("\n");
if(!WriteProcessMemory(hTargetProcess, (LPVOID)dwFunAddr, (LPVOID)&HookCreateFile, 8192, &numWritten))
{
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwPramaAddr, // 区域地址
0, // 区域大小sizeof(RemoteParam)
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
//::MessageBoxExW(NULL,L"释放空间失败!",NULL,NULL,NULL);
//::OutputDebugStringW(L"释放空间失败!");
return FALSE;
}
dwPramaAddr=(DWORD)NULL;
CloseHandle(hTargetProcess);
//FreeLibrary(hKernel32);
return FALSE;
}
//SIZE_T numWritten;
if(!WriteProcessMemory(hTargetProcess, (LPVOID)dwPramaAddr,
(LPVOID)&RParam, sizeof(RemoteParam), &numWritten))
{
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwPramaAddr, // 区域地址
0, // 区域大小sizeof(RemoteParam)
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwPramaAddr=(DWORD)NULL;
CloseHandle(hTargetProcess);
//FreeLibrary(hKernel32);
return FALSE;
}
if(!WriteProcessMemory(hTargetProcess, (LPVOID)RParam.dwCreateFile, (LPVOID)newcode, 10, &numWritten))
{
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwPramaAddr, // 区域地址
0, // 区域大小sizeof(RemoteParam)
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwPramaAddr=(DWORD)NULL;
CloseHandle(hTargetProcess);
//FreeLibrary(hKernel32);
return FALSE;
}
// printf( "Cannot open TestFile:Stream\n" );
//printf("\nThat's all, good luck :)\n");
return TRUE;
}
BOOL FreeHookCreateFileFunc(HANDLE CurrentProcHandle,unsigned char oldcode[10])
{
SIZE_T numWritten;
if(!WriteProcessMemory(CurrentProcHandle, (LPVOID)RParam.dwCreateFile, (LPVOID)oldcode, 10, &numWritten))
{
//printf("WriteRemoteProcessesMemory Error!\n");
CloseHandle(CurrentProcHandle);
//FreeLibrary(hKernel32);
return FALSE;
}
VirtualProtectEx(CurrentProcHandle, (LPVOID)RParam.dwCreateFile, 10, dwOldProt, &dwNewProt);
if((LPVOID)dwFunAddr!=NULL)
{
if(!VirtualFreeEx(CurrentProcHandle,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
CloseHandle(CurrentProcHandle);
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
}
if((LPVOID)dwPramaAddr!=NULL)
{
if(!VirtualFreeEx(CurrentProcHandle,
(LPVOID )dwPramaAddr, // 区域地址
0, // 区域大小sizeof(RemoteParam)
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
CloseHandle(CurrentProcHandle);
return FALSE;
}
dwPramaAddr=(DWORD)NULL;
}
CloseHandle(CurrentProcHandle);
return TRUE;
}
BOOL FreeHookCreateFileFuncCurrentProc(HANDLE CurrentProcHandle,unsigned char oldcode[10])
{
SIZE_T numWritten;
if(!WriteProcessMemory(CurrentProcHandle, (LPVOID)RParam.dwCreateFile, (LPVOID)oldcode, 10, &numWritten))
{
//printf("WriteRemoteProcessesMemory Error!\n");
CloseHandle(CurrentProcHandle);
//FreeLibrary(hKernel32);
return FALSE;
}
CloseHandle(CurrentProcHandle);
return TRUE;
}
//BOOL SetFileName(
// wchar_t chFileName[18],wchar_t chStreamName[31],
// wchar_t chSecFileName[18],wchar_t chSecStreamName[31])
//{
// wchar_t wchTmp='D';
// wchar_t wchTmp2='E';
// //HANDLE hTargetProcess;
// //HMODULE hUser32;
// //int praadd ;
// //int threadadd;
// //SIZE_T numRead;
// //DWORD offsetaddr;
// hStream = CreateFile( chStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
// if( hStream == INVALID_HANDLE_VALUE )
// {
//
// chStreamName[0]=wchTmp;
// chFileName[0]=wchTmp;
// hStream = CreateFile( chStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
// if( hStream == INVALID_HANDLE_VALUE )
// {
// //wchar_t wchTmp2='E';
// chStreamName[0]=wchTmp2;
// chFileName[0]=wchTmp2;
// hStream = CreateFile( chStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
// //d(_T("生成过渡性临时文件失败!"));
// if( hStream == INVALID_HANDLE_VALUE )
// {
// return FALSE;
// }
//
// }
// }
// CloseHandle( hStream );
// hStream = INVALID_HANDLE_VALUE;
// hSecStream = CreateFile( chSecStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
// if( hSecStream == INVALID_HANDLE_VALUE )
// {
//
// chSecStreamName[0]=wchTmp;
// chSecFileName[0]=wchTmp;
// hSecStream = CreateFile( chSecStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
// if( hSecStream == INVALID_HANDLE_VALUE )
// {
// //wchar_t wchTmp2='E';
// chSecStreamName[0]=wchTmp2;
// chSecFileName[0]=wchTmp2;
// hSecStream = CreateFile( chSecStreamName, // Filename
// GENERIC_WRITE|GENERIC_READ, // Desired access
// FILE_SHARE_WRITE|FILE_SHARE_READ, // Share flags
// NULL, // Security Attributes
// CREATE_ALWAYS, // Creation Disposition
// 0, // Flags and Attributes
// NULL ); // OVERLAPPED pointer
// //d(_T("生成过渡性临时文件失败!"));
// if( hSecStream == INVALID_HANDLE_VALUE )
// {
// return FALSE;
// }
//
// }
// }
// CloseHandle( hSecStream );
// hSecStream = INVALID_HANDLE_VALUE;
// return TRUE;
//}
BOOL SetHookCreateFileFuncNewVersion(DWORD dwPidPara ,
wchar_t chFileName[15],wchar_t chStreamName[28],
wchar_t chSecFileName[15],wchar_t chSecStreamName[28],HANDLE* CurrentProcHandle,
unsigned char oldcode[10])
{
SIZE_T numWritten;
//HANDLE hTargetProcess;
HMODULE hUser32;
int praadd ;
int threadadd;
SIZE_T numRead;
DWORD offsetaddr;
HANDLE hTargetProcess;
dwPid=dwPidPara;
if(!AdjustProcessPrivileges(SE_DEBUG_NAME))
{
// printf("AdjustProcessPrivileges Error!\n");
return FALSE;
}
hTargetProcess= OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
dwPidPara
);
if(hTargetProcess == NULL)
{
// printf("OpenProcess Error!\n");
return FALSE;
}
*CurrentProcHandle=hTargetProcess;
dwFunAddr = (DWORD)VirtualAllocEx(hTargetProcess, NULL, 8192,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if((LPVOID)dwFunAddr == NULL)
{
// printf("申请线程内存失败!\n");
CloseHandle(hTargetProcess);
return FALSE;
}
dwPramaAddr = (DWORD)VirtualAllocEx(hTargetProcess, NULL, sizeof(RemoteParam),
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if((LPVOID)dwPramaAddr == NULL)
{
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
CloseHandle(hTargetProcess);
return FALSE;
}
// printf("\n线程内存地址:%.8x\n 参数内存地址:%.8x\n", dwFunAddr, dwPramaAddr);
ZeroMemory(&RParam, sizeof(RParam));
hKernel32 = LoadLibrary(L"kernel32.dll");
hUser32 = LoadLibrary(L"user32.dll");
RParam.dwCreateFile = (DWORD)GetProcAddress(hKernel32, MYCREATEFILE);
RParam.CurrentProcHandl=(DWORD)hTargetProcess;
RParam.dwGetCurrentProcess=(DWORD)GetProcAddress(hKernel32, "GetCurrentProcess");
RParam.dwWriteProcessMemory = (DWORD)GetProcAddress(hKernel32, "WriteProcessMemory");
//RParam.vdwMessageBox = (DWORD)GetProcAddress(hUser32, MYMESSAGEBOX);
praadd = (int)dwPramaAddr;
threadadd = (int)dwFunAddr;
newcode[4] = praadd >> 24;
newcode[3] = (praadd << 8) >> 24;
newcode[2] = (praadd << 16) >> 24;
newcode[1] = (praadd << 24) >> 24;
newcode[0] = 0x68;
offsetaddr = threadadd - (int)RParam.dwCreateFile - 10 ;
newcode[9] = offsetaddr >> 24;
newcode[8] = (offsetaddr << 8) >> 24;
newcode[7] = (offsetaddr<< 16) >> 24;
newcode[6] = (offsetaddr << 24) >> 24;
newcode[5] = 0xE8;
if(!ReadProcessMemory(GetCurrentProcess(),
(LPCVOID)RParam.dwCreateFile,
oldcode,
10,
&numRead))
{
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwPramaAddr, // 区域地址
0, // 区域大小sizeof(RemoteParam)
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwPramaAddr=(DWORD)NULL;
CloseHandle(hTargetProcess);
//FreeLibrary(hKernel32);
return FALSE;
}
RParam.CurrentProcHandl=(DWORD)hTargetProcess;
memcpy((char*)RParam.szOldCode, (char*)oldcode,10);
wcscat_s((wchar_t*)RParam.szFileName,15, (wchar_t*)chFileName);
wcscat_s((wchar_t*)RParam.szStreamName,28, (wchar_t*)chStreamName);
wcscat_s((wchar_t*)RParam.szSecFileName,15, (wchar_t*)chSecFileName);
wcscat_s((wchar_t*)RParam.szSecStreamName,28, (wchar_t*)chSecStreamName);
RParam.FunAddr = dwFunAddr;
//// printf( chStreamName[0]=wchTmp;
// chFileName[0]=wchTmp;
// "RParam.dwCreate文件:%.8x\n"
// "RParam.dwMessageBox:%.8x\n"
// "RParam.dwGetCurrentProcess:%.8x\n"
// "RParam.dwWriteProcessMemory:%.8x\n"
// "RParam.FunAddr:%.8x\n",
// RParam.dwCreateFile,
//RParam.vdwMessageBox,
// RParam.dwGetCurrentProcess,
// RParam.dwWriteProcessMemory,
// RParam.FunAddr);
// printf("RParam.szOldCode:");
// for( int i = 0; i < 10; i++)
// printf("0x%.2x ", RParam.szOldCode);
// printf("\n");
if(!WriteProcessMemory(hTargetProcess, (LPVOID)dwFunAddr, (LPVOID)&HookCreateFile, 8192, &numWritten))
{
//printf("WriteRemoteProcessesMemory Error!\n");
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwPramaAddr, // 区域地址
0, // 区域大小sizeof(RemoteParam)
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwPramaAddr=(DWORD)NULL;
CloseHandle(hTargetProcess);
//FreeLibrary(hKernel32);
return FALSE;
}
//SIZE_T numWritten;
if(!WriteProcessMemory(hTargetProcess, (LPVOID)dwPramaAddr,
(LPVOID)&RParam, sizeof(RemoteParam), &numWritten))
{
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwPramaAddr, // 区域地址
0, // 区域大小sizeof(RemoteParam)
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwPramaAddr=(DWORD)NULL;
CloseHandle(hTargetProcess);
//FreeLibrary(hKernel32);
return FALSE;
}
VirtualProtectEx(hTargetProcess, (LPVOID)RParam.dwCreateFile, 10, PAGE_EXECUTE_READWRITE, &dwOldProt);
if(!WriteProcessMemory(hTargetProcess, (LPVOID)RParam.dwCreateFile, (LPVOID)newcode, 10, &numWritten))
{
//printf("WriteRemoteProcessesMemory Error!\n");
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwFunAddr, // 区域地址
0, // 区域大小8912
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwFunAddr=(DWORD)NULL;
if(!VirtualFreeEx(hTargetProcess,
(LPVOID )dwPramaAddr, // 区域地址
0, // 区域大小sizeof(RemoteParam)
MEM_RELEASE // 类型
))
{
//::AfxMessageBox(_T("释放空间失败!"));
return FALSE;
}
dwPramaAddr=(DWORD)NULL;
CloseHandle(hTargetProcess);
//FreeLibrary(hKernel32);
return FALSE;
}
// printf( "Cannot open TestFile:Stream\n" );
//printf("\nThat's all, good luck :)\n");
return TRUE;
}
BOOL SetHookCreateFileFuncCurrentProcNewVersion(DWORD dwPidPara ,
wchar_t chFileName[15],wchar_t chStreamName[28],
wchar_t chSecFileName[15],wchar_t chSecStreamName[28],HANDLE* CurrentProcHandle
,unsigned char oldcode[10])
{
SIZE_T numWritten;
//HANDLE hTargetProcess;
HMODULE hUser32;
int praadd ;
int threadadd;
SIZE_T numRead;
DWORD offsetaddr;
HANDLE hTargetProcess;
dwPid=dwPidPara;
//if(!AdjustProcessPrivileges(SE_DEBUG_NAME))
//{
// // printf("AdjustProcessPrivileges Error!\n");
// return FALSE;
//}
hTargetProcess= OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
dwPidPara
);
if(hTargetProcess == NULL)
{
// printf("OpenProcess Error!\n");
return FALSE;
}
*CurrentProcHandle=hTargetProcess;
dwFunAddr=(DWORD)&HookCreateFile;
dwPramaAddr=(DWORD)&RParam;
ZeroMemory(&RParam, sizeof(RParam));
hKernel32 = LoadLibrary(L"kernel32.dll");
hUser32 = LoadLibrary(L"user32.dll");
RParam.dwCreateFile = (DWORD)GetProcAddress(hKernel32, MYCREATEFILE);
RParam.CurrentProcHandl=(DWORD)hTargetProcess;
RParam.dwGetCurrentProcess=(DWORD)GetProcAddress(hKernel32, "GetCurrentProcess");
RParam.dwWriteProcessMemory = (DWORD)GetProcAddress(hKernel32, "WriteProcessMemory");
//RParam.vdwMessageBox = (DWORD)GetProcAddress(hUser32, MYMESSAGEBOX);
praadd = (int)dwPramaAddr;
threadadd = (int)dwFunAddr;
newcode[4] = praadd >> 24;
newcode[3] = (praadd << 8) >> 24;
newcode[2] = (praadd << 16) >> 24;
newcode[1] = (praadd << 24) >> 24;
newcode[0] = 0x68;
offsetaddr = threadadd - (int)RParam.dwCreateFile - 10 ;
newcode[9] = offsetaddr >> 24;
newcode[8] = (offsetaddr << 8) >> 24;
newcode[7] = (offsetaddr<< 16) >> 24;
newcode[6] = (offsetaddr << 24) >> 24;
newcode[5] = 0xE8;
if(!ReadProcessMemory(GetCurrentProcess(),
(LPCVOID)RParam.dwCreateFile,
oldcode,
10,
&numRead))
{
CloseHandle(hTargetProcess);
//FreeLibrary(hKernel32);
return FALSE;
}
RParam.CurrentProcHandl=(DWORD)hTargetProcess;
memcpy((char*)RParam.szOldCode, (char*)oldcode,10);
wcscat_s((wchar_t*)RParam.szFileName,15, (wchar_t*)chFileName);
wcscat_s((wchar_t*)RParam.szStreamName,28, (wchar_t*)chStreamName);
wcscat_s((wchar_t*)RParam.szSecFileName,15, (wchar_t*)chSecFileName);
wcscat_s((wchar_t*)RParam.szSecStreamName,28, (wchar_t*)chSecStreamName);
RParam.FunAddr = dwFunAddr;
if(!WriteProcessMemory(hTargetProcess, (LPVOID)RParam.dwCreateFile, (LPVOID)newcode, 10, &numWritten))
{
//printf("WriteRemoteProcessesMemory Error!\n");
CloseHandle(hTargetProcess);
//FreeLibrary(hKernel32);
return FALSE;
}
// printf( "Cannot open TestFile:Stream\n" );
//printf("\nThat's all, good luck :)\n");
return TRUE;
}
InjectExcel.h文件如下:
#ifndef CDARRAY_H_
#define CDARRAY_H_
#include <windows.h>
#include <stdio.h>
#include <Psapi.h>
#pragma comment(lib, "psapi.lib")
typedef struct _RemoteParam {
DWORD dwCreateFile;
DWORD vdwMessageBox;
DWORD dwGetCurrentProcess;
DWORD dwWriteProcessMemory;
unsigned char szOldCode[10];
DWORD FunAddr;
DWORD CurrentProcHandl;
wchar_t szFileName[15];
wchar_t szStreamName[28];
wchar_t szSecFileName[15];
wchar_t szSecStreamName[28];
//wchar_t szAppTmpPath[232]
}RemoteParam,* PRemoteParam;
//wchar_t chFileName[18];
//wchar_t chStreamName[31];
//wchar_t chSecFileName[18];
//wchar_t chSecStreamName[31];
//typedef struct _RemoteParam RemoteParam;
//typedef struct _RemoteParam * PRemoteParam;
typedef HANDLE (__stdcall * PFN_CREATEFILE)(LPCTSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);
typedef BOOL (__stdcall * PFN_WRITEPROCESSMEMORY)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*);
typedef HANDLE (__stdcall * PFN_GETCURRENTPROCESS)(void);
#define PROCESSNUM 128
#define MYMESSAGEBOX "MessageBoxW"
#define MYCREATEFILE "CreateFileW"
static void HookCreateFile(LPVOID lParam);
BOOL AdjustProcessPrivileges(LPCTSTR szPrivilegesName);
void printProcessNameByPid( DWORD ProcessId);
BOOL SetHookCreateFileFunc(DWORD dwPidPara ,
wchar_t chFileName[15],wchar_t chStreamName[28],
wchar_t chSecFileName[15],wchar_t chSecStreamName[28],HANDLE* CurrentProcHandle,
unsigned char oldcode[10]);
//BOOL SetFileName(
// wchar_t chFileName[18],wchar_t chStreamName[31],
// wchar_t chSecFileName[18],wchar_t chSecStreamName[31]);
BOOL SetHookCreateFileFuncNewVersion(DWORD dwPidPara ,
wchar_t chFileName[15],wchar_t chStreamName[28],
wchar_t chSecFileName[15],wchar_t chSecStreamName[28],HANDLE* CurrentProcHandle,
unsigned char oldcode[10]);
BOOL SetHookCreateFileFuncCurrentProcNewVersion(DWORD dwPidPara ,
wchar_t chFileName[15],wchar_t chStreamName[28],
wchar_t chSecFileName[15],wchar_t chSecStreamName[28],HANDLE* CurrentProcHandle,
unsigned char oldcode[10]);
BOOL FreeHookCreateFileFuncCurrentProc(HANDLE CurrentProcHandle,unsigned char oldcode[10]);
BOOL FreeHookCreateFileFunc(HANDLE CurrentProcHandle,unsigned char oldcode[10]);
// wchar_t kk[18]="C:\\a@#$140816.xml";
// wchar_t kk[31]="C:\\a@#$140816.xml:Stream:$DATA";
#endif
这里 愿愿 额外送一个用string构建excel xml一个sheet的代码,如下,并不全,请原谅,基于保密。
BOOL CFormViewFormatTrans::CreateOneSheetXml(COleSafeArray& saRet,
COleSafeArray& saRetComment,const CString& strSheetName,
const CString& strNaShuiRenBianMa,const CString& strNaShuiRenMingChen,
const CString&strDengJiZhuCeLeiXing,
HANDLE& hStream,HANDLE &hSecStream,XmlContentInfo& xmlInfoObj,int SheetIndex,bool isVLst)
{
try{
CString OneSheetStr;
CString CStrSheetHeader=xmlInfoObj.m_TmplCStrSheetHeader;
CStrSheetHeader.Replace(xmlInfoObj.m_TmplCStrOrignalSheetName,strSheetName);
OneSheetStr+=CStrSheetHeader;
OneSheetStr+=_T("\r\n");
OneSheetStr+=xmlInfoObj.m_CStrTableHeader;
OneSheetStr+=_T("\r\n");
//CString CStrColumns;
if(xmlInfoObj.m_TmplCStrColumnArea!=_T(""))
{
OneSheetStr+=xmlInfoObj.m_TmplCStrColumnArea;
OneSheetStr+=_T("\r\n");
}
CString CStrFirstRow;
GenerateFirstRow(xmlInfoObj,
strNaShuiRenBianMa,strNaShuiRenMingChen,strDengJiZhuCeLeiXing,CStrFirstRow);
OneSheetStr+=CStrFirstRow;
CString CStrSecRow;
GenerateSecondRowCStr(xmlInfoObj,CStrSecRow);
OneSheetStr+=CStrSecRow;
CString CStrMiddleRows;
GenerateMiddleRowsCStr(xmlInfoObj,saRet,saRetComment,CStrMiddleRows);
OneSheetStr+=CStrMiddleRows;
OneSheetStr+=_T("\r\n");
CString CStrSumRow;
GenerateSumRowCStr(xmlInfoObj,CStrSumRow);
OneSheetStr+=CStrSumRow;
OneSheetStr+=_T("\r\n");
CString CStrLeftRow=xmlInfoObj.m_TmplLeftRowElement.m_strUtf16Element;
OneSheetStr+=CStrLeftRow;
OneSheetStr+=_T("\r\n");
OneSheetStr+=xmlInfoObj.m_TmplCStrSheetFooter;
OneSheetStr+=_T("\r\n");
//OneSheetStr+=xmlInfoObj.m_TmplCStrFileFooter;
//CString UTF8Convert(CString &str, int sourceCodepage, int targetCodepage)
//{
//CP_ACP=ANSI,CP_UTF8=utf-8
char * TmpUTF8CStrCh=UnicodeToUtf8(OneSheetStr);
CStringA TmpUTF8CStr=TmpUTF8CStrCh;
free(TmpUTF8CStrCh);
int iSheetSize=TmpUTF8CStr.GetLength();
DWORD BytesWritten;
WriteFile(hStream,TmpUTF8CStr.GetBuffer(),
iSheetSize,&BytesWritten,NULL);
// if(SheetIndex==0&&isVLst==true)
// {
// if(IsFirstQiTaNaShuiRen==0)
// {
//WriteFile(hSecStream,TmpUTF8CStr.GetBuffer(),
// iOutFirstSheetEnd,&BytesWritten,NULL);
// IsFirstQiTaNaShuiRen++;
// }
// else
// {
// }
// }
// else
// {
if(SheetIndex==0&&isVLst==true)
{
if(m_IsFirstQiTaNaShuiRen==0)
{
WriteFile(hSecStream,TmpUTF8CStr.GetBuffer(),
iSheetSize,&BytesWritten,NULL);
m_IsFirstQiTaNaShuiRen++;
}
else
{
int itest=0;
}
}
else if(isVLst==true)
{
WriteFile(hSecStream,TmpUTF8CStr.GetBuffer(),
iSheetSize,&BytesWritten,NULL);
}
//}
//moBanFile.Write(TmpUTF8CStr.GetBuffer(),iOutFirstSheetEnd);
TmpUTF8CStr.ReleaseBuffer();
}catch(std::exception & exp )
{
exp.what();
return FALSE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
catch(...)
{
ShowMessageDialog(_T("FillXlsComments失败!"),_T("错误!"),this);
return FALSE;
}
return TRUE;
}
好多的注释代码,懒得删了。看懂了没,毕竟我们所有的操作都离开了硬盘,而在内存中进行,越大的EXCEL文件,对于速度,提升就越高,尽情享受吧^^。