当我们运行程序时,一般情况下会默认加载Ntdll.dll和Kernel32.dll这两个链接库,在进程未被创建之前Ntdll.dll库就被默认加载了,三环下任何对其劫持都是无效的,除了该Dll外,其他的Dll都是在程序运行时,在输入表中查找到对应关系后才会被装载到内存中的,理论上来说对除NtDll以外的其他库都是可操作的。

工具下载:工具下载地址:http://lyshark.github.io/soft/PETools.zip

而DLL的装载是存在先后顺序的,当系统开机时smss.exe会将系统中常用的DLL缓存到注册表计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs中的位置上,我们可以跳转过去看看里面存放的内容,都是一些常用的函数库。

当指定DLL需要加载时,系统会首先查询该表中是否存在有缓存数据,如果有则就直接调用NtMapViewOfSection函数将其映射到特定进程的内存中,如果没有则就需要根据如下顺序动态的查找。

  1. 先查找,正在加载DLL进程的可执行目录。
  2. 查找系统的system32目录下是否存在。
  3. 查找,正在加载DLL进程的当前目录。
  4. Path环境变量中的定义。

这里就先来演示一下简单的Dll劫持,首先我们必须指定要劫持的Dll文件,将其中的导出函数全部导出来,导出的输入表项目只能比原来的多,不能少,导出的方式有很多,比如可以使用AheadLib等工具,快速生成利用代码,通常可用于劫持的DLL有 lpk.dll,version.dll 等系统DLL,当前程序的第三方DLL同样可以,本教程并不适用AheadLib工具,而是使用GenEAT.exe工具:

1.先来创建一个DLL并导出两个函数,然后创建主程序动态的加载这个DLL。

lyshark.cpp 编译生成为DLL

#include <Windows.h>

extern "C" int __declspec(dllexport)add(int x, int y)
{
return x + y;
} extern "C" int __declspec(dllexport)sub(int x, int y)
{
return x - y;
} extern "C" int __declspec(dllexport)mul(int x, int y)
{
return x * y;
} extern "C" int __declspec(dllexport)divs(int x, int y)
{
return x / y;
} BOOL APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{ return true;
}

编译后使用上次制作的PETools工具,执行命令PETools c://lyshark.dll --ShowExport 可看到其导出的函数。

编译main.cpp 动态加载函数,将lyshark.dll放入同一个目录下即可,程序运行后会动态调用DLL中的导出函数。

#include <stdio.h>
#include <Windows.h> typedef int(*lpAdd)(int, int);
typedef int(*lpSub)(int, int);
typedef int(*lpMul)(int, int);
typedef int(*lpDiv)(int, int); int main(int argc, char *argv[])
{
HINSTANCE DllAddr;
lpAdd addFun; DllAddr = LoadLibrary(L"lyshark.dll"); addFun = (lpAdd)GetProcAddress(DllAddr, "add");
if (NULL != addFun)
{
int res = addFun(100, 200);
printf("结果: %d \n", res);
} FreeLibrary(DllAddr);
system("pause");
return 0;
}

下面就来实现函数转发功能,当程序访问原DLL时直接将请求转发到我们自己的DLL中,我们的DLL再将请求转发到真实的DLL上面,使用本节课的小工具可以快速构建转发函数表,执行如下命令即可:GenEAT.exe -d c://lyshark.dll -c inject.cpp -n Lok

默认会生成如下样子,直接在里面加上一个弹窗,然后编译DLL。

将生成的Dll改名为lyshark.dll把原来的lyshark.dll改为lok.dll

当再次打开时,会先加载弹窗,然后才会完成计算功能,也算是中转成功了。

你可以对其导出函数进行Hook转向,读取参数啥的都没问题,自由发挥吧。

通过中转DLL函数实现DLL劫持的更多相关文章

  1. GO语言 -- 调用DLL函数,填平所有的坑,最详尽攻略

    编译dll文件(源代码c++):g++ -shared main.cpp -o test.dll set GOARCH=386 第一个DLL函数,第一个参数,要求传入一个指针,直接指向[]byte类型 ...

  2. C#中可直接调用WIN32的API函数--USER32.DLL

    Win32的API函数可以直接在C#中直接调用,在做WinForm时还是很有帮助的.有时候直接调用Win32的API,可以很高效的实现想要的效果. using System; using System ...

  3. C#调用C++编写的DLL函数, 以及各种类型的参数传递 (转载)

        C#调用C++编写的DLL函数, 以及各种类型的参数传递 1. 如果函数只有传入参数,比如: C/C++ Code Copy Code To Clipboard //C++中的输出函数 int ...

  4. 在 C++Builder 工程里调用 DLL 函数

    调用 Visual C++ DLL 给 C++Builder 程序员提出了一些独特的挑战.在我们试图解决 Visual C++ 生成的 DLL 之前,回顾一下如何调用一个 C++Builder 创建的 ...

  5. DLL函数中内存分配及释放的问题

    DLL函数中内存分配及释放的问题 最近一直在写DLL,遇到了一些比较难缠的问题,不过目前基本都解决了.主要是一些内存分配引起问题,既有大家经常遇到的现象也有特殊的 情况,这里总结一下,做为资料. 错误 ...

  6. C#动态调用C++编写的DLL函数

    C#动态调用C++编写的DLL函数 动态加载DLL需要使用Windows API函数:LoadLibrary.GetProcAddress以及FreeLibrary.我们可以使用DllImport在C ...

  7. IronPython调用C# DLL函数方法

    C# DLL源码 using System; using System.Collections.Generic; using System.Text; using System.Security.Cr ...

  8. 一个简洁通用的调用DLL函数的帮助类

    本次介绍一种调用dll函数的通用简洁的方法,消除了原来调用方式的重复与繁琐,使得我们调用dll函数的方式更加方便简洁.用过dll的人会发现c++中调用dll中的函数有点繁琐,调用过程是这样的:在加载d ...

  9. dll的概念 dll导出变量 函数 类

    1. DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用. 静态链接库与动态链接库的区别:   (1)静态链接 ...

随机推荐

  1. 记录mysql查询数据遇到的一个小问题

    今天在测试的时候,需要使用mysql对插入的数据进行检验,但是写完查询语句的时候执行会报错.原因很简单,这个表名是order(订单),在MySQL语言中order是用来排序的关键字,原则上讲是不能作为 ...

  2. 【小菜学网络】MTU

    不同的以太网接入设备,一帧能传输的数据量是有差异的. 普通的以太网卡,一帧最多能够传输 1500 字节的数据:而某些虚拟设备,传输能力要打些折扣.此外,链路层除了以太网还有其他协议,这些协议中数据帧传 ...

  3. 医学图像 | DualGAN与儿科超声心动图分割 | MICCAI

    文章转自微信公众号:「机器学习炼丹术」 作者:炼丹兄(已授权) 联系方式:微信cyx645016617(欢迎交流共同进步) 论文名称:"Dual Network Generative Adv ...

  4. C++高精度计算(大整数类)

    Java和Pathon可以不用往下看了 C++的基本数据类型中,范围最大的数据类型不同编译器不同,但是最大的整数范围只有[-2^63-2^63-1](对应8个字节所对应的二进制数大小).但是对于某些需 ...

  5. Protobuf在Cmake中的正确使用

    Protobuf是google开发的一个序列化和反序列化的协议库,我们可以自己设计传递数据的格式,通过.proto文件定义我们的要传递的数据格式.例如,在深度学习中常用的ONNX交换模型就是使用.pr ...

  6. 2018.9.9 nowcoder 普及组第一场

    2018.9.9 nowcoder 普及组第一场 C-括号 题目大意:一个只包含左右括号的字符串\(S\),希望删掉S中若干个字符,使得剩下的字符串是一个合法的括号串,有多少不同的方案. Soluti ...

  7. apk签名、包名

    //通过各手机管理软件,如如360.豌豆荚等查看 //使用命令行,可以查看到permission.packagename.title.versionCode等 aapt dump badging ~/ ...

  8. Codeforces Round #545 B. Circus

    题面: 传送门 题目描述: 马戏团中一共有N个人(N是偶数),有的人会扮演小丑,有的人会表演杂技.给出每个人会什么,然后按照下列规则把这些人分成两组: 每个人只能在其中一组 两个组的人数相等(也就是把 ...

  9. Bug调试专项练习三笔记

    前言:大家需要将文件夹中"有问题的代码" 导入到自己的工作空间中一. 训练一: 正确效果:首先要求大家导入给大家的项目, 给项目的"虚拟路径" 设定为" ...

  10. 根据数据渲染DOM树形菜单——中途感想

    根据数据渲染DOM树形菜单,这个需求做了几天了.一开始觉得用while也可以实现一层一层查找数据,但后来发现while还是做不到,因为我查找这个动作必须有进入有出来然后进入下一个条目,但while只能 ...