- UID
- 2
- 精华
- 积分
- 7736
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
作为程序员,你是否经常遇到,在查找某注册表设置时,在网上查到某个超长的注册表路径,但是打开regedit后你需要一个个点开每个子项?
这样十分费事也无聊,所以这里我花了10分钟进行了研究,已取得成果:
首先想到的是reg命令,结果一看之下发现reg只是操作“真正的”注册表,对于regedit这种界面没有直接关系。那么如何让regedit打开某一个特定键值呢?
要分析regedit!
分析的第一步,自然想到看看regedit 的command怎么解析的,找到text:002A9498 ; __stdcall ParseCommandLine(x)
- signed int __thiscall ParseCommandLine(void *this)
- {
- LPWSTR v1; // eax@1
- const WCHAR *v2; // esi@1
- unsigned __int16 v3; // ax@1
- LPWSTR v4; // eax@2
- WCHAR v5; // ax@2
- int (__cdecl *v6)(const wchar_t *, const wchar_t *, size_t); // ebx@12
- int v7; // eax@16
- LPWSTR v8; // eax@18
- int v9; // eax@22
- bool v10; // zf@23
- int v11; // eax@23
- int v12; // eax@25
- int v13; // eax@26
- int v14; // eax@27
- int v15; // eax@28
- signed int result; // eax@42
- int v17; // eax@44
- LPARAM v18; // esi@44
- DWORD v19; // eax@48
- const WCHAR *v20; // esi@53
- int v21; // eax@53
- const WCHAR *v22; // edi@53
- int v23; // [sp-8h] [bp-230h]@31
- char v24; // [sp+0h] [bp-228h]@0
- void *v25; // [sp+Ch] [bp-21Ch]@1
- signed int bEnable; // [sp+10h] [bp-218h]@1
- signed int v27; // [sp+14h] [bp-214h]@1
- WCHAR szLongPath; // [sp+18h] [bp-210h]@48
- v25 = this;
- bEnable = 0;
- v27 = 0;
- v1 = GetCommandLineW();
- v2 = v1;
- v3 = *v1;
- if ( v3 != '"' )
- {
- if ( v3 > ' ' )
- {
- do
- v2 = CharNextW(v2);
- while ( *v2 > ' ' );
- }
- goto LABEL_11;
- }
- do
- {
- v4 = CharNextW(v2);
- v2 = v4;
- v5 = *v4;
- }
- while ( v5 && v5 != '"' );
- if ( *v2 != '"' )
- goto LABEL_11;
- do
- {
- v2 = CharNextW(v2);
- LABEL_11:
- ;
- }
- while ( *v2 && *v2 <= ' ' );
- v6 = __wcsnicmp;
- while ( 1 )
- {
- LABEL_13:
- if ( *v2 == ' ' )
- {
- do
- v2 = CharNextW(v2);
- while ( *v2 == 32 );
- v6 = __wcsnicmp;
- }
- v7 = *v2;
- if ( v7 != 47 && v7 != 45 )
- break;
- v8 = CharNextW(v2);
- v2 = v8;
- LOWORD(v8) = *v8;
- if ( (_WORD)v8 )
- {
- while ( 1 )
- {
- if ( (_WORD)v8 == ' ' )
- goto LABEL_13;
- v8 = (LPWSTR)(unsigned __int16)v8;
- if ( (signed int)(unsigned __int16)v8 > 'a' )
- {
- v11 = (int)((char *)v8 - 101);
- v10 = v11 == 0;
- }
- else
- {
- if ( (unsigned __int16)v8 == 'a' || (v9 = (int)((char *)v8 - 'A')) == 0 )
- {
- dword_2B90CC = 4;
- v27 = 1;
- goto LABEL_37;
- }
- v11 = v9 - 4;
- v10 = v11 == 0;
- }
- if ( v10 )
- {
- v27 = 1;
- }
- else
- {
- v12 = v11 - 7;
- if ( !v12 )
- goto LABEL_59;
- v13 = v12 - 1;
- if ( v13 )
- {
- v14 = v13 - 5;
- if ( !v14 )
- {
- LABEL_59:
- if ( v6(v2, L"regserver", 9u) )
- return 2;
- v23 = (int)L"RegExe";
- goto LABEL_61;
- }
- v15 = v14 - 1;
- if ( v15 )
- {
- if ( v15 == 2 && !v6(v2, L"unregserver", 0xBu) )
- {
- v23 = (int)L"UnregExe";
- LABEL_61:
- RegInstallW(g_hInstance, v23, 0);
- return 2;
- }
- }
- else
- {
- bEnable = 1;
- }
- }
- else
- {
- g_hRegEditWnd = 0;
- }
- }
- LABEL_37:
- v8 = CharNextW(v2);
- v2 = v8;
- LOWORD(v8) = *v8;
- if ( !(_WORD)v8 )
- goto LABEL_13;
- }
- }
- }
- if ( v25 == (void *)1 && (!bEnable || !*v2) )
- goto LABEL_56;
- result = v27;
- if ( !v27 )
- {
- if ( *v2 == (_WORD)v27 )
- return result;
- v17 = GetNextSubstring(v2);
- v18 = v17;
- if ( v25 == (void *)1 )
- {
- if ( !v17 )
- goto LABEL_56;
- }
- else if ( !v17 )
- {
- return 1;
- }
- do
- {
- v19 = GetLongPathNameW((LPCWSTR)v18, &szLongPath, 0x104u);
- if ( v19 && v19 < 0x104 )
- v18 = (LPARAM)&szLongPath;
- RegEdit_ImportRegFile(0, bEnable, v18, 0);
- v18 = GetNextSubstring(0);
- }
- while ( v18 );
- return 1;
- }
- v20 = (const WCHAR *)GetNextSubstring(v2);
- v21 = GetNextSubstring(0);
- v22 = (const WCHAR *)v21;
- if ( v25 != (void *)1 || v20 && v21 )
- {
- if ( !GetNextSubstring(0) )
- RegEdit_ExportRegFile(0, v20, v22);
- return 2;
- }
- LABEL_56:
- InternalMessageBox(g_hInstance, 0, (LPCVOID)0x28, (LPCWSTR)0x10, 16, v24);
- return 2;
- }
复制代码
几个子函数都进去看了看,发现除了regserver unregserver,便无任何字符串比较过程,于是通过给regedit传命令的方式打开注册表项的方法失败了,因为regedit没提供接口。既然如此在往上层看看,因为在记忆中,好像某些时候打开注册表时,给的并不是主界面,有时候也会打开某些位置。。。
进到主函数WinMain中:
- int __stdcall __noreturn WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
- {
- void *v4; // eax@1
- int v5; // eax@3
- HWND v6; // eax@8
- HWND v7; // esi@8
- HACCEL v8; // esi@13
- char v9; // [sp+0h] [bp-30h]@0
- INITCOMMONCONTROLSEX picce; // [sp+Ch] [bp-24h]@1
- struct tagMSG Msg; // [sp+14h] [bp-1Ch]@17
- HeapSetInformation(0, HeapEnableTerminationOnCorruption, 0, 0);
- GetThreadLocale();
- g_hInstance = GetModuleHandleW(0);
- picce.dwSize = 8;
- picce.dwICC = 0xFFFF;
- InitCommonControlsEx(&picce);
- g_hRegEditWnd = FindWindowW(L"RegEdit_RegEdit", 0);
- v4 = (void *)GetRegEditMode();
- if ( v4 == (void *)2 )
- {
- InternalMessageBox(g_hInstance, 0, (LPCVOID)0x28, (LPCWSTR)0x10, 16, v9);
- }
- else
- {
- v5 = ParseCommandLine(v4) - 1;
- if ( v5 )
- {
- if ( v5 != 1 )
- {
- if ( g_hRegEditWnd )
- {
- if ( IsIconic(g_hRegEditWnd) )
- {
- ShowWindow(g_hRegEditWnd, 9);
- }
- else
- {
- BringWindowToTop(g_hRegEditWnd);
- v6 = GetLastActivePopup(g_hRegEditWnd);
- v7 = v6;
- if ( v6 != g_hRegEditWnd )
- BringWindowToTop(v6);
- SetForegroundWindow(v7);
- }
- }
- else if ( RegisterRegEditClass() )
- {
- if ( RegisterHexEditClass() )
- {
- v8 = LoadAcceleratorsW(g_hInstance, (LPCWSTR)0x64);
- if ( v8 )
- {
- g_hRegEditWnd = CreateRegEditWnd();
- if ( g_hRegEditWnd )
- {
- RegisterApplicationRestart(0, 0);
- while ( GetMessageW(&Msg, 0, 0, 0) )
- {
- if ( g_fDisableAccelerators || !TranslateAcceleratorW(g_hRegEditWnd, v8, &Msg) )
- {
- TranslateMessage(&Msg);
- DispatchMessageW(&Msg);
- }
- }
- }
- }
- }
- }
- }
- }
- else if ( g_hRegEditWnd )
- {
- PostMessageW(g_hRegEditWnd, 0x111u, 0x288u, 0);
- }
- }
- ExitProcess(0);
- }
复制代码
可以看到,winmain也就是parse了下command,之后做消息循环去了,和普通的winmain没区别,只不过禁止双开是用FindWindow实现的!!!
regedit的界面相比都很熟悉,左边一个treeview右边一个listview,我们看下treeview怎么初始化的,以便寻找突破点:发现RegisterRegEditClass
里面肯定调用了RegisterWindowClass函数,该函数用于注册窗口类,里面一定有窗口回调,找到了回调就好办了
- int __stdcall RegisterRegEditClass()
- {
- WNDCLASSEXW Dst; // [sp+0h] [bp-30h]@1
- memset(&Dst.style, 0, 0x2Cu);
- Dst.cbSize = 48;
- Dst.style = 16392;
- Dst.lpfnWndProc = (WNDPROC)RegEditWndProc;
- Dst.hInstance = g_hInstance;
- Dst.hIcon = LoadIconW(g_hInstance, (LPCWSTR)0x64);
- Dst.hCursor = LoadCursorW(g_hInstance, (LPCWSTR)0x64);
- Dst.hbrBackground = (HBRUSH)16;
- Dst.lpszMenuName = (LPCWSTR)103;
- Dst.lpszClassName = L"RegEdit_RegEdit";
- Dst.hIconSm = (HICON)LoadImageW(g_hInstance, (LPCWSTR)0x64, 1u, 16, 16, 0);
- return RegisterClassExW(&Dst);
- }
复制代码
进到RegEditWndProc中看看:
int __stdcall RegEditWndProc(HWND hWnd, unsigned int Msg, unsigned int wParam, unsigned int lParam)
{
HWND v5; // eax@21
HWND v6; // esi@21
int v7; // edx@25
HWND v8; // [sp-10h] [bp-20h]@0
UINT v9; // [sp-Ch] [bp-1Ch]@0
int v10; // [sp+0h] [bp-10h]@0
if ( Msg > WM_CONTEXTMENU )
{
if ( Msg > WM_MENUSELECT )
{
if ( Msg == WM_LBUTTONDOWN )
{
RegEdit_OnLButtonDown(hWnd, 0, (signed __int16)lParam, SHIWORD(lParam), wParam);
return 0;
}
if ( Msg == WM_DROPFILES )
{
RegEdit_OnDropFiles(hWnd, (HDROP)wParam);
return 0;
}
if ( Msg == SB_SETTEXT )
{
RegEdit_UpdateStatusBar();
return 0;
}
}
else
{
if ( Msg == WM_MENUSELECT )
{
RegEdit_OnMenuSelect(hWnd, wParam, lParam);
return 0;
}
if ( Msg == WM_COMMAND )
{
RegEdit_OnCommand(hWnd, (unsigned __int16)wParam, lParam, wParam >> 16);
return 0;
}
if ( Msg == WM_TIMER )
{
RegEdit_OnSelChangedTimer(hWnd, v10);
return 0;
}
if ( Msg == WM_INITMENU )
{
dword_2B90BC = hMainMenu == (HMENU)wParam;
return 0;
}
if ( Msg == 279 )
{
RegEdit_OnInitMenuPopup((int)hWnd, (HMENU)wParam, (unsigned __int16)lParam, lParam >> 16);
return 0;
}
}
return DefWindowProcW(hWnd, Msg, wParam, lParam);
}
if ( Msg == WM_CONTEXTMENU )
{
v7 = lParam == -1;
if ( (HWND)wParam == g_RegEditData )
{
RegEdit_OnKeyTreeContextMenu(wParam, v7);
return 0;
}
if ( (HWND)wParam == g_RegListView )
{
RegEdit_OnValueListContextMenu(wParam, v7);
return 0;
}
return DefWindowProcW(hWnd, Msg, wParam, lParam);
}
if ( Msg > WM_SETFOCUS )
{
if ( Msg == WM_PAINT )
{
if ( dword_2B90C4 )
{
SendMessageW(g_RegEditData, 0xBu, 1u, 0);
UpdateWindow(g_RegEditData);
SendMessageW(g_RegEditData, 0xBu, 0, 0);
}
return DefWindowProcW(hWnd, Msg, wParam, lParam);
}
if ( Msg != WM_SYSCOLORCHANGE )
{
if ( Msg != WM_WININICHANGE )
{
if ( Msg == WM_NOTIFY )
return RegEdit_OnNotify(hWnd, wParam, lParam);
return DefWindowProcW(hWnd, Msg, wParam, lParam);
}
RegEdit_SetImageLists(hWnd);
}
RegEdit_SetSysColors();
while ( 1 )
{
v5 = GetWindow(v8, v9);
v6 = v5;
if ( !v5 )
break;
SendMessageW(v5, Msg, wParam, lParam);
v9 = 2;
v8 = v6;
}
LABEL_22:
RegEdit_ResizeWindow(hWnd, 0);
return 0;
}
if ( Msg == WM_SETFOCUS )
{
LABEL_10:
SetFocus(::hWnd);
return 0;
}
if ( Msg == 1 )
return (RegEdit_OnCreate(hWnd, (int *)lParam) != 0) - 1;
if ( Msg == 2 )
{
RegEdit_OnDestroy(hWnd);
return 0;
}
if ( Msg == 5 )
goto LABEL_22;
if ( Msg != 6 )
return DefWindowProcW(hWnd, Msg, wParam, lParam);
if ( wParam )
goto LABEL_10;
return 0;
}
我们最先关心的应该是WM_OnCreate消息,窗口初始化时就做好普通任务了以便展示给我们:所以进到RegEdit_OnCreate中
- signed int __stdcall RegEdit_OnCreate(HWND hWndParent, int *a2)
- {
- int v2; // eax@1
- DWORD v3; // esi@1
- signed int result; // eax@2
- HWND tree; // eax@13
- HWND list; // eax@14
- unsigned int v7; // esi@15
- HWND v8; // ecx@15
- int v9; // eax@17
- int v10; // esi@21
- HMENU v11; // edi@22
- int v12; // edx@25
- TVINSERTSTRUCTW Dst; // [sp+10h] [bp-A98h]@17
- LPARAM lParam; // [sp+58h] [bp-A50h]@21
- int v15; // [sp+60h] [bp-A48h]@21
- HLOCAL hMem; // [sp+64h] [bp-A44h]@21
- int v17; // [sp+84h] [bp-A24h]@1
- DWORD pdwDefaultLayout; // [sp+88h] [bp-A20h]@1
- int v19; // [sp+8Ch] [bp-A1Ch]@17
- HKEY phkResult; // [sp+90h] [bp-A18h]@23
- BYTE v21[4]; // [sp+94h] [bp-A14h]@1
- DWORD Type; // [sp+98h] [bp-A10h]@24
- DWORD cbData; // [sp+9Ch] [bp-A0Ch]@24
- BYTE Data; // [sp+A0h] [bp-A08h]@24
- WCHAR Name; // [sp+8A0h] [bp-208h]@19
- v2 = *a2;
- v3 = 512;
- *(_DWORD *)v21 = 0;
- pdwDefaultLayout = 0;
- v17 = v2;
- dword_2B9094 = (LPCWSTR)LoadDynamicString(0x14u);
- if ( !dword_2B9094 )
- goto LABEL_39;
- dword_2B9098 = LoadDynamicString(0x1Bu);
- if ( !dword_2B9098 )
- goto LABEL_39;
- dword_2B909C = LoadDynamicString(0x16u);
- if ( !dword_2B909C )
- goto LABEL_39;
- dword_2B90A0 = (LPCWSTR)LoadDynamicString(0x19u);
- if ( !dword_2B90A0 )
- goto LABEL_39;
- dword_2B90A4 = (LPCWSTR)LoadDynamicString(0x1Au);
- if ( !dword_2B90A4 )
- goto LABEL_39;
- lpNewItem = (LPCWSTR)LoadDynamicString(0x15u);
- if ( !lpNewItem )
- goto LABEL_39;
- pszFormat = (STRSAFE_LPCWSTR)LoadDynamicString(0x17u);
- if ( !pszFormat )
- goto LABEL_39;
- dword_2B90B0 = (STRSAFE_LPCWSTR)LoadDynamicString(0x18u);
- if ( !dword_2B90B0 )
- goto LABEL_39;
- if ( GetProcessDefaultLayout(&pdwDefaultLayout) && pdwDefaultLayout & 1 )
- v3 = 8704;
- tree = CreateWindowExW(v3, L"SysTreeView32", 0, 0x5001003Fu, 0, 0, 0, 0, hWndParent, (HMENU)1, g_hInstance, 0);
- g_RegEditData = tree;
- if ( tree
- && (SetWindowTheme(tree, L"Explorer", 0),
- SendMessageW(g_RegEditData, TVM_SETEXTENDEDSTYLE, 4u, 4),
- list = CreateWindowExW(v3, L"SysListView32", 0, 0x52018A41u, 0, 0, 0, 0, hWndParent, (HMENU)2, g_hInstance, 0),
- (g_RegListView = list) != 0)
- && (SendMessageW(list, LVM_SETEXTENDEDLISTVIEWSTYLE, 0x4000u, 0x4000),
- v7 = 0,
- v8 = CreateStatusWindowW(1073742096, 0, hWndParent, 3u),
- (hwndStatus = v8) != 0)
- && (dword_2B9090 = (*(_DWORD *)(v17 + 0x3C) & 1) != 0 ? 5 : 0,
- ShowWindow(v8, dword_2B9090),
- RegEdit_SetImageLists(hWndParent)) )
- {
- RegEdit_SetSysColors();
- memset(&Dst, 0, 0x44u);
- Dst.hParent = (HTREEITEM)-65536;
- Dst.hInsertAfter = (HTREEITEM)-65534;
- Dst.itemex.mask = 103;
- *(_QWORD *)&Dst.item.iImage = 0i64;
- *(_QWORD *)&Dst.item.cChildren = 1i64;
- Dst.itemex.pszText = (LPWSTR)LoadDynamicString(19u);
- Dst.hParent = (HTREEITEM)SendMessageW(g_RegEditData, TVM_INSERTITEMW, 0, (LPARAM)&Dst);
- LocalFree(Dst.itemex.pszText);
- *(_QWORD *)&Dst.item.iImage = 0x300000002i64;
- v9 = 0;
- v19 = 0;
- do
- {
- if ( v9 != 5 )
- {
- Dst.itemex.pszText = *(wchar_t **)((char *)&g_RegistryRoots + v7);
- Dst.itemex.lParam = *(int *)((char *)&dword_2A1494 + v7);
- Dst.itemex.cChildren = RegEnumKeyW((HKEY)Dst.itemex.lParam, 0, &Name, 0x100u) == 0;
- SendMessageW(g_RegEditData, TVM_INSERTITEMW, 0, (LPARAM)&Dst);
- v9 = v19;
- }
- ++v9;
- v7 += 12;
- v19 = v9;
- }
- while ( v7 < 72 );
- SendMessageW(g_RegEditData, TVM_EXPAND, 2u, (LPARAM)Dst.hParent);
- SendMessageW(g_RegEditData, TVM_SELECTITEM, 9u, (LPARAM)Dst.hParent);
- v10 = v17;
- dword_2B908C = 0;
- hWnd = g_RegEditData;
- dword_2B9080 = *(_DWORD *)(v17 + 44);
- lParam = 6;
- v15 = *(_DWORD *)(v17 + 48);
- hMem = (HLOCAL)LoadDynamicString(0x11u);
- SendMessageW(g_RegListView, LVM_INSERTCOLUMNW, 0, (LPARAM)&lParam);
- LocalFree(hMem);
- v15 = *(_DWORD *)(v10 + 52);
- hMem = (HLOCAL)LoadDynamicString(0x1Fu);
- SendMessageW(g_RegListView, LVM_INSERTCOLUMNW, 1u, (LPARAM)&lParam);
- LocalFree(hMem);
- v15 = *(_DWORD *)(v10 + 56);
- hMem = (HLOCAL)LoadDynamicString(0x12u);
- SendMessageW(g_RegListView, LVM_INSERTCOLUMNW, 2u, (LPARAM)&lParam);
- LocalFree(hMem);
- memset(&g_PrintDlg, 0, 0x54u);
- hMainMenu = GetMenu(hWndParent);
- LOBYTE(dword_2B90C0) = GetSystemMetrics(63) & 1;
- dword_2B90C0 = (unsigned __int8)dword_2B90C0;
- if ( !(_BYTE)dword_2B90C0 )
- {
- v11 = GetSubMenu(hMainMenu, 0);
- DeleteMenu(v11, 0x291u, 0);
- DeleteMenu(v11, 0x300u, 0);
- DeleteMenu(v11, 0x2A1u, 0);
- }
- pszSrc = (STRSAFE_LPCWSTR)SendMessageW(g_RegEditData, TVM_GETNEXTITEM, 9u, 0);
- if ( !RegOpenKeyW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit", &phkResult) )
- {
- cbData = 2048;
- if ( !RegQueryValueExW(phkResult, L"LastKey", 0, &Type, &Data, &cbData)
- && !RegEdit_QueryValueEx(&cbData)
- && Type == 1
- && cbData > 0 )
- RegEdit_ExpandKeyPath(v12);
- cbData = 4;
- if ( !RegQueryValueExW(phkResult, L"MultiStrings", 0, &Type, v21, &cbData)
- && !RegEdit_QueryValueEx(&cbData)
- && Type == 4
- && cbData > 0 )
- {
- if ( *(_DWORD *)v21 )
- g_fMultiLineStrings = 1;
- }
- RegCloseKey(phkResult);
- }
- result = 1;
- }
- else
- {
- LABEL_39:
- result = 0;
- }
- return result;
- }
复制代码
这里分别创建了TreeView和ListView,我们只关心前者,该函数中操作为:
加载某些字符串
创建和设置TreeView窗口,根节点设置为“计算机”
将HKEY_CLASS_ROOT HKEY_CURRENT_USER HKEY_LOCAL_MACHINE HKEY_USERS HKEY_CURRENT_CONFIG循环加入根节点中
检查Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit的值并执行RegEdit_ExpandKeyPath
这个就是我们感兴趣的!!!
我们只要设置该键值,再启动regedit,就可以达到目的!!
|
|