今日接到一逆向需求,要求修改一个按钮的功能。
初以为是较为常见的功能,仔细看过后才发现该软件采用了自研的二级框架
不过所幸软件的安全措施较为薄弱,经历了整整一天的折腾后终于打通,便在此处留个随笔做记录。

关键函数定位

先通过拆包和pe头分析,找出可疑xml文件,查看后发现为ui文件,于是通过该文件名在ida进行查找

同时一路分析代码调用,最终定位到了以下片段:

 

 

 

 

 

 

 

通过对其他dll模块进行分析,最终定位到该函数名为onSavePictureFileMenuClick,位于NTCourseExt.dll中

DLL注入

通过vs创建dll项目,再通过extern “C”等标识符导出目标函数。最后生成dll
再通过StudyPE在导入表中将测试dll及相关函数注入即可。

汇编hook

dll经进程弹窗检测注入成功,但是因为UI框架是对方自研,没法用现成的API进行按钮捕获,于是只能寄希望于修改汇编的函数调用来实现功能修改。
通过在ida中的分析,我们快速在x64dbg中定位到了相关call回调代码:

编者在此处尝试通过相对地址来调用所,但因为alsr等问题导致再次打开的时候变会出现寻址错误的问题

再关闭alsr中,相同的问题因系统原因仍无法避免。于是编者又开始尝试通过IAT表检索函数入口地址再进行导入,同样由于该段的空间有限。同时对IAT表的操作存在困难,此路不通,放弃。

DLL劫持与函数转发

既然汇编层面没有手段,那是否能通过劫持dll来做到对onSavePictureFileMenuClick()函数的重写呢?
于是编者开始研究起了DLL转发。
假设现在有a.exe与b.dll,那么dll转发就是做一个假的b.dll进去,然后充当中间商给真正的dll通信
也就变成了 a.exe b.dll(假的转发dll) c.dll(真正的b.dll改名而来)
而要进行dll转发,也就是要在假的dll中为b.dll中所有的函数建立信道,就编者目测这个dll库至少有数千条函数
于是果断放弃了人工编写,转而看向生成工具。这里编者推荐的是:SharpDllProxy
项目地址:https://github.com/Flangvik/SharpDllProxy
按照README.md使用该库,最终生成了专用于dll劫持的C语言文件:

对代码进行适应性修改后构建项目,测试生成的dll可完美充当exe与原生库的握手人,dll转发成功。

再通过微软提供的detour库编写代码实现函数的拦截重写:

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){

switch (fdwReason){

case DLL_PROCESS_ATTAC:{

// 在 DLL 加载时,使用 Microsoft Detours 修改被转发的函数地址

HMODULE moduleHandle = GetModuleHandle(L”NTCourseExt.dll”);

OriginalFunctionType originalFunction = reinterpret_cast<OriginalFunctionType>(GetProcAddress(moduleHandle, “?onSavePictureFileMenuClick@NTCourseEditView@NTCourseExt@@AEAAXXZ”));

OriginalFunctionType* originalFunctionPtr = &originalFunction;

DetourTransactionBegin();

DetourUpdateThread(GetCurrentThread());

DetourAttach(reinterpret_cast<void**>(originalFunctionPtr), reinterpret_cast<void*>(&onSavePictureFileMenuClick));

DetourTransactionCommit();

}

break;

 

case DLL_PROCESS_DETACH:{

// 在 DLL 卸载时,恢复被转发的函数地址

HMODULE moduleHandle = GetModuleHandle(L”NTCourseExt.dll”);

OriginalFunctionType originalFunction = reinterpret_cast<OriginalFunctionType>(GetProcAddress(moduleHandle, “?onSavePictureFileMenuClick@NTCourseEditView@NTCourseExt@@AEAAXXZ”));

OriginalFunctionType* originalFunctionPtr = &originalFunction;

DetourTransactionBegin();

DetourUpdateThread(GetCurrentThread());

DetourDetach(reinterpret_cast<void**>(originalFunctionPtr), reinterpret_cast<void*>(&onSavePictureFileMenuClick));

DetourTransactionCommit();

}

break;

}

return TRUE;

}

再次构建dll,进行测试,功能修改成功且运行正常。项目收尾完结。