首页
社区
课程
招聘
[原创]Dll hijack 的另一种编程实现方式及工具
发表于: 2019-3-17 21:42 8498

[原创]Dll hijack 的另一种编程实现方式及工具

2019-3-17 21:42
8498

AheadLib: https://github.com/Yonsm/AheadLib, https://github.com/strivexjun/AheadLib-x86-x64

AddExport: https://bbs.pediy.com/thread-154269.htm

技术上就是:动态加载函数和函数转发。


AheadLib 是动态加载函数; AddExport 是函数转发,不过呢是修改编译后 dll 的方式。

函数转发没见源代码实现方式。于是,就做了这个工具,技术上基于函数转发 ,产生 C 源代码,可修改性高,操作灵活。

编译函数转发 ,完全依赖于 MSVC linker。其它编译器的 linker 不支持函数转发。


举例来说:

主程序 test_dll.c


依赖的 dll 源文件 name_mangling.c

关于Dll hijack,早就有人研究过了:

AheadLib: https://github.com/Yonsm/AheadLib, https://github.com/strivexjun/AheadLib-x86-x64

AddExport: https://bbs.pediy.com/thread-154269.htm

技术上就是:动态加载函数和函数转发。


AheadLib 是动态加载函数; AddExport 是函数转发,不过呢是修改编译后 dll 的方式。

函数转发没见源代码实现方式。于是,就做了这个工具,技术上基于函数转发 ,产生 C 源代码,可修改性高,操作灵活。

编译函数转发 ,完全依赖于 MSVC linker。其它编译器的 linker 不支持函数转发。


举例来说:

主程序 test_dll.c

#include <stdlib.h>
#include <stdio.h>

int __cdecl    _e (int x);
int __cdecl    f (int x);
int __stdcall  g (int x);
int __fastcall h (int x);

int main(int argc, char **argv)
{
    printf("%d\n", _e(1));
    printf("%d\n", f(2));
    printf("%d\n", g(3));
    printf("%d\n", h(4));
    return 0;
}


依赖的 dll 源文件 name_mangling.c

#include <stdlib.h>

__declspec(dllexport) int __cdecl    _e (int x) { return x; }
__declspec(dllexport) int __cdecl    f (int x) { return x; }
__declspec(dllexport) int __stdcall  g (int x) { return x; }
__declspec(dllexport) int __fastcall h (int x) { return x; }

编译后,产生可运行的 test_dll. exe 和 name_mangling.dll。

使用工具,可根据 name_mangling.dll 产生 name_mangling~.c
// Created by hijackdll-helper
/* There should be dll hijacking possible first! */
/* cl.exe /Os /GD /LD /Fe */
/* https://en.wikipedia.org/wiki/Name_mangling */

#include <windows.h>

/*  Don't forward to itself!
    "C:\Windows\System32\version" is acceptable ;p
*/
#define HIJACKED_DLL_NAME "name_mangling_"    //<--- modify

/* gcc does't support this. */
#pragma comment(linker, "/EXPORT:__e="HIJACKED_DLL_NAME"._e,@1")
#pragma comment(linker, "/EXPORT:_g@4="HIJACKED_DLL_NAME"._g@4,@2")
#pragma comment(linker, "/EXPORT:f="HIJACKED_DLL_NAME".f,@3")
#pragma comment(linker, "/EXPORT:h="HIJACKED_DLL_NAME".h,@4")


// Add your implementations here, and comment the forwarders <---

extern int sideload();    //<---

/*  Less dependencies: _DllMainCRTStartup
    More functions: DllMain
    Take care of the core libs yourself: msvcrt, kernel32, ntdll, user32 */
BOOL WINAPI _DllMainCRTStartup(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
	switch (dwReason) {
	case DLL_PROCESS_ATTACH:
		sideload();    //<---
		break;
    /*
	case DLL_PROCESS_DETACH:
        break;
	case DLL_THREAD_ATTACH:
        break;
	case DLL_THREAD_DETACH:
        break;
    */
	}
	return TRUE;
}

旁路 sideload.c
#include <windows.h>

__declspec(dllexport) void sideload (void)
{
    MessageBox (0, "test", "From DLL", MB_ICONINFORMATION);
}

编译后,产生 name_mangling~.dll 和 sideload.dll 。 把原来的 name_mangling.dll 重命名为 name_mangling_.dll,name_mangling~.dll 重命名为 name_mangling.dll,放在一起即可验证劫持。可以使用 depends 查看。

最后,要说的是利用方式,可以有两种: 1,自己实现要修改的函数;2,从 dll 入口(旁路)加载额外的代码(当然把代码写进来也行,不过分离到其它 dll 更易于维护)。 生成的 c 文件中 “<---”标明了主要操作点。

开源地址:https://github.com/lifenjoiner/hijackdll_helper

#include <stdlib.h>
#include <stdio.h>

int __cdecl    _e (int x);
int __cdecl    f (int x);
int __stdcall  g (int x);
int __fastcall h (int x);

int main(int argc, char **argv)
{
    printf("%d\n", _e(1));
    printf("%d\n", f(2));
    printf("%d\n", g(3));
    printf("%d\n", h(4));
    return 0;
}
#include <stdlib.h>

__declspec(dllexport) int __cdecl    _e (int x) { return x; }
__declspec(dllexport) int __cdecl    f (int x) { return x; }
__declspec(dllexport) int __stdcall  g (int x) { return x; }
__declspec(dllexport) int __fastcall h (int x) { return x; }

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2019-3-18 09:35 被walkier编辑 ,原因: 补一下附件。之前明明选了附件的~
上传的附件:
收藏
免费 2
支持
分享
最新回复 (3)
雪    币: 3549
活跃值: (941)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
2
试一下
2019-3-19 11:47
0
雪    币: 190
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
我做了一个类似的软件,用的delphi. 也是动态载入dll转发函数
https://www.yge.me/public/addons/yakeblog/detail/show/id/23.html
有GUI,有源代码,有编译器,直接生成dll文件.(在资源文件里,执行时会自动解压的%tmp%目录)


补充:
编译器用的是DELPHI XE2.

发布后就发现一些bug,比如劫持的DLL导出函数带'_'下划线的会报错.一直没修改.
最后于 2019-3-19 17:49 被yake-job编辑 ,原因:
2019-3-19 17:47
0
雪    币: 314
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2019-3-22 10:30
0
游客
登录 | 注册 方可回帖
返回
//