首页
社区
课程
招聘
[求助]求IDA识别COM 接口的插件或方法,Dll中包含了typelib
2009-4-2 23:35 6826

[求助]求IDA识别COM 接口的插件或方法,Dll中包含了typelib

2009-4-2 23:35
6826
收藏
点赞0
打赏
分享
最新回复 (3)
雪    币: 28208
活跃值: (6635)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
风间仁 19 2009-4-3 12:59
2
0
旧版IDA好像有一个,不过不支持新版本的。
非要用IDA么,COMRaider也挺好用的
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sojoo 2009-4-3 12:59
3
0
没有好办法,如果他的接口实现 IDispatch..
以前想写这样的工具在 ida 自动标示接口名字,但发现最终无法实现理想效果。。。

-----


#define UNICODE
#define _UNICODE

#include <tchar.h>
#include <windows.h>
#include <ObjBase.h>
#include <ocidl.h>



void GetTypeInfoName(LPTYPEINFO pITypeInfo, LPTSTR pszName, MEMBERID memid)
{
BSTR pszTypeInfoName;

HRESULT hr = pITypeInfo->GetDocumentation(memid, &pszTypeInfoName, 0, 0, 0);
if ( S_OK != hr )
{
_tcscpy(pszName, _T("<unknown>"));
return;
}

#ifndef UNICODE
wcstombs(pszName, pszTypeInfoName, MAX_PATH);
#else
wcsncpy(pszName, pszTypeInfoName, MAX_PATH);
#endif

SysFreeString(pszTypeInfoName);
}

typedef BOOL (WINAPI* ENUMTYPELIBFUN_CALLBACK)(int nType, LPCTSTR lpClassName, LPCTSTR lpFunName, ULONG Address, LPARAM lParam);

DWORD EnumTypelibFun(LPCTSTR lpFilePath, ENUMTYPELIBFUN_CALLBACK pfnCallback, LPARAM lParam)
{
HRESULT hr;
LPTYPELIB lpTypeLib;
HMODULE hModule;
PIMAGE_DOS_HEADER lpDosHeader;
PIMAGE_NT_HEADERS lpNtHeader;
DWORD dwResult = 0;

hModule = LoadLibrary(lpFilePath);
if ( hModule == NULL )
{
return 0;
}

lpDosHeader = (PIMAGE_DOS_HEADER)hModule;
lpNtHeader = (PIMAGE_NT_HEADERS)((ULONG)hModule + lpDosHeader->e_lfanew);

hr = LoadTypeLib(lpFilePath, &lpTypeLib);
if ( S_OK != hr )
{
FreeLibrary(hModule);
return 0;
}

UINT nCount = lpTypeLib->GetTypeInfoCount();
for ( UINT i = 0; i < nCount; i++ )
{
LPTYPEINFO lpClassType;
LPTYPEATTR lpClassAttr;
IClassFactory* lpClassFactory;

hr = lpTypeLib->GetTypeInfo(i, &lpClassType);
if ( S_OK != hr )
{
continue;
}

hr = lpClassType->GetTypeAttr(&lpClassAttr);
if ( S_OK != hr )
{
lpClassType->Release();
continue;
}

if ( TKIND_COCLASS != lpClassAttr->typekind )
{
lpClassType->ReleaseTypeAttr(lpClassAttr);
lpClassType->Release();
continue;
}

hr = CoGetClassObject(lpClassAttr->guid,
CLSCTX_INPROC_SERVER,
NULL,
IID_IClassFactory,
(PVOID*)&lpClassFactory
);
if ( hr != S_OK )
{
lpClassType->ReleaseTypeAttr(lpClassAttr);
lpClassType->Release();
continue;
}

for ( UINT j = 0; j < lpClassAttr->cImplTypes; j++ )
{
HREFTYPE hRefType;
LPTYPEINFO lpRefTypeInfo;
LPTYPEATTR lpRefTypeAttr;
LPUNKNOWN lpUnknown;
DWORD Index;
TCHAR szClassName[MAX_PATH];
TCHAR szName[MAX_PATH];
PULONG VirtualTable;
IDispatch* lpDisptach;

hr = lpClassType->GetRefTypeOfImplType(j, &hRefType);
if ( S_OK != hr )
{
continue;
}

hr = lpClassType->GetRefTypeInfo(hRefType, &lpRefTypeInfo);
if ( S_OK != hr )
{
continue;
}

hr = lpRefTypeInfo->GetTypeAttr(&lpRefTypeAttr);
if ( S_OK != hr )
{
lpRefTypeInfo->Release();
continue;
}

hr = lpClassFactory->CreateInstance(NULL, IID_IDispatch, (PVOID*)&lpDisptach);
if ( S_OK != hr )
{
lpRefTypeInfo->ReleaseTypeAttr(lpRefTypeAttr);
lpRefTypeInfo->Release();
continue;
}

lpDisptach->QueryInterface(lpRefTypeAttr->guid, (PVOID*)&lpUnknown);
VirtualTable = *(PULONG*)lpUnknown; // 虚表基址

GetTypeInfoName(lpRefTypeInfo, szClassName, MEMBERID_NIL);
for ( Index = 0; Index < lpRefTypeAttr->cFuncs; Index++ )
{
LPFUNCDESC lpFuncDesc;
ULONG FunAddr;

hr = lpRefTypeInfo->GetFuncDesc(Index, &lpFuncDesc);
if ( hr != S_OK )
{
continue;
}

GetTypeInfoName(lpRefTypeInfo, szName, lpFuncDesc->memid);
dwResult++;

FunAddr = VirtualTable[Index] - (ULONG)hModule + lpNtHeader->OptionalHeader.ImageBase;
if ( !pfnCallback(0, szClassName, szName, FunAddr, lParam) )
{
lpRefTypeInfo->ReleaseFuncDesc(lpFuncDesc);
break;
}

lpRefTypeInfo->ReleaseFuncDesc(lpFuncDesc);
}

for ( Index = 0; Index < lpRefTypeAttr->cVars; Index++ )
{
LPVARDESC lpVarDesc;
DWORD VarAddr;

lpRefTypeInfo->GetVarDesc(Index, &lpVarDesc);
if ( hr != S_OK )
{
continue;
}

GetTypeInfoName(lpRefTypeInfo, szName, lpVarDesc->memid);
dwResult++;

VarAddr = VirtualTable[lpVarDesc->oInst] - (ULONG)hModule + lpNtHeader->OptionalHeader.ImageBase;
if ( !pfnCallback(1, szClassName, szName, VarAddr, lParam) )
{
lpRefTypeInfo->ReleaseVarDesc(lpVarDesc);
break;
}

lpRefTypeInfo->ReleaseVarDesc(lpVarDesc);
}

lpUnknown->Release();
lpRefTypeInfo->ReleaseTypeAttr(lpRefTypeAttr);
lpRefTypeInfo->Release();
}

lpClassFactory->Release();
lpClassType->ReleaseTypeAttr(lpClassAttr);
lpClassType->Release();
}

lpTypeLib->Release();

return dwResult;
}

BOOL WINAPI EnumTypeLibCallback(int nType, LPCTSTR lpClassName, LPCTSTR lpFunName, ULONG Address, LPARAM lParam)
{
return TRUE;
}

int main(int argc, char* argv[])
{
CoInitialize(NULL);

EnumTypelibFun(_T("d:\\ppstream\\PowerList.ocx"), EnumTypeLibCallback, 0);

CoUninitialize();
return 0;
}
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
newkey 2009-4-4 22:12
4
0
老版本的ida 4.3有com_plugin
但用5.2 SDK编译有些问题,ida的SDK升级到5.2改变较大

oleview可以直接获取idl文件,主要还是想添加到ida中,再用Hex-Rays
游客
登录 | 注册 方可回帖
返回