00:00
今天呢,咱们主要讲一下如何去开发一个动态连接库,以及呢,如何去把这个动态连接库进行这个正常的调用,以及注入的调用啊,那我们首先呢,要来了解啊,就是我们类似于这种程序啊,它呢,我们在运行的时候呢,实际上不止我们看到的这么一个点EE这么一个东西啊,就像是我们在写程序的时候啊,我们打开一个啊,比如说我们打开一个这个随便一个程序啊,这是我们上节课讲的,我把这些东西我先去掉一下啊,那么这时候呢,比如说我现在呢,我就调用一个这个非常简单的程序啊,就是box。啊麦A好,那现在呢,我首先它的这个几个参数呢,我简单给它填一下,比如说啊,我们用了这个数啊,用了这个数,那么这个数它里来的呢?它这个数来源是什么呢?是操作系统啊,来源是操作系统,操作系统说提供给我们的,那它如何提供给我们的,它提供了一个叫做SDK的一个东西啊,SDK的一个东西,那么这个东西呢,我们是什么呢?我们可以来简单的这个,呃,百度一下啊,看看它的定义SDK啊,你可以看到啊,这个SDK一般指的是软件开发工具包啊,也就是说呢,一定的这个开发工具的一个集合,那这个呢,就是我们的这个SDK啊,我微软提供给我们这个东西呢,就是SDK,然后呢,我们在使用的时候呢,实际上是依赖于什么呢?我们的项目属性里边啊,这有一个叫做Windows SDK的。
01:38
这个版本啊,那它里边有不同的各各种不同的这个版本的SDK啊,那实际上我们是依赖于这个东西的,那么我们也可以在哪看到呢?我们可以在我们的控制面板里啊,可以在这个,呃,我看一下啊,应该是应用里啊,然后我们找到我们的这个visual studio啊,我们找到我们的visual studio一个这个安装的啊,然后我们点击修改。我们点击啊。
02:03
那这个时候你可以看到啊,它有这么一个界面啊,你可以点击一下修改,点击完修改之后呢,它上面呢,就会给你显示出来你可以修改的一些项,那这时候呢,它里边是工作符和按照这个某一个类别来分的啊,你可以点一下它的这个单个组件,在单个组件里边,你可以看到它其实有非常非常非常多的这个SDK的,你可以看到这有SDK库和框架上面这些都比如说是一些这个卓的SDK,然后底下呢,还有一些这个的一个SDK在底下呢,这这部分呢,就什么这部分就是卓这个的一个SK,比如这有这个8.1的啊,然后有十的,包括这个十的不同的小版本啊,比如说一个14393啊,还有17763啊,还有10240这些呢,都是细分的什么呢?细分的SDK版本啊,根据不同的SDK版本,你可以调用它里边的一个东西啊,它里边呢,可能会有一些这个细微的差异啊,但是差异一般情况下呢,是不太大的,那我们了解了这个SDK的这个概念之后呢,我们再了解一个概念就是什么呢?就叫做API的这么一个概念啊,那我们还是啊,我们使用这个。
03:04
来查询一下API这么一个东西啊,API啊是什么呢?是应用程序啊,可以以这个计算机系统交换信息命令的一个工具集啊,其实这些东西没什么实际的意义啊,我们这个API通常情况下呢,就是什么?其实就是我们操作系统好的代码给我们开放出来,什么开放的啊,开放的函数接口啊,我们这些函数呢,都是由操系统啊提供给我们的,比如说我们ma bos啊,弹一个啊这种呢,都是我们操作系统给我们提供的,那么这些东西呢,都是在哪的呢?其实呢,都是在一个个的动态啊,动态链接库里啊提供的啊,那你说它所有的东西都是动态链接库里的代码吧,实际上不是啊,这里边涉及到一个叫做这个系统调用的这么一个概念啊,系统调用的一个概念,我们所有的这个API呢,有两,大致上分为两类,一类API呢,需要干嘛呢,需要这个去调用内核里的这个代码,一部分API呢,不需要啊啊所以说呢,这个里边也分为两种啊,它是根据这。
04:04
这个系统调用来决定的啊,通常情况下呢,如果是我们的32位呢,它会调用一个这个c enter啊,如果是64位呢,会调用一个这个CS,那如果说是比较早期的呢,还有用这个in特啊,用这个中来进入内核啊,来进行系统调用呢,去调用内核里的这个函数啊,因为什么?因为比如说我们这个有一个这个,呃,就以这个open而言啊,那如果说你这个open啊,它这个数啊,它实际上而在三环呢,只是做一个这个参数采集的作用,然后呢,它通过这个中转啊,然后呢,通过中转再进入什么呢?再去查找SSDD表,然后再进入这个内核去查找内核函数去调用,那这是一系列系统调用的一个过程,那我们现在呢,不深究那么深啊,我们现在只了解什么呢?只了解它在三环啊,也就是我们应用层的情况下啊,这个函数是哪来的,那通常情况下呢,这些东西呢,都是在我们的动态链接库里提供的啊,那这个动态链接库呢,也是可以查询到的,比如说我们这个。
05:04
可你就可以直接按F1啊,然后来看他MSDN里是如何说明的,一般情况下呢,在MSIDN的最后呢,它会给你一个说明性的文档,一个要求啊,比如说啊,它这个最低收支持的客户端啊,和这个最低是收支的服务器啊,它这个版本操作系统啊,目标平台啊,然后这个标头啊,你可以看到啊,这个使用它还需要什么样的一个头文件啊,它理论上应该用这个window.h但是实际上window.h包括在了这个windows.h里边,所以说一般同学你你包含一个windows.h就可以用了,但是呢,它实际上而言是在哪呢?它如果是静态库的情况下呢,它是u432.lab里,它如果是动态库的情况下呢,它在什么呢?在这个u432.d里啊,就是这个意思啊,那我们现在呢,就要知道了,它这个实际上是在动态链接库里边的啊,那我们这个是操作系统动态链链接库,如果说是我们自己的动态链接库,我们写一个函数提供给别人,我们不给,不想给别人源码的情况下,我们提供别人库也可以的啊,当然了,一般情况下,如果你是提供给别人用的情况下,你是提供这个静态库啊。
06:04
然后我们现在呢,教大家呢,是一个动态库的一个编写,我们首先呢,在文件这点击新建,点击项目啊,点击项目,点击项目之后呢,它现在呢,有一个这个呃选择,那么这个时候呢,你选择这个Windows缩面,它里边有一个这个叫做动态链接库的一个选项啊,当然你可以选择这个静态库,不是不是这个静态库来编写一个这个静态的啊,然后这儿还有一个具有导出项的啊,那我们使用这个这个就可以了,动态链接库就可以了,其实你可以使用这个空项目啊,也可以创建出来啊,没有什么实际上一个区别,那么现在呢,我们就选择这个动态链接库,然后呢,名字随意啊,然后我们直接点确定,确定之后呢,那现在呢,就会给你创建出一个带有最基本的啊,最基本的入口点的一个这个动态链接库的一个文件啊,那这个动态链接库的文件是什么意思呢?首先这个D妹啊d ma呢,实际上而言就是什么呢?就相当于我们动态链接库的一个入口,这个是动态链接库的一个入口,但是实际上而你像是我们那些啊,真正的A那种东西,它实际上。
07:04
不是在这里边进行处理的,它实际上是一种叫做导出函数的东西,导出函数的东西,那么这里边呢,涉及到一定的PE的知识啊,PE文件的支持,PE文件呢,就是我们Windows的一个这个可执行文件的一个格式啊,包括我们的这个ESE啊,D啊,还有我们的SYS这个驱动模块,它实际上都是属于P文件,那如果说你了解P文件的情况下,你应该知道P文件里边有一个东西叫做导出表啊,导出表,那么这个导出表里边呢,就是你别你这个别人,你或者别人提供给外界的一些东西啊,那比如说我现在呢,用一个load PE啊,我现在把它打开。我把这个load PE呢,也转到我的这个虚拟机里啊,我直接啊拷贝一下。好,我把它呢换个地方啊。
08:12
好,现在我们打开它打开之va之后呢,我们把这个这个程序,我把它拿上来,现在呢,你看到的就是一个PE文件的一个头信息,那么这个头信息里边呢,我们现在呢,就可以看到里边的一些这个相关信息了,比如说区段啊,或者说是这个目录啊,或者其他东西,我们点目录之后,你可以看到啊,它就是有这个输入表,导出表啊,资表例外什么乱七八糟的一些东西啊,还有重定位啊资源之类的,那我们现在呢,看到就是它的导出表,比如说我点这你可以看到它是没有导出表的,这为什么呢?因为它现在它是一个什么ESE程序,ESE程序一般情况下没有导出表,但是也有特殊情况,那我们什么样的情况下呢,是有导出表呢?比如说我现在呢,来到我的Windows下啊,来找到一个我的这个SYSTEM32啊,SYSTEM32WINDOWS system32啊,SYSTEM32在这儿呢。啊,我进去进去之后呢,比如说我现在呢,我就找到一个这个。
09:04
我看我找不到找找得到啊,我找一个这个动态链接库啊,熟悉一点的。啊,这呢,U432看到了吧?啊,然后我拖进去啊,我把它的这个关掉啊,然后关掉,我把U432拖进去,拖进去之后点开啊,我们现在点击这个目录啊,我把这个目录点开,目录点开之后,你现在看到它的有一个输出表,输出表,那我这个输出表你可以看到就里边就有什么,有各种各样的它的一些这个函数啊,函数这些呢,就是什么呢?就是UC32提供给我们,我们可以调用的UC32的里边的一些函数啊,你可以看到啊,就是这么多啊,可以看到里边有非常非常非常非常多的啊,就是这是一类啊,一般情况下我们系统里边啊,都是按照这个类别来分的,比如说U332它是归类于一类啊,然后这个CTR32是一类啊,然后GDS32是一类啊,然后还有什么其他的一些东西啊,这些库,然后呢,它有输导入就有导导出就有导入嘛,你看这还有导入表,导入什么意思呢?比如说啊,我使我在我的这个代码里使用的这个macbos啊,那这个时候实际上而言就是我这个程序啊,在这个UC32的这个库里边导入了什么呢?导入了我的这个ma box这个函数啊,实际上就是这个意思啊,那这个呢是系统的概念,那如果说我们自己写。
10:15
那也是类似的一个概念啊,那我们就需要干嘛呢,我们就需要声明导出函数啊,让它有导出,那比如说现在呢,我如果说我这个默,呃,我把它关掉啊,我默认的我这个动态链接库啊,我现在给它进行一个设置啊,我看一下你说什么。呃,为什么很多都是使用2017 2019 20222022,我不是,我知道是为什么2022,一般情况下它是兼容性有问题,呃,我们是不不用最新的啊,永远不用最新的东西啊,但是如果说2019的话,其实无所谓啊,2019现在兼容性已经跟上了啊,那这个就不知道为什么了啊,然后呢,我原来是用2015啊,之所以不用2015,用2017了,是因为我电脑装不上2015了。然后呢,我们给它改一下MTD,然后这样呢,我们就可以了,可以之后呢,我们给它重新生成。
11:05
重生成功了啊,然后我们右键打开,打开它的所在文件夹,然后在他的这个B目录下啊,把他的动态链接库拿到,拿到之后呢,我们还是用这个load PE啊,然后呢,来看一下,现在呢,它的这个目录里,你可以看到它的导出表实际上是空的啊,你看没有导出的内容,为什么呢?因为我没有写导出的内容啊,现在呢,我们就可以给它添加导出的内容,比说我现在呢,在这新建一个头文件啊,新建项啊,我直接建一个新建头文件,然后这是一个标准的一个标头啊,比如说我这是一个这个嗯。呃,就随便写个名字啊,然后点击添加,添加之后呢,现在呢,我就来实现一个函数啊,我就实现一个啊,首先我要ten啊ten一下这个C之所以叫ten c呢,这是因为我们现在呢,是以一个C加加的形式来编写它的这个动态链接库的,那么C加加呢,它有一个机制叫什么呢?叫做这个名称名称粉碎机制啊如如果说你不是不声明为SC的方式进行导出的情况下啊,那么这个时候你在你的导出表里头看到的这个名字呢,它是一个碎片化的一个东西,那么这个时候你就没有办法去利用它了啊,所以说呢,你要给它声明成C,然后呢,给它声明成导出的啊,用关键字给它声明导出的。
12:24
D。P好,导出函数啊,导出函数,然后呢,比如说我写一个啊ABD2个函数啊,两个参数in number AB int啊,Number啊我这个呃,ADDDD呢,我给它加一个东西啊,省着混淆啊,我给他用一个2K啊2K,然后现在呢,我快速重建啊,创建它的生命与定义啊,它直接在这给我创建出了一个这个我的函数,然后点CP啊,我现在呢,在我的函数点CP里进行实现,那么这个时候呢,我就可以干嘛呢来实现的,那么我们就可以干嘛呢?我们可以直接啊首先呢在这儿啊给它计算一下对不对啊,我可以啊我的加法嘛,我就直接把这两个东西啊,这个加法给它返回啊,把它的功能简单实现出来对不对啊好,实现出来之后呢,我现在的这个函数就已经成功导出了啊,我们右键啊来重新生成。
13:20
重新正常之后呢,我们就可以把它给拖出来啊,拖出来拖出来之后呢,现在呢,我们来看到它的这个动态镜库啊,动态库已经生成了啊,我们还是打开这个DR啊DR呢我们拖进去,拖进之后我们点击目录,你可以看到它现在就有输出表了,然后我们点开啊,点开看你看我们输出表的函数名是不是就是我们刚才声明出来的这个RKD,那么我们有了这个东西之后呢,我们就可以对它呢进行一个使用了啊,我们直接把它复制出来,复制出来之后呢,放到我们的这个想要调用的啊这个部分的这个呃,同步录下,如果是你在开发过程中,就放在你的这个代码的同步录下,如果是已经这个编程好了,你就放在exe的目录下啊,这是有区别的,然后比如说你刚才那个函数你是怎么用的啊,那现在有两种方式,一种方式你就把文供给他,那种情况下你就可以直接用文去调用,那如果是没有条文件的情况下呢,你就需要干嘛呢?你需要用函数指针啊,直接一个,然后把它的函数指针啊声明出来。
14:21
星啊星什么呢?星那个我想想啊,刚才叫什么玩意儿来着,算了,随便吧。FRK啊,AB in。啊,这样呢,给它声明出一个函数指针,然后呢,我们现在呢,就想要给它加载进来,怎么办啊,怎么用啊对不对,那我就要用两个函数,一个叫做第一个叫做什么叫做load library啊load library啊,我可以使用一个load library a,然后呢,这个函数呢,它是干嘛?它是加载动态链接库的,或者说叫显示加载动态链接库的,它返回是什么?是动态链接库的一个句柄,也可以说是动态链接库的一个加载机制,然后呢,它的这个类这个这个参数什么呢?它这个参数呢,就是我们的这个动态研究库的名字或者说路径啊,那我现在呢就给他啊填写上。
15:20
呃,叫什么来着。好,然后呢,它会返回一个什么呢?返返回一个这个模块句柄嘛,H mod u,好好返回一个模块句柄之后,现在呢,我们就已经拿到了模块的句柄,或者说加载机制,接下来呢,我们调用一个叫做get啊pcs address,然后现在呢,这个函数,它的第一个参数就是模块的一个这个模块的一个句柄啊,你这个东西在哪个模块里,我传进去,传去之后呢,它第二个参数呢,是你要找到函数的一个函数名啊,那我们刚才函数名叫什么呢?叫做RK对不对啊,所以说填在这儿,填在这之后呢,它呢有一个返回值,返回值呢,返回的是一个函数类型,那么这个时候呢,你就使用这个函数指针啊,然后来进行声明啊,比如说我现在呢是我的一个函数,等于什么呢?等于它啊,但是呢,它返回的虽然是一个地址,但是类型与它不符,这个时候你需要用函数指针对它的返回类型进行一个强制性的转换,转换完事之后,现在呢,你就可以对它进行一个调用了,比如说我现在传一个一啊。
16:30
诶传一个一啊,传一个二,然后这个时候呢,我就可以啊再用一个这个int,比如说啊res啊,我给它接收,接收完事之后,我给它对它进行一个输出。好,现在呢,我们来进行一个运行。啊,上面这个有弹窗啊,我忘了弹窗注释了,你可以看到啊,他现在输出的就是三对不对啊,说明我们这个动态库里的函数已经被我们重新成功的给他调用了啊,我们这个输出也就成功了,那么这个学完之后,我们就可以干嘛呢?就是在我们动态链接库里头啊去实现功能,然后提供给给其他人去使用,或者说呢,你不想让自己的ESE过于臃肿,那么这个时候呢,你就也可以这样做,而且呢,我们现在呢,把它关掉之后,我们可以再来看一下我们ESE。
17:26
我们这是我们的ESE程序,我们用我们的load PE,现在来看一下这个exe程序啊,我们给它拖进去,这时候你点击目录,你再看它的导入表啊,导入表你看现在导入表里边它会多一个啊,诶没有呢啊,我不对,它现在不会有啊,为什么不会有呢?因为我们这个是使用的这个动态加载的方式啊,是使用动态加载的方式啊,不是那种静态加载的方式,所以它不会有啊,我们是动态加载library啊。呃,大家没点关注的点点关注啊,然后直播回放可以联系咱们老板来领取,咱们有汇编Python系统编程等等的啊,这个公开课啊都可以领取回放。
18:08
然后有这个课程咨询的也可以联系咱们老板啊,然后每周六周日都会有这个直播啊,然后可以关注一下啊,点关注不迷路啊,这个我看一下刚才有什么说的啥。导入表是啥是吧?导入表就是我们文件的一个,呃,格式里边的一个表啊,我们文件里头有很多表,就像我们刚才看到这个啊,我们用P可以点进去看一下。还有这个目录,目录里边有很多很多表,输出表,也就是导出表,就是什么?就是我们动态链接库,刚才我们声明的内容啊,给提供给别人用的,然后呢,我们这个导入表是什么呢?就是我们啊用了哪个动态链接库里边的动态链接库和什么呢?和哪个动态链接库里边的这个函数看到没啊,就这个意思啊。好,那我们现在呢,就已经了解完了这套东西了啊,我们现在呢,再做一个简单的小实验,我们现在呢,调用自己的这个东西肯定是没有问题了,那么接下来呢,我们来调用一下S啊,调用S,大家可能说大家我这个东西有什么好调用的对不对,我直接调用就完事了啊,现在呢,我们使用什么呢?我们就使用不直接调用的方式啊,我们还是使用函数值N啊,怎么使用函数N呢?首先呢,我们通过这个load library a啊,我们把它这个模块加载出来啊,我们刚才已经知道了它是在哪啊,它是在我们的这个U的D里,所以说我们现在啊,动态的把这个U32我们给它加载进来。
19:34
然后接下来呢,我们啊调用啊,调用这个get PL address啊获取它的函数啊,首先第一个把它模块句柄传进去,第二个呢,我们就填写我们ma boxs a的一个名字啊,现在开始寻找啊,在它里边进行寻找,寻找之后呢,它进行返回,那这个函数指针呢,因为不是我们自己写的,我们可以有更轻松的方式找到它这个函数指针的内容,我们直接X12跟进去,看到它的这个它的这个原型啊,直接把它原型拷贝出来,拷贝出来之后呢,我们在这个win API前面加一括号,在它A后边加个括号,然后中间加个星,然后把它名字啊稍微改一下啊,跟原来的名字不一样,省的冲突啊,这就完事了啊,然后我们在这儿啊使用它啊,对它呢,进行一个获取啊,我们等于。
20:27
比如说我现在一个MSD啊,等于看嗯啊,我忘加type饭了啊,前面要加一个type饭啊,要给生物名称名啊,要不然的话它不是一个类型,好,现在呢,你可以看到啊,它是MSC就有了啊,接下来我要对它进行一个强制转换啊,强制接收成我们自己想要的一个类型,那么这个时候因为我接收到了它的这个地址啊,所以说呢,我这个MSC就可以当做ma boxx a来使用了啊,现在我们直接对它进行一个调用。
21:13
我们运行一下啊。你可以看到啊,也正常的调用了,对不对啊,没有任何问题,这说明什么呢?说明我们这种方式和刚才这种直接调用的没有什么实际上的区别,甚至于呢,你可以直接对他们呢,进行一个打印啊,就是print啊,Print f啊,然后呢,我们怎么打印呢?就是直接啊,比如说我现在是这个MC啊,它这个我函数指帧N的形式啊,那获取到的地址是什么哦,百分号大X啊,然后杠刚杠,那这个呢,我就直接打印一下MS的一个地址,那么接下来我还可以再打印一个什么呢?再打印一下max啊,它原来的一个地址啊,咱们以前就说过啊,Ma box就是函数啊,它本身的名字啊,就是什么呢?就是它的一个地址,那么这个时候我们想要打印ma Bo a的一个地址可以怎么样啊,就直接啊干嘛呢,去把他的名字拿过来,然后直接打印就行了啊,这种的能寻找到的,你就可以直接用啊,我们运行。
22:09
诶,你看啊,打印了,打印完事之后,你可以看到这两个地址啊,是一包一样的两个地址啊,就说明什么呢?我们自己加载的和这个我们直接调用的啊,实际上是没有区别的。好,然后呢,我们接着讲啊,就是我们。这是什么?这是属于正常加载啊,正常加载就是直接一个显示的动态加载,那如果说我们不想这么加载啊,我们想玩点别的,比如说我们想要在这个一个已经运行的这个进程里啊,来直接再执行一下这个动态间接库,可不可以呢?可以,那这个时候就用到了什么呢?就不是导出函数了,这里边导出函数就没有用了,为什么呢?因为它没有这个调用啊,没有调用啊,我们在内部它没有调用,但是其实也可以有机会调用,但是我们不想这么做,我们可以干嘛呢?你可以看到这不是一个D嘛,它是一个动态链接库的一个入口,那底下这几个是什么,这底下几是实际是就是什么,其实就是它的一个执行的时机,你比如这个这就是什,这个就是你刚刚注入到进程的候啊,那么这个case里的内容就会执行,这个是啊,附加到这个线程上的时候啊,它就会执行,这个是什么?这是从线程剥离的时候啊,它会执行,这个是从进程剥离的时候,它会执行,注意什么呢?你用它的时候,最好给每一个分支都加上啊,不然的话有时候它会不执行。
23:31
好,那么比如说我们现在呢,就让这个我们这个里边啊,我们点一下这个,我们写一个注入程序,然后把它注入到这里边儿去执行啊,那怎么怎么做呢?比如说我先把这个麦boss啊给写在这儿。
24:10
好,现在想完之后呢,我现在在这个下边,那它的执行时机就是什么呀,就在我附加到进程上的时候啊,就开始执行对不对,好那么我们重新生成,重新生成之后呢,我把它的这个可视程文件拿出来啊,在这啊。我给他拿出来,放到我桌面上。那接下来我想要给它注入进去啊,那我可以有两种方式,一种呢,就是我使用成熟的注入器,比如说我在这应该就是我放了个注入器来着,我看一下在哪。啊,这事啊。啊,算了,咱们不用代码路由器了,咱们直接写一个吧。好,咱们直接写一个啊,咱们就直接用这个来写一个吧,啊,那我顺便也能讲一下它注入的原理是什么,我把这个东西清掉。
25:10
那我们现在呢,写一个函数啊,它返回的是一个布尔值,当然你可以不返回啊,我们就是这个进行注入,那我们进行注入呢,需要两个东西,一个呢,就是它注入的一个进程ID。然后还需要一个什么呢?还需要一个这个路径。好,那我们注入的原理是什么呢?其实注入原理就是load library啊,就是library啊,我们现在呢,来看一下啊,Library这个东西我们前两节课啊,我们讲过了啊,讲过了进程,讲过了线程,讲了内存,那我们现在呢,就要把它这些知识啊,给它综合起来啊,进行一个这个组合应用啊,我们已经学过线程了啊,我们如何在本地开启一个线程,大家应该都已经知道了,就是create three对不对,那么create threead啊等re啊create three它这边有一个这个回调函数,这个对不对啊,这个回调函数我们把它的原形拿出来啊,拿出来你可以看一下它的原形长这样。
26:25
这是它的原型,对不对,那我们load library长什么样呢?我把load library的原型也拿出来啊,Load library诶在这儿。看啊,这是load library的原型,我们把它们之间呢,稍微改一下,让它们更为接近啊,这个是函数指针啊,所以说我们把它改成不是函数指针的一个状态,这个是什么?这实际上就是一个现成的一个call back。好,那么我们这两个东西放这之后呢,我们来进行一个简单的一个对比啊,那么这个是现成的回调函数,这个是load library,那么我们这块它是一个沃的,这是一个H啊,这个我们的一个这个模块聚柄,或者说模块加载机值,那么际上而言,我们这个函数这个东西,我们F12直接跟进去,它是这个东西,那这个东西呢,我们再往上跟是它啊,然后它实际上是一个什么东西呢?这个东西我告诉大家,它实际上就是一个四字节的整数啊,当然啊,这个是前提是什么呢?前提是啊,叉八六状态下,叉八六状态下它实际上就是一个四阶整数,那沃是什么东西啊,是不是也是一个四阶32位的一个整数啊,所以说他们俩返回值是一模一样的,然后中间都是什么API,它实际就是什么,就是SD啊S的一个调用约定,所以调用约定是一样的函数名这个无所谓啊,啥样都行,接着啊,我们这个的调啊。
27:47
是什么呢?是一个lp word,也就是一块内存地址,这是什么?LPCWSTR,这个F12跟进去你会发现它其实就是一个W叉,W叉那么它也是一块内存地址,也就是说我们这俩函数在忽略数名的情况下几乎是可以通用的,那么也就是说你完全可以把这个load library当做什么,当做create three的一个回调函数来进行使用,那么这种情况下我们就知道了啊,我们创建线程可以用这个加载,可以这个直接把load library当回调函数使用。那么我们有一个问题,我们可不可以在远程的这个其他进程体内创建线程的答案是可以的啊,这还有一个函数啊。
28:33
这个就是创建远程线程,也就是在目标的啊进程体内啊,在目标的进程体内创建一个这个线程啊,那它的这个原始的原型啊,它这个这个就是我们这个start address啊,这个原型实际上跟我们本地线程是一样的,也就是说它也可以用load library啊来作为这个。Load library啊来作为什么呢?来作为回调函数,那么底下这个是什么?它的参数是不是一个libraryp word,那这个就是可以干嘛呢?可以把我们L这个load library的参数啊,那它的参数啊,一个这个内存空间给它传过去啊,那所以说呢,我们大致上而言啊,会有这么一个流程啊,我们首先第一步是要打开打开这个目进程获取句柄,然后第二步呢,是在这个目标进程体内申请空间啊啊这个申请空间是干什么的呢?第三步啊,写入啊这个library所需要的D啊,这个路径啊,DL路径啊,你要把这个路径写到目标的进程体内,然后呢,你在这个调用远程线程创建的时候,你调用这个load library啊,然后它就可以在目标的体内内存内找到这个字符串了,你写到自己的那个空间内是没有用的,因为在这个有一个内存隔离,你们两个不能互相这个找,所以。
29:56
你需要把这个目标啊给写到目标的体内,那么这个时候呢,这是第三步啊,写入动态链接库,第四步,第四步写入之后了,你现在要干嘛呢?创建啊创建远程线程对不对?创建远程线程执行啊执行logo library回调对吧?执行回调,执行回调完事之后干嘛呢?第五步啊,你就可以干嘛呢?等待啊等待啊执行结束,等待远程线程。
30:30
线程啊,执行结束,那么它执行结束了,实际上就是什么呀?是不是其实就是load library返回了啊,是不是load返回了啊,这个其实就这意思,然后再接下来第六步啊,直接啊释放啊释放空间,然后第七步啊释放句柄,然后第八步返回结果,这就是一个完整的一个注入流程啊,那我们一步一步来实现,首先我们打开目标获取句柄,我们直接啊使用一个什么open process。
31:09
Open打开这个进程啊,那我们第一个首先呢,我们要获取什么样的权限,我们给他一个完整权限,一个all的一个权限,第二返回的句柄是否继承不继承,第三个你要打开的进程,进程ID是什么啊,那这个进程ID我们就来看一下我们MFC这个程序,它的进程ID是多少,奖励信息我们直接来找啊,C开头的。在这儿啊,2848。好,接着呢,它会返回什么?返回一个句柄啊,返回一个句柄,一个进程句柄,这就是第一步啊,打开目标进程,获取到它的进程句柄啊,然后接下来呢,我们就要来在目标体内申请空间,对不对,我们上节课讲了啊,我们如果使用这个lo啊,就是在本进程内啊申请空间如果使用lo ex就是在目标进程内开启空间,它们的区别就是第一个参数是不是进程句柄,然后我们把进程地表传进去,第二个参数啊,地址我们不指定地址随机分配啊no,第三个我们有一个长度啊,我们给他一个0S100逐够分配了啊接下来内存的一个属性。
32:29
诶。啊,不是啊,写错了,Re res。好,然后内存属性之后啊,就是它的页属性啊,我们因为要往里写东西,所以说呢,你要给他一个这个redw的一个可读可写好,那这样呢,就申请完了,申请完事之后呢,它会返回一个地址空间啊,一个指针,你就一个lp word啊给他接收一下。
33:08
好,然后呢,写入第二路径,这个呢,就调用一个远程写入的一个函数啊,就是跨进程写入的函数啊,We prices memory这些呢,都属于什么,都属于调试API,所以它可以跨进程啊,然后第一个参数还是把我们的这个进程句柄传进去啊,写入哪个进程,然后第二个参数啊,你要写到哪里去啊,就肯定写入到这里去,第三个参数啊,就是你这个啊要写什么,我们就把路径写进去,第四个你要写多长啊,那这块呢,计算一下它有多长WCS嫩啊,然后计算一下我们的它。计算完事之后,你要给它进行一个加一,然后加完一之后给它套起来,套起来再乘以一个二。
34:03
好,然后呢,这是长度,接下来呢,就是它实际上写入了多长啊,那它需要一个这个底word,或者说S-T啊,那我们直接使用一个S-T啊来写。S啊Y,我们给它初始化成零,然后呢,直接取地址啊传进去,这是由这个API我们填写的,那这里呢,你可以判断它返回是否成功,也可以不判断,如果判断的话呢,就给它加一个,然后接下来如果判断啊if。等于等于false啊,那就是失败了,或者说给他弹个窗也行啊。
35:18
好,如果说没有失败的情况下,我们就创下一步啊,创建远程线程,执行回调啊,创建远程线程啊,然后呢,它里边。第一个啊,还是要执行这个创建的啊,进程句柄啊,我们给它放进去。放进去第二个是你的一个安全属性啊,这个属性我们直接闹掉,然后第三个啊,是这个占尺寸啊,我们也给它闹掉,第四个啊,就是我们的回调函数,我们直接啊给他写一个这个low啊low library。我们给他写个load library w,然后呢,因为类型不符,你要进去把它回调的类型复制出来,然后呢,直接啊给它进行一个强转,这样就符了,完之后下一个就是它的参数,Low library的参数,就第二个路径啊,你现在呢,已经写入到这个地址上去了,就直接把这个地址传进来,传进来之后呢,我们现在呢,就已经写完了,剩下两个参数直接传到就可以了啊,创建完远程线程,创建完远程线程之后呢,现在呢,你要等待它的这个线程执行结束,所以说呢,你要得到一个什么呢?这个线程的一个线程距柄。
36:28
好,那我们在这儿呢,就使用一个这个等待。他的等待无限等待是负一啊,但是他有一个这个。啊,这个单词啊,这个单词可以是一个红啊,比负一好看啊,语义化更强啊,其实就是负一啊,然后我们等待啊,无限等待,等待它回来啊,等待他回来之后,如果他回来了啊,就是我的low瑞,其实就是执行结束了,然后呢,我这可以调用什么呢?调用我远程的释放啊v free。
37:10
Ex,然后首先第一个参数啊,哪个进程啊,你要释放哪个进程啊,你要把这个进程句表传进去啊,H process,然后第二啊,你要释放的地址啊,你把这个地址给传进去,然后第三个啊,第三个是这个size,因为我们要用的是memory这个release,所以你要传个零啊,接下来呢,是这个内存属性啊,我们直接一个memory release对它进行释放,接着呢,我们要释放句柄啊,我们直接一个close啊close handle,我们首先呢要把我们上边的这个h process啊释放掉,然后呢,我们刚才创建远程线程,还产生了一个线程句柄,也就是我们的S10瑞的,我们也要给它释放掉,然后呢,最后返回结果如果成功了,我们这返回的是一个处,那如果说没成功,在这个位置就失败了,那我们在这个位置return的是false。
38:06
好,理论上这个玩意儿就完事了啊,那接下来呢,我们在底下啊,对它呢,进行一个调用,我们首先啊当这啊,对这儿的这个不写死啊,这块呢,我们应该在这里啊,我们在这里传入啊,而这呢,我们的静态ID呢,是使用一个参数的方式进行传递啊,然后呢,首先是它接着呢是我们动态电辑库的路径啊,我们去采用一下我们桌面上的一个路径。
39:11
嗯。Constant啊,这要加一个好啊,我们给它修饰一下,然后现在呢就已经完事了啊,那我们现在呢,简单来测试一下啊,看看它会不会弹出来啊,如果弹出来它就直接弹了啊,我们现在呢,直接一运行。诶,运行完事之后,你可以看到啊,这弹出了一个窗啊,你可以看到在底下和我们correct它是属于同一个这个栏目下的,所以说它确实属于它里边的啊,我们直接点确定。好,那我们就已经成功的把我们的动态金库注入进去了啊,然后呢,我们这个今天要讲的就这两个部分,一部分就是我们使用手动的啊,我们给它进行一个这个load library一个显示加载,另一种呢,就是使用注入的形式把它注入进去,以及啊我们这个动态验库写的时候,它的时机都是什么意思啊,然后现在呢,如果说啊,有需要这个直播回放的啊,然后还有这个往期的直播回放啊,包括我们的汇编Python温度系统编程啊,可以直接联系咱们的老马啊,然后呢,我们呃,没点关注的点点关注,每周六日啊都会有这个直播。
我来说两句