发新话题
打印

[新鲜发布] 微软"查找目标的实现”附带三个小工具

微软"查找目标的实现”附带三个小工具

查看数: 179 回复数: 1 最新回复

与好友共享:

内容简介:点击关闭

一直使用VC++6.0,很希望自己实现一个插件能打开包含VC中打开文件的文件夹。以前用ShellExecuteEx实现过,但效果不理想,原因有1,同一个文件夹会打开多个实例,2.目标文件在文件夹中不会被选中。后来在网上发现可以通过执行explore /select 来完成上述功能,但还不够理 ...
一直使用VC++6.0,很希望自己实现一个插件能打开包含VC中打开文件文件夹。以前用ShellExecuteEx实现过,但效果不理想,原因有1,同一个文件夹会打开多个实例,2.目标文件文件夹中不会被选中。后来在网上发现可以通过执行explore /select 来完成上述功能,但还不够理想,原因是,如果文件夹已被打开,目标文件文件夹中不会被选中。

我看了不少有关Windows Shell的编程方面的书也没有找到答案。

在Windows桌面上的图标,右单击,选“属性”,按“查找目标”可以非常理想的完成上述功能。但是它是怎样实现的呢?

先打开属性对话框,在SoftICE下下万能断点hmemcpy, 经过几次F12, 来到Shell32.dll中,记下其虚拟地址,用IDA打开Shell32.dll:

.text:7FD04025 CreateShortcutPage proc near             CODE XREF: sub_7FD05C24+159p
.text:7FD04025
.text:7FD04025 var_34          = PROPSHEETPAGEA ptr -34h
.text:7FD04025 var_4           = dword ptr -4
.text:7FD04025 arg_0           = dword ptr  8
.text:7FD04025 lpString2       = dword ptr  0Ch
.text:7FD04025 arg_8           = dword ptr  10h
.text:7FD04025 arg_C           = dword ptr  14h
.text:7FD04025
.text:7FD04025                 push    ebp
.text:7FD04026                 mov     ebp, esp
.text:7FD04028                 sub     esp, 34h
.text:7FD0402B                 push    esi
.text:7FD0402C                 push    edi
.text:7FD0402D                 push    [ebp+lpString2]
.text:7FD04030                 call    IsLnkFile
.text:7FD04035                 test    eax, eax
.text:7FD04037                 jz      loc_7FD040F6
.text:7FD0403D                 lea     eax, [ebp+var_4]
.text:7FD04040                 push    eax
.text:7FD04041                 push    offset dword_7FCBCE50
.text:7FD04046                 push    0
.text:7FD04048                 call    sub_7FCBCA41
.text:7FD0404D                 test    eax, eax
.text:7FD0404F                 jl      loc_7FD040F6
.text:7FD04055                 push    220h             uBytes
.text:7FD0405A                 push    40h              uFlags
.text:7FD0405C                 call    ds:LocalAlloc
.text:7FD04062                 mov     esi, eax
.text:7FD04064                 test    esi, esi
.text:7FD04066                 jz      loc_7FD040ED
.text:7FD0406C                 mov     eax, ds:hModule
.text:7FD04071                 push    104h             iMaxLength
.text:7FD04076                 push    [ebp+lpString2]  lpString2
.text:7FD04079                 mov     [ebp+var_34.hInstance], eax
.text:7FD0407C                 lea     eax, [esi+18h]
.text:7FD0407F                 mov     [ebp+var_34.dwSize], 30h
.text:7FD04086                 push    eax              lpString1
.text:7FD04087                 mov     [ebp+var_34.dwFlags], 80h
.text:7FD0408E                 mov     dword ptr [ebp+var_34.anonymous_0], 1040
.text:7FD04095                 mov     [ebp+var_34.pfnDlgProc], offset PropDlgProc 注意这里!
.text:7FD0409C                 mov     [ebp+var_34.pfnCallback], offset loc_7FD03FFF
.text:7FD040A3                 mov     [ebp+var_34.lParam], esi
.text:7FD040A6                 call    ds:lstrcpynA
.text:7FD040AC                 mov     eax, [ebp+arg_0]
.text:7FD040AF                 or      dword ptr [esi+14h], 0FFFFFFFFh
.text:7FD040B3                 mov     [esi], eax
.text:7FD040B5                 mov     eax, [ebp+var_4]
.text:7FD040B8                 mov     [esi+4], eax
.text:7FD040BB                 lea     eax, [ebp+var_34]
.text:7FD040BE                 push    eax              LPCPROPSHEETPAGEA
.text:7FD040BF                 call    ds:CreatePropertySheetPageA
.text:7FD040C5                 mov     edi, eax
.text:7FD040C7                 test    edi, edi
.text:7FD040C9                 jz      short loc_7FD040E6
.text:7FD040CB                 push    [ebp+arg_C]
.text:7FD040CE                 push    edi
.text:7FD040CF                 call    [ebp+arg_8]
.text:7FD040D2                 test    eax, eax
.text:7FD040D4                 jz      short loc_7FD040DF
.text:7FD040D6                 push    1
.text:7FD040D8                 pop     eax
.text:7FD040D9
.text:7FD040D9 loc_7FD040D9:                            CODE XREF: CreateShortcutPage+D3j
.text:7FD040D9                 pop     edi
.text:7FD040DA                 pop     esi
.text:7FD040DB                 leave
.text:7FD040DC                 retn    10h
.text:7FD040DF  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
.text:7FD040DF
.text:7FD040DF loc_7FD040DF:                            CODE XREF: CreateShortcutPage+AFj
.text:7FD040DF                 push    edi              HPROPSHEETPAGE
.text:7FD040E0                 call    ds:DestroyPropertySheetPage
.text:7FD040E6
.text:7FD040E6 loc_7FD040E6:                            CODE XREF: CreateShortcutPage+A4j
.text:7FD040E6                 push    esi              hMem
.text:7FD040E7                 call    ds:LocalFree
.text:7FD040ED
.text:7FD040ED loc_7FD040ED:                            CODE XREF: CreateShortcutPage+41j
.text:7FD040ED                 mov     eax, [ebp+var_4]
.text:7FD040F0                 push    eax
.text:7FD040F1                 mov     ecx, [eax]
.text:7FD040F3                 call    dword ptr [ecx+8]
.text:7FD040F6
.text:7FD040F6 loc_7FD040F6:                            CODE XREF: CreateShortcutPage+12j
.text:7FD040F6                                          CreateShortcutPage+2Aj
.text:7FD040F6                 xor     eax, eax
.text:7FD040F8                 jmp     short loc_7FD040D9
.text:7FD040F8 CreateShortcutPage endp

经过整整4天的艰苦挖掘,得到了后面的源代码。这些源代码和作者(微软)手里的因该是完全等价的。说实在的,里面有些东西是值得学习的。从中我们可以发现问题的关键在于SHDOCVW.DLL中的SHGetIDispatchForFolder这个未公开函数,我曾试着在google搜索它,发现只有一个不能打开的网站上有它。虽然我极其佩服微软,但从这个例子中我们可以看出微软的技术垄断的痕迹。

为了干这活,我还做了一个工具CLSIDSEE, 它可以从4个dword查找CLS_ID, ProgID...,用于破解COM代码非常有用。
用这些代码我还做了一个VC插件,实现开始提到的功能,我个人觉得非常有用。
用这些代码我还做了一个Shell扩展,将查找目标这个功能直接放到桌面图标右单击的菜单中,我也觉得非常有用。
这三个小工具我会放到CrackABC的FTP上。

1. 源代码(1)

int GetNumberOfSelected(HGLOBAL hMem)
{
int ret = 0;
int* pInt;

if ((pInt = (int*)GlobalLock(hMem)) != NULL) {
ret = *pInt;
GlobalUnlock(hMem);
}

return ret;
}

BOOL _7FD0276A(DWORD* vp, DWORD var)
{
if (var <= vp[0])
return SHELL32_25((BYTE*)vp + vp[1], (BYTE*)vp + vp[var + 2]);

return FALSE;
}

LPCITEMIDLIST GetPIDL(HGLOBAL hGlobal, int var)
{
LPVOID vp;

if ((vp = GlobalLock(hGlobal)) != NULL) {
LPCITEMIDLIST pidl = _7FD0276A(vp, var);
GlobalUnlock(hGlobal);
return pidl;
}

return NULL;
}

BOOL GetTargetInfo(HGLOBAL hGlobal, int var, char FilePath[MAX_PATH], WIN32_FIND_DATA* lpFindData)
{
LPCITEMIDLIST pidl;

PathName[0] = '\0';
if ((pidl = GetPIDL(hGlobal, var)) != NULL) {
if (SHGetPathFromIDList(pidl, FilePath)) {
if (lpFindData) {
if ((hFff = FindFirstFile(FilePath, lpFindData)) == INVALID_HANDLE_VALUE)
memset(lpFindData, 0, sizeof(WIN32_FIND_DATA));
else
CloseHandle(hFff);
}

SHELL32_155_FreePidl(pidl);
return TRUE;
}
else {
SHELL32_155_FreePidl(pidl);
return FALSE;
}
}

return FALSE;
}

int CreatePropDialog(p1, pfn, IDataObject* pDataObj)
{
FORMATETC formatetc;
STGMEDIUM medium;
PROPSHEETPAGE psp;
HLOCAL hLocal;
HGLOBAL hGlobal;
WIN32_FIND_DATA ffd;
HPROPSHEETPAGE hPsp;
char PathName[MAX_PATH];

BOOL var_4;
int var_8;

formatetc.lindex = -1;
formatetc.cfFormat = gcfFormat;
formatetc.ptd = 0;
formatetc.dwAspect = 1;
formatetc.tymed = TYMED_HGLOBAL;

var_4 = FALSE;
var_8 = 0;

if (FAILED(pDataObj->GetData(&formatetc, &medium)))
return FALSE;

PathName[0] = 0;
psp.hInstance = ghModule;
psp.dwSize = 952; //NOT sizeof(psp); !!!
psp.dwFlags = PSP_USECALLBACK; //0x80;
psp.pfnCallback = PropCallback;
var_2a0 = 1;
var_3a8 = 0;
var_34 = 0;
var_30 = 0;

hGlobal = medium.hGlobal;
if (hGlobal) {
hLocal = LocalAlloc(LPTR, GlobalSize(hGlobal));
if (hLocal)
memmove(hLocal, hGlobal, GlobalSize(hGlobal));
}
else
hLocal = NULL;

if (GetNumberOfSelected(hGlobal) == 1) { // else 7fd05dd5
if (GetTargetInfo(hGlobal, 0, &PathName, &ffd)) { // else 7fd05d9f
psp.pfnDlgProc = ConventionalDlgProc;
psp.pResource = MAKEINTRESOURCE(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY? 1044 : 1041);
if ((hPsp = CreatePropertySheetPage(&psp)) != NULL) { // else loc_7FD05D9F
if (pfn(hPsp, p1)) { // else loc_7FD05E07
var_4 = 1;
if (CreateShortcutPage(hGlobal, &PathName, pfn, p1))
var_8 = 2;
CreateVersionPage(&PathName, pfn, p1);
}
else // loc_7FD05E07
DestroyPropertySheetPage(hPsp);
}
}
}
else { // loc_7FD05DD5
psp.pResource = MAKEINTRESOURCE(1043);
psp.pfnDlgProc = MultiSelDlgProc;
if ((hPsp = CreatePropertySheetPage(&psp)) != NULL) { // else loc_7FD05D9F
if (pfn(hPsp, p1))
var_4 = 1;
else
DestroyPropertySheetPage(hPsp);
}
}

// loc_7FD05D9F
_7FCC6204(&medium);
if (!var_4 && hLocal)
LocalFree(hLocal);

return var_8;
}

BOOL IsLnkFile(char* PathName)
{
if (PathName)
return lstrcmpi(PathFindExtension(PathName), ".lnk") == 0;

return FALSE;
}


HRESULT CreateShellInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv)
{
CShellFactory* pCShellFactory;
HRESULT hr;

if (pUnknownOuter)
return CLASS_E_NOAGGREGATION;

pCShellFactory = new CShellFactory;

if (pCShellFactory == NULL)
return E_OUTOFMEMORY;

pCShellFactory->m_cRef = 1;
pCShellFactory->Init();

hr = pCShellFactory->CreateInstance(iid, ppv);

pCShellFactory->Release();

return hr;
}

typedef struct FindTargetData
{
HGLOBAL hGlobal; // 0
IShellLinkA* pIShellLink; // 4
int hDlgWnd; // 8
int dwc; // c
int dw10; // 10
int dw14; // 14
int dw18; // 18
char Path[MAX_PATH]; // 1c
};

BOOL CreateShortcutPage(HGLOBAL hGlobal, char PathName[MAX_MATH], pfn, p1)
{
PROPSHEETPAGE psp;
IShellLink* pIShellLink;
FindTargetData* pFtd;
HPROPSHEETPAGE hPsp;

if (IsLinkFile(PathName) &&
SUCCEEDED(CreateShellInstance(NULL, IID_IShellLink, &pIShellLink)))
{ // else loc_7FD040F6
pFtd = (FindTargetData*) LocalAlloc(LPTR, sizeof(FindTargetData));
if (pFtd != NULL) { // else loc_7FD040ED
psp.hInstance = ghModule;
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_USECALLBACK;
psp.pResource = MAKEINTRESOURCE(1040);
psp.pfnDlgProc = ShortcutDlgProc;
psp.pfnCallback = CallbackProc;
psp.lParam = pFtd;
lstrcpyn(pFtd->Path, PathName, MAX_PATH);
pFtd->dw14 = -1;
pFtd->hGlobal = hGlobal;
pFtd->pIShellLink = pIShellLink;
if ((hPsp = CreatePropertySheetPage(&psp)) != NULL) {
if (pfn(hPsp, p1))
return TRUE;
DestroyPropertySheetPage(hPsp);
}
LocalFree(pFtd);
}
pObj->Release();
}

return FALSE;
}

#define IDC_
#define IDC_Name 0x66 // 名称
#define IDC_StartLocation 0x3002 // 起始位置
#define IDC_Target 0x3302 // 目标
#define IDC_TargetType 0x3303 // 目标类型
#define IDC_TargetLocation 0x3309 // 目标位置
#define IDC_Shortcut 0x3404 // 快捷键
#define IDC_FindTarget 0x3406 // 查找目标
#define IDC_ChangeIcon 0x3407 // 更改图标
#define IDC_RunMode 0x3408 // 运行方式

BOOL CALLBACK ShortcutDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LPPROPSHEETPAGE psp;
FindTargetData* pFtd;
LPNMHDR pnmh;
LPHELPINFO lphi;

pFtd = GetWindowLong(hWnd, DWL_USER);

switch (uMsg)
{
case WM_INITDIALOG:
psp = (LPPROPSHEETPAGE)lParam;
pFtd = psp->lParam;
SetWindowLong(hWnd, DWL_USER, pFtd);
pFtd->hDlgWnd = hWnd;

SendDlgItemMessage(hWnd, 0x3302/*ID for 目标*/, WM_LIMITTEXT, MAX_PATH - 1, 0);
COMCTL32_384(GetDlgItem(hWnd, 0x3302), 1);
SendDlgItemMessage(hWnd, 0x3002/*ID for 起始位置*/, EM_LIMITTEXT, MAX_PATH - 1, 0);
COMCTL32_384(GetDlgItem(hWnd, 0x3002), 1);

SendDlgItemMessage(hWnd, 0x3404/*ID for 快捷键*/, 0x403, 0xf, 6);

FindTargetInit(pFtd, 0);
return TRUE;

case WM_NOTIFY:
// If the message handler is in a dialog box procedure, you must use
// the SetWindowLong function with DWL_MSGRESULT to set a return value.
pnmh = (LPNMHDR) lParam;
if (pnmh->code != -202) {
if (pnmh->code == -201)
SetWindowLong(hwnd, DWL_MSGRESULT, !_7FD03BDA(pFtd));
}
else if (FAILED(_7FD03A38(pFtd)))
SetWindowLong(hWnd, DWL_MSGRESULT, 2);

return TRUE;

case WM_HELP:
lphi = (LPHELPINFO) lParam;
// HELP_WM_HELP:
// Displays the topic for the control identified
// by the hWndMain parameter in a pop-up window.
// HelpData:
// Address of an array of double word pairs.
// The first double word in each pair is a control identifier,
// and the second is a context identifier for a topic.
// The array must be terminated by a pair of zeros {0,0}.
// If you do not want to add Help to a particular control,
// set its context identifier to -1.
WinHelp(lphi->hItemHandle, NULL, HELP_WM_HELP, &HelpData);
break;

case WM_CONTEXTMENU:
WinHelp(lParam, NULL, HELP_CONTEXTMENU, &HelpData);
break;

case WM_COMMAND:
switch (LOWORD(wParam))
{
case 3002: // 起始位置
case 3302: // 目标
case 3404: // 快捷键
if (HIWORD(wParam) == 0x300) {
SendMessage(GetParent(hWnd), 0x468, hWnd, 0);
pFtd->dw10 = 1;
}
return TRUE;

case 3406: // 查找目标
OnCmdFindTarget(pFtd);
return TRUE;
你现在是游客:请登录或者注册

搜索更多相关主题的帖子:

Rojo google reader netvibes 哪吒 抓虾 my yahoo Feedsky FEED 订阅
作者: oeee 主题: APMserv5.2更新phpmyadmin的方法 时间: 2008-7-2 11:03
作者: oeee 主题: 小侃PHP出错的分析办法! 时间: 2008-5-15 12:18
作者: oeee 主题: 中小企业该如何推广自己的网站? 时间: 2008-5-1 13:44
作者: oeee 主题: apache基于域名和端口的虚拟主机 时间: 2008-5-1 13:21
作者: oeee 主题: 复制帖内任意内容时自动在末尾增加本文来自……详 ... 时间: 2008-4-19 09:27
为什么如此热爱分享这个词语?

TOP

最新网站秀: (还等什么?马上加入我们吧! 快速加入

 华中师范大  盱眙吧1  南邮风云   夜族网游公  在日中华情  生活大家坛  智商250  塞班智能手  论剑社区  潮州论坛  灵下异度  封开家园 
用户正在观看: 热门标签
美女人体艺术绝
杀破狼
樱之炫视频教程——五
雨儿短裙热舞
情圣【国语中字】DV
作品源自网络,请支持正版


山下智久正义代书战士


山下智久正义代书战士


求婚大作战 sp特别


危险放课后 01
case 3407:  // 更改图标
if (OnCmdChangeIcon(pFtd))
pFtd-&gt;dw10 = TURE;
return TRUE;

case 3408: // 运行方式
if (HIWORD(wParam) == 1)
SendMessage(GetParent(hWnd), 0x468, hWnd, 0);
return TRUE;
}
return FALSE;

case 0x464:
SwitchToThisWindo 限制字节输出
为什么如此热爱分享这个词语?

TOP

发新话题