实现
#include <afx.h>
#include <Shlobj.h>
#include <string>
#include <windows.h>
#include <iostream>
using namespace std;
int main(){
setlocale(LC_ALL, "");
CoInitialize(NULL);
IFileSaveDialog* pOpenFileDlg = NULL;
HRESULT hr = S_FALSE;
hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL, IID_IFileSaveDialog, (LPVOID*)&pOpenFileDlg);
COMDLG_FILTERSPEC rgSpec[] ={{ L"JPG", L"*.jpg;*.jpeg" },{ L"BMP", L"*.bmp" },{ L"All", L"*.*" },};
HRESULT SetFileTypes(UINT cFileTypes, const COMDLG_FILTERSPEC * rgFilterSpec);
pOpenFileDlg->SetFileTypes(3, rgSpec);
pOpenFileDlg->SetFileTypeIndex(3);
if (SUCCEEDED(hr)){
hr = pOpenFileDlg->Show(NULL);
if (SUCCEEDED(hr)){
//从对话框中获取文件名
IShellItem* pItem;
hr = pOpenFileDlg->GetResult(&pItem);
if (SUCCEEDED(hr)){
//结果成功,获取名字.
LPWSTR filePath;
LPWSTR fileName;
hr = pItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &filePath);//获取文件的完整路径
hr = pItem->GetDisplayName(SIGDN_NORMALDISPLAY, &fileName);///获取文件名
if (SUCCEEDED(hr)){
printf("%ws\n", filePath);
printf("%ws\n", fileName);
CoTaskMemFree(filePath);//释放内存
CoTaskMemFree(fileName);//释放内存
}
pItem->Release();
}
}
pOpenFileDlg->Release();//释放内存
}
CoUninitialize();
return 0;
}
HOOK
IFileSaveDialog* g_myFileSaveDialog = NULL;
Hook hook_CoCreateInstance;
Hook hook_FileSaveDialog_show;
Hook hook_FileSaveDialog_GetResult;
class MyIShellItem : public IShellItem {
public:
HRESULT STDMETHODCALLTYPE QueryInterface(
/* [in] */ REFIID riid,
/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject) {
return 0;
}
ULONG STDMETHODCALLTYPE AddRef(void) {
return 0;
}
ULONG STDMETHODCALLTYPE Release(void) {
return 0;
}
HRESULT STDMETHODCALLTYPE BindToHandler(
/* [unique][in] */ __RPC__in_opt IBindCtx* pbc,
/* [in] */ __RPC__in REFGUID bhid,
/* [in] */ __RPC__in REFIID riid,
/* [iid_is][out] */ __RPC__deref_out_opt void** ppv) {
return FALSE;
}
HRESULT STDMETHODCALLTYPE GetParent(
/* [out] */ __RPC__deref_out_opt IShellItem** ppsi) {
return FALSE;
}
HRESULT STDMETHODCALLTYPE GetDisplayName(
/* [in] */ SIGDN sigdnName,
/* [annotation][string][out] */
_Outptr_result_nullonfailure_ LPWSTR* ppszName) {
///printf("GetDisplayName \n");
LPWSTR lpPath = NULL;
获取文件的完整路径
if (SIGDN_DESKTOPABSOLUTEPARSING == sigdnName) {
lpPath = (LPWSTR)CoTaskMemAlloc(30);
memcpy(lpPath, L"c:\\log.txt", 22);
}
///获取文件名
else if (SIGDN_NORMALDISPLAY == sigdnName) {
lpPath = (LPWSTR)CoTaskMemAlloc(30);
memcpy(lpPath, L"log.txt", 16);
}
*ppszName = lpPath;
return TRUE;
}
HRESULT STDMETHODCALLTYPE GetAttributes(
/* [in] */ SFGAOF sfgaoMask,
/* [out] */ __RPC__out SFGAOF* psfgaoAttribs) {
return FALSE;
}
HRESULT STDMETHODCALLTYPE Compare(
/* [in] */ __RPC__in_opt IShellItem* psi,
/* [in] */ SICHINTF hint,
/* [out] */ __RPC__out int* piOrder) {
return FALSE;
}
};
//hr = pOpenFileDlg->GetResult(&pItem);
HRESULT _stdcall myFileSaveDialog_GetResult(PVOID obj, IShellItem** ppItem) {
HRESULT rt;
LPVOID func;
if (obj == g_myFileSaveDialog) {
*ppItem = new MyIShellItem();
return TRUE;
}
else {
func = hook_FileSaveDialog_GetResult.原函数地址;
Hook_调用原函数开始(&hook_FileSaveDialog_GetResult);
__asm {
push ppItem
push obj
call dword ptr[func]
mov dword ptr[rt], eax
}
Hook_调用原函数结束(&hook_FileSaveDialog_GetResult);
return rt;
}
}
//hr = pOpenFileDlg->Show(NULL);
HRESULT _stdcall myFileSaveDialog_show(PVOID obj, HWND hwnd) {
HRESULT rt;
LPVOID func;
if (obj != g_myFileSaveDialog) {
func = hook_FileSaveDialog_show.原函数地址;
Hook_调用原函数开始(&hook_FileSaveDialog_show);
__asm {
push hwnd
push obj
call dword ptr[func]
mov dword ptr[rt], eax
}
Hook_调用原函数结束(&hook_FileSaveDialog_show);
return rt;
}
return TRUE;
}
// hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL, IID_IFileSaveDialog, (LPVOID*)&pOpenFileDlg);
HRESULT _stdcall MyCoCreateInstance(_In_ REFCLSID rclsid, _In_opt_ LPUNKNOWN pUnkOuter, _In_ DWORD dwClsContext, _In_ REFIID riid, _COM_Outptr_ _At_(*ppv, _Post_readable_size_(_Inexpressible_(varies))) LPVOID FAR* ppv) {
HRESULT ret;
DWORD obj;
DWORD call;
Hook_调用原函数开始(&hook_CoCreateInstance);
ret = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
Hook_调用原函数结束(&hook_CoCreateInstance);
if (CLSID_FileSaveDialog == rclsid && !g_myFileSaveDialog) {
g_myFileSaveDialog = (IFileSaveDialog*)*ppv;
// 001F3308 6A 00 push 0
// 001F330A 50 push eax #g_myFileSaveDialog
// 001F330B 8B 08 mov ecx, dword ptr[eax]
// 001F330D FF 51 0C call dword ptr[ecx + 0Ch]
//show
obj = *(DWORD*)g_myFileSaveDialog;
call = *(DWORD*)(obj + 0x0C);
Hook_inHook(&hook_FileSaveDialog_show, (PVOID)call, &myFileSaveDialog_show);
//GetResult
call = *(DWORD*)(obj + 0x50);
Hook_inHook(&hook_FileSaveDialog_GetResult, (PVOID)call, &myFileSaveDialog_GetResult);
printf("FileSaveDialog已备份 %X\n", obj);
}
return ret;
}
void hook() {
Hook_inHook(&hook_CoCreateInstance, CoCreateInstance, &MyCoCreateInstance);
}