Finally, after a break during the May Day holiday, I completed the patch repair work on idaclang.exe by myself.
idaclang_fix.7z
// VCRUNTIME140_1_for_idaclang.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include <pro.h>
#include <idp.hpp>
#include <idd.hpp>
#include <typeinf.hpp>
#include "../ldr/pe/pe.h"
#include <clang-c/Index.h>
#include "Hook.h"
BEGIN_NAMESPACE_EX(UCode)
CAtlTypedPtrList<CXCursor*> t_lst_pcursor;
CAtlTypedPtrList<CXCursorVisitor> t_lst_Real_visitor;
enum CXChildVisitResult My_CXCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
{
t_lst_pcursor.AddTail(&cursor);
CXCursorVisitor Real_visitor = t_lst_Real_visitor.GetTail();
CXChildVisitResult ret = Real_visitor(cursor, parent, client_data);
t_lst_pcursor.RemoveTail();
return ret;
}
unsigned (*Real_clang_visitChildren)(CXCursor parent, CXCursorVisitor visitor, CXClientData client_data);
unsigned My_clang_visitChildren(CXCursor parent, CXCursorVisitor visitor, CXClientData client_data)
{
CXCursorVisitor visitor_bak = visitor;
t_lst_Real_visitor.AddTail(visitor);
visitor = My_CXCursorVisitor;
unsigned ret = Real_clang_visitChildren(parent, visitor, client_data);
t_lst_Real_visitor.RemoveTail();
return ret;
}
__int64(__fastcall* Real_visitVTableComponents_Callback)(int type, CXCursor* pcursor, __int64* a3);
__int64 __fastcall My_visitVTableComponents_Callback(int type, CXCursor* pcursor, __int64* a3)
{
t_lst_pcursor.AddTail(pcursor);
__int64 ret = Real_visitVTableComponents_Callback(type, pcursor, a3);
t_lst_pcursor.RemoveTail();
return ret;
}
bool (ida_export* Real_create_tinfo)(tinfo_t* _this, type_t bt, type_t bt2, void* ptr);
bool ida_export My_create_tinfo(tinfo_t* _this, type_t bt, type_t bt2, void* ptr)
{
if (bt == BT_FUNC && bt2 == BT_FUNC)
{
func_type_data_t* p = (func_type_data_t*)ptr;
CXCursor& cursor = *t_lst_pcursor.GetTail();
//CXCursorKind kind = clang_getCursorKind(cursor);
CXType funcType = clang_getCursorType(cursor);
CXCallingConv callingConv = CXCallingConv_Invalid;
if (funcType.kind == CXType_Typedef)
{
// 获取 typedef 的基础类型
CXType underlyingType = clang_getTypedefDeclUnderlyingType(cursor);
CXTypeKind underlyingTypeKind = underlyingType.kind;
// 检查基础类型是否是函数原型类型 (FunctionProto) 或函数非原型类型 (FunctionNoProto)
// 或者是指向这些函数类型的指针类型
CXType typeToInspect = underlyingType;
if (underlyingTypeKind == CXType_Pointer)
{
// 如果是函数指针,我们需要获取它指向的类型
CXType pointeeType = clang_getPointeeType(underlyingType);
if (pointeeType.kind == CXType_FunctionProto || pointeeType.kind == CXType_FunctionNoProto)
{
typeToInspect = pointeeType;
}
}
if (typeToInspect.kind == CXType_FunctionProto || typeToInspect.kind == CXType_FunctionNoProto)
{
callingConv = clang_getFunctionTypeCallingConv(typeToInspect);
}
}
else
{
callingConv = clang_getFunctionTypeCallingConv(funcType);
}
if (callingConv != CXCallingConv_Invalid)
{
switch (callingConv)
{
case CXCallingConv_X86StdCall:
p->cc = CM_CC_STDCALL;
break;
case CXCallingConv_C:
p->cc = CM_CC_CDECL;
break;
case CXCallingConv_X86ThisCall:
p->cc = CM_CC_THISCALL;
break;
case CXCallingConv_X86FastCall:
p->cc = CM_CC_FASTCALL;
break;
case CXCallingConv_X86Pascal:
p->cc = CM_CC_PASCAL;
break;
default:
ATLASSERT(FALSE);
break;
}
}
else
{
ATLASSERT(callingConv != CXCallingConv_Invalid);
}
}
bool result = Real_create_tinfo(_this, bt, bt2, ptr);
return result;
}
void StartMyWork()
{
//MessageBox(NULL, "Attach me?", "提示", MB_ICONWARNING);
TCHAR szAppName[MAX_PATH];
GetAppFileName(NULL, szAppName, _countof(szAppName));
if (_tcsicmp(szAppName, _T("idaclang.exe")))
{
return;
}
HMODULE hmod_libclang_dll = LoadLibrary(_T("..\\..\\libclang.dll"));
if (hmod_libclang_dll)
{
unsigned (*pfn_clang_visitChildren)(CXCursor parent, CXCursorVisitor visitor, CXClientData client_data) = (unsigned int(__cdecl*)(CXCursor, CXCursorVisitor, CXClientData))GetProcAddress(hmod_libclang_dll, "clang_visitChildren");
if (pfn_clang_visitChildren)
{
_HookFunction_With_CommitImmediately(pfn_clang_visitChildren, My_clang_visitChildren, (void**)&Real_clang_visitChildren);
}
}
HMODULE hmod_idaclang_exe = GetModuleHandle(_T("idaclang.exe"));
{
PBYTE pcbCode = 0x00007FF68B4F3350 - 0x7FF68B4F0000 + (PBYTE)hmod_idaclang_exe;
_HookFunction_With_CommitImmediately(pcbCode, My_visitVTableComponents_Callback, (void**)&Real_visitVTableComponents_Callback);
}
{
PBYTE pcbCode = 0x00007FF68B52DAD0 - 0x7FF68B4F0000 + (PBYTE)hmod_idaclang_exe;
_HookFunction_With_CommitImmediately(pcbCode, My_create_tinfo, (void**)&Real_create_tinfo);
}
}
void EndMyWork()
{
TCHAR szAppName[MAX_PATH];
GetAppFileName(NULL, szAppName, _countof(szAppName));
if (_tcsicmp(szAppName, _T("idaclang.exe")))
{
return;
}
HMODULE hmod_idaclang_exe = GetModuleHandle(_T("idaclang.exe"));
if (Real_create_tinfo)
{
PBYTE pcbCode = 0x00007FF68B52DAD0 - 0x7FF68B4F0000 + (PBYTE)hmod_idaclang_exe;
_UnhookFunction_With_CommitImmediately(pcbCode, My_create_tinfo, (void**)&Real_create_tinfo);
}
if (Real_visitVTableComponents_Callback)
{
PBYTE pcbCode = 0x00007FF68B4F3350 - 0x7FF68B4F0000 + (PBYTE)hmod_idaclang_exe;
_UnhookFunction_With_CommitImmediately(pcbCode, My_visitVTableComponents_Callback, (void**)&Real_visitVTableComponents_Callback);
}
if (Real_clang_visitChildren)
{
HMODULE hmod_libclang_dll = GetModuleHandle(_T("..\\..\\libclang.dll"));
if (hmod_libclang_dll)
{
unsigned (*pfn_clang_visitChildren)(CXCursor parent, CXCursorVisitor visitor, CXClientData client_data) = (unsigned int(__cdecl*)(CXCursor, CXCursorVisitor, CXClientData))GetProcAddress(hmod_libclang_dll, "clang_visitChildren");
if (pfn_clang_visitChildren)
{
_UnhookFunction_With_CommitImmediately(pfn_clang_visitChildren, My_clang_visitChildren, (void**)&Real_clang_visitChildren);
}
}
}
}
END_NAMESPACE_EX