Skip to content

Commit

Permalink
新增博文:逆向 COM dll
Browse files Browse the repository at this point in the history
  • Loading branch information
Young-Lord committed Jan 6, 2024
1 parent ffc606e commit 0cda67a
Showing 1 changed file with 173 additions and 0 deletions.
173 changes: 173 additions & 0 deletions _posts/2024-01-06-逆向COM_dll.md
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前打断点,然后追踪参数对应内存访问就行。

0 comments on commit 0cda67a

Please sign in to comment.