-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ffc606e
commit 0cda67a
Showing
1 changed file
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
--- | ||
tags: [Windows, 逆向, 网络安全] | ||
title: 逆向 COM dll | ||
slug: reverse-com-dll | ||
last_modified_at: 2024-1-6 | ||
--- | ||
|
||
## 本文附件 | ||
|
||
[PwdInfo.dll](https://github.com/Young-Lord/Young-Lord.github.io/releases/download/assets/PwdInfo.dll) | ||
|
||
[COMView](https://www.softpedia.com/get/System/System-Info/COMView.shtml) | ||
|
||
[火绒剑](https://www.52pojie.cn/thread-1859777-1-1.html) / [Procmon](https://learn.microsoft.com/zh-cn/sysinternals/downloads/procmon) | ||
|
||
IDA Pro | ||
|
||
[x64dbg](https://github.com/x64dbg/x64dbg/releases/latest) | ||
|
||
New Bing (有Windows API问题直接问就行) | ||
|
||
## 开始之前 | ||
|
||
首先注册一下dll:`regsvr32 PwdInfo.dll` | ||
|
||
## COMView | ||
|
||
`File` -> `Load Type Library`, 选择`PwdInfo.dll`,可以找到包含的函数、各个函数参数及返回值 | ||
|
||
## 调用 | ||
|
||
注意先[安装相关库](https://stackoverflow.com/questions/3898287/c-include-atlbase-h-is-not-found)。具体名称搜索ATL把看着像的装了就行。 | ||
|
||
```cpp | ||
// cl /Zi /Od /DEBUG:FULL -IE:\VisualStudio\2022\BuildTools\VC\Tools\MSVC\14.16.27023\atlmfc\lib\x86 -IE:\VisualStudio\2022\BuildTools\VC\Tools\MSVC\14.38.33130\atlmfc\include /EHsc .\test.cpp /link /libpath:"E:\VisualStudio\2022\BuildTools\VC\Tools\MSVC\14.16.27023\atlmfc\lib\x86" atls.lib /DEBUG:FULL ; .\test.exe | ||
#pragma comment(lib, "Ole32.lib") | ||
#include <Windows.h> | ||
#include <objbase.h> | ||
#include <combaseapi.h> | ||
#include <comdef.h> | ||
#include <iostream> | ||
#include <atlbase.h> | ||
|
||
using std::cin; | ||
using std::cout; | ||
using std::endl; | ||
|
||
// failfast macro with a function name if hr failed | ||
#define FAIL_FAST(name) \ | ||
if (FAILED(hr)) \ | ||
{ \ | ||
cout << "FAIL_FAST: " << #name << " failed " << hr << endl; \ | ||
return 0; \ | ||
} \ | ||
else \ | ||
{ \ | ||
cout << #name << " success" << endl; \ | ||
} | ||
|
||
#define FAIL_FAST_IF_NULL(name) \ | ||
if (name == NULL) \ | ||
{ \ | ||
cout << "FAIL_FAST: " << #name << " is NULL" << endl; \ | ||
return 0; \ | ||
} \ | ||
else \ | ||
{ \ | ||
cout << #name << " success" << endl; \ | ||
} | ||
|
||
#define WAIT_FOR_ENTER \ | ||
{ \ | ||
cout << "press enter to continue..."; \ | ||
std::getchar(); \ | ||
} | ||
|
||
struct CoInitHelper | ||
{ | ||
CoInitHelper() { CoInitialize(NULL); } | ||
~CoInitHelper() { CoUninitialize(); } | ||
}; | ||
|
||
int main() | ||
{ | ||
CoInitHelper coInitGuard; | ||
{ | ||
HRESULT hr; | ||
CLSID clsid; | ||
// hr = CLSIDFromString(L"{410C6850-4C6F-11D4-8654-0000E8E6E355}", &clsid); | ||
// FAIL_FAST(CLSIDFromString); | ||
hr = CLSIDFromProgID(L"PwdInfo.Password", &clsid); | ||
FAIL_FAST(CLSIDFromProgID); | ||
|
||
IDispatch *pOR; | ||
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void **)&pOR); | ||
FAIL_FAST(CoCreateInstance); | ||
|
||
DISPID PropertyID[1] = {0}; | ||
BSTR PropName[1]; | ||
|
||
PropName[0] = SysAllocString(L"UnLockPwd"); | ||
hr = pOR->GetIDsOfNames(IID_NULL, PropName, 1, LOCALE_USER_DEFAULT, PropertyID); | ||
FAIL_FAST(GetIDsOfNames); | ||
|
||
// unlockpwd | ||
BSTR account = SysAllocString(L"1234567"); | ||
BSTR pwd = SysAllocString(L"123456"); | ||
|
||
DISPPARAMS dp = {NULL, NULL, 0, 0}; | ||
VARIANT vResult; | ||
EXCEPINFO ei; | ||
UINT uArgErr; | ||
|
||
// Allocate memory for the arguments array | ||
dp.rgvarg = new VARIANT[2]; | ||
if (dp.rgvarg == NULL) | ||
return E_OUTOFMEMORY; | ||
|
||
// Set the number of arguments | ||
dp.cArgs = 2; | ||
|
||
// Initialize the arguments as empty variants | ||
VariantInit(&dp.rgvarg[0]); | ||
VariantInit(&dp.rgvarg[1]); | ||
|
||
// Set the arguments as BSTRs | ||
dp.rgvarg[0].vt = VT_BSTR; | ||
dp.rgvarg[0].bstrVal = pwd; | ||
dp.rgvarg[1].vt = VT_BSTR; | ||
dp.rgvarg[1].bstrVal = account; | ||
|
||
// Initialize the result as an empty variant | ||
VariantInit(&vResult); | ||
|
||
// Call the function using Invoke | ||
WAIT_FOR_ENTER | ||
hr = pOR->Invoke(PropertyID[0], IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dp, &vResult, &ei, &uArgErr); | ||
FAIL_FAST(Invoke); | ||
WAIT_FOR_ENTER | ||
|
||
// Free the memory for the arguments array | ||
delete[] dp.rgvarg; | ||
|
||
// Use the result if needed | ||
// ... | ||
// cout result | ||
char *strResult; | ||
VARIANT vString; | ||
|
||
VariantInit(&vString); | ||
hr = VariantChangeType(&vString, &vResult, 0, VT_BSTR); | ||
FAIL_FAST(VariantChangeType); | ||
|
||
// Convert the BSTR to a char* if needed | ||
strResult = _com_util::ConvertBSTRToString(vString.bstrVal); | ||
FAIL_FAST_IF_NULL(strResult) | ||
|
||
// Use the string result if needed | ||
// ... | ||
cout << "result: " << strResult << endl; | ||
|
||
// Free the memory for the BSTR and the char* | ||
SysFreeString(vString.bstrVal); | ||
delete[] strResult; | ||
VariantClear(&vString); | ||
VariantClear(&vResult); | ||
} | ||
} | ||
``` | ||
## 动态调试 | ||
直接在Invoke前打断点,然后追踪参数对应内存访问就行。 |